diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst" b/.nojekyll similarity index 100% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst" rename to .nojekyll diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/README.md" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/README.md" deleted file mode 100644 index 1bf3c58fb0a07b6bcf01d2071b0e00dc049cf896..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/README.md" +++ /dev/null @@ -1,29 +0,0 @@ -# my-g2-study - -## Project setup -``` -yarn install -``` - -### Compiles and hot-reloads for development -``` -yarn run serve -``` - -### Compiles and minifies for production -``` -yarn run build -``` - -### Run your tests -``` -yarn run test -``` - -### Lints and fixes files -``` -yarn run lint -``` - -### Customize configuration -See [Configuration Reference](https://cli.vuejs.org/config/). diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/babel.config.js" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/babel.config.js" deleted file mode 100644 index e9558405fdcc02f12d757acb308e02937a7444f1..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/babel.config.js" +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - presets: [ - '@vue/cli-plugin-babel/preset' - ] -} diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/package.json" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/package.json" deleted file mode 100644 index ccd465f62eeda935ce2cfe93a960bf8fc71e7d6b..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/package.json" +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "my-g2-study", - "version": "0.1.0", - "private": true, - "scripts": { - "serve": "vue-cli-service serve", - "build": "vue-cli-service build", - "lint": "vue-cli-service lint" - }, - "dependencies": { - "@antv/data-set": "^0.10.2", - "@antv/g2": "^3.5.11", - "core-js": "^3.4.3", - "echarts": "^4.5.0", - "less": "^3.10.3", - "less-loader": "^5.0.0", - "node-less": "^1.0.0", - "style-loader": "^1.1.1", - "vue": "^2.6.10" - }, - "devDependencies": { - "@vue/cli-plugin-babel": "^4.1.0", - "@vue/cli-plugin-eslint": "^4.1.0", - "@vue/cli-service": "^4.1.0", - "babel-eslint": "^10.0.3", - "eslint": "^5.16.0", - "eslint-plugin-vue": "^5.0.0", - "vue-template-compiler": "^2.6.10" - }, - "eslintConfig": { - "root": true, - "env": { - "node": true - }, - "extends": [ - "plugin:vue/essential", - "eslint:recommended" - ], - "rules": {}, - "parserOptions": { - "parser": "babel-eslint" - } - }, - "browserslist": [ - "> 1%", - "last 2 versions" - ] -} diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/public/index.html" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/public/index.html" deleted file mode 100644 index c0f8389c56dadbb640f8e2c22ea5bb58d2866d93..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/public/index.html" +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - my-g2-study - - - -
- - - diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/App.vue" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/App.vue" deleted file mode 100644 index fccdd0563c52dab1e0e81b660f285fc64498ab84..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/App.vue" +++ /dev/null @@ -1,150 +0,0 @@ - - - - - diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/assets/logo.png" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/assets/logo.png" deleted file mode 100644 index f3d2503fc2a44b5053b0837ebea6e87a2d339a43..0000000000000000000000000000000000000000 Binary files "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/assets/logo.png" and /dev/null differ diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/bardeposit.vue" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/bardeposit.vue" deleted file mode 100644 index 5206293e82b73b58cb851a46b4fd40c5bafb20e6..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/bardeposit.vue" +++ /dev/null @@ -1,102 +0,0 @@ - - - - - diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/barliability.vue" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/barliability.vue" deleted file mode 100644 index 43c50cf65b78e65f52189bca4e8e047777535f29..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/barliability.vue" +++ /dev/null @@ -1,97 +0,0 @@ - - - - - \ No newline at end of file diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/barservice.vue" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/barservice.vue" deleted file mode 100644 index 76212378b6c3d424a283c8c9b158becd55e2159c..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/barservice.vue" +++ /dev/null @@ -1,144 +0,0 @@ - - - - - diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/map.vue" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/map.vue" deleted file mode 100644 index 6e9257c6f5744feb9fae6ffa368d8302f051c5bd..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/map.vue" +++ /dev/null @@ -1,290 +0,0 @@ - - - - - diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/piedeposit.vue" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/piedeposit.vue" deleted file mode 100644 index a3856fef2c1b75b1a4ca0342aaaf230ac14164a4..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/piedeposit.vue" +++ /dev/null @@ -1,90 +0,0 @@ - - - - - \ No newline at end of file diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/radar.vue" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/radar.vue" deleted file mode 100644 index 3a54299d4febfd410b19c025b519eb22289a747d..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/radar.vue" +++ /dev/null @@ -1,136 +0,0 @@ - - - - - \ No newline at end of file diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/textdata.vue" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/textdata.vue" deleted file mode 100644 index 0d86148ad7bd6488bc8b145cc6f412f071566a0d..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/charts/textdata.vue" +++ /dev/null @@ -1,27 +0,0 @@ - - - - - diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/components/HelloG2.vue" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/components/HelloG2.vue" deleted file mode 100644 index ea080896fa44edbab3a4320c7f7d6433ed486e81..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/components/HelloG2.vue" +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/components/echarts/Index.vue" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/components/echarts/Index.vue" deleted file mode 100644 index 7ccfa25fe4d4219cc2f63e255cbc1f6445edd478..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/components/echarts/Index.vue" +++ /dev/null @@ -1,89 +0,0 @@ - - - - - diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/main.js" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/main.js" deleted file mode 100644 index 507763a980a07f5472d8aca52eb96112d25cf096..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/src/main.js" +++ /dev/null @@ -1,11 +0,0 @@ -import Vue from 'vue' -import App from './App.vue' - -Vue.config.productionTip = false -import echarts from 'echarts' - -Vue.use(echarts) - -new Vue({ - render: h => h(App), -}).$mount('#app') diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/yarn.lock" "b/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/yarn.lock" deleted file mode 100644 index 567a1d5955b75c96751e9c4c3a4bfcd86b39e0bf..0000000000000000000000000000000000000000 --- "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/yarn.lock" +++ /dev/null @@ -1,8678 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@antv/adjust@~0.1.0": - version "0.1.1" - resolved "https://registry.npm.taobao.org/@antv/adjust/download/@antv/adjust-0.1.1.tgz#e263ab0e1a1941a648842fc086cf65a7e3b75e98" - integrity sha1-4mOrDhoZQaZIhC/Ahs9lp+O3Xpg= - dependencies: - "@antv/util" "~1.3.1" - -"@antv/attr@~0.1.2": - version "0.1.2" - resolved "https://registry.npm.taobao.org/@antv/attr/download/@antv/attr-0.1.2.tgz#2eeb122fcaaf851a2d8749abc7c60519d3f77e37" - integrity sha1-LusSL8qvhRoth0mrx8YFGdP3fjc= - dependencies: - "@antv/util" "~1.3.1" - -"@antv/component@~0.3.3": - version "0.3.8" - resolved "https://registry.npm.taobao.org/@antv/component/download/@antv/component-0.3.8.tgz?cache=0&sync_timestamp=1576810844174&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40antv%2Fcomponent%2Fdownload%2F%40antv%2Fcomponent-0.3.8.tgz#677ecd3b5026907d4cb70d9082951d7c3c2b5434" - integrity sha1-Z37NO1AmkH1Mtw2QgpUdfDwrVDQ= - dependencies: - "@antv/attr" "~0.1.2" - "@antv/g" "~3.3.5" - "@antv/util" "~1.3.1" - wolfy87-eventemitter "~5.1.0" - -"@antv/coord@~0.1.0": - version "0.1.0" - resolved "https://registry.npm.taobao.org/@antv/coord/download/@antv/coord-0.1.0.tgz#48a80ae36d07552f96657e7f8095227c63f0c0a9" - integrity sha1-SKgK420HVS+WZX5/gJUifGPwwKk= - dependencies: - "@antv/util" "~1.3.1" - -"@antv/data-set@^0.10.2": - version "0.10.2" - resolved "https://registry.npm.taobao.org/@antv/data-set/download/@antv/data-set-0.10.2.tgz#584a9574e7e0853847cb658d51b9f7345a00032f" - integrity sha1-WEqVdOfghThHy2WNUbn3NFoAAy8= - dependencies: - "@antv/hierarchy" "~0.4.0" - "@antv/util" "~1.3.1" - d3-array "~1.2.0" - d3-composite-projections "~1.2.0" - d3-dsv "~1.0.5" - d3-geo "~1.6.4" - d3-geo-projection "~2.1.2" - d3-hexjson "~1.0.1" - d3-hierarchy "~1.1.5" - d3-sankey "~0.7.1" - d3-voronoi "~1.1.2" - dagre "~0.8.2" - point-at-length "~1.0.2" - regression "~2.0.0" - simple-statistics "~6.1.0" - topojson-client "~3.0.0" - wolfy87-eventemitter "~5.1.0" - -"@antv/g2@^3.5.11": - version "3.5.11" - resolved "https://registry.npm.taobao.org/@antv/g2/download/@antv/g2-3.5.11.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40antv%2Fg2%2Fdownload%2F%40antv%2Fg2-3.5.11.tgz#bd17f4911618671f115a249af410d3bb1c932e5e" - integrity sha1-vRf0kRYYZx8RWiSa9BDTuxyTLl4= - dependencies: - "@antv/adjust" "~0.1.0" - "@antv/attr" "~0.1.2" - "@antv/component" "~0.3.3" - "@antv/coord" "~0.1.0" - "@antv/g" "~3.3.6" - "@antv/scale" "~0.1.1" - "@antv/util" "~1.3.1" - venn.js "~0.2.20" - wolfy87-eventemitter "~5.1.0" - -"@antv/g@~3.3.5", "@antv/g@~3.3.6": - version "3.3.6" - resolved "https://registry.npm.taobao.org/@antv/g/download/@antv/g-3.3.6.tgz#11fed9ddc9ed4e5a2aa244b7c8abb982a003f201" - integrity sha1-Ef7Z3cntTloqokS3yKu5gqAD8gE= - dependencies: - "@antv/gl-matrix" "~2.7.1" - "@antv/util" "~1.3.1" - d3-ease "~1.0.3" - d3-interpolate "~1.1.5" - d3-timer "~1.0.6" - wolfy87-eventemitter "~5.1.0" - -"@antv/gl-matrix@^2.7.1", "@antv/gl-matrix@~2.7.1": - version "2.7.1" - resolved "https://registry.npm.taobao.org/@antv/gl-matrix/download/@antv/gl-matrix-2.7.1.tgz#acb8e37f7ab3df01345aba4372d7942be42eba14" - integrity sha1-rLjjf3qz3wE0WrpDcteUK+QuuhQ= - -"@antv/hierarchy@~0.4.0": - version "0.4.0" - resolved "https://registry.npm.taobao.org/@antv/hierarchy/download/@antv/hierarchy-0.4.0.tgz#712b5b4477ee0b8b8db174c682b5356b0411aab6" - integrity sha1-cStbRHfuC4uNsXTGgrU1awQRqrY= - dependencies: - "@antv/util" "~1.3.1" - -"@antv/scale@~0.1.1": - version "0.1.3" - resolved "https://registry.npm.taobao.org/@antv/scale/download/@antv/scale-0.1.3.tgz#4876e6140cb7dcda190e7fe2e780882dcac6b09d" - integrity sha1-SHbmFAy33NoZDn/i54CILcrGsJ0= - dependencies: - "@antv/util" "~1.3.1" - fecha "~2.3.3" - -"@antv/util@~1.3.1": - version "1.3.1" - resolved "https://registry.npm.taobao.org/@antv/util/download/@antv/util-1.3.1.tgz#30a34b201ff9126ec0d58c72c8166a9c3e644ccd" - integrity sha1-MKNLIB/5Em7A1YxyyBZqnD5kTM0= - dependencies: - "@antv/gl-matrix" "^2.7.1" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": - version "7.5.5" - resolved "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" - integrity sha1-vAeC9tafe31JUxIZaZuYj2aaj50= - dependencies: - "@babel/highlight" "^7.0.0" - -"@babel/core@^7.7.4": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/core/download/@babel/core-7.7.7.tgz#ee155d2e12300bcc0cff6a8ad46f2af5063803e9" - integrity sha1-7hVdLhIwC8wM/2qK1G8q9QY4A+k= - dependencies: - "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.7" - "@babel/helpers" "^7.7.4" - "@babel/parser" "^7.7.7" - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - convert-source-map "^1.7.0" - debug "^4.1.0" - json5 "^2.1.0" - lodash "^4.17.13" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/generator@^7.7.4", "@babel/generator@^7.7.7": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/generator/download/@babel/generator-7.7.7.tgz#859ac733c44c74148e1a72980a64ec84b85f4f45" - integrity sha1-hZrHM8RMdBSOGnKYCmTshLhfT0U= - dependencies: - "@babel/types" "^7.7.4" - jsesc "^2.5.1" - lodash "^4.17.13" - source-map "^0.5.0" - -"@babel/helper-annotate-as-pure@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-annotate-as-pure/download/@babel/helper-annotate-as-pure-7.7.4.tgz?cache=0&sync_timestamp=1574466005922&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.7.4.tgz#bb3faf1e74b74bd547e867e48f551fa6b098b6ce" - integrity sha1-uz+vHnS3S9VH6Gfkj1UfprCYts4= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-builder-binary-assignment-operator-visitor/download/@babel/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz?cache=0&sync_timestamp=1574465920635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-builder-binary-assignment-operator-visitor%2Fdownload%2F%40babel%2Fhelper-builder-binary-assignment-operator-visitor-7.7.4.tgz#5f73f2b28580e224b5b9bd03146a4015d6217f5f" - integrity sha1-X3PysoWA4iS1ub0DFGpAFdYhf18= - dependencies: - "@babel/helper-explode-assignable-expression" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-call-delegate@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-call-delegate/download/@babel/helper-call-delegate-7.7.4.tgz?cache=0&sync_timestamp=1574465922326&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-call-delegate%2Fdownload%2F%40babel%2Fhelper-call-delegate-7.7.4.tgz#621b83e596722b50c0066f9dc37d3232e461b801" - integrity sha1-YhuD5ZZyK1DABm+dw30yMuRhuAE= - dependencies: - "@babel/helper-hoist-variables" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-create-class-features-plugin@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-create-class-features-plugin/download/@babel/helper-create-class-features-plugin-7.7.4.tgz#fce60939fd50618610942320a8d951b3b639da2d" - integrity sha1-/OYJOf1QYYYQlCMgqNlRs7Y52i0= - dependencies: - "@babel/helper-function-name" "^7.7.4" - "@babel/helper-member-expression-to-functions" "^7.7.4" - "@babel/helper-optimise-call-expression" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.7.4" - "@babel/helper-split-export-declaration" "^7.7.4" - -"@babel/helper-create-regexp-features-plugin@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-create-regexp-features-plugin/download/@babel/helper-create-regexp-features-plugin-7.7.4.tgz#6d5762359fd34f4da1500e4cff9955b5299aaf59" - integrity sha1-bVdiNZ/TT02hUA5M/5lVtSmar1k= - dependencies: - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.6.0" - -"@babel/helper-define-map@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-define-map/download/@babel/helper-define-map-7.7.4.tgz#2841bf92eb8bd9c906851546fe6b9d45e162f176" - integrity sha1-KEG/kuuL2ckGhRVG/mudReFi8XY= - dependencies: - "@babel/helper-function-name" "^7.7.4" - "@babel/types" "^7.7.4" - lodash "^4.17.13" - -"@babel/helper-explode-assignable-expression@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-explode-assignable-expression/download/@babel/helper-explode-assignable-expression-7.7.4.tgz#fa700878e008d85dc51ba43e9fb835cddfe05c84" - integrity sha1-+nAIeOAI2F3FG6Q+n7g1zd/gXIQ= - dependencies: - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-function-name@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-function-name/download/@babel/helper-function-name-7.7.4.tgz?cache=0&sync_timestamp=1574465630791&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.7.4.tgz#ab6e041e7135d436d8f0a3eca15de5b67a341a2e" - integrity sha1-q24EHnE11DbY8KPsoV3ltno0Gi4= - dependencies: - "@babel/helper-get-function-arity" "^7.7.4" - "@babel/template" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-get-function-arity@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-get-function-arity/download/@babel/helper-get-function-arity-7.7.4.tgz#cb46348d2f8808e632f0ab048172130e636005f0" - integrity sha1-y0Y0jS+ICOYy8KsEgXITDmNgBfA= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-hoist-variables@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-hoist-variables/download/@babel/helper-hoist-variables-7.7.4.tgz?cache=0&sync_timestamp=1574466005056&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-hoist-variables%2Fdownload%2F%40babel%2Fhelper-hoist-variables-7.7.4.tgz#612384e3d823fdfaaf9fce31550fe5d4db0f3d12" - integrity sha1-YSOE49gj/fqvn84xVQ/l1NsPPRI= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-member-expression-to-functions@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-member-expression-to-functions/download/@babel/helper-member-expression-to-functions-7.7.4.tgz#356438e2569df7321a8326644d4b790d2122cb74" - integrity sha1-NWQ44lad9zIagyZkTUt5DSEiy3Q= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-module-imports/download/@babel/helper-module-imports-7.7.4.tgz#e5a92529f8888bf319a6376abfbd1cebc491ad91" - integrity sha1-5aklKfiIi/MZpjdqv70c68SRrZE= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-module-transforms@^7.7.4", "@babel/helper-module-transforms@^7.7.5": - version "7.7.5" - resolved "https://registry.npm.taobao.org/@babel/helper-module-transforms/download/@babel/helper-module-transforms-7.7.5.tgz#d044da7ffd91ec967db25cd6748f704b6b244835" - integrity sha1-0ETaf/2R7JZ9slzWdI9wS2skSDU= - dependencies: - "@babel/helper-module-imports" "^7.7.4" - "@babel/helper-simple-access" "^7.7.4" - "@babel/helper-split-export-declaration" "^7.7.4" - "@babel/template" "^7.7.4" - "@babel/types" "^7.7.4" - lodash "^4.17.13" - -"@babel/helper-optimise-call-expression@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-optimise-call-expression/download/@babel/helper-optimise-call-expression-7.7.4.tgz?cache=0&sync_timestamp=1574465630779&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-optimise-call-expression%2Fdownload%2F%40babel%2Fhelper-optimise-call-expression-7.7.4.tgz#034af31370d2995242aa4df402c3b7794b2dcdf2" - integrity sha1-A0rzE3DSmVJCqk30AsO3eUstzfI= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-plugin-utils@^7.0.0": - version "7.0.0" - resolved "https://registry.npm.taobao.org/@babel/helper-plugin-utils/download/@babel/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" - integrity sha1-u7P77phmHFaQNCN8wDlnupm08lA= - -"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": - version "7.5.5" - resolved "https://registry.npm.taobao.org/@babel/helper-regex/download/@babel/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351" - integrity sha1-CqaCT3EAouDonBUnwjk2wVLKs1E= - dependencies: - lodash "^4.17.13" - -"@babel/helper-remap-async-to-generator@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-remap-async-to-generator/download/@babel/helper-remap-async-to-generator-7.7.4.tgz#c68c2407350d9af0e061ed6726afb4fff16d0234" - integrity sha1-xowkBzUNmvDgYe1nJq+0//FtAjQ= - dependencies: - "@babel/helper-annotate-as-pure" "^7.7.4" - "@babel/helper-wrap-function" "^7.7.4" - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-replace-supers@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-replace-supers/download/@babel/helper-replace-supers-7.7.4.tgz?cache=0&sync_timestamp=1574465645820&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-replace-supers%2Fdownload%2F%40babel%2Fhelper-replace-supers-7.7.4.tgz#3c881a6a6a7571275a72d82e6107126ec9e2cdd2" - integrity sha1-PIgaamp1cSdactguYQcSbsnizdI= - dependencies: - "@babel/helper-member-expression-to-functions" "^7.7.4" - "@babel/helper-optimise-call-expression" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-simple-access@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-simple-access/download/@babel/helper-simple-access-7.7.4.tgz#a169a0adb1b5f418cfc19f22586b2ebf58a9a294" - integrity sha1-oWmgrbG19BjPwZ8iWGsuv1ipopQ= - dependencies: - "@babel/template" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-split-export-declaration@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-split-export-declaration/download/@babel/helper-split-export-declaration-7.7.4.tgz#57292af60443c4a3622cf74040ddc28e68336fd8" - integrity sha1-Vykq9gRDxKNiLPdAQN3Cjmgzb9g= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-wrap-function@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-wrap-function/download/@babel/helper-wrap-function-7.7.4.tgz#37ab7fed5150e22d9d7266e830072c0cdd8baace" - integrity sha1-N6t/7VFQ4i2dcmboMAcsDN2Lqs4= - dependencies: - "@babel/helper-function-name" "^7.7.4" - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helpers@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helpers/download/@babel/helpers-7.7.4.tgz#62c215b9e6c712dadc15a9a0dcab76c92a940302" - integrity sha1-YsIVuebHEtrcFamg3Kt2ySqUAwI= - dependencies: - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/highlight@^7.0.0": - version "7.5.0" - resolved "https://registry.npm.taobao.org/@babel/highlight/download/@babel/highlight-7.5.0.tgz?cache=0&sync_timestamp=1562245140883&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhighlight%2Fdownload%2F%40babel%2Fhighlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" - integrity sha1-VtETEr2SSPphlZHQJHK+boyzJUA= - dependencies: - chalk "^2.0.0" - esutils "^2.0.2" - js-tokens "^4.0.0" - -"@babel/parser@^7.0.0", "@babel/parser@^7.7.4", "@babel/parser@^7.7.7": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/parser/download/@babel/parser-7.7.7.tgz#1b886595419cf92d811316d5b715a53ff38b4937" - integrity sha1-G4hllUGc+S2BExbVtxWlP/OLSTc= - -"@babel/plugin-proposal-async-generator-functions@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-async-generator-functions/download/@babel/plugin-proposal-async-generator-functions-7.7.4.tgz?cache=0&sync_timestamp=1574465892135&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.7.4.tgz#0351c5ac0a9e927845fffd5b82af476947b7ce6d" - integrity sha1-A1HFrAqeknhF//1bgq9HaUe3zm0= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.7.4" - "@babel/plugin-syntax-async-generators" "^7.7.4" - -"@babel/plugin-proposal-class-properties@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-class-properties/download/@babel/plugin-proposal-class-properties-7.7.4.tgz#2f964f0cb18b948450362742e33e15211e77c2ba" - integrity sha1-L5ZPDLGLlIRQNidC4z4VIR53wro= - dependencies: - "@babel/helper-create-class-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-proposal-decorators@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-decorators/download/@babel/plugin-proposal-decorators-7.7.4.tgz?cache=0&sync_timestamp=1574466411881&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-decorators%2Fdownload%2F%40babel%2Fplugin-proposal-decorators-7.7.4.tgz#58c1e21d21ea12f9f5f0a757e46e687b94a7ab2b" - integrity sha1-WMHiHSHqEvn18KdX5G5oe5Snqys= - dependencies: - "@babel/helper-create-class-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-decorators" "^7.7.4" - -"@babel/plugin-proposal-dynamic-import@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-dynamic-import/download/@babel/plugin-proposal-dynamic-import-7.7.4.tgz?cache=0&sync_timestamp=1574465998853&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.7.4.tgz#dde64a7f127691758cbfed6cf70de0fa5879d52d" - integrity sha1-3eZKfxJ2kXWMv+1s9w3g+lh51S0= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.7.4" - -"@babel/plugin-proposal-json-strings@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-json-strings/download/@babel/plugin-proposal-json-strings-7.7.4.tgz?cache=0&sync_timestamp=1574466003110&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.7.4.tgz#7700a6bfda771d8dc81973249eac416c6b4c697d" - integrity sha1-dwCmv9p3HY3IGXMknqxBbGtMaX0= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.7.4" - -"@babel/plugin-proposal-object-rest-spread@^7.7.7": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-object-rest-spread/download/@babel/plugin-proposal-object-rest-spread-7.7.7.tgz?cache=0&sync_timestamp=1576716808008&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.7.7.tgz#9f27075004ab99be08c5c1bd653a2985813cb370" - integrity sha1-nycHUASrmb4IxcG9ZTophYE8s3A= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.7.4" - -"@babel/plugin-proposal-optional-catch-binding@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-optional-catch-binding/download/@babel/plugin-proposal-optional-catch-binding-7.7.4.tgz?cache=0&sync_timestamp=1574466000999&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.7.4.tgz#ec21e8aeb09ec6711bc0a39ca49520abee1de379" - integrity sha1-7CHorrCexnEbwKOcpJUgq+4d43k= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" - -"@babel/plugin-proposal-unicode-property-regex@^7.7.7": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-unicode-property-regex/download/@babel/plugin-proposal-unicode-property-regex-7.7.7.tgz#433fa9dac64f953c12578b29633f456b68831c4e" - integrity sha1-Qz+p2sZPlTwSV4spYz9Fa2iDHE4= - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-async-generators@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-async-generators/download/@babel/plugin-syntax-async-generators-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.7.4.tgz#331aaf310a10c80c44a66b238b6e49132bd3c889" - integrity sha1-MxqvMQoQyAxEpmsji25JEyvTyIk= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-decorators@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-decorators/download/@babel/plugin-syntax-decorators-7.7.4.tgz#3c91cfee2a111663ff3ac21b851140f5a52a4e0b" - integrity sha1-PJHP7ioRFmP/OsIbhRFA9aUqTgs= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-dynamic-import@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-dynamic-import/download/@babel/plugin-syntax-dynamic-import-7.7.4.tgz#29ca3b4415abfe4a5ec381e903862ad1a54c3aec" - integrity sha1-Kco7RBWr/kpew4HpA4Yq0aVMOuw= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-json-strings@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-json-strings/download/@babel/plugin-syntax-json-strings-7.7.4.tgz#86e63f7d2e22f9e27129ac4e83ea989a382e86cc" - integrity sha1-huY/fS4i+eJxKaxOg+qYmjguhsw= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-jsx@^7.2.0", "@babel/plugin-syntax-jsx@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-jsx/download/@babel/plugin-syntax-jsx-7.7.4.tgz?cache=0&sync_timestamp=1574466421110&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-jsx%2Fdownload%2F%40babel%2Fplugin-syntax-jsx-7.7.4.tgz#dab2b56a36fb6c3c222a1fbc71f7bf97f327a9ec" - integrity sha1-2rK1ajb7bDwiKh+8cfe/l/Mnqew= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-object-rest-spread@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-object-rest-spread/download/@babel/plugin-syntax-object-rest-spread-7.7.4.tgz#47cf220d19d6d0d7b154304701f468fc1cc6ff46" - integrity sha1-R88iDRnW0NexVDBHAfRo/BzG/0Y= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-optional-catch-binding/download/@babel/plugin-syntax-optional-catch-binding-7.7.4.tgz#a3e38f59f4b6233867b4a92dcb0ee05b2c334aa6" - integrity sha1-o+OPWfS2IzhntKktyw7gWywzSqY= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-top-level-await@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-top-level-await/download/@babel/plugin-syntax-top-level-await-7.7.4.tgz#bd7d8fa7b9fee793a36e4027fd6dd1aa32f946da" - integrity sha1-vX2Pp7n+55OjbkAn/W3RqjL5Rto= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-arrow-functions@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-arrow-functions/download/@babel/plugin-transform-arrow-functions-7.7.4.tgz?cache=0&sync_timestamp=1574465864396&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.7.4.tgz#76309bd578addd8aee3b379d809c802305a98a12" - integrity sha1-djCb1Xit3YruOzedgJyAIwWpihI= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-async-to-generator@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-async-to-generator/download/@babel/plugin-transform-async-to-generator-7.7.4.tgz?cache=0&sync_timestamp=1574465889738&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.7.4.tgz#694cbeae6d613a34ef0292713fa42fb45c4470ba" - integrity sha1-aUy+rm1hOjTvApJxP6QvtFxEcLo= - dependencies: - "@babel/helper-module-imports" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.7.4" - -"@babel/plugin-transform-block-scoped-functions@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoped-functions/download/@babel/plugin-transform-block-scoped-functions-7.7.4.tgz#d0d9d5c269c78eaea76227ace214b8d01e4d837b" - integrity sha1-0NnVwmnHjq6nYies4hS40B5Ng3s= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-block-scoping@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoping/download/@babel/plugin-transform-block-scoping-7.7.4.tgz#200aad0dcd6bb80372f94d9e628ea062c58bf224" - integrity sha1-IAqtDc1ruANy+U2eYo6gYsWL8iQ= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.13" - -"@babel/plugin-transform-classes@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-classes/download/@babel/plugin-transform-classes-7.7.4.tgz#c92c14be0a1399e15df72667067a8f510c9400ec" - integrity sha1-ySwUvgoTmeFd9yZnBnqPUQyUAOw= - dependencies: - "@babel/helper-annotate-as-pure" "^7.7.4" - "@babel/helper-define-map" "^7.7.4" - "@babel/helper-function-name" "^7.7.4" - "@babel/helper-optimise-call-expression" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.7.4" - "@babel/helper-split-export-declaration" "^7.7.4" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-computed-properties/download/@babel/plugin-transform-computed-properties-7.7.4.tgz#e856c1628d3238ffe12d668eb42559f79a81910d" - integrity sha1-6FbBYo0yOP/hLWaOtCVZ95qBkQ0= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-destructuring@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-destructuring/download/@babel/plugin-transform-destructuring-7.7.4.tgz#2b713729e5054a1135097b6a67da1b6fe8789267" - integrity sha1-K3E3KeUFShE1CXtqZ9obb+h4kmc= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-dotall-regex@^7.7.7": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-dotall-regex/download/@babel/plugin-transform-dotall-regex-7.7.7.tgz#3e9713f1b69f339e87fa796b097d73ded16b937b" - integrity sha1-PpcT8bafM56H+nlrCX1z3tFrk3s= - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-duplicate-keys@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-duplicate-keys/download/@babel/plugin-transform-duplicate-keys-7.7.4.tgz#3d21731a42e3f598a73835299dd0169c3b90ac91" - integrity sha1-PSFzGkLj9ZinODUpndAWnDuQrJE= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-exponentiation-operator@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-exponentiation-operator/download/@babel/plugin-transform-exponentiation-operator-7.7.4.tgz#dd30c0191e3a1ba19bcc7e389bdfddc0729d5db9" - integrity sha1-3TDAGR46G6GbzH44m9/dwHKdXbk= - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-for-of@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-for-of/download/@babel/plugin-transform-for-of-7.7.4.tgz#248800e3a5e507b1f103d8b4ca998e77c63932bc" - integrity sha1-JIgA46XlB7HxA9i0ypmOd8Y5Mrw= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-function-name@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-function-name/download/@babel/plugin-transform-function-name-7.7.4.tgz#75a6d3303d50db638ff8b5385d12451c865025b1" - integrity sha1-dabTMD1Q22OP+LU4XRJFHIZQJbE= - dependencies: - "@babel/helper-function-name" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-literals@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-literals/download/@babel/plugin-transform-literals-7.7.4.tgz#27fe87d2b5017a2a5a34d1c41a6b9f6a6262643e" - integrity sha1-J/6H0rUBeipaNNHEGmufamJiZD4= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-member-expression-literals@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-member-expression-literals/download/@babel/plugin-transform-member-expression-literals-7.7.4.tgz#aee127f2f3339fc34ce5e3055d7ffbf7aa26f19a" - integrity sha1-ruEn8vMzn8NM5eMFXX/796om8Zo= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-modules-amd@^7.7.5": - version "7.7.5" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-modules-amd/download/@babel/plugin-transform-modules-amd-7.7.5.tgz#39e0fb717224b59475b306402bb8eedab01e729c" - integrity sha1-OeD7cXIktZR1swZAK7ju2rAecpw= - dependencies: - "@babel/helper-module-transforms" "^7.7.5" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-commonjs@^7.7.5": - version "7.7.5" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-modules-commonjs/download/@babel/plugin-transform-modules-commonjs-7.7.5.tgz#1d27f5eb0bcf7543e774950e5b2fa782e637b345" - integrity sha1-HSf16wvPdUPndJUOWy+nguY3s0U= - dependencies: - "@babel/helper-module-transforms" "^7.7.5" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.7.4" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-systemjs@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-modules-systemjs/download/@babel/plugin-transform-modules-systemjs-7.7.4.tgz#cd98152339d3e763dfe838b7d4273edaf520bb30" - integrity sha1-zZgVIznT52Pf6Di31Cc+2vUguzA= - dependencies: - "@babel/helper-hoist-variables" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-umd@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-modules-umd/download/@babel/plugin-transform-modules-umd-7.7.4.tgz#1027c355a118de0aae9fee00ad7813c584d9061f" - integrity sha1-ECfDVaEY3gqun+4ArXgTxYTZBh8= - dependencies: - "@babel/helper-module-transforms" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-named-capturing-groups-regex/download/@babel/plugin-transform-named-capturing-groups-regex-7.7.4.tgz?cache=0&sync_timestamp=1574465998388&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.7.4.tgz#fb3bcc4ee4198e7385805007373d6b6f42c98220" - integrity sha1-+zvMTuQZjnOFgFAHNz1rb0LJgiA= - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.4" - -"@babel/plugin-transform-new-target@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-new-target/download/@babel/plugin-transform-new-target-7.7.4.tgz#4a0753d2d60639437be07b592a9e58ee00720167" - integrity sha1-SgdT0tYGOUN74HtZKp5Y7gByAWc= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-object-super@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-object-super/download/@babel/plugin-transform-object-super-7.7.4.tgz#48488937a2d586c0148451bf51af9d7dda567262" - integrity sha1-SEiJN6LVhsAUhFG/Ua+dfdpWcmI= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.7.4" - -"@babel/plugin-transform-parameters@^7.7.7": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-parameters/download/@babel/plugin-transform-parameters-7.7.7.tgz#7a884b2460164dc5f194f668332736584c760007" - integrity sha1-eohLJGAWTcXxlPZoMyc2WEx2AAc= - dependencies: - "@babel/helper-call-delegate" "^7.7.4" - "@babel/helper-get-function-arity" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-property-literals@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-property-literals/download/@babel/plugin-transform-property-literals-7.7.4.tgz#2388d6505ef89b266103f450f9167e6bd73f98c2" - integrity sha1-I4jWUF74myZhA/RQ+RZ+a9c/mMI= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-regenerator@^7.7.5": - version "7.7.5" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-regenerator/download/@babel/plugin-transform-regenerator-7.7.5.tgz#3a8757ee1a2780f390e89f246065ecf59c26fce9" - integrity sha1-OodX7hongPOQ6J8kYGXs9Zwm/Ok= - dependencies: - regenerator-transform "^0.14.0" - -"@babel/plugin-transform-reserved-words@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-reserved-words/download/@babel/plugin-transform-reserved-words-7.7.4.tgz#6a7cf123ad175bb5c69aec8f6f0770387ed3f1eb" - integrity sha1-anzxI60XW7XGmuyPbwdwOH7T8es= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-runtime@^7.7.4": - version "7.7.6" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-runtime/download/@babel/plugin-transform-runtime-7.7.6.tgz#4f2b548c88922fb98ec1c242afd4733ee3e12f61" - integrity sha1-TytUjIiSL7mOwcJCr9RzPuPhL2E= - dependencies: - "@babel/helper-module-imports" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - resolve "^1.8.1" - semver "^5.5.1" - -"@babel/plugin-transform-shorthand-properties@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-shorthand-properties/download/@babel/plugin-transform-shorthand-properties-7.7.4.tgz#74a0a9b2f6d67a684c6fbfd5f0458eb7ba99891e" - integrity sha1-dKCpsvbWemhMb7/V8EWOt7qZiR4= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-spread@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-spread/download/@babel/plugin-transform-spread-7.7.4.tgz#aa673b356fe6b7e70d69b6e33a17fef641008578" - integrity sha1-qmc7NW/mt+cNabbjOhf+9kEAhXg= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-sticky-regex@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-sticky-regex/download/@babel/plugin-transform-sticky-regex-7.7.4.tgz#ffb68c05090c30732076b1285dc1401b404a123c" - integrity sha1-/7aMBQkMMHMgdrEoXcFAG0BKEjw= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" - -"@babel/plugin-transform-template-literals@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-template-literals/download/@babel/plugin-transform-template-literals-7.7.4.tgz#1eb6411736dd3fe87dbd20cc6668e5121c17d604" - integrity sha1-HrZBFzbdP+h9vSDMZmjlEhwX1gQ= - dependencies: - "@babel/helper-annotate-as-pure" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-typeof-symbol@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-typeof-symbol/download/@babel/plugin-transform-typeof-symbol-7.7.4.tgz#3174626214f2d6de322882e498a38e8371b2140e" - integrity sha1-MXRiYhTy1t4yKILkmKOOg3GyFA4= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-unicode-regex@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-unicode-regex/download/@babel/plugin-transform-unicode-regex-7.7.4.tgz?cache=0&sync_timestamp=1574465997106&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.7.4.tgz#a3c0f65b117c4c81c5b6484f2a5e7b95346b83ae" - integrity sha1-o8D2WxF8TIHFtkhPKl57lTRrg64= - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/preset-env@^7.7.4": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/preset-env/download/@babel/preset-env-7.7.7.tgz#c294167b91e53e7e36d820e943ece8d0c7fe46ac" - integrity sha1-wpQWe5HlPn422CDpQ+zo0Mf+Rqw= - dependencies: - "@babel/helper-module-imports" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.7.4" - "@babel/plugin-proposal-dynamic-import" "^7.7.4" - "@babel/plugin-proposal-json-strings" "^7.7.4" - "@babel/plugin-proposal-object-rest-spread" "^7.7.7" - "@babel/plugin-proposal-optional-catch-binding" "^7.7.4" - "@babel/plugin-proposal-unicode-property-regex" "^7.7.7" - "@babel/plugin-syntax-async-generators" "^7.7.4" - "@babel/plugin-syntax-dynamic-import" "^7.7.4" - "@babel/plugin-syntax-json-strings" "^7.7.4" - "@babel/plugin-syntax-object-rest-spread" "^7.7.4" - "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" - "@babel/plugin-syntax-top-level-await" "^7.7.4" - "@babel/plugin-transform-arrow-functions" "^7.7.4" - "@babel/plugin-transform-async-to-generator" "^7.7.4" - "@babel/plugin-transform-block-scoped-functions" "^7.7.4" - "@babel/plugin-transform-block-scoping" "^7.7.4" - "@babel/plugin-transform-classes" "^7.7.4" - "@babel/plugin-transform-computed-properties" "^7.7.4" - "@babel/plugin-transform-destructuring" "^7.7.4" - "@babel/plugin-transform-dotall-regex" "^7.7.7" - "@babel/plugin-transform-duplicate-keys" "^7.7.4" - "@babel/plugin-transform-exponentiation-operator" "^7.7.4" - "@babel/plugin-transform-for-of" "^7.7.4" - "@babel/plugin-transform-function-name" "^7.7.4" - "@babel/plugin-transform-literals" "^7.7.4" - "@babel/plugin-transform-member-expression-literals" "^7.7.4" - "@babel/plugin-transform-modules-amd" "^7.7.5" - "@babel/plugin-transform-modules-commonjs" "^7.7.5" - "@babel/plugin-transform-modules-systemjs" "^7.7.4" - "@babel/plugin-transform-modules-umd" "^7.7.4" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.7.4" - "@babel/plugin-transform-new-target" "^7.7.4" - "@babel/plugin-transform-object-super" "^7.7.4" - "@babel/plugin-transform-parameters" "^7.7.7" - "@babel/plugin-transform-property-literals" "^7.7.4" - "@babel/plugin-transform-regenerator" "^7.7.5" - "@babel/plugin-transform-reserved-words" "^7.7.4" - "@babel/plugin-transform-shorthand-properties" "^7.7.4" - "@babel/plugin-transform-spread" "^7.7.4" - "@babel/plugin-transform-sticky-regex" "^7.7.4" - "@babel/plugin-transform-template-literals" "^7.7.4" - "@babel/plugin-transform-typeof-symbol" "^7.7.4" - "@babel/plugin-transform-unicode-regex" "^7.7.4" - "@babel/types" "^7.7.4" - browserslist "^4.6.0" - core-js-compat "^3.6.0" - invariant "^2.2.2" - js-levenshtein "^1.1.3" - semver "^5.5.0" - -"@babel/runtime@^7.7.4": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/runtime/download/@babel/runtime-7.7.7.tgz#194769ca8d6d7790ec23605af9ee3e42a0aa79cf" - integrity sha1-GUdpyo1td5DsI2Ba+e4+QqCqec8= - dependencies: - regenerator-runtime "^0.13.2" - -"@babel/template@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/template/download/@babel/template-7.7.4.tgz?cache=0&sync_timestamp=1574465630781&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftemplate%2Fdownload%2F%40babel%2Ftemplate-7.7.4.tgz#428a7d9eecffe27deac0a98e23bf8e3675d2a77b" - integrity sha1-Qop9nuz/4n3qwKmOI7+ONnXSp3s= - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/traverse@^7.0.0", "@babel/traverse@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/traverse/download/@babel/traverse-7.7.4.tgz?cache=0&sync_timestamp=1574465640801&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftraverse%2Fdownload%2F%40babel%2Ftraverse-7.7.4.tgz#9c1e7c60fb679fe4fcfaa42500833333c2058558" - integrity sha1-nB58YPtnn+T8+qQlAIMzM8IFhVg= - dependencies: - "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.4" - "@babel/helper-function-name" "^7.7.4" - "@babel/helper-split-export-declaration" "^7.7.4" - "@babel/parser" "^7.7.4" - "@babel/types" "^7.7.4" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.13" - -"@babel/types@^7.0.0", "@babel/types@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/types/download/@babel/types-7.7.4.tgz?cache=0&sync_timestamp=1574465636802&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.7.4.tgz#516570d539e44ddf308c07569c258ff94fde9193" - integrity sha1-UWVw1TnkTd8wjAdWnCWP+U/ekZM= - dependencies: - esutils "^2.0.2" - lodash "^4.17.13" - to-fast-properties "^2.0.0" - -"@hapi/address@2.x.x": - version "2.1.4" - resolved "https://registry.npm.taobao.org/@hapi/address/download/@hapi/address-2.1.4.tgz?cache=0&sync_timestamp=1573979090690&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40hapi%2Faddress%2Fdownload%2F%40hapi%2Faddress-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" - integrity sha1-XWftQ/P9QaadS5/3tW58DR0KgeU= - -"@hapi/bourne@1.x.x": - version "1.3.2" - resolved "https://registry.npm.taobao.org/@hapi/bourne/download/@hapi/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" - integrity sha1-CnCVreoGckPOMoPhtWuKj0U7JCo= - -"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": - version "8.5.0" - resolved "https://registry.npm.taobao.org/@hapi/hoek/download/@hapi/hoek-8.5.0.tgz#2f9ce301c8898e1c3248b0a8564696b24d1a9a5a" - integrity sha1-L5zjAciJjhwySLCoVkaWsk0amlo= - -"@hapi/joi@^15.0.1": - version "15.1.1" - resolved "https://registry.npm.taobao.org/@hapi/joi/download/@hapi/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" - integrity sha1-xnW4pxKW8Cgz+NbSQ7NMV7jOGdc= - dependencies: - "@hapi/address" "2.x.x" - "@hapi/bourne" "1.x.x" - "@hapi/hoek" "8.x.x" - "@hapi/topo" "3.x.x" - -"@hapi/topo@3.x.x": - version "3.1.6" - resolved "https://registry.npm.taobao.org/@hapi/topo/download/@hapi/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" - integrity sha1-aNk1+j6uf91asNf5U/MgXYsr/Ck= - dependencies: - "@hapi/hoek" "^8.3.0" - -"@intervolga/optimize-cssnano-plugin@^1.0.5": - version "1.0.6" - resolved "https://registry.npm.taobao.org/@intervolga/optimize-cssnano-plugin/download/@intervolga/optimize-cssnano-plugin-1.0.6.tgz#be7c7846128b88f6a9b1d1261a0ad06eb5c0fdf8" - integrity sha1-vnx4RhKLiPapsdEmGgrQbrXA/fg= - dependencies: - cssnano "^4.0.0" - cssnano-preset-default "^4.0.0" - postcss "^7.0.0" - -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.npm.taobao.org/@mrmlnc/readdir-enhanced/download/@mrmlnc/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - integrity sha1-UkryQNGjYFJ7cwR17PoTRKpUDd4= - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" - integrity sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs= - -"@soda/friendly-errors-webpack-plugin@^1.7.1": - version "1.7.1" - resolved "https://registry.npm.taobao.org/@soda/friendly-errors-webpack-plugin/download/@soda/friendly-errors-webpack-plugin-1.7.1.tgz#706f64bcb4a8b9642b48ae3ace444c70334d615d" - integrity sha1-cG9kvLSouWQrSK46zkRMcDNNYV0= - dependencies: - chalk "^1.1.3" - error-stack-parser "^2.0.0" - string-width "^2.0.0" - -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.npm.taobao.org/@types/color-name/download/@types/color-name-1.1.1.tgz?cache=0&sync_timestamp=1572460951965&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fcolor-name%2Fdownload%2F%40types%2Fcolor-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha1-HBJhu+qhCoBVu8XYq4S3sq/IRqA= - -"@types/events@*": - version "3.0.0" - resolved "https://registry.npm.taobao.org/@types/events/download/@types/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" - integrity sha1-KGLz9Yqaf3w+eNefEw3U1xwlwqc= - -"@types/glob@^7.1.1": - version "7.1.1" - resolved "https://registry.npm.taobao.org/@types/glob/download/@types/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" - integrity sha1-qlmhxuP7xCHgfM0xqUTDDrpSFXU= - dependencies: - "@types/events" "*" - "@types/minimatch" "*" - "@types/node" "*" - -"@types/minimatch@*": - version "3.0.3" - resolved "https://registry.npm.taobao.org/@types/minimatch/download/@types/minimatch-3.0.3.tgz?cache=0&sync_timestamp=1572463171410&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fminimatch%2Fdownload%2F%40types%2Fminimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha1-PcoOPzOyAPx9ETnAzZbBJoyt/Z0= - -"@types/node@*": - version "12.12.21" - resolved "https://registry.npm.taobao.org/@types/node/download/@types/node-12.12.21.tgz#aa44a6363291c7037111c47e4661ad210aded23f" - integrity sha1-qkSmNjKRxwNxEcR+RmGtIQre0j8= - -"@types/normalize-package-data@^2.4.0": - version "2.4.0" - resolved "https://registry.npm.taobao.org/@types/normalize-package-data/download/@types/normalize-package-data-2.4.0.tgz?cache=0&sync_timestamp=1572463173738&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnormalize-package-data%2Fdownload%2F%40types%2Fnormalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" - integrity sha1-5IbQ2XOW15vu3QpuM/RTT/a0lz4= - -"@types/q@^1.5.1": - version "1.5.2" - resolved "https://registry.npm.taobao.org/@types/q/download/@types/q-1.5.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fq%2Fdownload%2F%40types%2Fq-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" - integrity sha1-aQoUdbhPKohP0HzXl8APXzE1bqg= - -"@vue/babel-helper-vue-jsx-merge-props@^1.0.0": - version "1.0.0" - resolved "https://registry.npm.taobao.org/@vue/babel-helper-vue-jsx-merge-props/download/@vue/babel-helper-vue-jsx-merge-props-1.0.0.tgz#048fe579958da408fb7a8b2a3ec050b50a661040" - integrity sha1-BI/leZWNpAj7eosqPsBQtQpmEEA= - -"@vue/babel-plugin-transform-vue-jsx@^1.1.2": - version "1.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-plugin-transform-vue-jsx/download/@vue/babel-plugin-transform-vue-jsx-1.1.2.tgz#c0a3e6efc022e75e4247b448a8fc6b86f03e91c0" - integrity sha1-wKPm78Ai515CR7RIqPxrhvA+kcA= - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" - html-tags "^2.0.0" - lodash.kebabcase "^4.1.1" - svg-tags "^1.0.0" - -"@vue/babel-preset-app@^4.1.1": - version "4.1.1" - resolved "https://registry.npm.taobao.org/@vue/babel-preset-app/download/@vue/babel-preset-app-4.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-preset-app%2Fdownload%2F%40vue%2Fbabel-preset-app-4.1.1.tgz#a3982aca2e1a84d37457fdfdfc8da904d2b33b10" - integrity sha1-o5gqyi4ahNN0V/39/I2pBNKzOxA= - dependencies: - "@babel/core" "^7.7.4" - "@babel/helper-module-imports" "^7.7.4" - "@babel/plugin-proposal-class-properties" "^7.7.4" - "@babel/plugin-proposal-decorators" "^7.7.4" - "@babel/plugin-syntax-dynamic-import" "^7.7.4" - "@babel/plugin-syntax-jsx" "^7.7.4" - "@babel/plugin-transform-runtime" "^7.7.4" - "@babel/preset-env" "^7.7.4" - "@babel/runtime" "^7.7.4" - "@vue/babel-preset-jsx" "^1.1.2" - babel-plugin-dynamic-import-node "^2.2.0" - core-js "^3.4.3" - core-js-compat "^3.4.3" - -"@vue/babel-preset-jsx@^1.1.2": - version "1.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-preset-jsx/download/@vue/babel-preset-jsx-1.1.2.tgz?cache=0&sync_timestamp=1573270721644&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-preset-jsx%2Fdownload%2F%40vue%2Fbabel-preset-jsx-1.1.2.tgz#2e169eb4c204ea37ca66c2ea85a880bfc99d4f20" - integrity sha1-LhaetMIE6jfKZsLqhaiAv8mdTyA= - dependencies: - "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" - "@vue/babel-plugin-transform-vue-jsx" "^1.1.2" - "@vue/babel-sugar-functional-vue" "^1.1.2" - "@vue/babel-sugar-inject-h" "^1.1.2" - "@vue/babel-sugar-v-model" "^1.1.2" - "@vue/babel-sugar-v-on" "^1.1.2" - -"@vue/babel-sugar-functional-vue@^1.1.2": - version "1.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-sugar-functional-vue/download/@vue/babel-sugar-functional-vue-1.1.2.tgz#f7e24fba09e6f1ee70104560a8808057555f1a9a" - integrity sha1-9+JPugnm8e5wEEVgqICAV1VfGpo= - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - -"@vue/babel-sugar-inject-h@^1.1.2": - version "1.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-sugar-inject-h/download/@vue/babel-sugar-inject-h-1.1.2.tgz#8a5276b6d8e2ed16ffc8078aad94236274e6edf0" - integrity sha1-ilJ2ttji7Rb/yAeKrZQjYnTm7fA= - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - -"@vue/babel-sugar-v-model@^1.1.2": - version "1.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-sugar-v-model/download/@vue/babel-sugar-v-model-1.1.2.tgz#1ff6fd1b800223fc9cb1e84dceb5e52d737a8192" - integrity sha1-H/b9G4ACI/ycsehNzrXlLXN6gZI= - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" - "@vue/babel-plugin-transform-vue-jsx" "^1.1.2" - camelcase "^5.0.0" - html-tags "^2.0.0" - svg-tags "^1.0.0" - -"@vue/babel-sugar-v-on@^1.1.2": - version "1.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-sugar-v-on/download/@vue/babel-sugar-v-on-1.1.2.tgz?cache=0&sync_timestamp=1573270721318&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-sugar-v-on%2Fdownload%2F%40vue%2Fbabel-sugar-v-on-1.1.2.tgz#b2ef99b8f2fab09fbead25aad70ef42e1cf5b13b" - integrity sha1-su+ZuPL6sJ++rSWq1w70Lhz1sTs= - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-plugin-transform-vue-jsx" "^1.1.2" - camelcase "^5.0.0" - -"@vue/cli-overlay@^4.1.1": - version "4.1.1" - resolved "https://registry.npm.taobao.org/@vue/cli-overlay/download/@vue/cli-overlay-4.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-overlay%2Fdownload%2F%40vue%2Fcli-overlay-4.1.1.tgz#d4559c12e50075a4817ac977cc0bde504520d9de" - integrity sha1-1FWcEuUAdaSBesl3zAveUEUg2d4= - -"@vue/cli-plugin-babel@^4.1.0": - version "4.1.1" - resolved "https://registry.npm.taobao.org/@vue/cli-plugin-babel/download/@vue/cli-plugin-babel-4.1.1.tgz?cache=0&sync_timestamp=1574867837056&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-plugin-babel%2Fdownload%2F%40vue%2Fcli-plugin-babel-4.1.1.tgz#aa27100a25a385f54e2a7a2bc97af47dfdd57b25" - integrity sha1-qicQCiWjhfVOKnoryXr0ff3VeyU= - dependencies: - "@babel/core" "^7.7.4" - "@vue/babel-preset-app" "^4.1.1" - "@vue/cli-shared-utils" "^4.1.1" - babel-loader "^8.0.6" - cache-loader "^4.1.0" - thread-loader "^2.1.3" - webpack "^4.0.0" - -"@vue/cli-plugin-eslint@^4.1.0": - version "4.1.1" - resolved "https://registry.npm.taobao.org/@vue/cli-plugin-eslint/download/@vue/cli-plugin-eslint-4.1.1.tgz?cache=0&sync_timestamp=1574867851185&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-plugin-eslint%2Fdownload%2F%40vue%2Fcli-plugin-eslint-4.1.1.tgz#ad09b71f94dc7518a6c83debacd39e34f6d5a71e" - integrity sha1-rQm3H5TcdRimyD3rrNOeNPbVpx4= - dependencies: - "@vue/cli-shared-utils" "^4.1.1" - eslint-loader "^2.1.2" - globby "^9.2.0" - webpack "^4.0.0" - yorkie "^2.0.0" - -"@vue/cli-plugin-router@^4.1.1": - version "4.1.1" - resolved "https://registry.npm.taobao.org/@vue/cli-plugin-router/download/@vue/cli-plugin-router-4.1.1.tgz?cache=0&sync_timestamp=1574867856622&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-plugin-router%2Fdownload%2F%40vue%2Fcli-plugin-router-4.1.1.tgz#85c7f2d34f9217ad70b49a71dae6bf7067042759" - integrity sha1-hcfy00+SF61wtJpx2ua/cGcEJ1k= - dependencies: - "@vue/cli-shared-utils" "^4.1.1" - -"@vue/cli-plugin-vuex@^4.1.1": - version "4.1.1" - resolved "https://registry.npm.taobao.org/@vue/cli-plugin-vuex/download/@vue/cli-plugin-vuex-4.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-plugin-vuex%2Fdownload%2F%40vue%2Fcli-plugin-vuex-4.1.1.tgz#81908ee66370dda162b5517afc869f91d3abe2bf" - integrity sha1-gZCO5mNw3aFitVF6/IafkdOr4r8= - -"@vue/cli-service@^4.1.0": - version "4.1.1" - resolved "https://registry.npm.taobao.org/@vue/cli-service/download/@vue/cli-service-4.1.1.tgz?cache=0&sync_timestamp=1574867856121&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-service%2Fdownload%2F%40vue%2Fcli-service-4.1.1.tgz#a14e9d455752f1a8e4e87ac436ebde88cad82276" - integrity sha1-oU6dRVdS8ajk6HrENuveiMrYInY= - dependencies: - "@intervolga/optimize-cssnano-plugin" "^1.0.5" - "@soda/friendly-errors-webpack-plugin" "^1.7.1" - "@vue/cli-overlay" "^4.1.1" - "@vue/cli-plugin-router" "^4.1.1" - "@vue/cli-plugin-vuex" "^4.1.1" - "@vue/cli-shared-utils" "^4.1.1" - "@vue/component-compiler-utils" "^3.0.2" - "@vue/preload-webpack-plugin" "^1.1.0" - "@vue/web-component-wrapper" "^1.2.0" - acorn "^6.1.1" - acorn-walk "^6.1.1" - address "^1.1.2" - autoprefixer "^9.7.2" - browserslist "^4.7.3" - cache-loader "^4.1.0" - case-sensitive-paths-webpack-plugin "^2.2.0" - chalk "^2.4.2" - cli-highlight "^2.1.4" - clipboardy "^2.0.0" - cliui "^5.0.0" - copy-webpack-plugin "^5.0.5" - css-loader "^3.1.0" - cssnano "^4.1.10" - current-script-polyfill "^1.0.0" - debug "^4.1.1" - default-gateway "^5.0.5" - dotenv "^8.2.0" - dotenv-expand "^5.1.0" - file-loader "^4.2.0" - fs-extra "^7.0.1" - globby "^9.2.0" - hash-sum "^1.0.2" - html-webpack-plugin "^3.2.0" - launch-editor-middleware "^2.2.1" - lodash.defaultsdeep "^4.6.1" - lodash.mapvalues "^4.6.0" - lodash.transform "^4.6.0" - mini-css-extract-plugin "^0.8.0" - minimist "^1.2.0" - ora "^3.4.0" - portfinder "^1.0.25" - postcss-loader "^3.0.0" - read-pkg "^5.1.1" - semver "^6.1.0" - slash "^3.0.0" - source-map-url "^0.4.0" - ssri "^6.0.1" - string.prototype.padend "^3.0.0" - terser-webpack-plugin "^2.2.1" - thread-loader "^2.1.3" - url-loader "^2.2.0" - vue-loader "^15.7.2" - vue-style-loader "^4.1.0" - webpack "^4.0.0" - webpack-bundle-analyzer "^3.6.0" - webpack-chain "^6.0.0" - webpack-dev-server "^3.9.0" - webpack-merge "^4.2.2" - -"@vue/cli-shared-utils@^4.1.1": - version "4.1.1" - resolved "https://registry.npm.taobao.org/@vue/cli-shared-utils/download/@vue/cli-shared-utils-4.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-shared-utils%2Fdownload%2F%40vue%2Fcli-shared-utils-4.1.1.tgz#79e26b56fda185fda00e5787a8f4aac56757b123" - integrity sha1-eeJrVv2hhf2gDleHqPSqxWdXsSM= - dependencies: - "@hapi/joi" "^15.0.1" - chalk "^2.4.1" - execa "^1.0.0" - launch-editor "^2.2.1" - lru-cache "^5.1.1" - node-ipc "^9.1.1" - open "^6.3.0" - ora "^3.4.0" - request "^2.87.0" - request-promise-native "^1.0.8" - semver "^6.1.0" - string.prototype.padstart "^3.0.0" - strip-ansi "^6.0.0" - -"@vue/component-compiler-utils@^3.0.2", "@vue/component-compiler-utils@^3.1.0": - version "3.1.0" - resolved "https://registry.npm.taobao.org/@vue/component-compiler-utils/download/@vue/component-compiler-utils-3.1.0.tgz#64cd394925f5af1f9c3228c66e954536f5311857" - integrity sha1-ZM05SSX1rx+cMijGbpVFNvUxGFc= - dependencies: - consolidate "^0.15.1" - hash-sum "^1.0.2" - lru-cache "^4.1.2" - merge-source-map "^1.1.0" - postcss "^7.0.14" - postcss-selector-parser "^5.0.0" - prettier "^1.18.2" - source-map "~0.6.1" - vue-template-es2015-compiler "^1.9.0" - -"@vue/preload-webpack-plugin@^1.1.0": - version "1.1.1" - resolved "https://registry.npm.taobao.org/@vue/preload-webpack-plugin/download/@vue/preload-webpack-plugin-1.1.1.tgz#18723530d304f443021da2292d6ec9502826104a" - integrity sha1-GHI1MNME9EMCHaIpLW7JUCgmEEo= - -"@vue/web-component-wrapper@^1.2.0": - version "1.2.0" - resolved "https://registry.npm.taobao.org/@vue/web-component-wrapper/download/@vue/web-component-wrapper-1.2.0.tgz#bb0e46f1585a7e289b4ee6067dcc5a6ae62f1dd1" - integrity sha1-uw5G8VhafiibTuYGfcxaauYvHdE= - -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/ast/download/@webassemblyjs/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha1-UbHF/mV2o0lTv0slPfnw1JDZ41k= - dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/floating-point-hex-parser/download/@webassemblyjs/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha1-G6kmopI2E+3OSW/VsC6M6KX0lyE= - -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-api-error/download/@webassemblyjs/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha1-xJ2tIvZFInxe22EL25aX8aq3Ifc= - -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-buffer/download/@webassemblyjs/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha1-/qk+Qphj3V5DOFVfQikjhaZT8gQ= - -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-code-frame/download/@webassemblyjs/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha1-mnQP9I4/qjAisd/1RCPfmqKTwl4= - dependencies: - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-fsm/download/@webassemblyjs/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha1-ugt9Oz9+RzPaYFnJMyJ12GBwJFI= - -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-module-context/download/@webassemblyjs/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha1-3vS5knsBAdyMu9jR7bW3ucguskU= - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-wasm-bytecode/download/@webassemblyjs/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha1-U3p1Dt31weky83RCBlUckcG5PmE= - -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-wasm-section/download/@webassemblyjs/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha1-dMpqa8vhnlCjtrRihH5pUD5r/L8= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/ieee754/download/@webassemblyjs/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha1-cSMp2+8kDza/V70ve4+5v0FUQh4= - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/leb128/download/@webassemblyjs/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha1-BE7es06mefPgTNT9mCTV41dnrhA= - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/utf8/download/@webassemblyjs/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha1-qL87XY/+mGx8Hjc8y9wqCRXwztw= - -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/wasm-edit/download/@webassemblyjs/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha1-li2hKqWswcExyBxCMpkcgs5W4Bo= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/wasm-gen/download/@webassemblyjs/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha1-VIQHZsLBAC62TtGr5yCt7XFPmLw= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/wasm-opt/download/@webassemblyjs/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha1-sk2fa6UDlK8TSfUQr6j/y4pj0mQ= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/wasm-parser/download/@webassemblyjs/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha1-IVdvDsiLkUJzV7hTY4NmjvfGa40= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/wast-parser/download/@webassemblyjs/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha1-4Q7s1ULQ5705T2gnxJ899tTu+4w= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/wast-printer/download/@webassemblyjs/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha1-EUu8SB/RDKDiOzVg+oEnSLC65bw= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - "@xtuc/long" "4.2.2" - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.npm.taobao.org/@xtuc/ieee754/download/@xtuc/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha1-7vAUoxRa5Hehy8AM0eVSM23Ot5A= - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.npm.taobao.org/@xtuc/long/download/@xtuc/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha1-0pHGpOl5ibXGHZrPOWrk/hM6cY0= - -abs-svg-path@~0.1.1: - version "0.1.1" - resolved "https://registry.npm.taobao.org/abs-svg-path/download/abs-svg-path-0.1.1.tgz#df601c8e8d2ba10d4a76d625e236a9a39c2723bf" - integrity sha1-32Acjo0roQ1KdtYl4japo5wnI78= - -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha1-UxvHJlF6OytB+FACHGzBXqq1B80= - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn-jsx@^5.0.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/acorn-jsx/download/acorn-jsx-5.1.0.tgz?cache=0&sync_timestamp=1570991888898&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Facorn-jsx%2Fdownload%2Facorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384" - integrity sha1-KUrbcbVzmLBoABXwo4xWPuHbU4Q= - -acorn-walk@^6.1.1: - version "6.2.0" - resolved "https://registry.npm.taobao.org/acorn-walk/download/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" - integrity sha1-Ejy487hMIXHx9/slJhWxx4prGow= - -acorn@^6.0.2, acorn@^6.0.7, acorn@^6.1.1, acorn@^6.2.1: - version "6.4.0" - resolved "https://registry.npm.taobao.org/acorn/download/acorn-6.4.0.tgz?cache=0&sync_timestamp=1574806921127&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Facorn%2Fdownload%2Facorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" - integrity sha1-tlnS/7r6JLr12xzbsslKmD7NJ4Q= - -address@^1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/address/download/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" - integrity sha1-vxEWycdYxRt6kz0pa3LCIe2UKLY= - -aggregate-error@^3.0.0: - version "3.0.1" - resolved "https://registry.npm.taobao.org/aggregate-error/download/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0" - integrity sha1-2y/nJG5Tb0DZtUQqOeEX191qJOA= - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv-errors@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/ajv-errors/download/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" - integrity sha1-81mGrOuRr63sQQL72FAUlQzvpk0= - -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: - version "3.4.1" - resolved "https://registry.npm.taobao.org/ajv-keywords/download/ajv-keywords-3.4.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-keywords%2Fdownload%2Fajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha1-75FuJxxkrBIXH9g4TqrmsjRYVNo= - -ajv@^6.1.0, ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1: - version "6.10.2" - resolved "https://registry.npm.taobao.org/ajv/download/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" - integrity sha1-086gTWsBeyiUrWkED+yLYj60vVI= - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.npm.taobao.org/align-text/download/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - integrity sha1-DNkKVhCT810KmSVsIrcGlDP60Rc= - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - -alphanum-sort@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/alphanum-sort/download/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" - integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.npm.taobao.org/amdefine/download/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= - -ansi-colors@^3.0.0: - version "3.2.4" - resolved "https://registry.npm.taobao.org/ansi-colors/download/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" - integrity sha1-46PaS/uubIapwoViXeEkojQCb78= - -ansi-escapes@^3.2.0: - version "3.2.0" - resolved "https://registry.npm.taobao.org/ansi-escapes/download/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha1-h4C5j/nb9WOBUtHx/lwde0RCl2s= - -ansi-html@0.0.7: - version "0.0.7" - resolved "https://registry.npm.taobao.org/ansi-html/download/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" - integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-2.1.1.tgz?cache=0&sync_timestamp=1570188663907&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-regex%2Fdownload%2Fansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-3.0.0.tgz?cache=0&sync_timestamp=1570188663907&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-regex%2Fdownload%2Fansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz?cache=0&sync_timestamp=1570188663907&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-regex%2Fdownload%2Fansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc= - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz?cache=0&sync_timestamp=1570188663907&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-regex%2Fdownload%2Fansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U= - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-2.2.1.tgz?cache=0&sync_timestamp=1573557628456&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1573557628456&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0= - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.2.0" - resolved "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.2.0.tgz?cache=0&sync_timestamp=1573557628456&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.2.0.tgz#5681f0dcf7ae5880a7841d8831c4724ed9cc0172" - integrity sha1-VoHw3PeuWICnhB2IMcRyTtnMAXI= - dependencies: - "@types/color-name" "^1.1.1" - color-convert "^2.0.1" - -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.npm.taobao.org/any-promise/download/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/anymatch/download/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha1-vLJLTzeTTZqnrBe0ra+J58du8us= - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.npm.taobao.org/aproba/download/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha1-aALmJk79GMeQobDVF/DyYnvyyUo= - -arch@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/arch/download/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e" - integrity sha1-j1wnMao1owkpIhuwZA7tZRdeyE4= - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.npm.taobao.org/argparse/download/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE= - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/arr-diff/download/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/arr-flatten/download/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha1-NgSLv/TntH4TZkQxbJlmnqWukfE= - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/arr-union/download/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz?cache=0&sync_timestamp=1574313384951&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-flatten@^2.1.0: - version "2.1.2" - resolved "https://registry.npm.taobao.org/array-flatten/download/array-flatten-2.1.2.tgz?cache=0&sync_timestamp=1574313384951&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha1-JO+AoowaiTYX4hSbDG0NeIKTsJk= - -array-union@^1.0.1, array-union@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/array-union/download/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.npm.taobao.org/array-uniq/download/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.npm.taobao.org/array-unique/download/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.npm.taobao.org/asap/download/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= - -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.npm.taobao.org/asn1.js/download/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha1-ucK/WAXx5kqt7tbfOiv6+1pz9aA= - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha1-jSR136tVO7M+d7VOWeiAu4ziMTY= - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/assert-plus/download/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assert@^1.1.1: - version "1.5.0" - resolved "https://registry.npm.taobao.org/assert/download/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" - integrity sha1-VcEJqvbgrv2z3EtxJAxwv1dLGOs= - dependencies: - object-assign "^4.1.1" - util "0.10.3" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/assign-symbols/download/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/astral-regex/download/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha1-bIw/uCfdQ+45GPJ7gngqt2WKb9k= - -async-each@^1.0.1: - version "1.0.3" - resolved "https://registry.npm.taobao.org/async-each/download/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" - integrity sha1-tyfb+H12UWAvBvTUrDh/R9kbDL8= - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/async-limiter/download/async-limiter-1.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fasync-limiter%2Fdownload%2Fasync-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha1-3TeelPDbgxCwgpH51kwyCXZmF/0= - -async@^2.6.2: - version "2.6.3" - resolved "https://registry.npm.taobao.org/async/download/async-2.6.3.tgz?cache=0&sync_timestamp=1563385399810&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fasync%2Fdownload%2Fasync-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha1-1yYl4jRKNlbjo61Pp0n6gymdgv8= - dependencies: - lodash "^4.17.14" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -atob@^2.1.1: - version "2.1.2" - resolved "https://registry.npm.taobao.org/atob/download/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k= - -autoprefixer@^9.7.2: - version "9.7.3" - resolved "https://registry.npm.taobao.org/autoprefixer/download/autoprefixer-9.7.3.tgz#fd42ed03f53de9beb4ca0d61fb4f7268a9bb50b4" - integrity sha1-/ULtA/U96b60yg1h+09yaKm7ULQ= - dependencies: - browserslist "^4.8.0" - caniuse-lite "^1.0.30001012" - chalk "^2.4.2" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^7.0.23" - postcss-value-parser "^4.0.2" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.npm.taobao.org/aws-sign2/download/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.9.0" - resolved "https://registry.npm.taobao.org/aws4/download/aws4-1.9.0.tgz?cache=0&sync_timestamp=1574807521525&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faws4%2Fdownload%2Faws4-1.9.0.tgz#24390e6ad61386b0a747265754d2a17219de862c" - integrity sha1-JDkOatYThrCnRyZXVNKhchnehiw= - -babel-eslint@^10.0.3: - version "10.0.3" - resolved "https://registry.npm.taobao.org/babel-eslint/download/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a" - integrity sha1-gaLGab4PIF4ZRi/tJILTPkaHqIo= - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - eslint-visitor-keys "^1.0.0" - resolve "^1.12.0" - -babel-loader@^8.0.6: - version "8.0.6" - resolved "https://registry.npm.taobao.org/babel-loader/download/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb" - integrity sha1-4zvbbzYrA/S7FBoMIauHxQG3Dfs= - dependencies: - find-cache-dir "^2.0.0" - loader-utils "^1.0.2" - mkdirp "^0.5.1" - pify "^4.0.1" - -babel-plugin-dynamic-import-node@^2.2.0, babel-plugin-dynamic-import-node@^2.3.0: - version "2.3.0" - resolved "https://registry.npm.taobao.org/babel-plugin-dynamic-import-node/download/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" - integrity sha1-8A9Qe9qjw+P/bn5emNkKesq5b38= - dependencies: - object.assign "^4.1.0" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.npm.taobao.org/base64-js/download/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha1-WOzoy3XdB+ce0IxzarxfrE2/jfE= - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.npm.taobao.org/base/download/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha1-e95c7RRbbVUakNuH+DxVi060io8= - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.npm.taobao.org/batch/download/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/bcrypt-pbkdf/download/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -bfj@^6.1.1: - version "6.1.2" - resolved "https://registry.npm.taobao.org/bfj/download/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" - integrity sha1-MlyGGoIryzWKQceKM7jm4ght3n8= - dependencies: - bluebird "^3.5.5" - check-types "^8.0.3" - hoopy "^0.1.4" - tryer "^1.0.1" - -big.js@^3.1.3: - version "3.2.0" - resolved "https://registry.npm.taobao.org/big.js/download/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" - integrity sha1-pfwpi4G54Nyi5FiCR4S2XFK6WI4= - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.npm.taobao.org/big.js/download/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha1-ZfCvOC9Xi83HQr2cKB6cstd2gyg= - -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.npm.taobao.org/binary-extensions/download/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha1-WYr+VHVbKGilMw0q/51Ou1Mgm2U= - -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.npm.taobao.org/bindings/download/bindings-1.5.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbindings%2Fdownload%2Fbindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha1-EDU8npRTNLwFEabZCzj7x8nFBN8= - dependencies: - file-uri-to-path "1.0.0" - -bluebird@^3.1.1, bluebird@^3.5.5: - version "3.7.2" - resolved "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha1-nyKcFb4nJFT/qXOs4NvueaGww28= - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.npm.taobao.org/bn.js/download/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha1-LN4J617jQfSEdGuwMJsyU7GxRC8= - -body-parser@1.19.0: - version "1.19.0" - resolved "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io= - dependencies: - bytes "3.1.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" - -bonjour@^3.5.0: - version "3.5.0" - resolved "https://registry.npm.taobao.org/bonjour/download/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= - dependencies: - array-flatten "^2.1.0" - deep-equal "^1.0.1" - dns-equal "^1.0.0" - dns-txt "^2.0.2" - multicast-dns "^6.0.1" - multicast-dns-service-types "^1.1.0" - -boolbase@^1.0.0, boolbase@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/boolbase/download/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0= - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.npm.taobao.org/braces/download/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha1-WXn9PxTNUxVl5fot8av/8d+u5yk= - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.npm.taobao.org/brorand/download/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.2.0" - resolved "https://registry.npm.taobao.org/browserify-aes/download/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha1-Mmc0ZC9APavDADIJhTu3CtQo70g= - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/browserify-cipher/download/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha1-jWR0wbhwv9q807z8wZNKEOlPFfA= - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/browserify-des/download/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha1-OvTx9Zg5QDVy8cZiBDdfen9wPpw= - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.npm.taobao.org/browserify-rsa/download/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= - dependencies: - bn.js "^4.1.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.npm.taobao.org/browserify-sign/download/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.npm.taobao.org/browserify-zlib/download/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha1-KGlFnZqjviRf6P4sofRuLn9U1z8= - dependencies: - pako "~1.0.5" - -browserslist@^4.0.0, browserslist@^4.6.0, browserslist@^4.7.3, browserslist@^4.8.0, browserslist@^4.8.2: - version "4.8.2" - resolved "https://registry.npm.taobao.org/browserslist/download/browserslist-4.8.2.tgz#b45720ad5fbc8713b7253c20766f701c9a694289" - integrity sha1-tFcgrV+8hxO3JTwgdm9wHJppQok= - dependencies: - caniuse-lite "^1.0.30001015" - electron-to-chromium "^1.3.322" - node-releases "^1.1.42" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8= - -buffer-indexof@^1.0.0: - version "1.1.1" - resolved "https://registry.npm.taobao.org/buffer-indexof/download/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" - integrity sha1-Uvq8xqYG0aADAoAmSO9o9jnaJow= - -buffer-json@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/buffer-json/download/buffer-json-2.0.0.tgz#f73e13b1e42f196fe2fd67d001c7d7107edd7c23" - integrity sha1-9z4TseQvGW/i/WfQAcfXEH7dfCM= - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/buffer-xor/download/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= - -buffer@^4.3.0: - version "4.9.2" - resolved "https://registry.npm.taobao.org/buffer/download/buffer-4.9.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbuffer%2Fdownload%2Fbuffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha1-Iw6tNEACmIZEhBqwJEr4xEu+Pvg= - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/builtin-status-codes/download/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/bytes/download/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= - -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY= - -cacache@^12.0.2, cacache@^12.0.3: - version "12.0.3" - resolved "https://registry.npm.taobao.org/cacache/download/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" - integrity sha1-vpmruk4b9d9GHNWiwQcfxDJXM5A= - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cacache@^13.0.1: - version "13.0.1" - resolved "https://registry.npm.taobao.org/cacache/download/cacache-13.0.1.tgz#a8000c21697089082f85287a1aec6e382024a71c" - integrity sha1-qAAMIWlwiQgvhSh6GuxuOCAkpxw= - dependencies: - chownr "^1.1.2" - figgy-pudding "^3.5.1" - fs-minipass "^2.0.0" - glob "^7.1.4" - graceful-fs "^4.2.2" - infer-owner "^1.0.4" - lru-cache "^5.1.1" - minipass "^3.0.0" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - p-map "^3.0.0" - promise-inflight "^1.0.1" - rimraf "^2.7.1" - ssri "^7.0.0" - unique-filename "^1.1.1" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/cache-base/download/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha1-Cn9GQWgxyLZi7jb+TnxZ129marI= - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cache-loader@^4.1.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/cache-loader/download/cache-loader-4.1.0.tgz#9948cae353aec0a1fcb1eafda2300816ec85387e" - integrity sha1-mUjK41OuwKH8ser9ojAIFuyFOH4= - dependencies: - buffer-json "^2.0.0" - find-cache-dir "^3.0.0" - loader-utils "^1.2.3" - mkdirp "^0.5.1" - neo-async "^2.6.1" - schema-utils "^2.0.0" - -call-me-maybe@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/call-me-maybe/download/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" - integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= - -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/caller-callsite/download/caller-callsite-2.0.0.tgz?cache=0&sync_timestamp=1562668933683&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcaller-callsite%2Fdownload%2Fcaller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/caller-path/download/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/callsites/download/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/callsites/download/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M= - -camel-case@3.0.x: - version "3.0.0" - resolved "https://registry.npm.taobao.org/camel-case/download/camel-case-3.0.0.tgz?cache=0&sync_timestamp=1576748709736&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamel-case%2Fdownload%2Fcamel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" - integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= - dependencies: - no-case "^2.2.0" - upper-case "^1.1.1" - -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.npm.taobao.org/camelcase/download/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= - -camelcase@^5.0.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA= - -caniuse-api@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/caniuse-api/download/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" - integrity sha1-Xk2Q4idJYdRikZl99Znj7QCO5MA= - dependencies: - browserslist "^4.0.0" - caniuse-lite "^1.0.0" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" - -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001012, caniuse-lite@^1.0.30001015: - version "1.0.30001016" - resolved "https://registry.npm.taobao.org/caniuse-lite/download/caniuse-lite-1.0.30001016.tgz?cache=0&sync_timestamp=1576477999349&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcaniuse-lite%2Fdownload%2Fcaniuse-lite-1.0.30001016.tgz#16ea48d7d6e8caf3cad3295c2d746fe38c4e7f66" - integrity sha1-FupI19boyvPK0ylcLXRv44xOf2Y= - -case-sensitive-paths-webpack-plugin@^2.2.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/case-sensitive-paths-webpack-plugin/download/case-sensitive-paths-webpack-plugin-2.2.0.tgz#3371ef6365ef9c25fa4b81c16ace0e9c7dc58c3e" - integrity sha1-M3HvY2XvnCX6S4HBas4OnH3FjD4= - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.npm.taobao.org/caseless/download/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.npm.taobao.org/center-align/download/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - integrity sha1-qg0yYptu6XIgBBHL1EYckHvCt60= - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - -chalk@^1.1.1, chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.npm.taobao.org/chalk/download/chalk-1.1.3.tgz?cache=0&sync_timestamp=1573282918610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz?cache=0&sync_timestamp=1573282918610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ= - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/chalk/download/chalk-3.0.0.tgz?cache=0&sync_timestamp=1573282918610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha1-P3PCv1JlkfV0zEksUeJFY0n4ROQ= - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.npm.taobao.org/chardet/download/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha1-kAlISfCTfy7twkJdDSip5fDLrZ4= - -check-types@^8.0.3: - version "8.0.3" - resolved "https://registry.npm.taobao.org/check-types/download/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" - integrity sha1-M1bMoZyIlUTy16le1JzlCKDs9VI= - -chokidar@^2.0.2, chokidar@^2.1.8: - version "2.1.8" - resolved "https://registry.npm.taobao.org/chokidar/download/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha1-gEs6e2qZNYw8XGHnHYco8EHP+Rc= - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" - -chownr@^1.1.1, chownr@^1.1.2: - version "1.1.3" - resolved "https://registry.npm.taobao.org/chownr/download/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" - integrity sha1-Qtg31SOWiNVfMDADpQgjD6ZycUI= - -chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/chrome-trace-event/download/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha1-I0CQ7pfH1K0aLEvq4nUF3v/GCKQ= - dependencies: - tslib "^1.9.0" - -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.npm.taobao.org/ci-info/download/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha1-LKINu5zrMtRSSmgzAzE/AwSx5Jc= - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.npm.taobao.org/cipher-base/download/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.npm.taobao.org/class-utils/download/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha1-+TNprouafOAv1B+q0MqDAzGQxGM= - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -clean-css@4.2.x: - version "4.2.1" - resolved "https://registry.npm.taobao.org/clean-css/download/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" - integrity sha1-LUEe92uFabbQyEBo2r6FsKpeXBc= - dependencies: - source-map "~0.6.0" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/clean-stack/download/clean-stack-2.2.0.tgz?cache=0&sync_timestamp=1564586594378&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fclean-stack%2Fdownload%2Fclean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha1-7oRy27Ep5yezHooQpCfe6d/kAIs= - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/cli-cursor/download/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= - dependencies: - restore-cursor "^2.0.0" - -cli-highlight@^2.1.4: - version "2.1.4" - resolved "https://registry.npm.taobao.org/cli-highlight/download/cli-highlight-2.1.4.tgz?cache=0&sync_timestamp=1573948719956&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcli-highlight%2Fdownload%2Fcli-highlight-2.1.4.tgz#098cb642cf17f42adc1c1145e07f960ec4d7522b" - integrity sha1-CYy2Qs8X9CrcHBFF4H+WDsTXUis= - dependencies: - chalk "^3.0.0" - highlight.js "^9.6.0" - mz "^2.4.0" - parse5 "^5.1.1" - parse5-htmlparser2-tree-adapter "^5.1.1" - yargs "^15.0.0" - -cli-spinners@^2.0.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/cli-spinners/download/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" - integrity sha1-6LmI2SBsaSMC2O6DTnqFwBRNj3c= - -cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/cli-width/download/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= - -clipboardy@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/clipboardy/download/clipboardy-2.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fclipboardy%2Fdownload%2Fclipboardy-2.1.0.tgz#0123a0c8fac92f256dc56335e0bb8be97a4909a5" - integrity sha1-ASOgyPrJLyVtxWM14LuL6XpJCaU= - dependencies: - arch "^2.1.1" - execa "^1.0.0" - -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/cliui/download/cliui-2.1.0.tgz?cache=0&sync_timestamp=1573943292170&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcliui%2Fdownload%2Fcliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - integrity sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE= - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/cliui/download/cliui-4.1.0.tgz?cache=0&sync_timestamp=1573943292170&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcliui%2Fdownload%2Fcliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha1-NIQi2+gtgAswIu709qwQvy5NG0k= - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.npm.taobao.org/cliui/download/cliui-5.0.0.tgz?cache=0&sync_timestamp=1573943292170&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcliui%2Fdownload%2Fcliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha1-3u/P2y6AB4SqNPRvoI4GhRx7u8U= - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -cliui@^6.0.0: - version "6.0.0" - resolved "https://registry.npm.taobao.org/cliui/download/cliui-6.0.0.tgz?cache=0&sync_timestamp=1573943292170&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcliui%2Fdownload%2Fcliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" - integrity sha1-UR1wLAxOQcoVbX0OlgIfI+EyJbE= - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^6.2.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.npm.taobao.org/clone/download/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= - -clone@^2.1.1, clone@^2.1.2: - version "2.1.2" - resolved "https://registry.npm.taobao.org/clone/download/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= - -coa@^2.0.2: - version "2.0.2" - resolved "https://registry.npm.taobao.org/coa/download/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" - integrity sha1-Q/bCEVG07yv1cYfbDXPeIp4+fsM= - dependencies: - "@types/q" "^1.5.1" - chalk "^2.4.1" - q "^1.1.2" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/code-point-at/download/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/collection-visit/download/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0, color-convert@^1.9.1: - version "1.9.3" - resolved "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz?cache=0&sync_timestamp=1566248870121&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcolor-convert%2Fdownload%2Fcolor-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg= - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz?cache=0&sync_timestamp=1566248870121&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcolor-convert%2Fdownload%2Fcolor-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM= - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha1-wqCah6y95pVD3m9j+jmVyCbFNqI= - -color-string@^1.5.2: - version "1.5.3" - resolved "https://registry.npm.taobao.org/color-string/download/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha1-ybvF8BtYtUkvPWhXRZy2WQziBMw= - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@^3.0.0: - version "3.1.2" - resolved "https://registry.npm.taobao.org/color/download/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" - integrity sha1-aBSOf4XUGtdknF+oyBBvCY0inhA= - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha1-w9RaizT9cwYxoRCoolIGgrMdWn8= - dependencies: - delayed-stream "~1.0.0" - -commander@2, commander@^2.18.0, commander@^2.20.0, commander@~2.20.3: - version "2.20.3" - resolved "https://registry.npm.taobao.org/commander/download/commander-2.20.3.tgz?cache=0&sync_timestamp=1573464028535&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha1-/UhehMA+tIgcIHIrpIA16FMa6zM= - -commander@2.17.x: - version "2.17.1" - resolved "https://registry.npm.taobao.org/commander/download/commander-2.17.1.tgz?cache=0&sync_timestamp=1573464028535&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - integrity sha1-vXerfebelCBc6sxy8XFtKfIKd78= - -commander@~2.19.0: - version "2.19.0" - resolved "https://registry.npm.taobao.org/commander/download/commander-2.19.0.tgz?cache=0&sync_timestamp=1573464028535&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha1-9hmKqE5bg8RgVLlN3tv+1e6f8So= - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/commondir/download/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A= - -compressible@~2.0.16: - version "2.0.17" - resolved "https://registry.npm.taobao.org/compressible/download/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" - integrity sha1-bowQihatWDhKl386SCyiC/8vOME= - dependencies: - mime-db ">= 1.40.0 < 2" - -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.npm.taobao.org/compression/download/compression-1.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcompression%2Fdownload%2Fcompression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha1-lVI+/xcMpXwpoMpB5v4TH0Hlu48= - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.npm.taobao.org/concat-stream/download/concat-stream-1.6.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconcat-stream%2Fdownload%2Fconcat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ= - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -connect-history-api-fallback@^1.6.0: - version "1.6.0" - resolved "https://registry.npm.taobao.org/connect-history-api-fallback/download/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" - integrity sha1-izIIk1kwjRERFdgcrT/Oq4iPl7w= - -console-browserify@^1.1.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/console-browserify/download/console-browserify-1.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconsole-browserify%2Fdownload%2Fconsole-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" - integrity sha1-ZwY871fOts9Jk6KrOlWECujEkzY= - -consolidate@^0.15.1: - version "0.15.1" - resolved "https://registry.npm.taobao.org/consolidate/download/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" - integrity sha1-IasEMjXHGgfUXZqtmFk7DbpWurc= - dependencies: - bluebird "^3.1.1" - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/constants-browserify/download/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= - -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70= - dependencies: - safe-buffer "5.1.2" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha1-4TjMdeBAxyexlm/l5fjJruJW/js= - -contour_plot@^0.0.1: - version "0.0.1" - resolved "https://registry.npm.taobao.org/contour_plot/download/contour_plot-0.0.1.tgz#475870f032b8e338412aa5fc507880f0bf495c77" - integrity sha1-R1hw8DK44zhBKqX8UHiA8L9JXHc= - -convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.npm.taobao.org/convert-source-map/download/convert-source-map-1.7.0.tgz?cache=0&sync_timestamp=1573003637425&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconvert-source-map%2Fdownload%2Fconvert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha1-F6LLiC1/d9NJBYXizmxSRCSjpEI= - dependencies: - safe-buffer "~5.1.1" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.npm.taobao.org/cookie/download/cookie-0.4.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcookie%2Fdownload%2Fcookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha1-vrQ35wIrO21JAZ0IhmUwPr6cFLo= - -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.npm.taobao.org/copy-concurrently/download/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha1-kilzmMrjSTf8r9bsgTnBgFHwteA= - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.npm.taobao.org/copy-descriptor/download/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -copy-webpack-plugin@^5.0.5: - version "5.1.1" - resolved "https://registry.npm.taobao.org/copy-webpack-plugin/download/copy-webpack-plugin-5.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcopy-webpack-plugin%2Fdownload%2Fcopy-webpack-plugin-5.1.1.tgz#5481a03dea1123d88a988c6ff8b78247214f0b88" - integrity sha1-VIGgPeoRI9iKmIxv+LeCRyFPC4g= - dependencies: - cacache "^12.0.3" - find-cache-dir "^2.1.0" - glob-parent "^3.1.0" - globby "^7.1.1" - is-glob "^4.0.1" - loader-utils "^1.2.3" - minimatch "^3.0.4" - normalize-path "^3.0.0" - p-limit "^2.2.1" - schema-utils "^1.0.0" - serialize-javascript "^2.1.2" - webpack-log "^2.0.0" - -core-js-compat@^3.4.3, core-js-compat@^3.6.0: - version "3.6.0" - resolved "https://registry.npm.taobao.org/core-js-compat/download/core-js-compat-3.6.0.tgz?cache=0&sync_timestamp=1576713375694&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js-compat%2Fdownload%2Fcore-js-compat-3.6.0.tgz#4eb6cb69d03d99159ed7c860cd5fcf7d23a62ea9" - integrity sha1-TrbLadA9mRWe18hgzV/PfSOmLqk= - dependencies: - browserslist "^4.8.2" - semver "7.0.0" - -core-js@^3.4.3: - version "3.6.0" - resolved "https://registry.npm.taobao.org/core-js/download/core-js-3.6.0.tgz#2b854e451de1967d1e29896025cdc13a2518d9ea" - integrity sha1-K4VORR3hln0eKYlgJc3BOiUY2eo= - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cosmiconfig@^5.0.0: - version "5.2.1" - resolved "https://registry.npm.taobao.org/cosmiconfig/download/cosmiconfig-5.2.1.tgz?cache=0&sync_timestamp=1572710682964&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcosmiconfig%2Fdownload%2Fcosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - integrity sha1-BA9yaAnFked6F8CjYmykW08Wixo= - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - -create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.npm.taobao.org/create-ecdh/download/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha1-yREbbzMEXEaX8UR4f5JUzcd8Rf8= - dependencies: - bn.js "^4.1.0" - elliptic "^6.0.0" - -create-hash@^1.1.0, create-hash@^1.1.2: - version "1.2.0" - resolved "https://registry.npm.taobao.org/create-hash/download/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha1-iJB4rxGmN1a8+1m9IhmWvjqe8ZY= - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: - version "1.1.7" - resolved "https://registry.npm.taobao.org/create-hmac/download/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha1-aRcMeLOrlXFHsriwRXLkfq0iQ/8= - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q= - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^7.0.0: - version "7.0.1" - resolved "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" - integrity sha1-CrVihuD3wk4VPQTMKqAn5DqaXRQ= - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-browserify@^3.11.0: - version "3.12.0" - resolved "https://registry.npm.taobao.org/crypto-browserify/download/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha1-OWz58xN/A+S45TLFj2mCVOAPgOw= - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -css-color-names@0.0.4, css-color-names@^0.0.4: - version "0.0.4" - resolved "https://registry.npm.taobao.org/css-color-names/download/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= - -css-declaration-sorter@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/css-declaration-sorter/download/css-declaration-sorter-4.0.1.tgz?cache=0&sync_timestamp=1576525913209&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-declaration-sorter%2Fdownload%2Fcss-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" - integrity sha1-wZiUD2OnbX42wecQGLABchBUyyI= - dependencies: - postcss "^7.0.1" - timsort "^0.3.0" - -css-loader@^3.1.0: - version "3.4.0" - resolved "https://registry.npm.taobao.org/css-loader/download/css-loader-3.4.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-3.4.0.tgz#9fb263436783117a41d014e45e8eaeba54dd6670" - integrity sha1-n7JjQ2eDEXpB0BTkXo6uulTdZnA= - dependencies: - camelcase "^5.3.1" - cssesc "^3.0.0" - icss-utils "^4.1.1" - loader-utils "^1.2.3" - normalize-path "^3.0.0" - postcss "^7.0.23" - postcss-modules-extract-imports "^2.0.0" - postcss-modules-local-by-default "^3.0.2" - postcss-modules-scope "^2.1.1" - postcss-modules-values "^3.0.0" - postcss-value-parser "^4.0.2" - schema-utils "^2.6.0" - -css-select-base-adapter@^0.1.1: - version "0.1.1" - resolved "https://registry.npm.taobao.org/css-select-base-adapter/download/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" - integrity sha1-Oy/0lyzDYquIVhUHqVQIoUMhNdc= - -css-select@^1.1.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/css-select/download/css-select-1.2.0.tgz?cache=0&sync_timestamp=1573341911322&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-select%2Fdownload%2Fcss-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= - dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" - -css-select@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/css-select/download/css-select-2.1.0.tgz?cache=0&sync_timestamp=1573341911322&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-select%2Fdownload%2Fcss-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" - integrity sha1-ajRlM1ZjWTSoG6ymjQJVQyEF2+8= - dependencies: - boolbase "^1.0.0" - css-what "^3.2.1" - domutils "^1.7.0" - nth-check "^1.0.2" - -css-tree@1.0.0-alpha.37: - version "1.0.0-alpha.37" - resolved "https://registry.npm.taobao.org/css-tree/download/css-tree-1.0.0-alpha.37.tgz?cache=0&sync_timestamp=1575583846685&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-tree%2Fdownload%2Fcss-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" - integrity sha1-mL69YsTB2flg7DQM+fdSLjBwmiI= - dependencies: - mdn-data "2.0.4" - source-map "^0.6.1" - -css-unit-converter@^1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/css-unit-converter/download/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996" - integrity sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY= - -css-what@2.1: - version "2.1.3" - resolved "https://registry.npm.taobao.org/css-what/download/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha1-ptdgRXM2X+dGhsPzEcVlE9iChfI= - -css-what@^3.2.1: - version "3.2.1" - resolved "https://registry.npm.taobao.org/css-what/download/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" - integrity sha1-9KjxJCEGRiG0VnVeNKA6LCLfXaE= - -cssesc@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/cssesc/download/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" - integrity sha1-OxO9G7HLNuG8taTc0n9UxdyzVwM= - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/cssesc/download/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha1-N3QZGZA7hoVl4cCep0dEXNGJg+4= - -cssnano-preset-default@^4.0.0, cssnano-preset-default@^4.0.7: - version "4.0.7" - resolved "https://registry.npm.taobao.org/cssnano-preset-default/download/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" - integrity sha1-UexmLM/KD4izltzZZ5zbkxvhf3Y= - dependencies: - css-declaration-sorter "^4.0.1" - cssnano-util-raw-cache "^4.0.1" - postcss "^7.0.0" - postcss-calc "^7.0.1" - postcss-colormin "^4.0.3" - postcss-convert-values "^4.0.1" - postcss-discard-comments "^4.0.2" - postcss-discard-duplicates "^4.0.2" - postcss-discard-empty "^4.0.1" - postcss-discard-overridden "^4.0.1" - postcss-merge-longhand "^4.0.11" - postcss-merge-rules "^4.0.3" - postcss-minify-font-values "^4.0.2" - postcss-minify-gradients "^4.0.2" - postcss-minify-params "^4.0.2" - postcss-minify-selectors "^4.0.2" - postcss-normalize-charset "^4.0.1" - postcss-normalize-display-values "^4.0.2" - postcss-normalize-positions "^4.0.2" - postcss-normalize-repeat-style "^4.0.2" - postcss-normalize-string "^4.0.2" - postcss-normalize-timing-functions "^4.0.2" - postcss-normalize-unicode "^4.0.1" - postcss-normalize-url "^4.0.1" - postcss-normalize-whitespace "^4.0.2" - postcss-ordered-values "^4.1.2" - postcss-reduce-initial "^4.0.3" - postcss-reduce-transforms "^4.0.2" - postcss-svgo "^4.0.2" - postcss-unique-selectors "^4.0.1" - -cssnano-util-get-arguments@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/cssnano-util-get-arguments/download/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" - integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= - -cssnano-util-get-match@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/cssnano-util-get-match/download/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" - integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= - -cssnano-util-raw-cache@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/cssnano-util-raw-cache/download/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" - integrity sha1-sm1f1fcqEd/np4RvtMZyYPlr8oI= - dependencies: - postcss "^7.0.0" - -cssnano-util-same-parent@^4.0.0: - version "4.0.1" - resolved "https://registry.npm.taobao.org/cssnano-util-same-parent/download/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" - integrity sha1-V0CC+yhZ0ttDOFWDXZqEVuoYu/M= - -cssnano@^4.0.0, cssnano@^4.1.10: - version "4.1.10" - resolved "https://registry.npm.taobao.org/cssnano/download/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" - integrity sha1-CsQfCxPRPUZUh+ERt3jULaYxuLI= - dependencies: - cosmiconfig "^5.0.0" - cssnano-preset-default "^4.0.7" - is-resolvable "^1.0.0" - postcss "^7.0.0" - -csso@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/csso/download/csso-4.0.2.tgz#e5f81ab3a56b8eefb7f0092ce7279329f454de3d" - integrity sha1-5fgas6Vrju+38Aks5yeTKfRU3j0= - dependencies: - css-tree "1.0.0-alpha.37" - -current-script-polyfill@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/current-script-polyfill/download/current-script-polyfill-1.0.0.tgz#f31cf7e4f3e218b0726e738ca92a02d3488ef615" - integrity sha1-8xz35PPiGLBybnOMqSoC00iO9hU= - -cyclist@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/cyclist/download/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" - integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= - -d3-array@1, d3-array@~1.2.0: - version "1.2.4" - resolved "https://registry.npm.taobao.org/d3-array/download/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" - integrity sha1-Y1zk1e6nWfb2BYY9vPww7cc39x8= - -d3-collection@1: - version "1.0.7" - resolved "https://registry.npm.taobao.org/d3-collection/download/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" - integrity sha1-NJvSqpl32wcQkcExRNXk8WtbMQ4= - -d3-color@1: - version "1.4.0" - resolved "https://registry.npm.taobao.org/d3-color/download/d3-color-1.4.0.tgz#89c45a995ed773b13314f06460df26d60ba0ecaf" - integrity sha1-icRamV7Xc7EzFPBkYN8m1gug7K8= - -d3-composite-projections@~1.2.0: - version "1.2.3" - resolved "https://registry.npm.taobao.org/d3-composite-projections/download/d3-composite-projections-1.2.3.tgz?cache=0&sync_timestamp=1575570514199&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fd3-composite-projections%2Fdownload%2Fd3-composite-projections-1.2.3.tgz#d4283b32fca77ab0aeab92354f7726410f94b1cc" - integrity sha1-1Cg7MvynerCuq5I1T3cmQQ+Uscw= - dependencies: - d3-geo "^1.11.6" - d3-path "^1.0.7" - -d3-dispatch@1: - version "1.0.6" - resolved "https://registry.npm.taobao.org/d3-dispatch/download/d3-dispatch-1.0.6.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fd3-dispatch%2Fdownload%2Fd3-dispatch-1.0.6.tgz#00d37bcee4dd8cd97729dd893a0ac29caaba5d58" - integrity sha1-ANN7zuTdjNl3Kd2JOgrCnKq6XVg= - -d3-dsv@~1.0.5: - version "1.0.10" - resolved "https://registry.npm.taobao.org/d3-dsv/download/d3-dsv-1.0.10.tgz#4371c489a2a654a297aca16fcaf605a6f31a6f51" - integrity sha1-Q3HEiaKmVKKXrKFvyvYFpvMab1E= - dependencies: - commander "2" - iconv-lite "0.4" - rw "1" - -d3-ease@1, d3-ease@~1.0.3: - version "1.0.6" - resolved "https://registry.npm.taobao.org/d3-ease/download/d3-ease-1.0.6.tgz#ebdb6da22dfac0a22222f2d4da06f66c416a0ec0" - integrity sha1-69ttoi36wKIiIvLU2gb2bEFqDsA= - -d3-geo-projection@~2.1.2: - version "2.1.2" - resolved "https://registry.npm.taobao.org/d3-geo-projection/download/d3-geo-projection-2.1.2.tgz?cache=0&sync_timestamp=1573545296759&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fd3-geo-projection%2Fdownload%2Fd3-geo-projection-2.1.2.tgz#7df8e1e9d046d631c6509f7e531357d4adc24aa3" - integrity sha1-ffjh6dBG1jHGUJ9+UxNX1K3CSqM= - dependencies: - commander "2" - d3-array "1" - d3-geo "^1.1.0" - -d3-geo@^1.1.0, d3-geo@^1.11.6: - version "1.11.9" - resolved "https://registry.npm.taobao.org/d3-geo/download/d3-geo-1.11.9.tgz?cache=0&sync_timestamp=1573929664411&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fd3-geo%2Fdownload%2Fd3-geo-1.11.9.tgz#77eaed14ba62fc2c0aef55cd2943849c866f7ae6" - integrity sha1-d+rtFLpi/CwK71XNKUOEnIZveuY= - dependencies: - d3-array "1" - -d3-geo@~1.6.4: - version "1.6.4" - resolved "https://registry.npm.taobao.org/d3-geo/download/d3-geo-1.6.4.tgz?cache=0&sync_timestamp=1573929664411&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fd3-geo%2Fdownload%2Fd3-geo-1.6.4.tgz#f20e1e461cb1845f5a8be55ab6f876542a7e3199" - integrity sha1-8g4eRhyxhF9ai+Vatvh2VCp+MZk= - dependencies: - d3-array "1" - -d3-hexjson@~1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/d3-hexjson/download/d3-hexjson-1.0.1.tgz#6a23111e8359f1e214f5d0afa379c02b2b67df0b" - integrity sha1-aiMRHoNZ8eIU9dCvo3nAKytn3ws= - dependencies: - d3-array "1" - -d3-hierarchy@~1.1.5: - version "1.1.9" - resolved "https://registry.npm.taobao.org/d3-hierarchy/download/d3-hierarchy-1.1.9.tgz#2f6bee24caaea43f8dc37545fa01628559647a83" - integrity sha1-L2vuJMqupD+Nw3VF+gFihVlkeoM= - -d3-interpolate@1: - version "1.4.0" - resolved "https://registry.npm.taobao.org/d3-interpolate/download/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" - integrity sha1-Um554tgNqjg/ngwcHH3MDwWD6Yc= - dependencies: - d3-color "1" - -d3-interpolate@~1.1.5: - version "1.1.6" - resolved "https://registry.npm.taobao.org/d3-interpolate/download/d3-interpolate-1.1.6.tgz#2cf395ae2381804df08aa1bf766b7f97b5f68fb6" - integrity sha1-LPOVriOBgE3wiqG/dmt/l7X2j7Y= - dependencies: - d3-color "1" - -d3-path@1, d3-path@^1.0.7: - version "1.0.9" - resolved "https://registry.npm.taobao.org/d3-path/download/d3-path-1.0.9.tgz?cache=0&sync_timestamp=1573930859389&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fd3-path%2Fdownload%2Fd3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" - integrity sha1-SMBQux/owmJJOoyvVSTj6VkXAc8= - -d3-sankey@~0.7.1: - version "0.7.1" - resolved "https://registry.npm.taobao.org/d3-sankey/download/d3-sankey-0.7.1.tgz#d229832268fc69a7fec84803e96c2256a614c521" - integrity sha1-0imDImj8aaf+yEgD6WwiVqYUxSE= - dependencies: - d3-array "1" - d3-collection "1" - d3-shape "^1.2.0" - -d3-selection@^1.0.2, d3-selection@^1.1.0: - version "1.4.1" - resolved "https://registry.npm.taobao.org/d3-selection/download/d3-selection-1.4.1.tgz?cache=0&sync_timestamp=1573957585177&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fd3-selection%2Fdownload%2Fd3-selection-1.4.1.tgz#98eedbbe085fbda5bafa2f9e3f3a2f4d7d622a98" - integrity sha1-mO7bvghfvaW6+i+ePzovTX1iKpg= - -d3-shape@^1.2.0: - version "1.3.7" - resolved "https://registry.npm.taobao.org/d3-shape/download/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" - integrity sha1-32OAG+B7yYa8VPY3ibT+UCmStdc= - dependencies: - d3-path "1" - -d3-timer@1, d3-timer@~1.0.6: - version "1.0.10" - resolved "https://registry.npm.taobao.org/d3-timer/download/d3-timer-1.0.10.tgz?cache=0&sync_timestamp=1573938297645&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fd3-timer%2Fdownload%2Fd3-timer-1.0.10.tgz#dfe76b8a91748831b13b6d9c793ffbd508dd9de5" - integrity sha1-3+dripF0iDGxO22ceT/71QjdneU= - -d3-transition@^1.0.1: - version "1.3.2" - resolved "https://registry.npm.taobao.org/d3-transition/download/d3-transition-1.3.2.tgz#a98ef2151be8d8600543434c1ca80140ae23b398" - integrity sha1-qY7yFRvo2GAFQ0NMHKgBQK4js5g= - dependencies: - d3-color "1" - d3-dispatch "1" - d3-ease "1" - d3-interpolate "1" - d3-selection "^1.1.0" - d3-timer "1" - -d3-voronoi@~1.1.2: - version "1.1.4" - resolved "https://registry.npm.taobao.org/d3-voronoi/download/d3-voronoi-1.1.4.tgz#dd3c78d7653d2bb359284ae478645d95944c8297" - integrity sha1-3Tx412U9K7NZKErkeGRdlZRMgpc= - -dagre@~0.8.2: - version "0.8.5" - resolved "https://registry.npm.taobao.org/dagre/download/dagre-0.8.5.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdagre%2Fdownload%2Fdagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee" - integrity sha1-ujCwBV2sErbB/MJHgXRCd30Gr+4= - dependencies: - graphlib "^2.1.8" - lodash "^4.17.15" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.npm.taobao.org/dashdash/download/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -de-indent@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" - integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= - -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8= - dependencies: - ms "2.0.0" - -debug@^3.0.0, debug@^3.1.1, debug@^3.2.5: - version "3.2.6" - resolved "https://registry.npm.taobao.org/debug/download/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha1-6D0X3hbYp++3cX7b5fsQE17uYps= - dependencies: - ms "^2.1.1" - -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.1.1" - resolved "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E= - dependencies: - ms "^2.1.1" - -decamelize@^1.0.0, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/decamelize/download/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.npm.taobao.org/decode-uri-component/download/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -deep-equal@^1.0.1, deep-equal@~1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/deep-equal/download/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha1-tcmMlCzv+vfLBR4k4UNKJaLmB2o= - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.npm.taobao.org/deep-is/download/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -deepmerge@^1.5.2: - version "1.5.2" - resolved "https://registry.npm.taobao.org/deepmerge/download/deepmerge-1.5.2.tgz?cache=0&sync_timestamp=1572279720382&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdeepmerge%2Fdownload%2Fdeepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753" - integrity sha1-EEmdhohEza1P7ghC34x/bwyVp1M= - -default-gateway@^4.2.0: - version "4.2.0" - resolved "https://registry.npm.taobao.org/default-gateway/download/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" - integrity sha1-FnEEx1AMIRX23WmwpTa7jtcgVSs= - dependencies: - execa "^1.0.0" - ip-regex "^2.1.0" - -default-gateway@^5.0.5: - version "5.0.5" - resolved "https://registry.npm.taobao.org/default-gateway/download/default-gateway-5.0.5.tgz#4fd6bd5d2855d39b34cc5a59505486e9aafc9b10" - integrity sha1-T9a9XShV05s0zFpZUFSG6ar8mxA= - dependencies: - execa "^3.3.0" - -defaults@^1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/defaults/download/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= - dependencies: - clone "^1.0.2" - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.npm.taobao.org/define-properties/download/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE= - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.npm.taobao.org/define-property/download/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/define-property/download/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.npm.taobao.org/define-property/download/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha1-1Flono1lS6d+AqgX+HENcCyxbp0= - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -defined@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/defined/download/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= - -del@^4.1.1: - version "4.1.1" - resolved "https://registry.npm.taobao.org/del/download/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" - integrity sha1-no8RciLqRKMf86FWwEm5kFKp8LQ= - dependencies: - "@types/glob" "^7.1.1" - globby "^6.1.0" - is-path-cwd "^2.0.0" - is-path-in-cwd "^2.0.0" - p-map "^2.0.0" - pify "^4.0.1" - rimraf "^2.6.3" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/des.js/download/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha1-U4IULhvcU/hdhtU+X0qn3rkeCEM= - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detect-node@^2.0.4: - version "2.0.4" - resolved "https://registry.npm.taobao.org/detect-node/download/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" - integrity sha1-AU7o+PZpxcWAI9pkuBecCDooxGw= - -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.npm.taobao.org/diffie-hellman/download/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha1-QOjumPVaIUlgcUaSHGPhrl89KHU= - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -dir-glob@^2.0.0, dir-glob@^2.2.2: - version "2.2.2" - resolved "https://registry.npm.taobao.org/dir-glob/download/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" - integrity sha1-+gnwaUFTyJGLGLoN6vrpR2n8UMQ= - dependencies: - path-type "^3.0.0" - -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/dns-equal/download/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= - -dns-packet@^1.3.1: - version "1.3.1" - resolved "https://registry.npm.taobao.org/dns-packet/download/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" - integrity sha1-EqpCaYEHW+UAuRDu3NC0fdfe2lo= - dependencies: - ip "^1.1.0" - safe-buffer "^5.0.1" - -dns-txt@^2.0.2: - version "2.0.2" - resolved "https://registry.npm.taobao.org/dns-txt/download/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= - dependencies: - buffer-indexof "^1.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/doctrine/download/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha1-rd6+rXKmV023g2OdyHoSF3OXOWE= - dependencies: - esutils "^2.0.2" - -dom-converter@^0.2: - version "0.2.0" - resolved "https://registry.npm.taobao.org/dom-converter/download/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" - integrity sha1-ZyGp2u4uKTaClVtq/kFncWJ7t2g= - dependencies: - utila "~0.4" - -dom-serializer@0: - version "0.2.2" - resolved "https://registry.npm.taobao.org/dom-serializer/download/dom-serializer-0.2.2.tgz?cache=0&sync_timestamp=1573447907918&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdom-serializer%2Fdownload%2Fdom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" - integrity sha1-GvuB9TNxcXXUeGVd68XjMtn5u1E= - dependencies: - domelementtype "^2.0.1" - entities "^2.0.0" - -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.npm.taobao.org/domain-browser/download/domain-browser-1.2.0.tgz?cache=0&sync_timestamp=1575879298649&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdomain-browser%2Fdownload%2Fdomain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - integrity sha1-PTH1AZGmdJ3RN1p/Ui6CPULlTto= - -domelementtype@1, domelementtype@^1.3.1: - version "1.3.1" - resolved "https://registry.npm.taobao.org/domelementtype/download/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha1-0EjESzew0Qp/Kj1f7j9DM9eQSB8= - -domelementtype@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/domelementtype/download/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" - integrity sha1-H4vf6R9aeAYydOgDtL3O326U+U0= - -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.npm.taobao.org/domhandler/download/domhandler-2.4.2.tgz?cache=0&sync_timestamp=1564708909977&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdomhandler%2Fdownload%2Fdomhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha1-iAUJfpM9ZehVRvcm1g9euItE+AM= - dependencies: - domelementtype "1" - -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.npm.taobao.org/domutils/download/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= - dependencies: - dom-serializer "0" - domelementtype "1" - -domutils@^1.5.1, domutils@^1.7.0: - version "1.7.0" - resolved "https://registry.npm.taobao.org/domutils/download/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha1-Vuo0HoNOBuZ0ivehyyXaZ+qfjCo= - dependencies: - dom-serializer "0" - domelementtype "1" - -dot-prop@^4.1.1: - version "4.2.0" - resolved "https://registry.npm.taobao.org/dot-prop/download/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" - integrity sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc= - dependencies: - is-obj "^1.0.0" - -dotenv-expand@^5.1.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/dotenv-expand/download/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" - integrity sha1-P7rwIL/XlIhAcuomsel5HUWmKfA= - -dotenv@^8.2.0: - version "8.2.0" - resolved "https://registry.npm.taobao.org/dotenv/download/dotenv-8.2.0.tgz?cache=0&sync_timestamp=1571190696472&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdotenv%2Fdownload%2Fdotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" - integrity sha1-l+YZJZradQ7qPk6j4mvO6lQksWo= - -duplexer@^0.1.1: - version "0.1.1" - resolved "https://registry.npm.taobao.org/duplexer/download/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= - -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.npm.taobao.org/duplexify/download/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha1-Kk31MX9sz9kfhtb9JdjYoQO4gwk= - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -easy-stack@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/easy-stack/download/easy-stack-1.0.0.tgz#12c91b3085a37f0baa336e9486eac4bf94e3e788" - integrity sha1-EskbMIWjfwuqM26UhurEv5Tj54g= - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.npm.taobao.org/ecc-jsbn/download/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -echarts@^4.5.0: - version "4.5.0" - resolved "https://registry.npm.taobao.org/echarts/download/echarts-4.5.0.tgz#2111960645a345eb819ddac4792a2c065bdff162" - integrity sha1-IRGWBkWjReuBndrEeSosBlvf8WI= - dependencies: - zrender "4.1.2" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -ejs@^2.6.1: - version "2.7.4" - resolved "https://registry.npm.taobao.org/ejs/download/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" - integrity sha1-SGYSh1c9zFPjZsehrlLDoSDuybo= - -electron-to-chromium@^1.3.322: - version "1.3.322" - resolved "https://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.322.tgz#a6f7e1c79025c2b05838e8e344f6e89eb83213a8" - integrity sha1-pvfhx5AlwrBYOOjjRPbonrgyE6g= - -elliptic@^6.0.0: - version "6.5.2" - resolved "https://registry.npm.taobao.org/elliptic/download/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" - integrity sha1-BcVnjXFzwEnYykM1UiJKSV0ON2I= - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY= - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc= - -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/emojis-list/download/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.npm.taobao.org/end-of-stream/download/end-of-stream-1.4.4.tgz?cache=0&sync_timestamp=1569416367473&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fend-of-stream%2Fdownload%2Fend-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha1-WuZKX0UFe682JuwU2gyl5LJDHrA= - dependencies: - once "^1.4.0" - -enhanced-resolve@^4.1.0: - version "4.1.1" - resolved "https://registry.npm.taobao.org/enhanced-resolve/download/enhanced-resolve-4.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" - integrity sha1-KTfiuAZs0P584JkKmPDXGjUYn2Y= - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.5.0" - tapable "^1.0.0" - -entities@^1.1.1: - version "1.1.2" - resolved "https://registry.npm.taobao.org/entities/download/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha1-vfpzUplmTfr9NFKe1PhSKidf6lY= - -entities@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/entities/download/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" - integrity sha1-aNYITKsbB5dnVA2A5Wo5tCPkq/Q= - -errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.npm.taobao.org/errno/download/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha1-RoTXF3mtOa8Xfj8AeZb3xnyFJhg= - dependencies: - prr "~1.0.1" - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.npm.taobao.org/error-ex/download/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha1-tKxAZIEH/c3PriQvQovqihTU8b8= - dependencies: - is-arrayish "^0.2.1" - -error-stack-parser@^2.0.0: - version "2.0.4" - resolved "https://registry.npm.taobao.org/error-stack-parser/download/error-stack-parser-2.0.4.tgz#a757397dc5d9de973ac9a5d7d4e8ade7cfae9101" - integrity sha1-p1c5fcXZ3pc6yaXX1Oit58+ukQE= - dependencies: - stackframe "^1.1.0" - -es-abstract@^1.17.0-next.1: - version "1.17.0" - resolved "https://registry.npm.taobao.org/es-abstract/download/es-abstract-1.17.0.tgz?cache=0&sync_timestamp=1576883946566&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fes-abstract%2Fdownload%2Fes-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1" - integrity sha1-9CpRfQA2pVkduyxGNZHci7UDCbE= - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.1.5" - is-regex "^1.0.5" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimleft "^2.1.1" - string.prototype.trimright "^2.1.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.npm.taobao.org/es-to-primitive/download/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha1-5VzUyc3BiLzvsDs2bHNjI/xciYo= - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-loader@^2.1.2: - version "2.2.1" - resolved "https://registry.npm.taobao.org/eslint-loader/download/eslint-loader-2.2.1.tgz#28b9c12da54057af0845e2a6112701a2f6bf8337" - integrity sha1-KLnBLaVAV68IReKmEScBova/gzc= - dependencies: - loader-fs-cache "^1.0.0" - loader-utils "^1.0.2" - object-assign "^4.0.1" - object-hash "^1.1.4" - rimraf "^2.6.1" - -eslint-plugin-vue@^5.0.0: - version "5.2.3" - resolved "https://registry.npm.taobao.org/eslint-plugin-vue/download/eslint-plugin-vue-5.2.3.tgz?cache=0&sync_timestamp=1573637216763&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-vue%2Fdownload%2Feslint-plugin-vue-5.2.3.tgz#3ee7597d823b5478804b2feba9863b1b74273961" - integrity sha1-PudZfYI7VHiASy/rqYY7G3QnOWE= - dependencies: - vue-eslint-parser "^5.0.0" - -eslint-scope@^4.0.0, eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.npm.taobao.org/eslint-scope/download/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha1-ygODMxD2iJoyZHgaqC5j65z+eEg= - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-utils@^1.3.1: - version "1.4.3" - resolved "https://registry.npm.taobao.org/eslint-utils/download/eslint-utils-1.4.3.tgz?cache=0&sync_timestamp=1571580716410&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-utils%2Fdownload%2Feslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha1-dP7HxU0Hdrb2fgJRBAtYBlZOmB8= - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/eslint-visitor-keys/download/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" - integrity sha1-4qgs6oT/JGrW+1f5veW0ZiFFnsI= - -eslint@^5.16.0: - version "5.16.0" - resolved "https://registry.npm.taobao.org/eslint/download/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" - integrity sha1-oeOsGq5KP72Clvz496tzFMu2q+o= - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.9.1" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^4.0.3" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^5.0.1" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob "^7.1.2" - globals "^11.7.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^6.2.2" - js-yaml "^3.13.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.11" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.2" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^5.5.1" - strip-ansi "^4.0.0" - strip-json-comments "^2.0.1" - table "^5.2.3" - text-table "^0.2.0" - -espree@^4.1.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/espree/download/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" - integrity sha1-co1UUeD9FWwEOEp62J7VH/VOsl8= - dependencies: - acorn "^6.0.2" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" - -espree@^5.0.1: - version "5.0.1" - resolved "https://registry.npm.taobao.org/espree/download/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" - integrity sha1-XWUm+k/H8HiKXPdbFfMDI+L4H3o= - dependencies: - acorn "^6.0.7" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.npm.taobao.org/esprima/download/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha1-E7BM2z5sXRnfkatph6hpVhmwqnE= - -esquery@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/esquery/download/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" - integrity sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg= - dependencies: - estraverse "^4.0.0" - -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.npm.taobao.org/esrecurse/download/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8= - dependencies: - estraverse "^4.1.0" - -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.npm.taobao.org/estraverse/download/estraverse-4.3.0.tgz?cache=0&sync_timestamp=1565734335990&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0= - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.npm.taobao.org/esutils/download/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q= - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.npm.taobao.org/etag/download/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -event-pubsub@4.3.0: - version "4.3.0" - resolved "https://registry.npm.taobao.org/event-pubsub/download/event-pubsub-4.3.0.tgz#f68d816bc29f1ec02c539dc58c8dd40ce72cb36e" - integrity sha1-9o2Ba8KfHsAsU53FjI3UDOcss24= - -eventemitter3@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/eventemitter3/download/eventemitter3-4.0.0.tgz?cache=0&sync_timestamp=1560950873670&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feventemitter3%2Fdownload%2Feventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" - integrity sha1-1lF2FjiH7lnzhtZMgmELaWpKdOs= - -events@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/events/download/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" - integrity sha1-mgoN+vYok9krh1uPJpjKQRSXPog= - -eventsource@^1.0.7: - version "1.0.7" - resolved "https://registry.npm.taobao.org/eventsource/download/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" - integrity sha1-j7xyyT/NNAiAkLwKTmT0tc7m2NA= - dependencies: - original "^1.0.0" - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/evp_bytestokey/download/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI= - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@^0.8.0: - version "0.8.0" - resolved "https://registry.npm.taobao.org/execa/download/execa-0.8.0.tgz?cache=0&sync_timestamp=1576749091315&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" - integrity sha1-2NdrvBtVIX7RkP1t1J08d07PyNo= - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/execa/download/execa-1.0.0.tgz?cache=0&sync_timestamp=1576749091315&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha1-xiNqW7TfbW8V6I5/AXeYIWdJ3dg= - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^3.3.0: - version "3.4.0" - resolved "https://registry.npm.taobao.org/execa/download/execa-3.4.0.tgz?cache=0&sync_timestamp=1576749091315&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" - integrity sha1-wI7UVQ72XYWPrCaf/IVyRG8364k= - dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - p-finally "^2.0.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.npm.taobao.org/expand-brackets/download/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -express@^4.16.3, express@^4.17.1: - version "4.17.1" - resolved "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ= - dependencies: - accepts "~1.3.7" - array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" - content-type "~1.0.4" - cookie "0.4.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" - range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo= - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.npm.taobao.org/external-editor/download/external-editor-3.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexternal-editor%2Fdownload%2Fexternal-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha1-ywP3QL764D6k0oPK7SdBqD8zVJU= - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.npm.taobao.org/extglob/download/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM= - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.npm.taobao.org/extsprintf/download/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.npm.taobao.org/extsprintf/download/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= - -fast-glob@^2.2.6: - version "2.2.7" - resolved "https://registry.npm.taobao.org/fast-glob/download/fast-glob-2.2.7.tgz?cache=0&sync_timestamp=1575197566634&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-glob%2Fdownload%2Ffast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" - integrity sha1-aVOFfDr6R1//ku5gFdUtpwpM050= - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.1.0.tgz?cache=0&sync_timestamp=1576340291001&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-json-stable-stringify%2Fdownload%2Ffast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM= - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.npm.taobao.org/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -faye-websocket@^0.10.0: - version "0.10.0" - resolved "https://registry.npm.taobao.org/faye-websocket/download/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" - integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= - dependencies: - websocket-driver ">=0.5.1" - -faye-websocket@~0.11.1: - version "0.11.3" - resolved "https://registry.npm.taobao.org/faye-websocket/download/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" - integrity sha1-XA6aiWjokSwoZjn96XeosgnyUI4= - dependencies: - websocket-driver ">=0.5.1" - -fecha@~2.3.3: - version "2.3.3" - resolved "https://registry.npm.taobao.org/fecha/download/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" - integrity sha1-lI50FX3xoy/RsSw6PDzctuydls0= - -figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.npm.taobao.org/figgy-pudding/download/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - integrity sha1-hiRwESkBxyeg5JWoB0S9W6odZ5A= - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/figures/download/figures-2.0.0.tgz?cache=0&sync_timestamp=1571715625804&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffigures%2Fdownload%2Ffigures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.npm.taobao.org/file-entry-cache/download/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha1-yg9u+m3T1WEzP7FFFQZcL6/fQ5w= - dependencies: - flat-cache "^2.0.1" - -file-loader@^4.2.0: - version "4.3.0" - resolved "https://registry.npm.taobao.org/file-loader/download/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af" - integrity sha1-eA8ED3KbPRgBnyBgX3I+hEuKWK8= - dependencies: - loader-utils "^1.2.3" - schema-utils "^2.5.0" - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/file-uri-to-path/download/file-uri-to-path-1.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffile-uri-to-path%2Fdownload%2Ffile-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90= - -filesize@^3.6.1: - version "3.6.1" - resolved "https://registry.npm.taobao.org/filesize/download/filesize-3.6.1.tgz?cache=0&sync_timestamp=1573255715350&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffilesize%2Fdownload%2Ffilesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" - integrity sha1-CQuz7gG2+AGoqL6Z0xcQs0Irsxc= - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/fill-range/download/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/finalhandler/download/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0= - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -find-cache-dir@^0.1.1: - version "0.1.1" - resolved "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" - integrity sha1-yN765XyKUqinhPnjHFfHQumToLk= - dependencies: - commondir "^1.0.1" - mkdirp "^0.5.1" - pkg-dir "^1.0.0" - -find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha1-jQ+UzRP+Q8bHwmGg2GEVypGMBfc= - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-cache-dir@^3.0.0, find-cache-dir@^3.2.0: - version "3.2.0" - resolved "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-3.2.0.tgz#e7fe44c1abc1299f516146e563108fd1006c1874" - integrity sha1-5/5EwavBKZ9RYUblYxCP0QBsGHQ= - dependencies: - commondir "^1.0.1" - make-dir "^3.0.0" - pkg-dir "^4.1.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.npm.taobao.org/find-up/download/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/find-up/download/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha1-SRafHXmTQwZG2mHsxa41XCHJe3M= - dependencies: - locate-path "^3.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk= - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/flat-cache/download/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha1-XSltbwS9pEpGMKMBQTvbwuwIXsA= - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flatted@^2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/flatted/download/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" - integrity sha1-aeV8qo8OrLwoHS4stFjUb9tEngg= - -flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.npm.taobao.org/flush-write-stream/download/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha1-jdfYc6G6vCB9lOrQwuDkQnbr8ug= - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - -fmin@0.0.2: - version "0.0.2" - resolved "https://registry.npm.taobao.org/fmin/download/fmin-0.0.2.tgz#59bbb40d43ffdc1c94cd00a568c41f95f1973017" - integrity sha1-Wbu0DUP/3ByUzQClaMQflfGXMBc= - dependencies: - contour_plot "^0.0.1" - json2module "^0.0.3" - rollup "^0.25.8" - tape "^4.5.1" - uglify-js "^2.6.2" - -follow-redirects@^1.0.0: - version "1.9.0" - resolved "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.9.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.9.0.tgz#8d5bcdc65b7108fe1508649c79c12d732dcedb4f" - integrity sha1-jVvNxltxCP4VCGScecEtcy3O208= - dependencies: - debug "^3.0.0" - -for-each@~0.3.3: - version "0.3.3" - resolved "https://registry.npm.taobao.org/for-each/download/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha1-abRH6IoKXTLD5whPPxcQA0shN24= - dependencies: - is-callable "^1.1.3" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/for-in/download/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.npm.taobao.org/forever-agent/download/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.npm.taobao.org/form-data/download/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha1-3M5SwF9kTymManq5Nr1yTO/786Y= - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.npm.taobao.org/forwarded/download/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.npm.taobao.org/fragment-cache/download/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.npm.taobao.org/from2/download/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.npm.taobao.org/fs-extra/download/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha1-TxicRKoSO4lfcigE9V6iPq3DSOk= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-minipass@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/fs-minipass/download/fs-minipass-2.0.0.tgz#a6415edab02fae4b9e9230bc87ee2e4472003cd1" - integrity sha1-pkFe2rAvrkuekjC8h+4uRHIAPNE= - dependencies: - minipass "^3.0.0" - -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.npm.taobao.org/fs-write-stream-atomic/download/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.7: - version "1.2.11" - resolved "https://registry.npm.taobao.org/fsevents/download/fsevents-1.2.11.tgz?cache=0&sync_timestamp=1576322865545&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffsevents%2Fdownload%2Ffsevents-1.2.11.tgz#67bf57f4758f02ede88fb2a1712fef4d15358be3" - integrity sha1-Z79X9HWPAu3oj7KhcS/vTRU1i+M= - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - -function-bind@^1.1.1, function-bind@~1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0= - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/functional-red-black-tree/download/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.npm.taobao.org/get-caller-file/download/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha1-+Xj6TJDR3+f/LWvtoqUV5xO9z0o= - -get-caller-file@^2.0.1: - version "2.0.5" - resolved "https://registry.npm.taobao.org/get-caller-file/download/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha1-T5RBKoLbMvNuOwuXQfipf+sDH34= - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/get-stream/download/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/get-stream/download/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha1-wbJVV189wh1Zv8ec09K0axw6VLU= - dependencies: - pump "^3.0.0" - -get-stream@^5.0.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/get-stream/download/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" - integrity sha1-ASA83JJZf5uQkGfD5lbMH008Tck= - dependencies: - pump "^3.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.npm.taobao.org/get-value/download/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.npm.taobao.org/getpass/download/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/glob-parent/download/glob-parent-3.1.0.tgz?cache=0&sync_timestamp=1569108917227&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglob-parent%2Fdownload%2Fglob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.npm.taobao.org/glob-to-regexp/download/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= - -glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.6: - version "7.1.6" - resolved "https://registry.npm.taobao.org/glob/download/glob-7.1.6.tgz?cache=0&sync_timestamp=1573078121947&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglob%2Fdownload%2Fglob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY= - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0, globals@^11.7.0: - version "11.12.0" - resolved "https://registry.npm.taobao.org/globals/download/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha1-q4eVM4hooLq9hSV1gBjCp+uVxC4= - -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.npm.taobao.org/globby/download/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -globby@^7.1.1: - version "7.1.1" - resolved "https://registry.npm.taobao.org/globby/download/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" - integrity sha1-+yzP+UAfhgCUXfral0QMypcrhoA= - dependencies: - array-union "^1.0.1" - dir-glob "^2.0.0" - glob "^7.1.2" - ignore "^3.3.5" - pify "^3.0.0" - slash "^1.0.0" - -globby@^9.2.0: - version "9.2.0" - resolved "https://registry.npm.taobao.org/globby/download/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" - integrity sha1-/QKacGxwPSm90XD0tts6P3p8tj0= - dependencies: - "@types/glob" "^7.1.1" - array-union "^1.0.2" - dir-glob "^2.2.2" - fast-glob "^2.2.6" - glob "^7.1.3" - ignore "^4.0.3" - pify "^4.0.1" - slash "^2.0.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.2: - version "4.2.3" - resolved "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha1-ShL/G2A3bvCYYsIJPt2Qgyi+hCM= - -graphlib@^2.1.8: - version "2.1.8" - resolved "https://registry.npm.taobao.org/graphlib/download/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da" - integrity sha1-V2HUFHN4cAhMkux7XbywWSydNdo= - dependencies: - lodash "^4.17.15" - -gzip-size@^5.0.0: - version "5.1.1" - resolved "https://registry.npm.taobao.org/gzip-size/download/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" - integrity sha1-y5vuaS+HwGErIyhAqHOQTkwTUnQ= - dependencies: - duplexer "^0.1.1" - pify "^4.0.1" - -handle-thing@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/handle-thing/download/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" - integrity sha1-DgOWlf9QyT/CiFV9aW88HcZ3Z1Q= - -handlebars@^4.5.3: - version "4.5.3" - resolved "https://registry.npm.taobao.org/handlebars/download/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482" - integrity sha1-XPdb2HFPdgVxNRGla+fDSb7LBII= - dependencies: - neo-async "^2.6.0" - optimist "^0.6.1" - source-map "^0.6.1" - optionalDependencies: - uglify-js "^3.1.4" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/har-schema/download/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.0: - version "5.1.3" - resolved "https://registry.npm.taobao.org/har-validator/download/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha1-HvievT5JllV2de7ZiTEQ3DUPoIA= - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/has-ansi/download/has-ansi-2.0.0.tgz?cache=0&sync_timestamp=1568144533484&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-ansi%2Fdownload%2Fhas-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s= - -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/has-symbols/download/has-symbols-1.0.1.tgz?cache=0&sync_timestamp=1573950719586&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-symbols%2Fdownload%2Fhas-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha1-n1IUdYpEGWxAbZvXbOv4HsLdMeg= - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.npm.taobao.org/has-value/download/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/has-value/download/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.npm.taobao.org/has-values/download/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/has-values/download/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.0, has@^1.0.3, has@~1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/has/download/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y= - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.npm.taobao.org/hash-base/download/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -hash-sum@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/hash-sum/download/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" - integrity sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ= - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.npm.taobao.org/hash.js/download/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha1-C6vKU46NTuSg+JiNaIZlN6ADz0I= - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -he@1.2.x, he@^1.1.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/he/download/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha1-hK5l+n6vsWX922FWauFLrwVmTw8= - -hex-color-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/hex-color-regex/download/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" - integrity sha1-TAb8y0YC/iYCs8k9+C1+fb8aio4= - -highlight.js@^9.6.0: - version "9.17.1" - resolved "https://registry.npm.taobao.org/highlight.js/download/highlight.js-9.17.1.tgz?cache=0&sync_timestamp=1576163806990&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhighlight.js%2Fdownload%2Fhighlight.js-9.17.1.tgz#14a4eded23fd314b05886758bb906e39dd627f9a" - integrity sha1-FKTt7SP9MUsFiGdYu5BuOd1if5o= - dependencies: - handlebars "^4.5.3" - -hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/hmac-drbg/download/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -hoopy@^0.1.4: - version "0.1.4" - resolved "https://registry.npm.taobao.org/hoopy/download/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" - integrity sha1-YJIH1mEQADOpqUAq096mdzgcGx0= - -hosted-git-info@^2.1.4: - version "2.8.5" - resolved "https://registry.npm.taobao.org/hosted-git-info/download/hosted-git-info-2.8.5.tgz?cache=0&sync_timestamp=1570493686863&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhosted-git-info%2Fdownload%2Fhosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" - integrity sha1-dZz88sTRVq3lmwst+r3cQqa5xww= - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.npm.taobao.org/hpack.js/download/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -hsl-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/hsl-regex/download/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" - integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= - -hsla-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/hsla-regex/download/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" - integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= - -html-comment-regex@^1.1.0: - version "1.1.2" - resolved "https://registry.npm.taobao.org/html-comment-regex/download/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" - integrity sha1-l9RoiutcgYhqNk+qDK0d2hTUM6c= - -html-entities@^1.2.1: - version "1.2.1" - resolved "https://registry.npm.taobao.org/html-entities/download/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" - integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= - -html-minifier@^3.2.3: - version "3.5.21" - resolved "https://registry.npm.taobao.org/html-minifier/download/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" - integrity sha1-0AQOBUcw41TbAIRjWTGUAVIS0gw= - dependencies: - camel-case "3.0.x" - clean-css "4.2.x" - commander "2.17.x" - he "1.2.x" - param-case "2.1.x" - relateurl "0.2.x" - uglify-js "3.4.x" - -html-tags@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/html-tags/download/html-tags-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-tags%2Fdownload%2Fhtml-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b" - integrity sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos= - -html-webpack-plugin@^3.2.0: - version "3.2.0" - resolved "https://registry.npm.taobao.org/html-webpack-plugin/download/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" - integrity sha1-sBq71yOsqqeze2r0SS69oD2d03s= - dependencies: - html-minifier "^3.2.3" - loader-utils "^0.2.16" - lodash "^4.17.3" - pretty-error "^2.0.2" - tapable "^1.0.0" - toposort "^1.0.0" - util.promisify "1.0.0" - -htmlparser2@^3.3.0: - version "3.10.1" - resolved "https://registry.npm.taobao.org/htmlparser2/download/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha1-vWedw/WYl7ajS7EHSchVu1OpOS8= - dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.npm.taobao.org/http-deceiver/download/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= - -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha1-bGGeT5xgMIw4UZSYwU+7EKrOuwY= - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -"http-parser-js@>=0.4.0 <0.4.11": - version "0.4.10" - resolved "https://registry.npm.taobao.org/http-parser-js/download/http-parser-js-0.4.10.tgz?cache=0&sync_timestamp=1572714277347&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-parser-js%2Fdownload%2Fhttp-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" - integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= - -http-proxy-middleware@0.19.1: - version "0.19.1" - resolved "https://registry.npm.taobao.org/http-proxy-middleware/download/http-proxy-middleware-0.19.1.tgz?cache=0&sync_timestamp=1567540672067&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-proxy-middleware%2Fdownload%2Fhttp-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" - integrity sha1-GDx9xKoUeRUDBkmMIQza+WCApDo= - dependencies: - http-proxy "^1.17.0" - is-glob "^4.0.0" - lodash "^4.17.11" - micromatch "^3.1.10" - -http-proxy@^1.17.0: - version "1.18.0" - resolved "https://registry.npm.taobao.org/http-proxy/download/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a" - integrity sha1-2+VfY+daNH2389mZdPJpKjFKajo= - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/http-signature/download/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/https-browserify/download/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= - -human-signals@^1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/human-signals/download/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" - integrity sha1-xbHNFPUK6uCatsWf5jujOV/k36M= - -iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha1-ICK0sl+93CHS9SSXSkdKr+czkIs= - dependencies: - safer-buffer ">= 2.1.2 < 3" - -icss-utils@^4.0.0, icss-utils@^4.1.1: - version "4.1.1" - resolved "https://registry.npm.taobao.org/icss-utils/download/icss-utils-4.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ficss-utils%2Fdownload%2Ficss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" - integrity sha1-IRcLU3ie4nRHwvR91oMIFAP5pGc= - dependencies: - postcss "^7.0.14" - -ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.npm.taobao.org/ieee754/download/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha1-7BaFWOlaoYH9h9N/VcMrvLZwi4Q= - -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.npm.taobao.org/iferr/download/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= - -ignore@^3.3.5: - version "3.3.10" - resolved "https://registry.npm.taobao.org/ignore/download/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" - integrity sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM= - -ignore@^4.0.3, ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.npm.taobao.org/ignore/download/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw= - -image-size@~0.5.0: - version "0.5.5" - resolved "https://registry.npm.taobao.org/image-size/download/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" - integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= - -import-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/import-cwd/download/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" - integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= - dependencies: - import-from "^2.1.0" - -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/import-fresh/download/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - -import-fresh@^3.0.0: - version "3.2.1" - resolved "https://registry.npm.taobao.org/import-fresh/download/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha1-Yz/2GFBueTr1rJG/SLcmd+FcvmY= - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-from@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/import-from/download/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" - integrity sha1-M1238qev/VOqpHHUuAId7ja387E= - dependencies: - resolve-from "^3.0.0" - -import-local@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/import-local/download/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha1-VQcL44pZk88Y72236WH1vuXFoJ0= - dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npm.taobao.org/imurmurhash/download/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/indent-string/download/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha1-Yk+PRJfWGbLZdoUx1Y9BIoVNclE= - -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/indexes-of/download/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= - -infer-owner@^1.0.3, infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.npm.taobao.org/infer-owner/download/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha1-xM78qo5RBRwqQLos6KPScpWvlGc= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: - version "2.0.4" - resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w= - -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -inquirer@^6.2.2: - version "6.5.2" - resolved "https://registry.npm.taobao.org/inquirer/download/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" - integrity sha1-rVCUI3XQNtMn/1KMCL1fqwiZKMo= - dependencies: - ansi-escapes "^3.2.0" - chalk "^2.4.2" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.12" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.4.0" - string-width "^2.1.0" - strip-ansi "^5.1.0" - through "^2.3.6" - -internal-ip@^4.3.0: - version "4.3.0" - resolved "https://registry.npm.taobao.org/internal-ip/download/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" - integrity sha1-hFRSuq2dLKO2nGNaE3rLmg2tCQc= - dependencies: - default-gateway "^4.2.0" - ipaddr.js "^1.9.0" - -invariant@^2.2.2: - version "2.2.4" - resolved "https://registry.npm.taobao.org/invariant/download/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha1-YQ88ksk1nOHbYW5TgAjSP/NRWOY= - dependencies: - loose-envify "^1.0.0" - -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/invert-kv/download/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha1-c5P1r6Weyf9fZ6J2INEcIm4+7AI= - -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/ip-regex/download/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= - -ip@^1.1.0, ip@^1.1.5: - version "1.1.5" - resolved "https://registry.npm.taobao.org/ip/download/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -ipaddr.js@1.9.0: - version "1.9.0" - resolved "https://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" - integrity sha1-N9905DCg5HVQ/lSi3v4w2KzZX2U= - -ipaddr.js@^1.9.0: - version "1.9.1" - resolved "https://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha1-v/OFQ+64mEglB5/zoqjmy9RngbM= - -is-absolute-url@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/is-absolute-url/download/is-absolute-url-2.1.0.tgz?cache=0&sync_timestamp=1569736493122&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-absolute-url%2Fdownload%2Fis-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" - integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= - -is-absolute-url@^3.0.3: - version "3.0.3" - resolved "https://registry.npm.taobao.org/is-absolute-url/download/is-absolute-url-3.0.3.tgz?cache=0&sync_timestamp=1569736493122&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-absolute-url%2Fdownload%2Fis-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" - integrity sha1-lsaiK2ojkpsR6gr7GDbDatSl1pg= - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY= - dependencies: - kind-of "^6.0.0" - -is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.npm.taobao.org/is-arguments/download/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha1-P6+WbHy6D/Q3+zH2JQCC/PBEjPM= - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.npm.taobao.org/is-arrayish/download/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.npm.taobao.org/is-arrayish/download/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha1-RXSirlb3qyBolvtDHq7tBm/fjwM= - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/is-binary-path/download/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.npm.taobao.org/is-buffer/download/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha1-76ouqdqg16suoTqXsritUf776L4= - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.npm.taobao.org/is-callable/download/is-callable-1.1.5.tgz?cache=0&sync_timestamp=1576778381051&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-callable%2Fdownload%2Fis-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha1-9+RrWWiQRW23Tn9ul2yzJz0G+qs= - -is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.npm.taobao.org/is-ci/download/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha1-43ecjuF/zPQoSI9uKBGH8uYyhBw= - dependencies: - ci-info "^1.5.0" - -is-color-stop@^1.0.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/is-color-stop/download/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" - integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= - dependencies: - css-color-names "^0.0.4" - hex-color-regex "^1.1.0" - hsl-regex "^1.0.0" - hsla-regex "^1.0.0" - rgb-regex "^1.0.1" - rgba-regex "^1.0.0" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc= - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.npm.taobao.org/is-date-object/download/is-date-object-1.0.2.tgz?cache=0&sync_timestamp=1576729165697&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-date-object%2Fdownload%2Fis-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha1-vac28s2P0G0yhE53Q7+nSUw7/X4= - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco= - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw= - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.npm.taobao.org/is-directory/download/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.npm.taobao.org/is-extendable/download/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/is-extendable/download/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ= - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0= - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/is-glob/download/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0, is-glob@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/is-glob/download/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw= - dependencies: - is-extglob "^2.1.1" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/is-number/download/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/is-obj/download/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - -is-path-cwd@^2.0.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/is-path-cwd/download/is-path-cwd-2.2.0.tgz?cache=0&sync_timestamp=1562347283002&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-path-cwd%2Fdownload%2Fis-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha1-Z9Q7gmZKe1GR/ZEZEn6zAASKn9s= - -is-path-in-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/is-path-in-cwd/download/is-path-in-cwd-2.1.0.tgz?cache=0&sync_timestamp=1562347183080&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-path-in-cwd%2Fdownload%2Fis-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" - integrity sha1-v+Lcomxp85cmWkAJljYCk1oFOss= - dependencies: - is-path-inside "^2.1.0" - -is-path-inside@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/is-path-inside/download/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" - integrity sha1-fJgQWH1lmkDSe8201WFuqwWUlLI= - dependencies: - path-is-inside "^1.0.2" - -is-plain-obj@^1.0.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/is-plain-obj/download/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.npm.taobao.org/is-plain-object/download/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc= - dependencies: - isobject "^3.0.1" - -is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/is-promise/download/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= - -is-regex@^1.0.4, is-regex@^1.0.5, is-regex@~1.0.5: - version "1.0.5" - resolved "https://registry.npm.taobao.org/is-regex/download/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha1-OdWJo1i/GJZ/cmlnEguPwa7XTq4= - dependencies: - has "^1.0.3" - -is-resolvable@^1.0.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/is-resolvable/download/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - integrity sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg= - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/is-stream/download/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/is-stream/download/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha1-venDJoDW+uBBKdasnZIc54FfeOM= - -is-svg@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/is-svg/download/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" - integrity sha1-kyHb0pwhLlypnE+peUxxS8r6L3U= - dependencies: - html-comment-regex "^1.1.0" - -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.npm.taobao.org/is-symbol/download/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha1-OOEBS55jKb4N6dJKQU/XRB7GGTc= - dependencies: - has-symbols "^1.0.1" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/is-windows/download/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0= - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/is-wsl/download/is-wsl-1.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-wsl%2Fdownload%2Fis-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz?cache=0&sync_timestamp=1562592096220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisarray%2Fdownload%2Fisarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isarray@~0.0.1: - version "0.0.1" - resolved "https://registry.npm.taobao.org/isarray/download/isarray-0.0.1.tgz?cache=0&sync_timestamp=1562592096220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisarray%2Fdownload%2Fisarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisexe%2Fdownload%2Fisexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/isobject/download/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.npm.taobao.org/isobject/download/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.npm.taobao.org/isstream/download/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -javascript-stringify@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/javascript-stringify/download/javascript-stringify-2.0.1.tgz?cache=0&sync_timestamp=1572948916758&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjavascript-stringify%2Fdownload%2Fjavascript-stringify-2.0.1.tgz#6ef358035310e35d667c675ed63d3eb7c1aa19e5" - integrity sha1-bvNYA1MQ411mfGde1j0+t8GqGeU= - -jest-worker@^24.9.0: - version "24.9.0" - resolved "https://registry.npm.taobao.org/jest-worker/download/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" - integrity sha1-Xb/bWy0yLphWeJgjipaXvM5ns+U= - dependencies: - merge-stream "^2.0.0" - supports-color "^6.1.0" - -js-levenshtein@^1.1.3: - version "1.1.6" - resolved "https://registry.npm.taobao.org/js-levenshtein/download/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" - integrity sha1-xs7ljrNVA3LfjeuF+tXOZs4B1Z0= - -js-message@1.0.5: - version "1.0.5" - resolved "https://registry.npm.taobao.org/js-message/download/js-message-1.0.5.tgz#2300d24b1af08e89dd095bc1a4c9c9cfcb892d15" - integrity sha1-IwDSSxrwjondCVvBpMnJz8uJLRU= - -js-queue@2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/js-queue/download/js-queue-2.0.0.tgz#362213cf860f468f0125fc6c96abc1742531f948" - integrity sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug= - dependencies: - easy-stack "^1.0.0" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/js-tokens/download/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha1-GSA/tZmR35jjoocFDUZHzerzJJk= - -js-yaml@^3.13.0, js-yaml@^3.13.1: - version "3.13.1" - resolved "https://registry.npm.taobao.org/js-yaml/download/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha1-r/FRswv9+o5J4F2iLnQV6d+jeEc= - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.npm.taobao.org/jsbn/download/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.npm.taobao.org/jsesc/download/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha1-gFZNLkg9rPbo7yCWUKZ98/DCg6Q= - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.npm.taobao.org/jsesc/download/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/json-parse-better-errors/download/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npm.taobao.org/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha1-afaofZUTq4u4/mO9sJecRI5oRmA= - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.npm.taobao.org/json-schema/download/json-schema-0.2.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson-schema%2Fdownload%2Fjson-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/json-stable-stringify-without-jsonify/download/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json2module@^0.0.3: - version "0.0.3" - resolved "https://registry.npm.taobao.org/json2module/download/json2module-0.0.3.tgz#00fb5f4a9b7adfc3f0647c29cb17bcd1979be9b2" - integrity sha1-APtfSpt638PwZHwpyxe80Zeb6bI= - dependencies: - rw "^1.3.2" - -json3@^3.3.2: - version "3.3.3" - resolved "https://registry.npm.taobao.org/json3/download/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" - integrity sha1-f8EON1/FrkLEcFpcwKpvYr4wW4E= - -json5@^0.5.0: - version "0.5.1" - resolved "https://registry.npm.taobao.org/json5/download/json5-0.5.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/json5/download/json5-1.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha1-d5+wAYYE+oVOrL9iUhgNg1Q+Pb4= - dependencies: - minimist "^1.2.0" - -json5@^2.1.0: - version "2.1.1" - resolved "https://registry.npm.taobao.org/json5/download/json5-2.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" - integrity sha1-gbbLBOm6SW8ccAXQe0NoomOPkLY= - dependencies: - minimist "^1.2.0" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.npm.taobao.org/jsprim/download/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -killable@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/killable/download/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" - integrity sha1-TIzkQRh6Bhx0dPuHygjipjgZSJI= - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha1-cpyR4thXt6QZofmqZWhcTDP1hF0= - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha1-ARRrNqYhjmTljzqNZt5df8b20FE= - -launch-editor-middleware@^2.2.1: - version "2.2.1" - resolved "https://registry.npm.taobao.org/launch-editor-middleware/download/launch-editor-middleware-2.2.1.tgz#e14b07e6c7154b0a4b86a0fd345784e45804c157" - integrity sha1-4UsH5scVSwpLhqD9NFeE5FgEwVc= - dependencies: - launch-editor "^2.2.1" - -launch-editor@^2.2.1: - version "2.2.1" - resolved "https://registry.npm.taobao.org/launch-editor/download/launch-editor-2.2.1.tgz#871b5a3ee39d6680fcc26d37930b6eeda89db0ca" - integrity sha1-hxtaPuOdZoD8wm03kwtu7aidsMo= - dependencies: - chalk "^2.3.0" - shell-quote "^1.6.1" - -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.npm.taobao.org/lazy-cache/download/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= - -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/lcid/download/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha1-bvXS32DlL4LrIopMNz6NHzlyU88= - dependencies: - invert-kv "^2.0.0" - -less-loader@^5.0.0: - version "5.0.0" - resolved "https://registry.npm.taobao.org/less-loader/download/less-loader-5.0.0.tgz#498dde3a6c6c4f887458ee9ed3f086a12ad1b466" - integrity sha1-SY3eOmxsT4h0WO6e0/CGoSrRtGY= - dependencies: - clone "^2.1.1" - loader-utils "^1.1.0" - pify "^4.0.1" - -less@^3.10.3: - version "3.10.3" - resolved "https://registry.npm.taobao.org/less/download/less-3.10.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fless%2Fdownload%2Fless-3.10.3.tgz#417a0975d5eeecc52cff4bcfa3c09d35781e6792" - integrity sha1-QXoJddXu7MUs/0vPo8CdNXgeZ5I= - dependencies: - clone "^2.1.2" - optionalDependencies: - errno "^0.1.1" - graceful-fs "^4.1.2" - image-size "~0.5.0" - mime "^1.4.1" - mkdirp "^0.5.0" - promise "^7.1.1" - request "^2.83.0" - source-map "~0.6.0" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.npm.taobao.org/levn/download/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.npm.taobao.org/lines-and-columns/download/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= - -loader-fs-cache@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/loader-fs-cache/download/loader-fs-cache-1.0.2.tgz#54cedf6b727e1779fd8f01205f05f6e88706f086" - integrity sha1-VM7fa3J+F3n9jwEgXwX26IcG8IY= - dependencies: - find-cache-dir "^0.1.1" - mkdirp "0.5.1" - -loader-runner@^2.3.1, loader-runner@^2.4.0: - version "2.4.0" - resolved "https://registry.npm.taobao.org/loader-runner/download/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" - integrity sha1-7UcGa/5TTX6ExMe5mYwqdWB9k1c= - -loader-utils@^0.2.16: - version "0.2.17" - resolved "https://registry.npm.taobao.org/loader-utils/download/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" - integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - object-assign "^4.0.1" - -loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: - version "1.2.3" - resolved "https://registry.npm.taobao.org/loader-utils/download/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" - integrity sha1-H/XcaRHJ8KBiUxpMBLYJQGEIwsc= - dependencies: - big.js "^5.2.2" - emojis-list "^2.0.0" - json5 "^1.0.1" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/locate-path/download/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4= - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha1-Gvujlq/WdqbUJQTQpno6frn2KqA= - dependencies: - p-locate "^4.1.0" - -lodash.defaultsdeep@^4.6.1: - version "4.6.1" - resolved "https://registry.npm.taobao.org/lodash.defaultsdeep/download/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" - integrity sha1-US6b1yHSctlOPTpjZT+hdRZ0HKY= - -lodash.kebabcase@^4.1.1: - version "4.1.1" - resolved "https://registry.npm.taobao.org/lodash.kebabcase/download/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" - integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= - -lodash.mapvalues@^4.6.0: - version "4.6.0" - resolved "https://registry.npm.taobao.org/lodash.mapvalues/download/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" - integrity sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw= - -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.npm.taobao.org/lodash.memoize/download/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - -lodash.transform@^4.6.0: - version "4.6.0" - resolved "https://registry.npm.taobao.org/lodash.transform/download/lodash.transform-4.6.0.tgz#12306422f63324aed8483d3f38332b5f670547a0" - integrity sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A= - -lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= - -lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3: - version "4.17.15" - resolved "https://registry.npm.taobao.org/lodash/download/lodash-4.17.15.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha1-tEf2ZwoEVbv+7dETku/zMOoJdUg= - -log-symbols@^2.2.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/log-symbols/download/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - integrity sha1-V0Dhxdbw39pK2TI7UzIQfva0xAo= - dependencies: - chalk "^2.0.1" - -loglevel@^1.6.6: - version "1.6.6" - resolved "https://registry.npm.taobao.org/loglevel/download/loglevel-1.6.6.tgz?cache=0&sync_timestamp=1573147510261&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Floglevel%2Fdownload%2Floglevel-1.6.6.tgz#0ee6300cc058db6b3551fa1c4bf73b83bb771312" - integrity sha1-DuYwDMBY22s1UfocS/c7g7t3ExI= - -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/longest/download/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.npm.taobao.org/loose-envify/download/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8= - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lower-case@^1.1.1: - version "1.1.4" - resolved "https://registry.npm.taobao.org/lower-case/download/lower-case-1.1.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flower-case%2Fdownload%2Flower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" - integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= - -lru-cache@^4.0.1, lru-cache@^4.1.2: - version "4.1.5" - resolved "https://registry.npm.taobao.org/lru-cache/download/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha1-i75Q6oW+1ZvJ4z3KuCNe6bz0Q80= - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.npm.taobao.org/lru-cache/download/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha1-HaJ+ZxAnGUdpXa9oSOhH8B2EuSA= - dependencies: - yallist "^3.0.2" - -make-dir@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/make-dir/download/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha1-XwMQ4YuL6JjMBwCSlaMK5B6R5vU= - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -make-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/make-dir/download/make-dir-3.0.0.tgz#1b5f39f6b9270ed33f9f054c5c0f84304989f801" - integrity sha1-G1859rknDtM/nwVMXA+EMEmJ+AE= - dependencies: - semver "^6.0.0" - -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.npm.taobao.org/mamacro/download/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha1-rSyVdhl8nxq/MI0Hh4Zb2XWj8+Q= - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.npm.taobao.org/map-age-cleaner/download/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha1-fVg6cwZDTAVf5HSw9FB45uG0uSo= - dependencies: - p-defer "^1.0.0" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.npm.taobao.org/map-cache/download/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/map-visit/download/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.npm.taobao.org/md5.js/download/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha1-tdB7jjIW4+J81yjXL3DR5qNCAF8= - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -mdn-data@2.0.4: - version "2.0.4" - resolved "https://registry.npm.taobao.org/mdn-data/download/mdn-data-2.0.4.tgz?cache=0&sync_timestamp=1573816265745&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmdn-data%2Fdownload%2Fmdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" - integrity sha1-aZs8OKxvHXKAkaZGULZdOIUC/Vs= - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.npm.taobao.org/mem/download/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha1-Rhr0l7xK4JYIzbLmDu+2m/90QXg= - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -memory-fs@^0.4.1: - version "0.4.1" - resolved "https://registry.npm.taobao.org/memory-fs/download/memory-fs-0.4.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -memory-fs@^0.5.0: - version "0.5.0" - resolved "https://registry.npm.taobao.org/memory-fs/download/memory-fs-0.5.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" - integrity sha1-MkwBKIuIZSlm0WHbd4OHIIRajjw= - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -merge-source-map@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/merge-source-map/download/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" - integrity sha1-L93n5gIJOfcJBqaPLXrmheTIxkY= - dependencies: - source-map "^0.6.1" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/merge-stream/download/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A= - -merge2@^1.2.3: - version "1.3.0" - resolved "https://registry.npm.taobao.org/merge2/download/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" - integrity sha1-WzZu6DsvFYLEj4fkfPGpNSEDyoE= - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.npm.taobao.org/micromatch/download/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha1-cIWbyVyYQJUvNZoGij/En57PrCM= - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.npm.taobao.org/miller-rabin/download/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha1-8IA1HIZbDcViqEYpZtqlNUPHik0= - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mime-db@1.42.0, "mime-db@>= 1.40.0 < 2": - version "1.42.0" - resolved "https://registry.npm.taobao.org/mime-db/download/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" - integrity sha1-PiUpB7THrbkGWXtLZWNics+ee6w= - -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.25" - resolved "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" - integrity sha1-OXctRmIfk+KoCoVsU7hqYhVqZDc= - dependencies: - mime-db "1.42.0" - -mime@1.6.0, mime@^1.4.1: - version "1.6.0" - resolved "https://registry.npm.taobao.org/mime/download/mime-1.6.0.tgz?cache=0&sync_timestamp=1560034758817&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime%2Fdownload%2Fmime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE= - -mime@^2.4.4: - version "2.4.4" - resolved "https://registry.npm.taobao.org/mime/download/mime-2.4.4.tgz?cache=0&sync_timestamp=1560034758817&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime%2Fdownload%2Fmime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" - integrity sha1-vXuRE1/GsBzePpuuM9ZZtj2IV+U= - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/mimic-fn/download/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI= - -mimic-fn@^2.0.0, mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/mimic-fn/download/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs= - -mini-css-extract-plugin@^0.8.0: - version "0.8.2" - resolved "https://registry.npm.taobao.org/mini-css-extract-plugin/download/mini-css-extract-plugin-0.8.2.tgz?cache=0&sync_timestamp=1576856499989&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmini-css-extract-plugin%2Fdownload%2Fmini-css-extract-plugin-0.8.2.tgz#a875e169beb27c88af77dd962771c9eedc3da161" - integrity sha1-qHXhab6yfIivd92WJ3HJ7tw9oWE= - dependencies: - loader-utils "^1.1.0" - normalize-url "1.9.1" - schema-utils "^1.0.0" - webpack-sources "^1.1.0" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/minimalistic-assert/download/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha1-LhlN4ERibUoQ5/f7wAznPoPk1cc= - -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/minimalistic-crypto-utils/download/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM= - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.npm.taobao.org/minimist/download/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.0, minimist@~1.2.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.npm.taobao.org/minimist/download/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= - -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/minipass-collect/download/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha1-IrgTv3Rdxu26JXa5QAIq1u3Ixhc= - dependencies: - minipass "^3.0.0" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.npm.taobao.org/minipass-flush/download/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" - integrity sha1-gucTXX6JpQ/+ZGEKeHlTxMTLs3M= - dependencies: - minipass "^3.0.0" - -minipass-pipeline@^1.2.2: - version "1.2.2" - resolved "https://registry.npm.taobao.org/minipass-pipeline/download/minipass-pipeline-1.2.2.tgz#3dcb6bb4a546e32969c7ad710f2c79a86abba93a" - integrity sha1-PctrtKVG4ylpx61xDyx5qGq7qTo= - dependencies: - minipass "^3.0.0" - -minipass@^3.0.0, minipass@^3.1.1: - version "3.1.1" - resolved "https://registry.npm.taobao.org/minipass/download/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" - integrity sha1-dgfOd4RyoYWtbYkIKqIHD3nO3NU= - dependencies: - yallist "^4.0.0" - -mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/mississippi/download/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - integrity sha1-6goykfl+C16HdrNj1fChLZTGcCI= - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.npm.taobao.org/mixin-deep/download/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha1-ESC0PcNZp4Xc5ltVuC4lfM9HlWY= - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: - version "0.5.1" - resolved "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/ms/download/ms-2.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo= - -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk= - -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/multicast-dns-service-types/download/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^6.0.1: - version "6.2.3" - resolved "https://registry.npm.taobao.org/multicast-dns/download/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" - integrity sha1-oOx72QVcQoL3kMPIL04o2zsxsik= - dependencies: - dns-packet "^1.3.1" - thunky "^1.0.2" - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.npm.taobao.org/mute-stream/download/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - -mz@^2.4.0: - version "2.7.0" - resolved "https://registry.npm.taobao.org/mz/download/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha1-lQCAV6Vsr63CvGPd5/n/aVWUjjI= - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -nan@^2.12.1: - version "2.14.0" - resolved "https://registry.npm.taobao.org/nan/download/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha1-eBj3IgJ7JFmobwKV1DTR/CM2xSw= - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.npm.taobao.org/nanomatch/download/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk= - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npm.taobao.org/natural-compare/download/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs= - -neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1: - version "2.6.1" - resolved "https://registry.npm.taobao.org/neo-async/download/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha1-rCetpmFn+ohJpq3dg39rGJrSCBw= - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.npm.taobao.org/nice-try/download/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y= - -no-case@^2.2.0: - version "2.3.2" - resolved "https://registry.npm.taobao.org/no-case/download/no-case-2.3.2.tgz?cache=0&sync_timestamp=1576721537540&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" - integrity sha1-YLgTOWvjmz8SiKTB7V0efSi0ZKw= - dependencies: - lower-case "^1.1.1" - -node-forge@0.9.0: - version "0.9.0" - resolved "https://registry.npm.taobao.org/node-forge/download/node-forge-0.9.0.tgz?cache=0&sync_timestamp=1569524876130&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-forge%2Fdownload%2Fnode-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" - integrity sha1-1iQFDtu0SHStyhK7mlLsY8t4JXk= - -node-ipc@^9.1.1: - version "9.1.1" - resolved "https://registry.npm.taobao.org/node-ipc/download/node-ipc-9.1.1.tgz#4e245ed6938e65100e595ebc5dc34b16e8dd5d69" - integrity sha1-TiRe1pOOZRAOWV68XcNLFujdXWk= - dependencies: - event-pubsub "4.3.0" - js-message "1.0.5" - js-queue "2.0.0" - -node-less@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/node-less/download/node-less-1.0.0.tgz#4843df149c510e85d8c15f4434ed803b736b8029" - integrity sha1-SEPfFJxRDoXYwV9ENO2AO3NrgCk= - -node-libs-browser@^2.2.1: - version "2.2.1" - resolved "https://registry.npm.taobao.org/node-libs-browser/download/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" - integrity sha1-tk9RPRgzhiX5A0bSew0jXmMfZCU= - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^3.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.1" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.11.0" - vm-browserify "^1.0.1" - -node-releases@^1.1.42: - version "1.1.43" - resolved "https://registry.npm.taobao.org/node-releases/download/node-releases-1.1.43.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-releases%2Fdownload%2Fnode-releases-1.1.43.tgz#2c6ca237f88ce11d49631f11190bb01f8d0549f2" - integrity sha1-LGyiN/iM4R1JYx8RGQuwH40FSfI= - dependencies: - semver "^6.3.0" - -normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.npm.taobao.org/normalize-package-data/download/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha1-5m2xg4sgDB38IzIl0SyzZSDiNKg= - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/normalize-path/download/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" - integrity sha1-MtDkcvkf80VwHBWoMRAY07CpA3k= - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/normalize-path/download/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/normalize-path/download/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU= - -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.npm.taobao.org/normalize-range/download/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= - -normalize-url@1.9.1: - version "1.9.1" - resolved "https://registry.npm.taobao.org/normalize-url/download/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" - integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= - dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" - -normalize-url@^3.0.0: - version "3.3.0" - resolved "https://registry.npm.taobao.org/normalize-url/download/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" - integrity sha1-suHE3E98bVd0PfczpPWXjRhlBVk= - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-2.0.2.tgz?cache=0&sync_timestamp=1571055744220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnpm-run-path%2Fdownload%2Fnpm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npm-run-path@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-4.0.0.tgz?cache=0&sync_timestamp=1571055744220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnpm-run-path%2Fdownload%2Fnpm-run-path-4.0.0.tgz#d644ec1bd0569187d2a52909971023a0a58e8438" - integrity sha1-1kTsG9BWkYfSpSkJlxAjoKWOhDg= - dependencies: - path-key "^3.0.0" - -nth-check@^1.0.2, nth-check@~1.0.1: - version "1.0.2" - resolved "https://registry.npm.taobao.org/nth-check/download/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha1-sr0pXDfj3VijvwcAN2Zjuk2c8Fw= - dependencies: - boolbase "~1.0.0" - -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.npm.taobao.org/num2fraction/download/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/number-is-nan/download/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.npm.taobao.org/oauth-sign/download/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU= - -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.npm.taobao.org/object-copy/download/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-hash@^1.1.4: - version "1.3.1" - resolved "https://registry.npm.taobao.org/object-hash/download/object-hash-1.3.1.tgz?cache=0&sync_timestamp=1575157999857&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject-hash%2Fdownload%2Fobject-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" - integrity sha1-/eRSCYqVHLFF8Dm7fUVUSd3BJt8= - -object-inspect@^1.7.0, object-inspect@~1.7.0: - version "1.7.0" - resolved "https://registry.npm.taobao.org/object-inspect/download/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha1-9Pa9GBrXfwBrXs5gvQtvOY/3Smc= - -object-is@^1.0.1: - version "1.0.2" - resolved "https://registry.npm.taobao.org/object-is/download/object-is-1.0.2.tgz?cache=0&sync_timestamp=1576479681769&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject-is%2Fdownload%2Fobject-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4" - integrity sha1-a4DrhP5FFJj2UAeYLwNaW0Re3sQ= - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/object-keys/download/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha1-HEfyct8nfzsdrwYWd9nILiMixg4= - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/object-visit/download/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/object.assign/download/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha1-lovxEA15Vrs8oIbwBvhGs7xACNo= - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.getownpropertydescriptors@^2.0.3: - version "2.1.0" - resolved "https://registry.npm.taobao.org/object.getownpropertydescriptors/download/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha1-Npvx+VktiridcS3O1cuBx8U1Jkk= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.npm.taobao.org/object.pick/download/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -object.values@^1.1.0: - version "1.1.1" - resolved "https://registry.npm.taobao.org/object.values/download/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha1-aKmezeNWt+kpWjxeDOMdyMlT3l4= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - has "^1.0.3" - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/obuf/download/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha1-Cb6jND1BhZ69RGKS0RydTbYZCE4= - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/on-headers/download/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha1-dysK5qqlJcOZ5Imt+tkMQD6zwo8= - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/onetime/download/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= - dependencies: - mimic-fn "^1.0.0" - -onetime@^5.1.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/onetime/download/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" - integrity sha1-//DzyRYX/mK7UBiWNumayKbfe+U= - dependencies: - mimic-fn "^2.1.0" - -open@^6.3.0: - version "6.4.0" - resolved "https://registry.npm.taobao.org/open/download/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" - integrity sha1-XBPpbQ3IlGhhZPGJZez+iJ7PyKk= - dependencies: - is-wsl "^1.1.0" - -opener@^1.5.1: - version "1.5.1" - resolved "https://registry.npm.taobao.org/opener/download/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" - integrity sha1-bS8Od/GgrwAyrKcWwsH7uOfoq+0= - -opn@^5.5.0: - version "5.5.0" - resolved "https://registry.npm.taobao.org/opn/download/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" - integrity sha1-/HFk+rVtI1kExRw7J9pnWMo7m/w= - dependencies: - is-wsl "^1.1.0" - -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.npm.taobao.org/optimist/download/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - -optionator@^0.8.2: - version "0.8.3" - resolved "https://registry.npm.taobao.org/optionator/download/optionator-0.8.3.tgz?cache=0&sync_timestamp=1573078174520&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Foptionator%2Fdownload%2Foptionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha1-hPodA2/p08fiHZmIS2ARZ+yPtJU= - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -ora@^3.4.0: - version "3.4.0" - resolved "https://registry.npm.taobao.org/ora/download/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" - integrity sha1-vwdSSRBZo+8+1MhQl1Md6f280xg= - dependencies: - chalk "^2.4.2" - cli-cursor "^2.1.0" - cli-spinners "^2.0.0" - log-symbols "^2.2.0" - strip-ansi "^5.2.0" - wcwidth "^1.0.1" - -original@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/original/download/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" - integrity sha1-5EKmHP/hxf0gpl8yYcJmY7MD8l8= - dependencies: - url-parse "^1.4.3" - -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.npm.taobao.org/os-browserify/download/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= - -os-locale@^3.0.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/os-locale/download/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha1-qAKm7hfyTBBIOrmTVxnO9O0Wvxo= - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/os-tmpdir/download/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/p-defer/download/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/p-finally/download/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-finally@^2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/p-finally/download/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" - integrity sha1-vW/KqcVZoJa2gIBvTWV7Pw8kBWE= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/p-is-promise/download/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha1-kYzrrqJIpiz3/6uOO8qMX4gvxC4= - -p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1: - version "2.2.1" - resolved "https://registry.npm.taobao.org/p-limit/download/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" - integrity sha1-qgeniMwxUck5tRMfY1cPDdIAlTc= - dependencies: - p-try "^2.0.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/p-locate/download/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ= - dependencies: - p-limit "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha1-o0KLtwiLOmApL2aRkni3wpetTwc= - dependencies: - p-limit "^2.2.0" - -p-map@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/p-map/download/p-map-2.1.0.tgz?cache=0&sync_timestamp=1563032875018&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-map%2Fdownload%2Fp-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha1-MQko/u+cnsxltosXaTAYpmXOoXU= - -p-map@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/p-map/download/p-map-3.0.0.tgz?cache=0&sync_timestamp=1563032875018&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-map%2Fdownload%2Fp-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" - integrity sha1-1wTZr4orpoTiYA2aIVmD1BQal50= - dependencies: - aggregate-error "^3.0.0" - -p-retry@^3.0.1: - version "3.0.1" - resolved "https://registry.npm.taobao.org/p-retry/download/p-retry-3.0.1.tgz?cache=0&sync_timestamp=1572521210242&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-retry%2Fdownload%2Fp-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" - integrity sha1-MWtMiJPiyNwc+okfQGxLQivr8yg= - dependencies: - retry "^0.12.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha1-yyhoVA4xPWHeWPr741zpAE1VQOY= - -pako@~1.0.5: - version "1.0.10" - resolved "https://registry.npm.taobao.org/pako/download/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" - integrity sha1-Qyi621CGpCaqkPVBl31JVdpclzI= - -parallel-transform@^1.1.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/parallel-transform/download/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" - integrity sha1-kEnKN9bLIYLDsdLHIL6U0UpYFPw= - dependencies: - cyclist "^1.0.1" - inherits "^2.0.3" - readable-stream "^2.1.5" - -param-case@2.1.x: - version "2.1.1" - resolved "https://registry.npm.taobao.org/param-case/download/param-case-2.1.1.tgz?cache=0&sync_timestamp=1576721509342&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparam-case%2Fdownload%2Fparam-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" - integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= - dependencies: - no-case "^2.2.0" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/parent-module/download/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha1-aR0nCeeMefrjoVZiJFLQB2LKqqI= - dependencies: - callsites "^3.0.0" - -parse-asn1@^5.0.0: - version "5.1.5" - resolved "https://registry.npm.taobao.org/parse-asn1/download/parse-asn1-5.1.5.tgz?cache=0&sync_timestamp=1568806095714&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-asn1%2Fdownload%2Fparse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" - integrity sha1-ADJxND2ljclMrOSU+u89IUfs6g4= - dependencies: - asn1.js "^4.0.0" - browserify-aes "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/parse-json/download/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0: - version "5.0.0" - resolved "https://registry.npm.taobao.org/parse-json/download/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" - integrity sha1-c+URTJhtFD76NxLU6iTbmkJm9g8= - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - lines-and-columns "^1.1.6" - -parse-svg-path@~0.1.1: - version "0.1.2" - resolved "https://registry.npm.taobao.org/parse-svg-path/download/parse-svg-path-0.1.2.tgz#7a7ec0d1eb06fa5325c7d3e009b859a09b5d49eb" - integrity sha1-en7A0esG+lMlx9PgCbhZoJtdSes= - -parse5-htmlparser2-tree-adapter@^5.1.1: - version "5.1.1" - resolved "https://registry.npm.taobao.org/parse5-htmlparser2-tree-adapter/download/parse5-htmlparser2-tree-adapter-5.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse5-htmlparser2-tree-adapter%2Fdownload%2Fparse5-htmlparser2-tree-adapter-5.1.1.tgz#e8c743d4e92194d5293ecde2b08be31e67461cbc" - integrity sha1-6MdD1OkhlNUpPs3isIvjHmdGHLw= - dependencies: - parse5 "^5.1.1" - -parse5@^5.1.1: - version "5.1.1" - resolved "https://registry.npm.taobao.org/parse5/download/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" - integrity sha1-9o5OW6GFKsLK3AD0VV//bCq7YXg= - -parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ= - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.npm.taobao.org/pascalcase/download/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.npm.taobao.org/path-browserify/download/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" - integrity sha1-5sTd1+06onxoogzE5Q4aTug7vEo= - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/path-dirname/download/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/path-exists/download/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/path-exists/download/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha1-UTvb4tO5XXdi6METfvoZXGxhtbM= - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/path-is-inside/download/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/path-key/download/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.npm.taobao.org/path-key/download/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.npm.taobao.org/path-parse/download/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha1-1i27VnlAXXLEc37FhgDp3c8G0kw= - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/path-type/download/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha1-zvMdyOCho7sNEFwM2Xzzv0f0428= - dependencies: - pify "^3.0.0" - -pbkdf2@^3.0.3: - version "3.0.17" - resolved "https://registry.npm.taobao.org/pbkdf2/download/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" - integrity sha1-l2wgZTBhexTrsyEUI597CTNuk6Y= - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.npm.taobao.org/pify/download/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/pify/download/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE= - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/pinkie-promise/download/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.npm.taobao.org/pinkie/download/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= - dependencies: - find-up "^1.0.0" - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha1-J0kCDyOe2ZCIGx9xIQ1R62UjvqM= - dependencies: - find-up "^3.0.0" - -pkg-dir@^4.1.0: - version "4.2.0" - resolved "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha1-8JkTPfft5CLoHR2ESCcO6z5CYfM= - dependencies: - find-up "^4.0.0" - -point-at-length@~1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/point-at-length/download/point-at-length-1.0.2.tgz#9176d8d6d7c8162f12b646f707db9f0ea728125e" - integrity sha1-kXbY1tfIFi8Stkb3B9ufDqcoEl4= - dependencies: - abs-svg-path "~0.1.1" - isarray "~0.0.1" - parse-svg-path "~0.1.1" - -portfinder@^1.0.25: - version "1.0.25" - resolved "https://registry.npm.taobao.org/portfinder/download/portfinder-1.0.25.tgz#254fd337ffba869f4b9d37edc298059cb4d35eca" - integrity sha1-JU/TN/+6hp9LnTftwpgFnLTTXso= - dependencies: - async "^2.6.2" - debug "^3.1.1" - mkdirp "^0.5.1" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.npm.taobao.org/posix-character-classes/download/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -postcss-calc@^7.0.1: - version "7.0.1" - resolved "https://registry.npm.taobao.org/postcss-calc/download/postcss-calc-7.0.1.tgz#36d77bab023b0ecbb9789d84dcb23c4941145436" - integrity sha1-Ntd7qwI7Dsu5eJ2E3LI8SUEUVDY= - dependencies: - css-unit-converter "^1.1.1" - postcss "^7.0.5" - postcss-selector-parser "^5.0.0-rc.4" - postcss-value-parser "^3.3.1" - -postcss-colormin@^4.0.3: - version "4.0.3" - resolved "https://registry.npm.taobao.org/postcss-colormin/download/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" - integrity sha1-rgYLzpPteUrHEmTwgTLVUJVr04E= - dependencies: - browserslist "^4.0.0" - color "^3.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-convert-values@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-convert-values/download/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" - integrity sha1-yjgT7U2g+BL51DcDWE5Enr4Ymn8= - dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-discard-comments@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-discard-comments/download/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" - integrity sha1-H7q9LCRr/2qq15l7KwkY9NevQDM= - dependencies: - postcss "^7.0.0" - -postcss-discard-duplicates@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-discard-duplicates/download/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" - integrity sha1-P+EzzTyCKC5VD8myORdqkge3hOs= - dependencies: - postcss "^7.0.0" - -postcss-discard-empty@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-discard-empty/download/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" - integrity sha1-yMlR6fc+2UKAGUWERKAq2Qu592U= - dependencies: - postcss "^7.0.0" - -postcss-discard-overridden@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-discard-overridden/download/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" - integrity sha1-ZSrvipZybwKfXj4AFG7npOdV/1c= - dependencies: - postcss "^7.0.0" - -postcss-load-config@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/postcss-load-config/download/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003" - integrity sha1-yE1pK3u3tB3c7ZTuYuirMbQXsAM= - dependencies: - cosmiconfig "^5.0.0" - import-cwd "^2.0.0" - -postcss-loader@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/postcss-loader/download/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" - integrity sha1-a5eUPkfHLYRfqeA/Jzdz1OjdbC0= - dependencies: - loader-utils "^1.1.0" - postcss "^7.0.0" - postcss-load-config "^2.0.0" - schema-utils "^1.0.0" - -postcss-merge-longhand@^4.0.11: - version "4.0.11" - resolved "https://registry.npm.taobao.org/postcss-merge-longhand/download/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" - integrity sha1-YvSaE+Sg7gTnuY9CuxYGLKJUniQ= - dependencies: - css-color-names "0.0.4" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - stylehacks "^4.0.0" - -postcss-merge-rules@^4.0.3: - version "4.0.3" - resolved "https://registry.npm.taobao.org/postcss-merge-rules/download/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" - integrity sha1-NivqT/Wh+Y5AdacTxsslrv75plA= - dependencies: - browserslist "^4.0.0" - caniuse-api "^3.0.0" - cssnano-util-same-parent "^4.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - vendors "^1.0.0" - -postcss-minify-font-values@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-minify-font-values/download/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" - integrity sha1-zUw0TM5HQ0P6xdgiBqssvLiv1aY= - dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-minify-gradients@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-minify-gradients/download/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" - integrity sha1-k7KcL/UJnFNe7NpWxKpuZlpmNHE= - dependencies: - cssnano-util-get-arguments "^4.0.0" - is-color-stop "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-minify-params@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-minify-params/download/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" - integrity sha1-a5zvAwwR41Jh+V9hjJADbWgNuHQ= - dependencies: - alphanum-sort "^1.0.0" - browserslist "^4.0.0" - cssnano-util-get-arguments "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - uniqs "^2.0.0" - -postcss-minify-selectors@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-minify-selectors/download/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" - integrity sha1-4uXrQL/uUA0M2SQ1APX46kJi+9g= - dependencies: - alphanum-sort "^1.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - -postcss-modules-extract-imports@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/postcss-modules-extract-imports/download/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" - integrity sha1-gYcZoa4doyX5gyRGsBE27rSTzX4= - dependencies: - postcss "^7.0.5" - -postcss-modules-local-by-default@^3.0.2: - version "3.0.2" - resolved "https://registry.npm.taobao.org/postcss-modules-local-by-default/download/postcss-modules-local-by-default-3.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-local-by-default%2Fdownload%2Fpostcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915" - integrity sha1-6KZWG+kUqvPAUodjd1JMqQ27eRU= - dependencies: - icss-utils "^4.1.1" - postcss "^7.0.16" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.0.0" - -postcss-modules-scope@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/postcss-modules-scope/download/postcss-modules-scope-2.1.1.tgz?cache=0&sync_timestamp=1574936987092&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-scope%2Fdownload%2Fpostcss-modules-scope-2.1.1.tgz#33d4fc946602eb5e9355c4165d68a10727689dba" - integrity sha1-M9T8lGYC616TVcQWXWihBydonbo= - dependencies: - postcss "^7.0.6" - postcss-selector-parser "^6.0.0" - -postcss-modules-values@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/postcss-modules-values/download/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" - integrity sha1-W1AA1uuuKbQlUwG0o6VFdEI+fxA= - dependencies: - icss-utils "^4.0.0" - postcss "^7.0.6" - -postcss-normalize-charset@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-normalize-charset/download/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" - integrity sha1-izWt067oOhNrBHHg1ZvlilAoXdQ= - dependencies: - postcss "^7.0.0" - -postcss-normalize-display-values@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-normalize-display-values/download/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" - integrity sha1-Db4EpM6QY9RmftK+R2u4MMglk1o= - dependencies: - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-positions@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-normalize-positions/download/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" - integrity sha1-BfdX+E8mBDc3g2ipH4ky1LECkX8= - dependencies: - cssnano-util-get-arguments "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-repeat-style@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-normalize-repeat-style/download/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" - integrity sha1-xOu8KJ85kaAo1EdRy90RkYsXkQw= - dependencies: - cssnano-util-get-arguments "^4.0.0" - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-string@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-normalize-string/download/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" - integrity sha1-zUTECrB6DHo23F6Zqs4eyk7CaQw= - dependencies: - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-timing-functions@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-normalize-timing-functions/download/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" - integrity sha1-jgCcoqOUnNr4rSPmtquZy159KNk= - dependencies: - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-unicode@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-normalize-unicode/download/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" - integrity sha1-hBvUj9zzAZrUuqdJOj02O1KuHPs= - dependencies: - browserslist "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-url@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-normalize-url/download/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" - integrity sha1-EOQ3+GvHx+WPe5ZS7YeNqqlfquE= - dependencies: - is-absolute-url "^2.0.0" - normalize-url "^3.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-whitespace@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-normalize-whitespace/download/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" - integrity sha1-vx1AcP5Pzqh9E0joJdjMDF+qfYI= - dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-ordered-values@^4.1.2: - version "4.1.2" - resolved "https://registry.npm.taobao.org/postcss-ordered-values/download/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" - integrity sha1-DPdcgg7H1cTSgBiVWeC1ceusDu4= - dependencies: - cssnano-util-get-arguments "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-reduce-initial@^4.0.3: - version "4.0.3" - resolved "https://registry.npm.taobao.org/postcss-reduce-initial/download/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" - integrity sha1-f9QuvqXpyBRgljniwuhK4nC6SN8= - dependencies: - browserslist "^4.0.0" - caniuse-api "^3.0.0" - has "^1.0.0" - postcss "^7.0.0" - -postcss-reduce-transforms@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-reduce-transforms/download/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" - integrity sha1-F++kBerMbge+NBSlyi0QdGgdTik= - dependencies: - cssnano-util-get-match "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-selector-parser@^3.0.0: - version "3.1.1" - resolved "https://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-3.1.1.tgz#4f875f4afb0c96573d5cf4d74011aee250a7e865" - integrity sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU= - dependencies: - dot-prop "^4.1.1" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-selector-parser@^5.0.0, postcss-selector-parser@^5.0.0-rc.4: - version "5.0.0" - resolved "https://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" - integrity sha1-JJBENWaXsztk8aj3yAki3d7nGVw= - dependencies: - cssesc "^2.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: - version "6.0.2" - resolved "https://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" - integrity sha1-k0z3mdAWyDQRhZ4J3Oyt4BKG7Fw= - dependencies: - cssesc "^3.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-svgo@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-svgo/download/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" - integrity sha1-F7mXvHEbMzurFDqu07jT1uPTglg= - dependencies: - is-svg "^3.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - svgo "^1.0.0" - -postcss-unique-selectors@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-unique-selectors/download/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" - integrity sha1-lEaRHzKJv9ZMbWgPBzwDsfnuS6w= - dependencies: - alphanum-sort "^1.0.0" - postcss "^7.0.0" - uniqs "^2.0.0" - -postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.1: - version "3.3.1" - resolved "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" - integrity sha1-n/giVH4okyE88cMO+lGsX9G6goE= - -postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" - integrity sha1-SCKCwJpCcG0fyaBptz9E7Ag5Hck= - -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.23, postcss@^7.0.5, postcss@^7.0.6: - version "7.0.25" - resolved "https://registry.npm.taobao.org/postcss/download/postcss-7.0.25.tgz#dd2a2a753d50b13bed7a2009b4a18ac14d9db21e" - integrity sha1-3SoqdT1QsTvteiAJtKGKwU2dsh4= - dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.1.0" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/prelude-ls/download/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -prepend-http@^1.0.0: - version "1.0.4" - resolved "https://registry.npm.taobao.org/prepend-http/download/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - -prettier@^1.18.2: - version "1.19.1" - resolved "https://registry.npm.taobao.org/prettier/download/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha1-99f1/4qc2HKnvkyhQglZVqYHl8s= - -pretty-error@^2.0.2: - version "2.1.1" - resolved "https://registry.npm.taobao.org/pretty-error/download/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" - integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= - dependencies: - renderkid "^2.0.1" - utila "~0.4" - -private@^0.1.6: - version "0.1.8" - resolved "https://registry.npm.taobao.org/private/download/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha1-I4Hts2ifelPWUxkAYPz4ItLzaP8= - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha1-eCDZsWEgzFXKmud5JoCufbptf+I= - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.npm.taobao.org/process/download/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.npm.taobao.org/progress/download/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha1-foz42PW48jnBvGi+tOt4Vn1XLvg= - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/promise-inflight/download/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= - -promise@^7.1.1: - version "7.3.1" - resolved "https://registry.npm.taobao.org/promise/download/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078= - dependencies: - asap "~2.0.3" - -proxy-addr@~2.0.5: - version "2.0.5" - resolved "https://registry.npm.taobao.org/proxy-addr/download/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" - integrity sha1-NMvWSi2B9LH9IedvnwbIpFKZ7jQ= - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.0" - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/prr/download/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/pseudomap/download/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.24, psl@^1.1.28: - version "1.6.0" - resolved "https://registry.npm.taobao.org/psl/download/psl-1.6.0.tgz?cache=0&sync_timestamp=1575592071652&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpsl%2Fdownload%2Fpsl-1.6.0.tgz#60557582ee23b6c43719d9890fb4170ecd91e110" - integrity sha1-YFV1gu4jtsQ3GdmJD7QXDs2R4RA= - -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.npm.taobao.org/public-encrypt/download/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha1-T8ydd6B+SLp1J+fL4N4z0HATMeA= - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/pump/download/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha1-Ejma3W5M91Jtlzy8i1zi4pCLOQk= - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/pump/download/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ= - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.npm.taobao.org/pumpify/download/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha1-NlE74karJ1cLGjdKXOJ4v9dDcM4= - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.npm.taobao.org/punycode/download/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@^1.2.4, punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.npm.taobao.org/punycode/download/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha1-tYsBCsQMIsVldhbI0sLALHv0eew= - -q@^1.1.2: - version "1.5.1" - resolved "https://registry.npm.taobao.org/q/download/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= - -qs@6.7.0: - version "6.7.0" - resolved "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha1-QdwaAV49WB8WIXdr4xr7KHapsbw= - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha1-yzroBuh0BERYTvFUzo7pjUA/PjY= - -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.npm.taobao.org/query-string/download/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" - integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -querystring-es3@^0.2.0: - version "0.2.1" - resolved "https://registry.npm.taobao.org/querystring-es3/download/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.npm.taobao.org/querystring/download/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -querystringify@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/querystringify/download/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" - integrity sha1-YOWl/WSn+L+k0qsu1v30yFutFU4= - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.1.0" - resolved "https://registry.npm.taobao.org/randombytes/download/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo= - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.npm.taobao.org/randomfill/download/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha1-ySGW/IarQr6YPxvzF3giSTHWFFg= - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.npm.taobao.org/range-parser/download/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE= - -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.npm.taobao.org/raw-body/download/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha1-oc5vucm8NWylLoklarWQWeE9AzI= - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - -read-pkg@^5.1.1: - version "5.2.0" - resolved "https://registry.npm.taobao.org/read-pkg/download/read-pkg-5.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg%2Fdownload%2Fread-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - integrity sha1-e/KVQ4yloz5WzTDgU7NO5yUMk8w= - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6, readable-stream@^3.1.1: - version "3.4.0" - resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" - integrity sha1-pRwmdUZY4KPCHb9ZFjvUW6b0R/w= - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.npm.taobao.org/readdirp/download/readdirp-2.2.1.tgz?cache=0&sync_timestamp=1575629866543&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freaddirp%2Fdownload%2Freaddirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha1-DodiKjMlqjPokihcr4tOhGUppSU= - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - -regenerate-unicode-properties@^8.1.0: - version "8.1.0" - resolved "https://registry.npm.taobao.org/regenerate-unicode-properties/download/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" - integrity sha1-71Hg8OpK1CS3e/fLQfPgFccKPw4= - dependencies: - regenerate "^1.4.0" - -regenerate@^1.4.0: - version "1.4.0" - resolved "https://registry.npm.taobao.org/regenerate/download/regenerate-1.4.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerate%2Fdownload%2Fregenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - integrity sha1-SoVuxLVuQHfFV1icroXnpMiGmhE= - -regenerator-runtime@^0.13.2: - version "0.13.3" - resolved "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.13.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" - integrity sha1-fPanfY9cb2Drc8X8GVWyzrAea/U= - -regenerator-transform@^0.14.0: - version "0.14.1" - resolved "https://registry.npm.taobao.org/regenerator-transform/download/regenerator-transform-0.14.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-transform%2Fdownload%2Fregenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb" - integrity sha1-Oy/OThq3cywI9mXf2zFHScfd0vs= - dependencies: - private "^0.1.6" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/regex-not/download/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw= - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp.prototype.flags@^1.2.0: - version "1.3.0" - resolved "https://registry.npm.taobao.org/regexp.prototype.flags/download/regexp.prototype.flags-1.3.0.tgz?cache=0&sync_timestamp=1576388141321&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregexp.prototype.flags%2Fdownload%2Fregexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha1-erqJs8E6ZFCdq888qNn7ub31y3U= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/regexpp/download/regexpp-2.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregexpp%2Fdownload%2Fregexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha1-jRnTHPYySCtYkEn4KB+T28uk0H8= - -regexpu-core@^4.6.0: - version "4.6.0" - resolved "https://registry.npm.taobao.org/regexpu-core/download/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" - integrity sha1-IDfBizJ8/Oim/qKk7EQfJDKvuLY= - dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.1.0" - regjsgen "^0.5.0" - regjsparser "^0.6.0" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.1.0" - -regjsgen@^0.5.0: - version "0.5.1" - resolved "https://registry.npm.taobao.org/regjsgen/download/regjsgen-0.5.1.tgz?cache=0&sync_timestamp=1571560410206&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregjsgen%2Fdownload%2Fregjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" - integrity sha1-SPC/Gl6iBRlpKcDZeYtC0e2YRDw= - -regjsparser@^0.6.0: - version "0.6.2" - resolved "https://registry.npm.taobao.org/regjsparser/download/regjsparser-0.6.2.tgz?cache=0&sync_timestamp=1576908177912&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregjsparser%2Fdownload%2Fregjsparser-0.6.2.tgz#fd62c753991467d9d1ffe0a9f67f27a529024b96" - integrity sha1-/WLHU5kUZ9nR/+Cp9n8npSkCS5Y= - dependencies: - jsesc "~0.5.0" - -regression@~2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/regression/download/regression-2.0.1.tgz#8d29c3e8224a10850c35e337e85a8b2fac3b0c87" - integrity sha1-jSnD6CJKEIUMNeM36FqLL6w7DIc= - -relateurl@0.2.x: - version "0.2.7" - resolved "https://registry.npm.taobao.org/relateurl/download/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.npm.taobao.org/remove-trailing-separator/download/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -renderkid@^2.0.1: - version "2.0.3" - resolved "https://registry.npm.taobao.org/renderkid/download/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" - integrity sha1-OAF5wv9a4TZcUivy/Pz/AcW3QUk= - dependencies: - css-select "^1.1.0" - dom-converter "^0.2" - htmlparser2 "^3.3.0" - strip-ansi "^3.0.0" - utila "^0.4.0" - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.npm.taobao.org/repeat-element/download/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha1-eC4NglwMWjuzlzH4Tv7mt0Lmsc4= - -repeat-string@^1.5.2, repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.npm.taobao.org/repeat-string/download/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -request-promise-core@1.1.3: - version "1.1.3" - resolved "https://registry.npm.taobao.org/request-promise-core/download/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" - integrity sha1-6aPAgbUTgN/qZ3M2Bh/qh5qCnuk= - dependencies: - lodash "^4.17.15" - -request-promise-native@^1.0.8: - version "1.0.8" - resolved "https://registry.npm.taobao.org/request-promise-native/download/request-promise-native-1.0.8.tgz?cache=0&sync_timestamp=1572829683581&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frequest-promise-native%2Fdownload%2Frequest-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" - integrity sha1-pFW5YLgm5E4r+Jma9k3/K/5YyzY= - dependencies: - request-promise-core "1.1.3" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.83.0, request@^2.87.0: - version "2.88.0" - resolved "https://registry.npm.taobao.org/request/download/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha1-nC/KT301tZLv5Xx/ClXoEFIST+8= - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.0" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.4.3" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/require-directory/download/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/require-main-filename/download/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/require-main-filename/download/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha1-0LMp7MfMD2Fkn2IhW+aa9UqomJs= - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/requires-port/download/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/resolve-cwd/download/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/resolve-from/download/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/resolve-from/download/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY= - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.npm.taobao.org/resolve-url/download/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@^1.10.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.8.1: - version "1.14.1" - resolved "https://registry.npm.taobao.org/resolve/download/resolve-1.14.1.tgz#9e018c540fcf0c427d678b9931cbf45e984bcaff" - integrity sha1-ngGMVA/PDEJ9Z4uZMcv0XphLyv8= - dependencies: - path-parse "^1.0.6" - -resolve@~1.13.1: - version "1.13.1" - resolved "https://registry.npm.taobao.org/resolve/download/resolve-1.13.1.tgz#be0aa4c06acd53083505abb35f4d66932ab35d16" - integrity sha1-vgqkwGrNUwg1BauzX01mkyqzXRY= - dependencies: - path-parse "^1.0.6" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/restore-cursor/download/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -resumer@~0.0.0: - version "0.0.0" - resolved "https://registry.npm.taobao.org/resumer/download/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" - integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= - dependencies: - through "~2.3.4" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.npm.taobao.org/ret/download/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w= - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.npm.taobao.org/retry/download/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - -rgb-regex@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/rgb-regex/download/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" - integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= - -rgba-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/rgba-regex/download/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" - integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= - -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.npm.taobao.org/right-align/download/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - integrity sha1-YTObci/mo1FWiSENJOFMlhSGE+8= - dependencies: - align-text "^0.1.1" - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.npm.taobao.org/rimraf/download/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha1-stEE/g2Psnz54KHNqCYt04M8bKs= - dependencies: - glob "^7.1.3" - -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1: - version "2.7.1" - resolved "https://registry.npm.taobao.org/rimraf/download/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha1-NXl/E6f9rcVmFCwp1PB8ytSD4+w= - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.npm.taobao.org/ripemd160/download/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha1-ocGm9iR1FXe6XQeRTLyShQWFiQw= - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rollup@^0.25.8: - version "0.25.8" - resolved "https://registry.npm.taobao.org/rollup/download/rollup-0.25.8.tgz#bf6ce83b87510d163446eeaa577ed6a6fc5835e0" - integrity sha1-v2zoO4dRDRY0Ru6qV37WpvxYNeA= - dependencies: - chalk "^1.1.1" - minimist "^1.2.0" - source-map-support "^0.3.2" - -run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.npm.taobao.org/run-async/download/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= - dependencies: - is-promise "^2.1.0" - -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/run-queue/download/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= - dependencies: - aproba "^1.1.1" - -rw@1, rw@^1.3.2: - version "1.3.3" - resolved "https://registry.npm.taobao.org/rw/download/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" - integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q= - -rxjs@^6.4.0: - version "6.5.3" - resolved "https://registry.npm.taobao.org/rxjs/download/rxjs-6.5.3.tgz?cache=0&sync_timestamp=1568815796923&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" - integrity sha1-UQ4mMX9NuRp+sd532d2boKSJmjo= - dependencies: - tslib "^1.9.0" - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha1-mR7GnSluAxN0fVm9/St0XDX4go0= - -safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha1-t02uxJsRSPiMZLaNSbHoFcHy9Rk= - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/safe-regex/download/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsafer-buffer%2Fdownload%2Fsafer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo= - -sax@~1.2.4: - version "1.2.4" - resolved "https://registry.npm.taobao.org/sax/download/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha1-KBYjTiN4vdxOU1T6tcqold9xANk= - -schema-utils@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/schema-utils/download/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" - integrity sha1-C3mpMgTXtgDUsoUNH2bCo0lRx3A= - dependencies: - ajv "^6.1.0" - ajv-errors "^1.0.0" - ajv-keywords "^3.1.0" - -schema-utils@^2.0.0, schema-utils@^2.0.1, schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.1: - version "2.6.1" - resolved "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.6.1.tgz#eb78f0b945c7bcfa2082b3565e8db3548011dc4f" - integrity sha1-63jwuUXHvPoggrNWXo2zVIAR3E8= - dependencies: - ajv "^6.10.2" - ajv-keywords "^3.4.1" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/select-hose/download/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= - -selfsigned@^1.10.7: - version "1.10.7" - resolved "https://registry.npm.taobao.org/selfsigned/download/selfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b" - integrity sha1-2lgZ/QSdVXTyjoipvMbbxubzkGs= - dependencies: - node-forge "0.9.0" - -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha1-qVT5Ma66UI0we78Gnv8MAclhFvc= - -semver@7.0.0: - version "7.0.0" - resolved "https://registry.npm.taobao.org/semver/download/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha1-XzyjV2HkfgWyBsba/yz4FPAxa44= - -semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0= - -send@0.17.1: - version "0.17.1" - resolved "https://registry.npm.taobao.org/send/download/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha1-wdiwWfeQD3Rm3Uk4vcROEd2zdsg= - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.7.2" - mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -serialize-javascript@^2.1.2: - version "2.1.2" - resolved "https://registry.npm.taobao.org/serialize-javascript/download/serialize-javascript-2.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-javascript%2Fdownload%2Fserialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" - integrity sha1-7OxTsOAxe9yV73arcHS3OEeF+mE= - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.npm.taobao.org/serve-index/download/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.npm.taobao.org/serve-static/download/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha1-Zm5jbcTwEPfvKZcKiKZ0MgiYsvk= - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/set-blocking/download/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/set-value/download/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha1-oY1AUw5vB95CKMfe/kInr4ytAFs= - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.4: - version "1.0.5" - resolved "https://registry.npm.taobao.org/setimmediate/download/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY= - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM= - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.npm.taobao.org/sha.js/download/sha.js-2.4.11.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsha.js%2Fdownload%2Fsha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha1-N6XPC4HsvGlD3hCbopYNGyZYSuc= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/shebang-command/download/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo= - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI= - -shell-quote@^1.6.1: - version "1.7.2" - resolved "https://registry.npm.taobao.org/shell-quote/download/shell-quote-1.7.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fshell-quote%2Fdownload%2Fshell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" - integrity sha1-Z6fQLHbJ2iT5nSCAj8re0ODgS+I= - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -simple-statistics@~6.1.0: - version "6.1.1" - resolved "https://registry.npm.taobao.org/simple-statistics/download/simple-statistics-6.1.1.tgz#e3a0799ffc49914d6f421c5a4ac585f6a13e2bad" - integrity sha1-46B5n/xJkU1vQhxaSsWF9qE+K60= - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.npm.taobao.org/simple-swizzle/download/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/slash/download/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/slash/download/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q= - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ= - -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/slice-ansi/download/slice-ansi-2.1.0.tgz?cache=0&sync_timestamp=1568743500638&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fslice-ansi%2Fdownload%2Fslice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha1-ys12k0YaY3pXiNkqfdT7oGjoFjY= - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/snapdragon-node/download/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha1-bBdfhv8UvbByRWPo88GwIaKGhTs= - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.npm.taobao.org/snapdragon-util/download/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI= - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.npm.taobao.org/snapdragon/download/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0= - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -sockjs-client@1.4.0: - version "1.4.0" - resolved "https://registry.npm.taobao.org/sockjs-client/download/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5" - integrity sha1-yfJWjhnI/YFztJl+o0IOC7MGx9U= - dependencies: - debug "^3.2.5" - eventsource "^1.0.7" - faye-websocket "~0.11.1" - inherits "^2.0.3" - json3 "^3.3.2" - url-parse "^1.4.3" - -sockjs@0.3.19: - version "0.3.19" - resolved "https://registry.npm.taobao.org/sockjs/download/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" - integrity sha1-2Xa76ACve9IK4IWY1YI5NQiZPA0= - dependencies: - faye-websocket "^0.10.0" - uuid "^3.0.1" - -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.npm.taobao.org/sort-keys/download/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= - dependencies: - is-plain-obj "^1.0.0" - -source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/source-list-map/download/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha1-OZO9hzv8SEecyp6jpUeDXHwVSzQ= - -source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.npm.taobao.org/source-map-resolve/download/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha1-cuLMNAlVQ+Q7LGKyxMENSpBU8lk= - dependencies: - atob "^2.1.1" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@^0.3.2: - version "0.3.3" - resolved "https://registry.npm.taobao.org/source-map-support/download/source-map-support-0.3.3.tgz?cache=0&sync_timestamp=1572389965235&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map-support%2Fdownload%2Fsource-map-support-0.3.3.tgz#34900977d5ba3f07c7757ee72e73bb1a9b53754f" - integrity sha1-NJAJd9W6PwfHdX7nLnO7GptTdU8= - dependencies: - source-map "0.1.32" - -source-map-support@~0.5.12: - version "0.5.16" - resolved "https://registry.npm.taobao.org/source-map-support/download/source-map-support-0.5.16.tgz?cache=0&sync_timestamp=1572389965235&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map-support%2Fdownload%2Fsource-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" - integrity sha1-CuBp5/47p1OMZMmFFeNTOerFoEI= - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.npm.taobao.org/source-map-url/download/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@0.1.32: - version "0.1.32" - resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.1.32.tgz#c8b6c167797ba4740a8ea33252162ff08591b266" - integrity sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY= - dependencies: - amdefine ">=0.0.4" - -source-map@^0.5.0, source-map@^0.5.6, source-map@~0.5.1: - version "0.5.7" - resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha1-dHIq8y6WFOnCh6jQu95IteLxomM= - -spdx-correct@^3.0.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/spdx-correct/download/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha1-+4PlBERSaPFUsHTiGMh8ADzTHfQ= - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/spdx-exceptions/download/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha1-LqRQrudPKom/uUUZwH/Nb0EyKXc= - -spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/spdx-expression-parse/download/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha1-meEZt6XaAOBUkcn6M4t5BII7QdA= - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.5" - resolved "https://registry.npm.taobao.org/spdx-license-ids/download/spdx-license-ids-3.0.5.tgz?cache=0&sync_timestamp=1562834220236&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" - integrity sha1-NpS1gEVnpFjTyARYQqY1hjL2JlQ= - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/spdy-transport/download/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha1-ANSGOmQArXXfkzYaFghgXl3NzzE= - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/spdy/download/spdy-4.0.1.tgz#6f12ed1c5db7ea4f24ebb8b89ba58c87c08257f2" - integrity sha1-bxLtHF236k8k67i4m6WMh8CCV/I= - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.npm.taobao.org/split-string/download/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha1-fLCd2jqGWFcFxks5pkZgOGguj+I= - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.0.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsprintf-js%2Fdownload%2Fsprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.npm.taobao.org/sshpk/download/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha1-+2YcC+8ps520B2nuOfpwCT1vaHc= - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.npm.taobao.org/ssri/download/ssri-6.0.1.tgz?cache=0&sync_timestamp=1571961201744&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fssri%2Fdownload%2Fssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - integrity sha1-KjxBso3UW2K2Nnbst0ABJlrp7dg= - dependencies: - figgy-pudding "^3.5.1" - -ssri@^7.0.0: - version "7.1.0" - resolved "https://registry.npm.taobao.org/ssri/download/ssri-7.1.0.tgz?cache=0&sync_timestamp=1571961201744&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fssri%2Fdownload%2Fssri-7.1.0.tgz#92c241bf6de82365b5c7fb4bd76e975522e1294d" - integrity sha1-ksJBv23oI2W1x/tL126XVSLhKU0= - dependencies: - figgy-pudding "^3.5.1" - minipass "^3.1.1" - -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.npm.taobao.org/stable/download/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha1-g26zyDgv4pNv6vVEYxAXzn1Ho88= - -stackframe@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/stackframe/download/stackframe-1.1.0.tgz#e3fc2eb912259479c9822f7d1f1ff365bd5cbc83" - integrity sha1-4/wuuRIllHnJgi99Hx/zZb1cvIM= - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.npm.taobao.org/static-extend/download/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.npm.taobao.org/statuses/download/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/stealthy-require/download/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - -stream-browserify@^2.0.1: - version "2.0.2" - resolved "https://registry.npm.taobao.org/stream-browserify/download/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" - integrity sha1-h1IdOKRKp+6RzhzSpH3wy0ndZgs= - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.npm.taobao.org/stream-each/download/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha1-6+J6DDibBPvMIzZClS4Qcxr6m64= - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.npm.taobao.org/stream-http/download/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha1-stJCRpKIpaJ+xP6JM6z2I95lFPw= - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/stream-shift/download/stream-shift-1.0.1.tgz?cache=0&sync_timestamp=1576147168429&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstream-shift%2Fdownload%2Fstream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" - integrity sha1-1wiCgVWasneEJCebCHfaPDktWj0= - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/strict-uri-encode/download/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.npm.taobao.org/string-width/download/string-width-1.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring-width%2Fdownload%2Fstring-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/string-width/download/string-width-2.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring-width%2Fdownload%2Fstring-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4= - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/string-width/download/string-width-3.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring-width%2Fdownload%2Fstring-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha1-InZ74htirxCBV0MG9prFG2IgOWE= - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.npm.taobao.org/string-width/download/string-width-4.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring-width%2Fdownload%2Fstring-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha1-lSGCxGzHssMT0VluYjmSvRY7crU= - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string.prototype.padend@^3.0.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/string.prototype.padend/download/string.prototype.padend-3.1.0.tgz#dc08f57a8010dc5c153550318f67e13adbb72ac3" - integrity sha1-3Aj1eoAQ3FwVNVAxj2fhOtu3KsM= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -string.prototype.padstart@^3.0.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/string.prototype.padstart/download/string.prototype.padstart-3.1.0.tgz?cache=0&sync_timestamp=1576312396721&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.padstart%2Fdownload%2Fstring.prototype.padstart-3.1.0.tgz#b47c087540d0710be5a49375751a0a627bd4ff90" - integrity sha1-tHwIdUDQcQvlpJN1dRoKYnvU/5A= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -string.prototype.trim@~1.2.1: - version "1.2.1" - resolved "https://registry.npm.taobao.org/string.prototype.trim/download/string.prototype.trim-1.2.1.tgz#141233dff32c82bfad80684d7e5f0869ee0fb782" - integrity sha1-FBIz3/Msgr+tgGhNfl8Iae4Pt4I= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - -string.prototype.trimleft@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/string.prototype.trimleft/download/string.prototype.trimleft-2.1.1.tgz?cache=0&sync_timestamp=1576706744979&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimleft%2Fdownload%2Fstring.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha1-m9uKxqvW1gKxek7TIYcNL43O/HQ= - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string.prototype.trimright@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/string.prototype.trimright/download/string.prototype.trimright-2.1.1.tgz?cache=0&sync_timestamp=1576706745939&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimright%2Fdownload%2Fstring.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha1-RAMUsVmWyGbOigNBiU1FGGIAxdk= - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string_decoder@^1.0.0, string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.3.0.tgz?cache=0&sync_timestamp=1565170823020&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring_decoder%2Fdownload%2Fstring_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha1-QvEUWUpGzxqOMLCoT1bHjD7awh4= - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz?cache=0&sync_timestamp=1565170823020&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring_decoder%2Fdownload%2Fstring_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha1-nPFhG6YmhdcDCunkujQUnDrwP8g= - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-3.0.1.tgz?cache=0&sync_timestamp=1573280518303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-4.0.0.tgz?cache=0&sync_timestamp=1573280518303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz?cache=0&sync_timestamp=1573280518303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4= - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz?cache=0&sync_timestamp=1573280518303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI= - dependencies: - ansi-regex "^5.0.0" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/strip-eof/download/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/strip-final-newline/download/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha1-ibhS+y/L6Tb29LMYevsKEsGrWK0= - -strip-indent@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/strip-indent/download/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" - integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= - -strip-json-comments@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/strip-json-comments/download/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -style-loader@^1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/style-loader/download/style-loader-1.1.1.tgz?cache=0&sync_timestamp=1576852147369&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstyle-loader%2Fdownload%2Fstyle-loader-1.1.1.tgz#8290d915dffe820916790cdcab5aa58c38ab605c" - integrity sha1-gpDZFd/+ggkWeQzcq1qljDirYFw= - dependencies: - loader-utils "^1.2.3" - schema-utils "^2.0.1" - -stylehacks@^4.0.0: - version "4.0.3" - resolved "https://registry.npm.taobao.org/stylehacks/download/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" - integrity sha1-Zxj8r00eB9ihMYaQiB6NlnJqcdU= - dependencies: - browserslist "^4.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha1-4uaaRKyHcveKHsCzW2id9lMO/I8= - dependencies: - has-flag "^3.0.0" - -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-6.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha1-B2Srxpxj1ayELdSGfo0CXogN+PM= - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.1.0" - resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-7.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" - integrity sha1-aOMlkd9z4lrRxLSRCKLsUHliv9E= - dependencies: - has-flag "^4.0.0" - -svg-tags@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/svg-tags/download/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" - integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= - -svgo@^1.0.0: - version "1.3.2" - resolved "https://registry.npm.taobao.org/svgo/download/svgo-1.3.2.tgz?cache=0&sync_timestamp=1572433263159&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsvgo%2Fdownload%2Fsvgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" - integrity sha1-ttxRHAYzRsnkFbgeQ0ARRbltQWc= - dependencies: - chalk "^2.4.1" - coa "^2.0.2" - css-select "^2.0.0" - css-select-base-adapter "^0.1.1" - css-tree "1.0.0-alpha.37" - csso "^4.0.2" - js-yaml "^3.13.1" - mkdirp "~0.5.1" - object.values "^1.1.0" - sax "~1.2.4" - stable "^0.1.8" - unquote "~1.1.1" - util.promisify "~1.0.0" - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.npm.taobao.org/table/download/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha1-EpLRlQDOP4YFOwXw6Ofko7shB54= - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -tapable@^1.0.0, tapable@^1.1.3: - version "1.1.3" - resolved "https://registry.npm.taobao.org/tapable/download/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha1-ofzMBrWNth/XpF2i2kT186Pme6I= - -tape@^4.5.1: - version "4.12.0" - resolved "https://registry.npm.taobao.org/tape/download/tape-4.12.0.tgz?cache=0&sync_timestamp=1576912033059&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftape%2Fdownload%2Ftape-4.12.0.tgz#eb5382ac5d450f9c858819b2233458e69aeda4a8" - integrity sha1-61OCrF1FD5yFiBmyIzRY5prtpKg= - dependencies: - deep-equal "~1.1.1" - defined "~1.0.0" - for-each "~0.3.3" - function-bind "~1.1.1" - glob "~7.1.6" - has "~1.0.3" - inherits "~2.0.4" - is-regex "~1.0.5" - minimist "~1.2.0" - object-inspect "~1.7.0" - resolve "~1.13.1" - resumer "~0.0.0" - string.prototype.trim "~1.2.1" - through "~2.3.8" - -terser-webpack-plugin@^1.4.3: - version "1.4.3" - resolved "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-1.4.3.tgz?cache=0&sync_timestamp=1576580745773&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" - integrity sha1-Xsry29xfuZdF/QZ5H0b8ndscmnw= - dependencies: - cacache "^12.0.2" - find-cache-dir "^2.1.0" - is-wsl "^1.1.0" - schema-utils "^1.0.0" - serialize-javascript "^2.1.2" - source-map "^0.6.1" - terser "^4.1.2" - webpack-sources "^1.4.0" - worker-farm "^1.7.0" - -terser-webpack-plugin@^2.2.1: - version "2.3.1" - resolved "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-2.3.1.tgz?cache=0&sync_timestamp=1576580745773&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-2.3.1.tgz#6a63c27debc15b25ffd2588562ee2eeabdcab923" - integrity sha1-amPCfevBWyX/0liFYu4u6r3KuSM= - dependencies: - cacache "^13.0.1" - find-cache-dir "^3.2.0" - jest-worker "^24.9.0" - schema-utils "^2.6.1" - serialize-javascript "^2.1.2" - source-map "^0.6.1" - terser "^4.4.3" - webpack-sources "^1.4.3" - -terser@^4.1.2, terser@^4.4.3: - version "4.4.3" - resolved "https://registry.npm.taobao.org/terser/download/terser-4.4.3.tgz?cache=0&sync_timestamp=1576537299951&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser%2Fdownload%2Fterser-4.4.3.tgz#401abc52b88869cf904412503b1eb7da093ae2f0" - integrity sha1-QBq8UriIac+QRBJQOx632gk64vA= - dependencies: - commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npm.taobao.org/text-table/download/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.npm.taobao.org/thenify-all/download/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.0" - resolved "https://registry.npm.taobao.org/thenify/download/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" - integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk= - dependencies: - any-promise "^1.0.0" - -thread-loader@^2.1.3: - version "2.1.3" - resolved "https://registry.npm.taobao.org/thread-loader/download/thread-loader-2.1.3.tgz#cbd2c139fc2b2de6e9d28f62286ab770c1acbdda" - integrity sha1-y9LBOfwrLebp0o9iKGq3cMGsvdo= - dependencies: - loader-runner "^2.3.1" - loader-utils "^1.1.0" - neo-async "^2.6.0" - -through2@^2.0.0: - version "2.0.5" - resolved "https://registry.npm.taobao.org/through2/download/through2-2.0.5.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fthrough2%2Fdownload%2Fthrough2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha1-AcHjnrMdB8t9A6lqcIIyYLIxMs0= - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through@^2.3.6, through@~2.3.4, through@~2.3.8: - version "2.3.8" - resolved "https://registry.npm.taobao.org/through/download/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.npm.taobao.org/thunky/download/thunky-1.1.0.tgz?cache=0&sync_timestamp=1571043401546&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fthunky%2Fdownload%2Fthunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha1-Wrr3FKlAXbBQRzK7zNLO3Z75U30= - -timers-browserify@^2.0.4: - version "2.0.11" - resolved "https://registry.npm.taobao.org/timers-browserify/download/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" - integrity sha1-gAsfPu4nLlvFPuRloE0OgEwxIR8= - dependencies: - setimmediate "^1.0.4" - -timsort@^0.3.0: - version "0.3.0" - resolved "https://registry.npm.taobao.org/timsort/download/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" - integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.npm.taobao.org/tmp/download/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha1-bTQzWIl2jSGyvNoKonfO07G/rfk= - dependencies: - os-tmpdir "~1.0.2" - -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/to-arraybuffer/download/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/to-fast-properties/download/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.npm.taobao.org/to-object-path/download/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.npm.taobao.org/to-regex/download/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4= - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM= - -topojson-client@~3.0.0: - version "3.0.1" - resolved "https://registry.npm.taobao.org/topojson-client/download/topojson-client-3.0.1.tgz#774c0343b44fc4ec29c3a2274d7a1a9c3b213cd9" - integrity sha1-d0wDQ7RPxOwpw6InTXoanDshPNk= - dependencies: - commander "2" - -toposort@^1.0.0: - version "1.0.7" - resolved "https://registry.npm.taobao.org/toposort/download/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" - integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk= - -tough-cookie@^2.3.3: - version "2.5.0" - resolved "https://registry.npm.taobao.org/tough-cookie/download/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha1-zZ+yoKodWhK0c72fuW+j3P9lreI= - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.npm.taobao.org/tough-cookie/download/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha1-U/Nto/R3g7CSWvoG/587FlKA94E= - dependencies: - psl "^1.1.24" - punycode "^1.4.1" - -tryer@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/tryer/download/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" - integrity sha1-8shUBoALmw90yfdGW4HqrSQSUvg= - -tslib@^1.9.0: - version "1.10.0" - resolved "https://registry.npm.taobao.org/tslib/download/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha1-w8GflZc/sKYpc/sJ2Q2WHuQ+XIo= - -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.npm.taobao.org/tty-browserify/download/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.npm.taobao.org/tunnel-agent/download/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.npm.taobao.org/tweetnacl/download/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.npm.taobao.org/type-check/download/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.npm.taobao.org/type-fest/download/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha1-jSojcNPfiG61yQraHFv2GIrPg4s= - -type-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.npm.taobao.org/type-is/download/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha1-TlUs0F3wlGfcvE73Od6J8s83wTE= - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.npm.taobao.org/typedarray/download/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -uglify-js@3.4.x: - version "3.4.10" - resolved "https://registry.npm.taobao.org/uglify-js/download/uglify-js-3.4.10.tgz?cache=0&sync_timestamp=1575828721812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" - integrity sha1-mtlWPY6zrN+404WX0q8dgV9qdV8= - dependencies: - commander "~2.19.0" - source-map "~0.6.1" - -uglify-js@^2.6.2: - version "2.8.29" - resolved "https://registry.npm.taobao.org/uglify-js/download/uglify-js-2.8.29.tgz?cache=0&sync_timestamp=1575828721812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" - integrity sha1-KcVzMUgFe7Th913zW3qcty5qWd0= - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-js@^3.1.4: - version "3.7.2" - resolved "https://registry.npm.taobao.org/uglify-js/download/uglify-js-3.7.2.tgz?cache=0&sync_timestamp=1575828721812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.7.2.tgz#cb1a601e67536e9ed094a92dd1e333459643d3f9" - integrity sha1-yxpgHmdTbp7QlKkt0eMzRZZD0/k= - dependencies: - commander "~2.20.3" - source-map "~0.6.1" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/uglify-to-browserify/download/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc= - -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.npm.taobao.org/unicode-canonical-property-names-ecmascript/download/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha1-JhmADEyCWADv3YNDr33Zkzy+KBg= - -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.npm.taobao.org/unicode-match-property-ecmascript/download/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha1-jtKjJWmWG86SJ9Cc0/+7j+1fAgw= - dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" - -unicode-match-property-value-ecmascript@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/unicode-match-property-value-ecmascript/download/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" - integrity sha1-W0tCbgjROoA2Xg1lesemwexGonc= - -unicode-property-aliases-ecmascript@^1.0.4: - version "1.0.5" - resolved "https://registry.npm.taobao.org/unicode-property-aliases-ecmascript/download/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" - integrity sha1-qcxsx85joKMCP8meNBuUQx1AWlc= - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/union-value/download/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha1-C2/nuDWuzaYcbqTU8CwUIh4QmEc= - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/uniq/download/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= - -uniqs@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/uniqs/download/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" - integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= - -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/unique-filename/download/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha1-HWl2k2mtoFgxA6HmrodoG1ZXMjA= - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.npm.taobao.org/unique-slug/download/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha1-uqvOkQg/xk6UWw861hPiZPfNTmw= - dependencies: - imurmurhash "^0.1.4" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY= - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unquote@~1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/unquote/download/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" - integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/unset-value/download/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.1: - version "1.2.0" - resolved "https://registry.npm.taobao.org/upath/download/upath-1.2.0.tgz?cache=0&sync_timestamp=1567457281208&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fupath%2Fdownload%2Fupath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha1-j2bbzVWog6za5ECK+LA1pQRMGJQ= - -upper-case@^1.1.1: - version "1.1.3" - resolved "https://registry.npm.taobao.org/upper-case/download/upper-case-1.1.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fupper-case%2Fdownload%2Fupper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" - integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.npm.taobao.org/uri-js/download/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha1-lMVA4f93KVbiKZUHwBCupsiDjrA= - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.npm.taobao.org/urix/download/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -url-loader@^2.2.0: - version "2.3.0" - resolved "https://registry.npm.taobao.org/url-loader/download/url-loader-2.3.0.tgz?cache=0&sync_timestamp=1574768466952&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Furl-loader%2Fdownload%2Furl-loader-2.3.0.tgz#e0e2ef658f003efb8ca41b0f3ffbf76bab88658b" - integrity sha1-4OLvZY8APvuMpBsPP/v3a6uIZYs= - dependencies: - loader-utils "^1.2.3" - mime "^2.4.4" - schema-utils "^2.5.0" - -url-parse@^1.4.3: - version "1.4.7" - resolved "https://registry.npm.taobao.org/url-parse/download/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" - integrity sha1-qKg1NejACjFuQDpdtKwbm4U64ng= - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.npm.taobao.org/url/download/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.npm.taobao.org/use/download/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha1-1QyMrHmhn7wg8pEfVuuXP04QBw8= - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util.promisify@1.0.0, util.promisify@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/util.promisify/download/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha1-RA9xZaRZyaFtwUXrjnLzVocJcDA= - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - -util@0.10.3: - version "0.10.3" - resolved "https://registry.npm.taobao.org/util/download/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= - dependencies: - inherits "2.0.1" - -util@^0.11.0: - version "0.11.1" - resolved "https://registry.npm.taobao.org/util/download/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - integrity sha1-MjZzNyDsZLsn9uJvQhqqLhtYjWE= - dependencies: - inherits "2.0.3" - -utila@^0.4.0, utila@~0.4: - version "0.4.0" - resolved "https://registry.npm.taobao.org/utila/download/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -uuid@^3.0.1, uuid@^3.3.2: - version "3.3.3" - resolved "https://registry.npm.taobao.org/uuid/download/uuid-3.3.3.tgz?cache=0&sync_timestamp=1566221202613&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuuid%2Fdownload%2Fuuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" - integrity sha1-RWjwIW54dg7h2/Ok0s9T4iQRKGY= - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.npm.taobao.org/validate-npm-package-license/download/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha1-/JH2uce6FchX9MssXe/uw51PQQo= - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -vendors@^1.0.0: - version "1.0.3" - resolved "https://registry.npm.taobao.org/vendors/download/vendors-1.0.3.tgz#a6467781abd366217c050f8202e7e50cc9eef8c0" - integrity sha1-pkZ3gavTZiF8BQ+CAuflDMnu+MA= - -venn.js@~0.2.20: - version "0.2.20" - resolved "https://registry.npm.taobao.org/venn.js/download/venn.js-0.2.20.tgz#3f0e50cc75cba1f58692a8a32f67bd7aaf1aa6fa" - integrity sha1-Pw5QzHXLofWGkqijL2e9eq8apvo= - dependencies: - d3-selection "^1.0.2" - d3-transition "^1.0.1" - fmin "0.0.2" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.npm.taobao.org/verror/download/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vm-browserify@^1.0.1: - version "1.1.2" - resolved "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz?cache=0&sync_timestamp=1572870717730&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvm-browserify%2Fdownload%2Fvm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" - integrity sha1-eGQcSIuObKkadfUR56OzKobl3aA= - -vue-eslint-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.npm.taobao.org/vue-eslint-parser/download/vue-eslint-parser-5.0.0.tgz?cache=0&sync_timestamp=1573306368916&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-eslint-parser%2Fdownload%2Fvue-eslint-parser-5.0.0.tgz#00f4e4da94ec974b821a26ff0ed0f7a78402b8a1" - integrity sha1-APTk2pTsl0uCGib/DtD3p4QCuKE= - dependencies: - debug "^4.1.0" - eslint-scope "^4.0.0" - eslint-visitor-keys "^1.0.0" - espree "^4.1.0" - esquery "^1.0.1" - lodash "^4.17.11" - -vue-hot-reload-api@^2.3.0: - version "2.3.4" - resolved "https://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.3.4.tgz?cache=0&sync_timestamp=1568190386192&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-hot-reload-api%2Fdownload%2Fvue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2" - integrity sha1-UylVzB6yCKPZkLOp+acFdGV+CPI= - -vue-loader@^15.7.2: - version "15.8.3" - resolved "https://registry.npm.taobao.org/vue-loader/download/vue-loader-15.8.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-15.8.3.tgz#857cb9e30eb5fc25e66db48dce7e4f768602a23c" - integrity sha1-hXy54w61/CXmbbSNzn5PdoYCojw= - dependencies: - "@vue/component-compiler-utils" "^3.1.0" - hash-sum "^1.0.2" - loader-utils "^1.1.0" - vue-hot-reload-api "^2.3.0" - vue-style-loader "^4.1.0" - -vue-style-loader@^4.1.0: - version "4.1.2" - resolved "https://registry.npm.taobao.org/vue-style-loader/download/vue-style-loader-4.1.2.tgz#dedf349806f25ceb4e64f3ad7c0a44fba735fcf8" - integrity sha1-3t80mAbyXOtOZPOtfApE+6c1/Pg= - dependencies: - hash-sum "^1.0.2" - loader-utils "^1.0.2" - -vue-template-compiler@^2.6.10: - version "2.6.11" - resolved "https://registry.npm.taobao.org/vue-template-compiler/download/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080" - integrity sha1-wEcE749JixUxMAGJk+VjCdRpgIA= - dependencies: - de-indent "^1.0.2" - he "^1.1.0" - -vue-template-es2015-compiler@^1.9.0: - version "1.9.1" - resolved "https://registry.npm.taobao.org/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" - integrity sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU= - -vue@^2.6.10: - version "2.6.11" - resolved "https://registry.npm.taobao.org/vue/download/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5" - integrity sha1-dllNh31LEiNEBuhONSdcbVFBJcU= - -watchpack@^1.6.0: - version "1.6.0" - resolved "https://registry.npm.taobao.org/watchpack/download/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha1-S8EsLr6KonenHx0/FNaFx7RGzQA= - dependencies: - chokidar "^2.0.2" - graceful-fs "^4.1.2" - neo-async "^2.5.0" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.npm.taobao.org/wbuf/download/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha1-wdjRSTFtPqhShIiVy2oL/oh7h98= - dependencies: - minimalistic-assert "^1.0.0" - -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/wcwidth/download/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= - dependencies: - defaults "^1.0.3" - -webpack-bundle-analyzer@^3.6.0: - version "3.6.0" - resolved "https://registry.npm.taobao.org/webpack-bundle-analyzer/download/webpack-bundle-analyzer-3.6.0.tgz#39b3a8f829ca044682bc6f9e011c95deb554aefd" - integrity sha1-ObOo+CnKBEaCvG+eARyV3rVUrv0= - dependencies: - acorn "^6.0.7" - acorn-walk "^6.1.1" - bfj "^6.1.1" - chalk "^2.4.1" - commander "^2.18.0" - ejs "^2.6.1" - express "^4.16.3" - filesize "^3.6.1" - gzip-size "^5.0.0" - lodash "^4.17.15" - mkdirp "^0.5.1" - opener "^1.5.1" - ws "^6.0.0" - -webpack-chain@^6.0.0: - version "6.2.0" - resolved "https://registry.npm.taobao.org/webpack-chain/download/webpack-chain-6.2.0.tgz#bcea7b0ad5feae6845d70e6fd7a048953f8ae77c" - integrity sha1-vOp7CtX+rmhF1w5v16BIlT+K53w= - dependencies: - deepmerge "^1.5.2" - javascript-stringify "^2.0.1" - -webpack-dev-middleware@^3.7.2: - version "3.7.2" - resolved "https://registry.npm.taobao.org/webpack-dev-middleware/download/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" - integrity sha1-ABnD23FuP6XOy/ZPKriKdLqzMfM= - dependencies: - memory-fs "^0.4.1" - mime "^2.4.4" - mkdirp "^0.5.1" - range-parser "^1.2.1" - webpack-log "^2.0.0" - -webpack-dev-server@^3.9.0: - version "3.10.1" - resolved "https://registry.npm.taobao.org/webpack-dev-server/download/webpack-dev-server-3.10.1.tgz?cache=0&sync_timestamp=1576754522893&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-dev-server%2Fdownload%2Fwebpack-dev-server-3.10.1.tgz#1ff3e5cccf8e0897aa3f5909c654e623f69b1c0e" - integrity sha1-H/PlzM+OCJeqP1kJxlTmI/abHA4= - dependencies: - ansi-html "0.0.7" - bonjour "^3.5.0" - chokidar "^2.1.8" - compression "^1.7.4" - connect-history-api-fallback "^1.6.0" - debug "^4.1.1" - del "^4.1.1" - express "^4.17.1" - html-entities "^1.2.1" - http-proxy-middleware "0.19.1" - import-local "^2.0.0" - internal-ip "^4.3.0" - ip "^1.1.5" - is-absolute-url "^3.0.3" - killable "^1.0.1" - loglevel "^1.6.6" - opn "^5.5.0" - p-retry "^3.0.1" - portfinder "^1.0.25" - schema-utils "^1.0.0" - selfsigned "^1.10.7" - semver "^6.3.0" - serve-index "^1.9.1" - sockjs "0.3.19" - sockjs-client "1.4.0" - spdy "^4.0.1" - strip-ansi "^3.0.1" - supports-color "^6.1.0" - url "^0.11.0" - webpack-dev-middleware "^3.7.2" - webpack-log "^2.0.0" - ws "^6.2.1" - yargs "12.0.5" - -webpack-log@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/webpack-log/download/webpack-log-2.0.0.tgz?cache=0&sync_timestamp=1564684667159&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-log%2Fdownload%2Fwebpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" - integrity sha1-W3ko4GN1k/EZ0y9iJ8HgrDHhtH8= - dependencies: - ansi-colors "^3.0.0" - uuid "^3.3.2" - -webpack-merge@^4.2.2: - version "4.2.2" - resolved "https://registry.npm.taobao.org/webpack-merge/download/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" - integrity sha1-onxS6ng9E5iv0gh/VH17nS9DY00= - dependencies: - lodash "^4.17.15" - -webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: - version "1.4.3" - resolved "https://registry.npm.taobao.org/webpack-sources/download/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha1-7t2OwLko+/HL/plOItLYkPMwqTM= - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -webpack@^4.0.0: - version "4.41.4" - resolved "https://registry.npm.taobao.org/webpack/download/webpack-4.41.4.tgz?cache=0&sync_timestamp=1576740705108&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.41.4.tgz#4bec4125224bdf50efa8be6226c19047599cd034" - integrity sha1-S+xBJSJL31DvqL5iJsGQR1mc0DQ= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.1" - ajv "^6.10.2" - ajv-keywords "^3.4.1" - chrome-trace-event "^1.0.2" - enhanced-resolve "^4.1.0" - eslint-scope "^4.0.3" - json-parse-better-errors "^1.0.2" - loader-runner "^2.4.0" - loader-utils "^1.2.3" - memory-fs "^0.4.1" - micromatch "^3.1.10" - mkdirp "^0.5.1" - neo-async "^2.6.1" - node-libs-browser "^2.2.1" - schema-utils "^1.0.0" - tapable "^1.1.3" - terser-webpack-plugin "^1.4.3" - watchpack "^1.6.0" - webpack-sources "^1.4.1" - -websocket-driver@>=0.5.1: - version "0.7.3" - resolved "https://registry.npm.taobao.org/websocket-driver/download/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" - integrity sha1-otTg1PTxFvHmKX66WLBdQwEA6fk= - dependencies: - http-parser-js ">=0.4.0 <0.4.11" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.3" - resolved "https://registry.npm.taobao.org/websocket-extensions/download/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" - integrity sha1-XS/yKXcAPsaHpLhwc9+7rBRszyk= - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/which-module/download/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@^1.2.9: - version "1.3.1" - resolved "https://registry.npm.taobao.org/which/download/which-1.3.1.tgz?cache=0&sync_timestamp=1574116720213&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo= - dependencies: - isexe "^2.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.npm.taobao.org/which/download/which-2.0.2.tgz?cache=0&sync_timestamp=1574116720213&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE= - dependencies: - isexe "^2.0.0" - -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.npm.taobao.org/window-size/download/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0= - -wolfy87-eventemitter@~5.1.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/wolfy87-eventemitter/download/wolfy87-eventemitter-5.1.0.tgz#35c1ac0dd1ac0c15e35d981508fc22084a13a011" - integrity sha1-NcGsDdGsDBXjXZgVCPwiCEoToBE= - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.npm.taobao.org/word-wrap/download/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha1-YQY29rH3A4kb00dxzLF/uTtHB5w= - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.npm.taobao.org/wordwrap/download/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8= - -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.npm.taobao.org/wordwrap/download/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= - -worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.npm.taobao.org/worker-farm/download/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha1-JqlMU5G7ypJhUgAvabhKS/dy5ag= - dependencies: - errno "~0.1.7" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha1-H9H2cjXVttD+54EFYAG/tpTAOwk= - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha1-6Tk7oHEC5skaOyIUePAlfNKFblM= - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.npm.taobao.org/wrappy/download/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write@1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/write/download/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha1-CADhRSO5I6OH5BUSPIZWFqrg9cM= - dependencies: - mkdirp "^0.5.1" - -ws@^6.0.0, ws@^6.2.1: - version "6.2.1" - resolved "https://registry.npm.taobao.org/ws/download/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" - integrity sha1-RC/fCkftZPWbal2P8TD0dI7VJPs= - dependencies: - async-limiter "~1.0.0" - -xtend@^4.0.0, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.npm.taobao.org/xtend/download/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha1-u3J3n1+kZRhrH0OPZ0+jR/2121Q= - -"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/y18n/download/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha1-le+U+F7MgdAHwmThkKEg8KPIVms= - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.npm.taobao.org/yallist/download/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.npm.taobao.org/yallist/download/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha1-27fa+b/YusmrRev2ArjLrQ1dCP0= - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI= - -yargs-parser@^11.1.1: - version "11.1.1" - resolved "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" - integrity sha1-h5oIZZc7yp9rq1y987HGfsfTvPQ= - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^16.1.0: - version "16.1.0" - resolved "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-16.1.0.tgz#73747d53ae187e7b8dbe333f95714c76ea00ecf1" - integrity sha1-c3R9U64YfnuNvjM/lXFMduoA7PE= - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs@12.0.5: - version "12.0.5" - resolved "https://registry.npm.taobao.org/yargs/download/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha1-BfWZe2CWR7ZPZrgeO0sQo2jnrRM= - dependencies: - cliui "^4.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" - -yargs@^15.0.0: - version "15.0.2" - resolved "https://registry.npm.taobao.org/yargs/download/yargs-15.0.2.tgz#4248bf218ef050385c4f7e14ebdf425653d13bd3" - integrity sha1-Qki/IY7wUDhcT34U699CVlPRO9M= - dependencies: - cliui "^6.0.0" - decamelize "^1.2.0" - find-up "^4.1.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^4.2.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^16.1.0" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.npm.taobao.org/yargs/download/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - integrity sha1-9+572FfdfB0tOMDnTvvWgdFDH9E= - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" - -yorkie@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/yorkie/download/yorkie-2.0.0.tgz#92411912d435214e12c51c2ae1093e54b6bb83d9" - integrity sha1-kkEZEtQ1IU4SxRwq4Qk+VLa7g9k= - dependencies: - execa "^0.8.0" - is-ci "^1.0.10" - normalize-path "^1.0.0" - strip-indent "^2.0.0" - -zrender@4.1.2: - version "4.1.2" - resolved "https://registry.npm.taobao.org/zrender/download/zrender-4.1.2.tgz#8368deff24c7e237cbcbd3a2ff93017905ae43f7" - integrity sha1-g2je/yTH4jfLy9Oi/5MBeQWuQ/c= diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/.gitignore" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/.gitignore" deleted file mode 100644 index a0dddc6fb8c6b3feeeffa6e29bedca338e483382..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/.gitignore" +++ /dev/null @@ -1,21 +0,0 @@ -.DS_Store -node_modules -/dist - -# local env files -.env.local -.env.*.local - -# Log files -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Editor directories and files -.idea -.vscode -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/README.md" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/README.md" deleted file mode 100644 index 413ec395ebef040730de588e849492f8dbf811e0..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/README.md" +++ /dev/null @@ -1,29 +0,0 @@ -# antd-demo - -## Project setup -``` -yarn install -``` - -### Compiles and hot-reloads for development -``` -yarn run serve -``` - -### Compiles and minifies for production -``` -yarn run build -``` - -### Run your tests -``` -yarn run test -``` - -### Lints and fixes files -``` -yarn run lint -``` - -### Customize configuration -See [Configuration Reference](https://cli.vuejs.org/config/). diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/babel.config.js" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/babel.config.js" deleted file mode 100644 index e9558405fdcc02f12d757acb308e02937a7444f1..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/babel.config.js" +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - presets: [ - '@vue/cli-plugin-babel/preset' - ] -} diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/package-lock.json" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/package-lock.json" deleted file mode 100644 index 68701be9af7095f1f789729ee1751805a9bb38b3..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/package-lock.json" +++ /dev/null @@ -1,11499 +0,0 @@ -{ - "name": "antd-demo", - "version": "0.1.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@ant-design/colors": { - "version": "3.2.2", - "resolved": "https://registry.npm.taobao.org/@ant-design/colors/download/@ant-design/colors-3.2.2.tgz", - "integrity": "sha1-WtQ9YZ6RHzSI66wwPWBuZqhCOQM=", - "requires": { - "tinycolor2": "^1.4.1" - } - }, - "@ant-design/icons": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/@ant-design/icons/download/@ant-design/icons-2.1.1.tgz", - "integrity": "sha1-e5wI3/1PXUHbZn2dvl4BB9C9mko=" - }, - "@ant-design/icons-vue": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/@ant-design/icons-vue/download/@ant-design/icons-vue-2.0.0.tgz", - "integrity": "sha1-A1f1AQpATp80qHpLQbKgjfaR284=", - "requires": { - "@ant-design/colors": "^3.1.0", - "babel-runtime": "^6.26.0" - } - }, - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.5.5.tgz?cache=0&sync_timestamp=1563398593063&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcode-frame%2Fdownload%2F%40babel%2Fcode-frame-7.5.5.tgz", - "integrity": "sha1-vAeC9tafe31JUxIZaZuYj2aaj50=", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/core": { - "version": "7.7.7", - "resolved": "https://registry.npm.taobao.org/@babel/core/download/@babel/core-7.7.7.tgz?cache=0&sync_timestamp=1576716811303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fcore%2Fdownload%2F%40babel%2Fcore-7.7.7.tgz", - "integrity": "sha1-7hVdLhIwC8wM/2qK1G8q9QY4A+k=", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.7", - "@babel/helpers": "^7.7.4", - "@babel/parser": "^7.7.7", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz", - "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "json5": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.1.tgz", - "integrity": "sha1-gbbLBOm6SW8ccAXQe0NoomOPkLY=", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.7.7", - "resolved": "https://registry.npm.taobao.org/@babel/generator/download/@babel/generator-7.7.7.tgz", - "integrity": "sha1-hZrHM8RMdBSOGnKYCmTshLhfT0U=", - "dev": true, - "requires": { - "@babel/types": "^7.7.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-annotate-as-pure/download/@babel/helper-annotate-as-pure-7.7.4.tgz?cache=0&sync_timestamp=1574465857294&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.7.4.tgz", - "integrity": "sha1-uz+vHnS3S9VH6Gfkj1UfprCYts4=", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-builder-binary-assignment-operator-visitor/download/@babel/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-builder-binary-assignment-operator-visitor%2Fdownload%2F%40babel%2Fhelper-builder-binary-assignment-operator-visitor-7.7.4.tgz", - "integrity": "sha1-X3PysoWA4iS1ub0DFGpAFdYhf18=", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-call-delegate": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-call-delegate/download/@babel/helper-call-delegate-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-call-delegate%2Fdownload%2F%40babel%2Fhelper-call-delegate-7.7.4.tgz", - "integrity": "sha1-YhuD5ZZyK1DABm+dw30yMuRhuAE=", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-create-class-features-plugin/download/@babel/helper-create-class-features-plugin-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.7.4.tgz", - "integrity": "sha1-/OYJOf1QYYYQlCMgqNlRs7Y52i0=", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-member-expression-to-functions": "^7.7.4", - "@babel/helper-optimise-call-expression": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-create-regexp-features-plugin/download/@babel/helper-create-regexp-features-plugin-7.7.4.tgz", - "integrity": "sha1-bVdiNZ/TT02hUA5M/5lVtSmar1k=", - "dev": true, - "requires": { - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.6.0" - } - }, - "@babel/helper-define-map": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-define-map/download/@babel/helper-define-map-7.7.4.tgz", - "integrity": "sha1-KEG/kuuL2ckGhRVG/mudReFi8XY=", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.7.4", - "@babel/types": "^7.7.4", - "lodash": "^4.17.13" - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-explode-assignable-expression/download/@babel/helper-explode-assignable-expression-7.7.4.tgz", - "integrity": "sha1-+nAIeOAI2F3FG6Q+n7g1zd/gXIQ=", - "dev": true, - "requires": { - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-function-name": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-function-name/download/@babel/helper-function-name-7.7.4.tgz?cache=0&sync_timestamp=1574465949765&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.7.4.tgz", - "integrity": "sha1-q24EHnE11DbY8KPsoV3ltno0Gi4=", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-get-function-arity/download/@babel/helper-get-function-arity-7.7.4.tgz", - "integrity": "sha1-y0Y0jS+ICOYy8KsEgXITDmNgBfA=", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-hoist-variables/download/@babel/helper-hoist-variables-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-hoist-variables%2Fdownload%2F%40babel%2Fhelper-hoist-variables-7.7.4.tgz", - "integrity": "sha1-YSOE49gj/fqvn84xVQ/l1NsPPRI=", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-member-expression-to-functions/download/@babel/helper-member-expression-to-functions-7.7.4.tgz?cache=0&sync_timestamp=1574465859608&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-member-expression-to-functions%2Fdownload%2F%40babel%2Fhelper-member-expression-to-functions-7.7.4.tgz", - "integrity": "sha1-NWQ44lad9zIagyZkTUt5DSEiy3Q=", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-module-imports": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-module-imports/download/@babel/helper-module-imports-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-imports%2Fdownload%2F%40babel%2Fhelper-module-imports-7.7.4.tgz", - "integrity": "sha1-5aklKfiIi/MZpjdqv70c68SRrZE=", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.7.5", - "resolved": "https://registry.npm.taobao.org/@babel/helper-module-transforms/download/@babel/helper-module-transforms-7.7.5.tgz", - "integrity": "sha1-0ETaf/2R7JZ9slzWdI9wS2skSDU=", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.7.4", - "@babel/helper-simple-access": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4", - "lodash": "^4.17.13" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-optimise-call-expression/download/@babel/helper-optimise-call-expression-7.7.4.tgz?cache=0&sync_timestamp=1574465948578&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-optimise-call-expression%2Fdownload%2F%40babel%2Fhelper-optimise-call-expression-7.7.4.tgz", - "integrity": "sha1-A0rzE3DSmVJCqk30AsO3eUstzfI=", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.0.0", - "resolved": "https://registry.npm.taobao.org/@babel/helper-plugin-utils/download/@babel/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha1-u7P77phmHFaQNCN8wDlnupm08lA=", - "dev": true - }, - "@babel/helper-regex": { - "version": "7.5.5", - "resolved": "https://registry.npm.taobao.org/@babel/helper-regex/download/@babel/helper-regex-7.5.5.tgz", - "integrity": "sha1-CqaCT3EAouDonBUnwjk2wVLKs1E=", - "dev": true, - "requires": { - "lodash": "^4.17.13" - } - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-remap-async-to-generator/download/@babel/helper-remap-async-to-generator-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-remap-async-to-generator%2Fdownload%2F%40babel%2Fhelper-remap-async-to-generator-7.7.4.tgz", - "integrity": "sha1-xowkBzUNmvDgYe1nJq+0//FtAjQ=", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.7.4", - "@babel/helper-wrap-function": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-replace-supers": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-replace-supers/download/@babel/helper-replace-supers-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-replace-supers%2Fdownload%2F%40babel%2Fhelper-replace-supers-7.7.4.tgz", - "integrity": "sha1-PIgaamp1cSdactguYQcSbsnizdI=", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.7.4", - "@babel/helper-optimise-call-expression": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-simple-access": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-simple-access/download/@babel/helper-simple-access-7.7.4.tgz", - "integrity": "sha1-oWmgrbG19BjPwZ8iWGsuv1ipopQ=", - "dev": true, - "requires": { - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-split-export-declaration/download/@babel/helper-split-export-declaration-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.7.4.tgz", - "integrity": "sha1-Vykq9gRDxKNiLPdAQN3Cjmgzb9g=", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-wrap-function": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helper-wrap-function/download/@babel/helper-wrap-function-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-wrap-function%2Fdownload%2F%40babel%2Fhelper-wrap-function-7.7.4.tgz", - "integrity": "sha1-N6t/7VFQ4i2dcmboMAcsDN2Lqs4=", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helpers": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/helpers/download/@babel/helpers-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelpers%2Fdownload%2F%40babel%2Fhelpers-7.7.4.tgz", - "integrity": "sha1-YsIVuebHEtrcFamg3Kt2ySqUAwI=", - "dev": true, - "requires": { - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npm.taobao.org/@babel/highlight/download/@babel/highlight-7.5.0.tgz", - "integrity": "sha1-VtETEr2SSPphlZHQJHK+boyzJUA=", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.7.7", - "resolved": "https://registry.npm.taobao.org/@babel/parser/download/@babel/parser-7.7.7.tgz", - "integrity": "sha1-G4hllUGc+S2BExbVtxWlP/OLSTc=", - "dev": true - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-async-generator-functions/download/@babel/plugin-proposal-async-generator-functions-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.7.4.tgz", - "integrity": "sha1-A1HFrAqeknhF//1bgq9HaUe3zm0=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.7.4", - "@babel/plugin-syntax-async-generators": "^7.7.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-class-properties/download/@babel/plugin-proposal-class-properties-7.7.4.tgz?cache=0&sync_timestamp=1574465953354&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.7.4.tgz", - "integrity": "sha1-L5ZPDLGLlIRQNidC4z4VIR53wro=", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-proposal-decorators": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-decorators/download/@babel/plugin-proposal-decorators-7.7.4.tgz?cache=0&sync_timestamp=1574465968165&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-decorators%2Fdownload%2F%40babel%2Fplugin-proposal-decorators-7.7.4.tgz", - "integrity": "sha1-WMHiHSHqEvn18KdX5G5oe5Snqys=", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-decorators": "^7.7.4" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-dynamic-import/download/@babel/plugin-proposal-dynamic-import-7.7.4.tgz", - "integrity": "sha1-3eZKfxJ2kXWMv+1s9w3g+lh51S0=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-dynamic-import": "^7.7.4" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-json-strings/download/@babel/plugin-proposal-json-strings-7.7.4.tgz?cache=0&sync_timestamp=1574466144048&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.7.4.tgz", - "integrity": "sha1-dwCmv9p3HY3IGXMknqxBbGtMaX0=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-json-strings": "^7.7.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.7.7", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-object-rest-spread/download/@babel/plugin-proposal-object-rest-spread-7.7.7.tgz", - "integrity": "sha1-nycHUASrmb4IxcG9ZTophYE8s3A=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.7.4" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-optional-catch-binding/download/@babel/plugin-proposal-optional-catch-binding-7.7.4.tgz?cache=0&sync_timestamp=1574466142661&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.7.4.tgz", - "integrity": "sha1-7CHorrCexnEbwKOcpJUgq+4d43k=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.7.4" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.7.7", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-unicode-property-regex/download/@babel/plugin-proposal-unicode-property-regex-7.7.7.tgz", - "integrity": "sha1-Qz+p2sZPlTwSV4spYz9Fa2iDHE4=", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-async-generators/download/@babel/plugin-syntax-async-generators-7.7.4.tgz", - "integrity": "sha1-MxqvMQoQyAxEpmsji25JEyvTyIk=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-decorators": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-decorators/download/@babel/plugin-syntax-decorators-7.7.4.tgz", - "integrity": "sha1-PJHP7ioRFmP/OsIbhRFA9aUqTgs=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-dynamic-import/download/@babel/plugin-syntax-dynamic-import-7.7.4.tgz?cache=0&sync_timestamp=1574466134311&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-dynamic-import%2Fdownload%2F%40babel%2Fplugin-syntax-dynamic-import-7.7.4.tgz", - "integrity": "sha1-Kco7RBWr/kpew4HpA4Yq0aVMOuw=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-json-strings/download/@babel/plugin-syntax-json-strings-7.7.4.tgz?cache=0&sync_timestamp=1574466138398&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-json-strings%2Fdownload%2F%40babel%2Fplugin-syntax-json-strings-7.7.4.tgz", - "integrity": "sha1-huY/fS4i+eJxKaxOg+qYmjguhsw=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-jsx/download/@babel/plugin-syntax-jsx-7.7.4.tgz?cache=0&sync_timestamp=1574466135844&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-jsx%2Fdownload%2F%40babel%2Fplugin-syntax-jsx-7.7.4.tgz", - "integrity": "sha1-2rK1ajb7bDwiKh+8cfe/l/Mnqew=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-object-rest-spread/download/@babel/plugin-syntax-object-rest-spread-7.7.4.tgz?cache=0&sync_timestamp=1574466135349&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-syntax-object-rest-spread-7.7.4.tgz", - "integrity": "sha1-R88iDRnW0NexVDBHAfRo/BzG/0Y=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-optional-catch-binding/download/@babel/plugin-syntax-optional-catch-binding-7.7.4.tgz?cache=0&sync_timestamp=1574466135469&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-syntax-optional-catch-binding-7.7.4.tgz", - "integrity": "sha1-o+OPWfS2IzhntKktyw7gWywzSqY=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-top-level-await/download/@babel/plugin-syntax-top-level-await-7.7.4.tgz?cache=0&sync_timestamp=1574466726312&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.7.4.tgz", - "integrity": "sha1-vX2Pp7n+55OjbkAn/W3RqjL5Rto=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-arrow-functions/download/@babel/plugin-transform-arrow-functions-7.7.4.tgz?cache=0&sync_timestamp=1574466137008&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.7.4.tgz", - "integrity": "sha1-djCb1Xit3YruOzedgJyAIwWpihI=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-async-to-generator/download/@babel/plugin-transform-async-to-generator-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.7.4.tgz", - "integrity": "sha1-aUy+rm1hOjTvApJxP6QvtFxEcLo=", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.7.4" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoped-functions/download/@babel/plugin-transform-block-scoped-functions-7.7.4.tgz?cache=0&sync_timestamp=1574466137204&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.7.4.tgz", - "integrity": "sha1-0NnVwmnHjq6nYies4hS40B5Ng3s=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoping/download/@babel/plugin-transform-block-scoping-7.7.4.tgz", - "integrity": "sha1-IAqtDc1ruANy+U2eYo6gYsWL8iQ=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.13" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-classes/download/@babel/plugin-transform-classes-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.7.4.tgz", - "integrity": "sha1-ySwUvgoTmeFd9yZnBnqPUQyUAOw=", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.7.4", - "@babel/helper-define-map": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-optimise-call-expression": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-computed-properties/download/@babel/plugin-transform-computed-properties-7.7.4.tgz?cache=0&sync_timestamp=1574466138069&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-computed-properties%2Fdownload%2F%40babel%2Fplugin-transform-computed-properties-7.7.4.tgz", - "integrity": "sha1-6FbBYo0yOP/hLWaOtCVZ95qBkQ0=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-destructuring/download/@babel/plugin-transform-destructuring-7.7.4.tgz?cache=0&sync_timestamp=1574466137334&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-destructuring%2Fdownload%2F%40babel%2Fplugin-transform-destructuring-7.7.4.tgz", - "integrity": "sha1-K3E3KeUFShE1CXtqZ9obb+h4kmc=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.7.7", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-dotall-regex/download/@babel/plugin-transform-dotall-regex-7.7.7.tgz", - "integrity": "sha1-PpcT8bafM56H+nlrCX1z3tFrk3s=", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-duplicate-keys/download/@babel/plugin-transform-duplicate-keys-7.7.4.tgz?cache=0&sync_timestamp=1574466141354&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.7.4.tgz", - "integrity": "sha1-PSFzGkLj9ZinODUpndAWnDuQrJE=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-exponentiation-operator/download/@babel/plugin-transform-exponentiation-operator-7.7.4.tgz?cache=0&sync_timestamp=1574466136890&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.7.4.tgz", - "integrity": "sha1-3TDAGR46G6GbzH44m9/dwHKdXbk=", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-for-of/download/@babel/plugin-transform-for-of-7.7.4.tgz?cache=0&sync_timestamp=1574466137301&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.7.4.tgz", - "integrity": "sha1-JIgA46XlB7HxA9i0ypmOd8Y5Mrw=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-function-name/download/@babel/plugin-transform-function-name-7.7.4.tgz", - "integrity": "sha1-dabTMD1Q22OP+LU4XRJFHIZQJbE=", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-literals/download/@babel/plugin-transform-literals-7.7.4.tgz?cache=0&sync_timestamp=1574466139771&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.7.4.tgz", - "integrity": "sha1-J/6H0rUBeipaNNHEGmufamJiZD4=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-member-expression-literals/download/@babel/plugin-transform-member-expression-literals-7.7.4.tgz?cache=0&sync_timestamp=1574466727087&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-member-expression-literals%2Fdownload%2F%40babel%2Fplugin-transform-member-expression-literals-7.7.4.tgz", - "integrity": "sha1-ruEn8vMzn8NM5eMFXX/796om8Zo=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.7.5", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-amd/download/@babel/plugin-transform-modules-amd-7.7.5.tgz?cache=0&sync_timestamp=1575638364880&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-amd%2Fdownload%2F%40babel%2Fplugin-transform-modules-amd-7.7.5.tgz", - "integrity": "sha1-OeD7cXIktZR1swZAK7ju2rAecpw=", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.7.5", - "@babel/helper-plugin-utils": "^7.0.0", - "babel-plugin-dynamic-import-node": "^2.3.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.7.5", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-commonjs/download/@babel/plugin-transform-modules-commonjs-7.7.5.tgz?cache=0&sync_timestamp=1575638380026&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.7.5.tgz", - "integrity": "sha1-HSf16wvPdUPndJUOWy+nguY3s0U=", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.7.5", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.7.4", - "babel-plugin-dynamic-import-node": "^2.3.0" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-systemjs/download/@babel/plugin-transform-modules-systemjs-7.7.4.tgz", - "integrity": "sha1-zZgVIznT52Pf6Di31Cc+2vUguzA=", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "babel-plugin-dynamic-import-node": "^2.3.0" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-umd/download/@babel/plugin-transform-modules-umd-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.7.4.tgz", - "integrity": "sha1-ECfDVaEY3gqun+4ArXgTxYTZBh8=", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-named-capturing-groups-regex/download/@babel/plugin-transform-named-capturing-groups-regex-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.7.4.tgz", - "integrity": "sha1-+zvMTuQZjnOFgFAHNz1rb0LJgiA=", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.4" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-new-target/download/@babel/plugin-transform-new-target-7.7.4.tgz?cache=0&sync_timestamp=1574466140101&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.7.4.tgz", - "integrity": "sha1-SgdT0tYGOUN74HtZKp5Y7gByAWc=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-object-super/download/@babel/plugin-transform-object-super-7.7.4.tgz?cache=0&sync_timestamp=1574466136400&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-object-super%2Fdownload%2F%40babel%2Fplugin-transform-object-super-7.7.4.tgz", - "integrity": "sha1-SEiJN6LVhsAUhFG/Ua+dfdpWcmI=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.7.4" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.7.7", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-parameters/download/@babel/plugin-transform-parameters-7.7.7.tgz", - "integrity": "sha1-eohLJGAWTcXxlPZoMyc2WEx2AAc=", - "dev": true, - "requires": { - "@babel/helper-call-delegate": "^7.7.4", - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-property-literals/download/@babel/plugin-transform-property-literals-7.7.4.tgz", - "integrity": "sha1-I4jWUF74myZhA/RQ+RZ+a9c/mMI=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.7.5", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-regenerator/download/@babel/plugin-transform-regenerator-7.7.5.tgz?cache=0&sync_timestamp=1575638379269&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.7.5.tgz", - "integrity": "sha1-OodX7hongPOQ6J8kYGXs9Zwm/Ok=", - "dev": true, - "requires": { - "regenerator-transform": "^0.14.0" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-reserved-words/download/@babel/plugin-transform-reserved-words-7.7.4.tgz", - "integrity": "sha1-anzxI60XW7XGmuyPbwdwOH7T8es=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-runtime": { - "version": "7.7.6", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-runtime/download/@babel/plugin-transform-runtime-7.7.6.tgz", - "integrity": "sha1-TytUjIiSL7mOwcJCr9RzPuPhL2E=", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "resolve": "^1.8.1", - "semver": "^5.5.1" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-shorthand-properties/download/@babel/plugin-transform-shorthand-properties-7.7.4.tgz?cache=0&sync_timestamp=1574466143471&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-shorthand-properties%2Fdownload%2F%40babel%2Fplugin-transform-shorthand-properties-7.7.4.tgz", - "integrity": "sha1-dKCpsvbWemhMb7/V8EWOt7qZiR4=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-spread/download/@babel/plugin-transform-spread-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.7.4.tgz", - "integrity": "sha1-qmc7NW/mt+cNabbjOhf+9kEAhXg=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-sticky-regex/download/@babel/plugin-transform-sticky-regex-7.7.4.tgz?cache=0&sync_timestamp=1574466146247&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.7.4.tgz", - "integrity": "sha1-/7aMBQkMMHMgdrEoXcFAG0BKEjw=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-template-literals/download/@babel/plugin-transform-template-literals-7.7.4.tgz?cache=0&sync_timestamp=1574466128847&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.7.4.tgz", - "integrity": "sha1-HrZBFzbdP+h9vSDMZmjlEhwX1gQ=", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-typeof-symbol/download/@babel/plugin-transform-typeof-symbol-7.7.4.tgz?cache=0&sync_timestamp=1574466144984&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-typeof-symbol%2Fdownload%2F%40babel%2Fplugin-transform-typeof-symbol-7.7.4.tgz", - "integrity": "sha1-MXRiYhTy1t4yKILkmKOOg3GyFA4=", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-unicode-regex/download/@babel/plugin-transform-unicode-regex-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.7.4.tgz", - "integrity": "sha1-o8D2WxF8TIHFtkhPKl57lTRrg64=", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/preset-env": { - "version": "7.7.7", - "resolved": "https://registry.npm.taobao.org/@babel/preset-env/download/@babel/preset-env-7.7.7.tgz", - "integrity": "sha1-wpQWe5HlPn422CDpQ+zo0Mf+Rqw=", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-async-generator-functions": "^7.7.4", - "@babel/plugin-proposal-dynamic-import": "^7.7.4", - "@babel/plugin-proposal-json-strings": "^7.7.4", - "@babel/plugin-proposal-object-rest-spread": "^7.7.7", - "@babel/plugin-proposal-optional-catch-binding": "^7.7.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.7.7", - "@babel/plugin-syntax-async-generators": "^7.7.4", - "@babel/plugin-syntax-dynamic-import": "^7.7.4", - "@babel/plugin-syntax-json-strings": "^7.7.4", - "@babel/plugin-syntax-object-rest-spread": "^7.7.4", - "@babel/plugin-syntax-optional-catch-binding": "^7.7.4", - "@babel/plugin-syntax-top-level-await": "^7.7.4", - "@babel/plugin-transform-arrow-functions": "^7.7.4", - "@babel/plugin-transform-async-to-generator": "^7.7.4", - "@babel/plugin-transform-block-scoped-functions": "^7.7.4", - "@babel/plugin-transform-block-scoping": "^7.7.4", - "@babel/plugin-transform-classes": "^7.7.4", - "@babel/plugin-transform-computed-properties": "^7.7.4", - "@babel/plugin-transform-destructuring": "^7.7.4", - "@babel/plugin-transform-dotall-regex": "^7.7.7", - "@babel/plugin-transform-duplicate-keys": "^7.7.4", - "@babel/plugin-transform-exponentiation-operator": "^7.7.4", - "@babel/plugin-transform-for-of": "^7.7.4", - "@babel/plugin-transform-function-name": "^7.7.4", - "@babel/plugin-transform-literals": "^7.7.4", - "@babel/plugin-transform-member-expression-literals": "^7.7.4", - "@babel/plugin-transform-modules-amd": "^7.7.5", - "@babel/plugin-transform-modules-commonjs": "^7.7.5", - "@babel/plugin-transform-modules-systemjs": "^7.7.4", - "@babel/plugin-transform-modules-umd": "^7.7.4", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.7.4", - "@babel/plugin-transform-new-target": "^7.7.4", - "@babel/plugin-transform-object-super": "^7.7.4", - "@babel/plugin-transform-parameters": "^7.7.7", - "@babel/plugin-transform-property-literals": "^7.7.4", - "@babel/plugin-transform-regenerator": "^7.7.5", - "@babel/plugin-transform-reserved-words": "^7.7.4", - "@babel/plugin-transform-shorthand-properties": "^7.7.4", - "@babel/plugin-transform-spread": "^7.7.4", - "@babel/plugin-transform-sticky-regex": "^7.7.4", - "@babel/plugin-transform-template-literals": "^7.7.4", - "@babel/plugin-transform-typeof-symbol": "^7.7.4", - "@babel/plugin-transform-unicode-regex": "^7.7.4", - "@babel/types": "^7.7.4", - "browserslist": "^4.6.0", - "core-js-compat": "^3.6.0", - "invariant": "^2.2.2", - "js-levenshtein": "^1.1.3", - "semver": "^5.5.0" - } - }, - "@babel/runtime": { - "version": "7.7.7", - "resolved": "https://registry.npm.taobao.org/@babel/runtime/download/@babel/runtime-7.7.7.tgz", - "integrity": "sha1-GUdpyo1td5DsI2Ba+e4+QqCqec8=", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@babel/template": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/template/download/@babel/template-7.7.4.tgz?cache=0&sync_timestamp=1574465948896&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftemplate%2Fdownload%2F%40babel%2Ftemplate-7.7.4.tgz", - "integrity": "sha1-Qop9nuz/4n3qwKmOI7+ONnXSp3s=", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/traverse": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/traverse/download/@babel/traverse-7.7.4.tgz", - "integrity": "sha1-nB58YPtnn+T8+qQlAIMzM8IFhVg=", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz", - "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@babel/types": { - "version": "7.7.4", - "resolved": "https://registry.npm.taobao.org/@babel/types/download/@babel/types-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.7.4.tgz", - "integrity": "sha1-UWVw1TnkTd8wjAdWnCWP+U/ekZM=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@hapi/address": { - "version": "2.1.4", - "resolved": "https://registry.npm.taobao.org/@hapi/address/download/@hapi/address-2.1.4.tgz", - "integrity": "sha1-XWftQ/P9QaadS5/3tW58DR0KgeU=", - "dev": true - }, - "@hapi/bourne": { - "version": "1.3.2", - "resolved": "https://registry.npm.taobao.org/@hapi/bourne/download/@hapi/bourne-1.3.2.tgz", - "integrity": "sha1-CnCVreoGckPOMoPhtWuKj0U7JCo=", - "dev": true - }, - "@hapi/hoek": { - "version": "8.5.0", - "resolved": "https://registry.npm.taobao.org/@hapi/hoek/download/@hapi/hoek-8.5.0.tgz", - "integrity": "sha1-L5zjAciJjhwySLCoVkaWsk0amlo=", - "dev": true - }, - "@hapi/joi": { - "version": "15.1.1", - "resolved": "https://registry.npm.taobao.org/@hapi/joi/download/@hapi/joi-15.1.1.tgz", - "integrity": "sha1-xnW4pxKW8Cgz+NbSQ7NMV7jOGdc=", - "dev": true, - "requires": { - "@hapi/address": "2.x.x", - "@hapi/bourne": "1.x.x", - "@hapi/hoek": "8.x.x", - "@hapi/topo": "3.x.x" - } - }, - "@hapi/topo": { - "version": "3.1.6", - "resolved": "https://registry.npm.taobao.org/@hapi/topo/download/@hapi/topo-3.1.6.tgz", - "integrity": "sha1-aNk1+j6uf91asNf5U/MgXYsr/Ck=", - "dev": true, - "requires": { - "@hapi/hoek": "^8.3.0" - } - }, - "@intervolga/optimize-cssnano-plugin": { - "version": "1.0.6", - "resolved": "https://registry.npm.taobao.org/@intervolga/optimize-cssnano-plugin/download/@intervolga/optimize-cssnano-plugin-1.0.6.tgz", - "integrity": "sha1-vnx4RhKLiPapsdEmGgrQbrXA/fg=", - "dev": true, - "requires": { - "cssnano": "^4.0.0", - "cssnano-preset-default": "^4.0.0", - "postcss": "^7.0.0" - } - }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npm.taobao.org/@mrmlnc/readdir-enhanced/download/@mrmlnc/readdir-enhanced-2.2.1.tgz", - "integrity": "sha1-UkryQNGjYFJ7cwR17PoTRKpUDd4=", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - } - }, - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-1.1.3.tgz", - "integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=", - "dev": true - }, - "@soda/friendly-errors-webpack-plugin": { - "version": "1.7.1", - "resolved": "https://registry.npm.taobao.org/@soda/friendly-errors-webpack-plugin/download/@soda/friendly-errors-webpack-plugin-1.7.1.tgz", - "integrity": "sha1-cG9kvLSouWQrSK46zkRMcDNNYV0=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "error-stack-parser": "^2.0.0", - "string-width": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-1.1.3.tgz?cache=0&sync_timestamp=1573282918610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-2.0.0.tgz?cache=0&sync_timestamp=1569557271992&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/@types/color-name/download/@types/color-name-1.1.1.tgz?cache=0&sync_timestamp=1572460951965&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fcolor-name%2Fdownload%2F%40types%2Fcolor-name-1.1.1.tgz", - "integrity": "sha1-HBJhu+qhCoBVu8XYq4S3sq/IRqA=", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/@types/events/download/@types/events-3.0.0.tgz", - "integrity": "sha1-KGLz9Yqaf3w+eNefEw3U1xwlwqc=", - "dev": true - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npm.taobao.org/@types/glob/download/@types/glob-7.1.1.tgz", - "integrity": "sha1-qlmhxuP7xCHgfM0xqUTDDrpSFXU=", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npm.taobao.org/@types/minimatch/download/@types/minimatch-3.0.3.tgz", - "integrity": "sha1-PcoOPzOyAPx9ETnAzZbBJoyt/Z0=", - "dev": true - }, - "@types/node": { - "version": "13.1.2", - "resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-13.1.2.tgz?cache=0&sync_timestamp=1577727780099&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-13.1.2.tgz", - "integrity": "sha1-/pQoW/XgeC4anlqMSCscNEZfo4U=", - "dev": true - }, - "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npm.taobao.org/@types/normalize-package-data/download/@types/normalize-package-data-2.4.0.tgz", - "integrity": "sha1-5IbQ2XOW15vu3QpuM/RTT/a0lz4=", - "dev": true - }, - "@types/q": { - "version": "1.5.2", - "resolved": "https://registry.npm.taobao.org/@types/q/download/@types/q-1.5.2.tgz", - "integrity": "sha1-aQoUdbhPKohP0HzXl8APXzE1bqg=", - "dev": true - }, - "@vue/babel-helper-vue-jsx-merge-props": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/@vue/babel-helper-vue-jsx-merge-props/download/@vue/babel-helper-vue-jsx-merge-props-1.0.0.tgz", - "integrity": "sha1-BI/leZWNpAj7eosqPsBQtQpmEEA=", - "dev": true - }, - "@vue/babel-plugin-transform-vue-jsx": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/@vue/babel-plugin-transform-vue-jsx/download/@vue/babel-plugin-transform-vue-jsx-1.1.2.tgz", - "integrity": "sha1-wKPm78Ai515CR7RIqPxrhvA+kcA=", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "html-tags": "^2.0.0", - "lodash.kebabcase": "^4.1.1", - "svg-tags": "^1.0.0" - } - }, - "@vue/babel-preset-app": { - "version": "4.1.2", - "resolved": "https://registry.npm.taobao.org/@vue/babel-preset-app/download/@vue/babel-preset-app-4.1.2.tgz?cache=0&sync_timestamp=1577537773193&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-preset-app%2Fdownload%2F%40vue%2Fbabel-preset-app-4.1.2.tgz", - "integrity": "sha1-3FJVmz/DTC9ETau447sKoDhA6Ns=", - "dev": true, - "requires": { - "@babel/core": "^7.7.4", - "@babel/helper-module-imports": "^7.7.4", - "@babel/plugin-proposal-class-properties": "^7.7.4", - "@babel/plugin-proposal-decorators": "^7.7.4", - "@babel/plugin-syntax-dynamic-import": "^7.7.4", - "@babel/plugin-syntax-jsx": "^7.7.4", - "@babel/plugin-transform-runtime": "^7.7.4", - "@babel/preset-env": "^7.7.4", - "@babel/runtime": "^7.7.4", - "@vue/babel-preset-jsx": "^1.1.2", - "babel-plugin-dynamic-import-node": "^2.2.0", - "core-js": "^3.4.4", - "core-js-compat": "^3.4.4" - }, - "dependencies": { - "core-js": { - "version": "3.6.1", - "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.6.1.tgz", - "integrity": "sha1-OdXi40YljMAet9RDRbHDwBTKPwU=", - "dev": true - } - } - }, - "@vue/babel-preset-jsx": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/@vue/babel-preset-jsx/download/@vue/babel-preset-jsx-1.1.2.tgz", - "integrity": "sha1-LhaetMIE6jfKZsLqhaiAv8mdTyA=", - "dev": true, - "requires": { - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", - "@vue/babel-sugar-functional-vue": "^1.1.2", - "@vue/babel-sugar-inject-h": "^1.1.2", - "@vue/babel-sugar-v-model": "^1.1.2", - "@vue/babel-sugar-v-on": "^1.1.2" - } - }, - "@vue/babel-sugar-functional-vue": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/@vue/babel-sugar-functional-vue/download/@vue/babel-sugar-functional-vue-1.1.2.tgz", - "integrity": "sha1-9+JPugnm8e5wEEVgqICAV1VfGpo=", - "dev": true, - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@vue/babel-sugar-inject-h": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/@vue/babel-sugar-inject-h/download/@vue/babel-sugar-inject-h-1.1.2.tgz", - "integrity": "sha1-ilJ2ttji7Rb/yAeKrZQjYnTm7fA=", - "dev": true, - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0" - } - }, - "@vue/babel-sugar-v-model": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/@vue/babel-sugar-v-model/download/@vue/babel-sugar-v-model-1.1.2.tgz", - "integrity": "sha1-H/b9G4ACI/ycsehNzrXlLXN6gZI=", - "dev": true, - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", - "camelcase": "^5.0.0", - "html-tags": "^2.0.0", - "svg-tags": "^1.0.0" - } - }, - "@vue/babel-sugar-v-on": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/@vue/babel-sugar-v-on/download/@vue/babel-sugar-v-on-1.1.2.tgz", - "integrity": "sha1-su+ZuPL6sJ++rSWq1w70Lhz1sTs=", - "dev": true, - "requires": { - "@babel/plugin-syntax-jsx": "^7.2.0", - "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", - "camelcase": "^5.0.0" - } - }, - "@vue/cli-overlay": { - "version": "4.1.2", - "resolved": "https://registry.npm.taobao.org/@vue/cli-overlay/download/@vue/cli-overlay-4.1.2.tgz", - "integrity": "sha1-1dqIE5pSLZimDtzG9hwKBs36l/E=", - "dev": true - }, - "@vue/cli-plugin-babel": { - "version": "4.1.2", - "dev": true, - "requires": { - "@babel/core": "^7.7.4", - "@vue/babel-preset-app": "^4.1.2", - "@vue/cli-shared-utils": "^4.1.2", - "babel-loader": "^8.0.6", - "cache-loader": "^4.1.0", - "thread-loader": "^2.1.3", - "webpack": "^4.0.0" - } - }, - "@vue/cli-plugin-eslint": { - "version": "4.1.2", - "dev": true, - "requires": { - "@vue/cli-shared-utils": "^4.1.2", - "eslint-loader": "^2.1.2", - "globby": "^9.2.0", - "webpack": "^4.0.0", - "yorkie": "^2.0.0" - } - }, - "@vue/cli-plugin-router": { - "version": "4.1.2", - "resolved": "https://registry.npm.taobao.org/@vue/cli-plugin-router/download/@vue/cli-plugin-router-4.1.2.tgz", - "integrity": "sha1-3A/d+kuIEvioF0asW+/7kWjcyB8=", - "dev": true, - "requires": { - "@vue/cli-shared-utils": "^4.1.2" - } - }, - "@vue/cli-plugin-vuex": { - "version": "4.1.2", - "resolved": "https://registry.npm.taobao.org/@vue/cli-plugin-vuex/download/@vue/cli-plugin-vuex-4.1.2.tgz", - "integrity": "sha1-XnKLVq2d4vBiqJRPg4r/oCl8y5k=", - "dev": true - }, - "@vue/cli-service": { - "version": "4.1.2", - "dev": true, - "requires": { - "@intervolga/optimize-cssnano-plugin": "^1.0.5", - "@soda/friendly-errors-webpack-plugin": "^1.7.1", - "@vue/cli-overlay": "^4.1.2", - "@vue/cli-plugin-router": "^4.1.2", - "@vue/cli-plugin-vuex": "^4.1.2", - "@vue/cli-shared-utils": "^4.1.2", - "@vue/component-compiler-utils": "^3.0.2", - "@vue/preload-webpack-plugin": "^1.1.0", - "@vue/web-component-wrapper": "^1.2.0", - "acorn": "^6.1.1", - "acorn-walk": "^6.1.1", - "address": "^1.1.2", - "autoprefixer": "^9.7.2", - "browserslist": "^4.7.3", - "cache-loader": "^4.1.0", - "case-sensitive-paths-webpack-plugin": "^2.2.0", - "cli-highlight": "^2.1.4", - "clipboardy": "^2.0.0", - "cliui": "^5.0.0", - "copy-webpack-plugin": "^5.0.5", - "css-loader": "^3.1.0", - "cssnano": "^4.1.10", - "current-script-polyfill": "^1.0.0", - "debug": "^4.1.1", - "default-gateway": "^5.0.5", - "dotenv": "^8.2.0", - "dotenv-expand": "^5.1.0", - "file-loader": "^4.2.0", - "fs-extra": "^7.0.1", - "globby": "^9.2.0", - "hash-sum": "^1.0.2", - "html-webpack-plugin": "^3.2.0", - "launch-editor-middleware": "^2.2.1", - "lodash.defaultsdeep": "^4.6.1", - "lodash.mapvalues": "^4.6.0", - "lodash.transform": "^4.6.0", - "mini-css-extract-plugin": "^0.8.0", - "minimist": "^1.2.0", - "portfinder": "^1.0.25", - "postcss-loader": "^3.0.0", - "read-pkg": "^5.1.1", - "ssri": "^7.1.0", - "terser-webpack-plugin": "^2.2.1", - "thread-loader": "^2.1.3", - "url-loader": "^2.2.0", - "vue-loader": "^15.7.2", - "vue-style-loader": "^4.1.0", - "webpack": "^4.0.0", - "webpack-bundle-analyzer": "^3.6.0", - "webpack-chain": "^6.0.0", - "webpack-dev-server": "^3.9.0", - "webpack-merge": "^4.2.2" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz", - "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "@vue/cli-shared-utils": { - "version": "4.1.2", - "resolved": "https://registry.npm.taobao.org/@vue/cli-shared-utils/download/@vue/cli-shared-utils-4.1.2.tgz?cache=0&sync_timestamp=1577537777874&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-shared-utils%2Fdownload%2F%40vue%2Fcli-shared-utils-4.1.2.tgz", - "integrity": "sha1-0zmEyHkK2Gnvd/Uimr0+jlhP5Ys=", - "dev": true, - "requires": { - "@hapi/joi": "^15.0.1", - "chalk": "^2.4.2", - "execa": "^1.0.0", - "launch-editor": "^2.2.1", - "lru-cache": "^5.1.1", - "node-ipc": "^9.1.1", - "open": "^6.3.0", - "ora": "^3.4.0", - "request": "^2.87.0", - "request-promise-native": "^1.0.8", - "semver": "^6.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz", - "integrity": "sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz", - "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz?cache=0&sync_timestamp=1573280549549&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-6.0.0.tgz", - "integrity": "sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI=", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "@vue/component-compiler-utils": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/@vue/component-compiler-utils/download/@vue/component-compiler-utils-3.1.0.tgz?cache=0&sync_timestamp=1575823514995&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcomponent-compiler-utils%2Fdownload%2F%40vue%2Fcomponent-compiler-utils-3.1.0.tgz", - "integrity": "sha1-ZM05SSX1rx+cMijGbpVFNvUxGFc=", - "dev": true, - "requires": { - "consolidate": "^0.15.1", - "hash-sum": "^1.0.2", - "lru-cache": "^4.1.2", - "merge-source-map": "^1.1.0", - "postcss": "^7.0.14", - "postcss-selector-parser": "^5.0.0", - "prettier": "^1.18.2", - "source-map": "~0.6.1", - "vue-template-es2015-compiler": "^1.9.0" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-4.1.5.tgz", - "integrity": "sha1-i75Q6oW+1ZvJ4z3KuCNe6bz0Q80=", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } - }, - "@vue/preload-webpack-plugin": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/@vue/preload-webpack-plugin/download/@vue/preload-webpack-plugin-1.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fpreload-webpack-plugin%2Fdownload%2F%40vue%2Fpreload-webpack-plugin-1.1.1.tgz", - "integrity": "sha1-GHI1MNME9EMCHaIpLW7JUCgmEEo=", - "dev": true - }, - "@vue/web-component-wrapper": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/@vue/web-component-wrapper/download/@vue/web-component-wrapper-1.2.0.tgz", - "integrity": "sha1-uw5G8VhafiibTuYGfcxaauYvHdE=", - "dev": true - }, - "@webassemblyjs/ast": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/ast/download/@webassemblyjs/ast-1.8.5.tgz", - "integrity": "sha1-UbHF/mV2o0lTv0slPfnw1JDZ41k=", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/floating-point-hex-parser/download/@webassemblyjs/floating-point-hex-parser-1.8.5.tgz", - "integrity": "sha1-G6kmopI2E+3OSW/VsC6M6KX0lyE=", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-api-error/download/@webassemblyjs/helper-api-error-1.8.5.tgz", - "integrity": "sha1-xJ2tIvZFInxe22EL25aX8aq3Ifc=", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-buffer/download/@webassemblyjs/helper-buffer-1.8.5.tgz", - "integrity": "sha1-/qk+Qphj3V5DOFVfQikjhaZT8gQ=", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-code-frame/download/@webassemblyjs/helper-code-frame-1.8.5.tgz", - "integrity": "sha1-mnQP9I4/qjAisd/1RCPfmqKTwl4=", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-fsm/download/@webassemblyjs/helper-fsm-1.8.5.tgz", - "integrity": "sha1-ugt9Oz9+RzPaYFnJMyJ12GBwJFI=", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-module-context/download/@webassemblyjs/helper-module-context-1.8.5.tgz", - "integrity": "sha1-3vS5knsBAdyMu9jR7bW3ucguskU=", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "mamacro": "^0.0.3" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-wasm-bytecode/download/@webassemblyjs/helper-wasm-bytecode-1.8.5.tgz", - "integrity": "sha1-U3p1Dt31weky83RCBlUckcG5PmE=", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-wasm-section/download/@webassemblyjs/helper-wasm-section-1.8.5.tgz", - "integrity": "sha1-dMpqa8vhnlCjtrRihH5pUD5r/L8=", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/ieee754/download/@webassemblyjs/ieee754-1.8.5.tgz", - "integrity": "sha1-cSMp2+8kDza/V70ve4+5v0FUQh4=", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/leb128/download/@webassemblyjs/leb128-1.8.5.tgz", - "integrity": "sha1-BE7es06mefPgTNT9mCTV41dnrhA=", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/utf8/download/@webassemblyjs/utf8-1.8.5.tgz", - "integrity": "sha1-qL87XY/+mGx8Hjc8y9wqCRXwztw=", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-edit/download/@webassemblyjs/wasm-edit-1.8.5.tgz", - "integrity": "sha1-li2hKqWswcExyBxCMpkcgs5W4Bo=", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/helper-wasm-section": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-opt": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-gen/download/@webassemblyjs/wasm-gen-1.8.5.tgz", - "integrity": "sha1-VIQHZsLBAC62TtGr5yCt7XFPmLw=", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-opt/download/@webassemblyjs/wasm-opt-1.8.5.tgz", - "integrity": "sha1-sk2fa6UDlK8TSfUQr6j/y4pj0mQ=", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-parser/download/@webassemblyjs/wasm-parser-1.8.5.tgz", - "integrity": "sha1-IVdvDsiLkUJzV7hTY4NmjvfGa40=", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wast-parser/download/@webassemblyjs/wast-parser-1.8.5.tgz", - "integrity": "sha1-4Q7s1ULQ5705T2gnxJ899tTu+4w=", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/floating-point-hex-parser": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-code-frame": "1.8.5", - "@webassemblyjs/helper-fsm": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.8.5", - "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wast-printer/download/@webassemblyjs/wast-printer-1.8.5.tgz", - "integrity": "sha1-EUu8SB/RDKDiOzVg+oEnSLC65bw=", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/@xtuc/ieee754/download/@xtuc/ieee754-1.2.0.tgz", - "integrity": "sha1-7vAUoxRa5Hehy8AM0eVSM23Ot5A=", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npm.taobao.org/@xtuc/long/download/@xtuc/long-4.2.2.tgz", - "integrity": "sha1-0pHGpOl5ibXGHZrPOWrk/hM6cY0=", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz", - "integrity": "sha1-UxvHJlF6OytB+FACHGzBXqq1B80=", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "6.4.0", - "resolved": "https://registry.npm.taobao.org/acorn/download/acorn-6.4.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Facorn%2Fdownload%2Facorn-6.4.0.tgz", - "integrity": "sha1-tlnS/7r6JLr12xzbsslKmD7NJ4Q=", - "dev": true - }, - "acorn-jsx": { - "version": "5.1.0", - "resolved": "https://registry.npm.taobao.org/acorn-jsx/download/acorn-jsx-5.1.0.tgz?cache=0&sync_timestamp=1570992134935&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Facorn-jsx%2Fdownload%2Facorn-jsx-5.1.0.tgz", - "integrity": "sha1-KUrbcbVzmLBoABXwo4xWPuHbU4Q=", - "dev": true - }, - "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npm.taobao.org/acorn-walk/download/acorn-walk-6.2.0.tgz", - "integrity": "sha1-Ejy487hMIXHx9/slJhWxx4prGow=", - "dev": true - }, - "add-dom-event-listener": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/add-dom-event-listener/download/add-dom-event-listener-1.1.0.tgz", - "integrity": "sha1-apLbOg3Qq8JU4JXA8dwUrLuq4xA=", - "requires": { - "object-assign": "4.x" - } - }, - "address": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/address/download/address-1.1.2.tgz", - "integrity": "sha1-vxEWycdYxRt6kz0pa3LCIe2UKLY=", - "dev": true - }, - "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npm.taobao.org/aggregate-error/download/aggregate-error-3.0.1.tgz?cache=0&sync_timestamp=1570167911603&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faggregate-error%2Fdownload%2Faggregate-error-3.0.1.tgz", - "integrity": "sha1-2y/nJG5Tb0DZtUQqOeEX191qJOA=", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-6.10.2.tgz", - "integrity": "sha1-086gTWsBeyiUrWkED+yLYj60vVI=", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/ajv-errors/download/ajv-errors-1.0.1.tgz", - "integrity": "sha1-81mGrOuRr63sQQL72FAUlQzvpk0=", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npm.taobao.org/ajv-keywords/download/ajv-keywords-3.4.1.tgz", - "integrity": "sha1-75FuJxxkrBIXH9g4TqrmsjRYVNo=", - "dev": true - }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/alphanum-sort/download/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npm.taobao.org/ansi-colors/download/ansi-colors-3.2.4.tgz", - "integrity": "sha1-46PaS/uubIapwoViXeEkojQCb78=", - "dev": true - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npm.taobao.org/ansi-escapes/download/ansi-escapes-3.2.0.tgz?cache=0&sync_timestamp=1573923784843&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-escapes%2Fdownload%2Fansi-escapes-3.2.0.tgz", - "integrity": "sha1-h4C5j/nb9WOBUtHx/lwde0RCl2s=", - "dev": true - }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npm.taobao.org/ansi-html/download/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz", - "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "ant-design-vue": { - "version": "1.4.10", - "resolved": "https://registry.npm.taobao.org/ant-design-vue/download/ant-design-vue-1.4.10.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fant-design-vue%2Fdownload%2Fant-design-vue-1.4.10.tgz", - "integrity": "sha1-Jr81cKPJPVS65XHpjylFew/RFtg=", - "requires": { - "@ant-design/icons": "^2.1.1", - "@ant-design/icons-vue": "^2.0.0", - "add-dom-event-listener": "^1.0.2", - "array-tree-filter": "^2.1.0", - "async-validator": "^3.0.3", - "babel-helper-vue-jsx-merge-props": "^2.0.3", - "babel-runtime": "6.x", - "classnames": "^2.2.5", - "component-classes": "^1.2.6", - "dom-align": "^1.7.0", - "dom-closest": "^0.2.0", - "dom-scroll-into-view": "^1.2.1", - "enquire.js": "^2.1.6", - "intersperse": "^1.0.0", - "is-negative-zero": "^2.0.0", - "ismobilejs": "^0.5.1", - "json2mq": "^0.2.0", - "lodash": "^4.17.5", - "moment": "^2.21.0", - "mutationobserver-shim": "^0.3.2", - "node-emoji": "^1.10.0", - "omit.js": "^1.0.0", - "raf": "^3.4.0", - "resize-observer-polyfill": "^1.5.1", - "shallow-equal": "^1.0.0", - "shallowequal": "^1.0.2", - "vue-ref": "^1.0.4", - "warning": "^3.0.0" - } - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npm.taobao.org/any-promise/download/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/anymatch/download/anymatch-2.0.0.tgz", - "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/normalize-path/download/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/aproba/download/aproba-1.2.0.tgz", - "integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo=", - "dev": true - }, - "arch": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/arch/download/arch-2.1.1.tgz", - "integrity": "sha1-j1wnMao1owkpIhuwZA7tZRdeyE4=", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npm.taobao.org/argparse/download/argparse-1.0.10.tgz", - "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/arr-diff/download/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/arr-flatten/download/arr-flatten-1.1.0.tgz", - "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/arr-union/download/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "array-tree-filter": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/array-tree-filter/download/array-tree-filter-2.1.0.tgz", - "integrity": "sha1-hzrAD+yDdJ8lWsjdCDgUtPYykZA=" - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/array-union/download/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/array-uniq/download/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npm.taobao.org/array-unique/download/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz", - "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npm.taobao.org/asn1.js/download/asn1.js-4.10.1.tgz", - "integrity": "sha1-ucK/WAXx5kqt7tbfOiv6+1pz9aA=", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npm.taobao.org/assert/download/assert-1.5.0.tgz", - "integrity": "sha1-VcEJqvbgrv2z3EtxJAxwv1dLGOs=", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.1.tgz?cache=0&sync_timestamp=1560975547815&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Finherits%2Fdownload%2Finherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npm.taobao.org/util/download/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/assert-plus/download/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/assign-symbols/download/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/astral-regex/download/astral-regex-1.0.0.tgz", - "integrity": "sha1-bIw/uCfdQ+45GPJ7gngqt2WKb9k=", - "dev": true - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npm.taobao.org/async/download/async-2.6.3.tgz", - "integrity": "sha1-1yYl4jRKNlbjo61Pp0n6gymdgv8=", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/async-each/download/async-each-1.0.3.tgz", - "integrity": "sha1-tyfb+H12UWAvBvTUrDh/R9kbDL8=", - "dev": true - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/async-limiter/download/async-limiter-1.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fasync-limiter%2Fdownload%2Fasync-limiter-1.0.1.tgz", - "integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=", - "dev": true - }, - "async-validator": { - "version": "3.2.3", - "resolved": "https://registry.npm.taobao.org/async-validator/download/async-validator-3.2.3.tgz", - "integrity": "sha1-s4ty+cCMHShUjfE7smC2kIRIykk=" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npm.taobao.org/atob/download/atob-2.1.2.tgz", - "integrity": "sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k=", - "dev": true - }, - "autoprefixer": { - "version": "9.7.3", - "resolved": "https://registry.npm.taobao.org/autoprefixer/download/autoprefixer-9.7.3.tgz", - "integrity": "sha1-/ULtA/U96b60yg1h+09yaKm7ULQ=", - "dev": true, - "requires": { - "browserslist": "^4.8.0", - "caniuse-lite": "^1.0.30001012", - "chalk": "^2.4.2", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.23", - "postcss-value-parser": "^4.0.2" - }, - "dependencies": { - "postcss-value-parser": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-4.0.2.tgz", - "integrity": "sha1-SCKCwJpCcG0fyaBptz9E7Ag5Hck=", - "dev": true - } - } - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npm.taobao.org/aws-sign2/download/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.9.0", - "resolved": "https://registry.npm.taobao.org/aws4/download/aws4-1.9.0.tgz", - "integrity": "sha1-JDkOatYThrCnRyZXVNKhchnehiw=", - "dev": true - }, - "babel-eslint": { - "version": "10.0.3", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - } - }, - "babel-helper-vue-jsx-merge-props": { - "version": "2.0.3", - "resolved": "https://registry.npm.taobao.org/babel-helper-vue-jsx-merge-props/download/babel-helper-vue-jsx-merge-props-2.0.3.tgz", - "integrity": "sha1-Iq69OzOQIyjlEyk6jkmSs4T58bY=" - }, - "babel-loader": { - "version": "8.0.6", - "resolved": "https://registry.npm.taobao.org/babel-loader/download/babel-loader-8.0.6.tgz", - "integrity": "sha1-4zvbbzYrA/S7FBoMIauHxQG3Dfs=", - "dev": true, - "requires": { - "find-cache-dir": "^2.0.0", - "loader-utils": "^1.0.2", - "mkdirp": "^0.5.1", - "pify": "^4.0.1" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.0", - "resolved": "https://registry.npm.taobao.org/babel-plugin-dynamic-import-node/download/babel-plugin-dynamic-import-node-2.3.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-plugin-dynamic-import-node%2Fdownload%2Fbabel-plugin-dynamic-import-node-2.3.0.tgz", - "integrity": "sha1-8A9Qe9qjw+P/bn5emNkKesq5b38=", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npm.taobao.org/babel-runtime/download/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-2.6.11.tgz", - "integrity": "sha1-OIMUafmSK97Y7iHJ3EaYXgOZMIw=" - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.11.1.tgz", - "integrity": "sha1-vgWtf5v30i4Fb5cmzuUBf78Z4uk=" - } - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npm.taobao.org/base/download/base-0.11.2.tgz", - "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-1.0.0.tgz", - "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-1.0.2.tgz", - "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npm.taobao.org/base64-js/download/base64-js-1.3.1.tgz", - "integrity": "sha1-WOzoy3XdB+ce0IxzarxfrE2/jfE=", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npm.taobao.org/batch/download/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/bcrypt-pbkdf/download/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bfj": { - "version": "6.1.2", - "resolved": "https://registry.npm.taobao.org/bfj/download/bfj-6.1.2.tgz", - "integrity": "sha1-MlyGGoIryzWKQceKM7jm4ght3n8=", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "check-types": "^8.0.3", - "hoopy": "^0.1.4", - "tryer": "^1.0.1" - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npm.taobao.org/big.js/download/big.js-5.2.2.tgz", - "integrity": "sha1-ZfCvOC9Xi83HQr2cKB6cstd2gyg=", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npm.taobao.org/binary-extensions/download/binary-extensions-1.13.1.tgz", - "integrity": "sha1-WYr+VHVbKGilMw0q/51Ou1Mgm2U=", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npm.taobao.org/bindings/download/bindings-1.5.0.tgz", - "integrity": "sha1-EDU8npRTNLwFEabZCzj7x8nFBN8=", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz", - "integrity": "sha1-nyKcFb4nJFT/qXOs4NvueaGww28=", - "dev": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-4.11.8.tgz", - "integrity": "sha1-LN4J617jQfSEdGuwMJsyU7GxRC8=", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz", - "integrity": "sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io=", - "dev": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - } - }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npm.taobao.org/bonjour/download/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dev": true, - "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - }, - "dependencies": { - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npm.taobao.org/array-flatten/download/array-flatten-2.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-2.1.2.tgz", - "integrity": "sha1-JO+AoowaiTYX4hSbDG0NeIKTsJk=", - "dev": true - } - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/boolbase/download/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz", - "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npm.taobao.org/braces/download/braces-2.3.2.tgz", - "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/brorand/download/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/browserify-aes/download/browserify-aes-1.2.0.tgz", - "integrity": "sha1-Mmc0ZC9APavDADIJhTu3CtQo70g=", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/browserify-cipher/download/browserify-cipher-1.0.1.tgz", - "integrity": "sha1-jWR0wbhwv9q807z8wZNKEOlPFfA=", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/browserify-des/download/browserify-des-1.0.2.tgz", - "integrity": "sha1-OvTx9Zg5QDVy8cZiBDdfen9wPpw=", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/browserify-rsa/download/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npm.taobao.org/browserify-sign/download/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npm.taobao.org/browserify-zlib/download/browserify-zlib-0.2.0.tgz", - "integrity": "sha1-KGlFnZqjviRf6P4sofRuLn9U1z8=", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "4.8.3", - "resolved": "https://registry.npm.taobao.org/browserslist/download/browserslist-4.8.3.tgz", - "integrity": "sha1-ZYAvzXcXfIeOAV8OMYnyxPYnukQ=", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001017", - "electron-to-chromium": "^1.3.322", - "node-releases": "^1.1.44" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npm.taobao.org/buffer/download/buffer-4.9.2.tgz?cache=0&sync_timestamp=1573257183822&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbuffer%2Fdownload%2Fbuffer-4.9.2.tgz", - "integrity": "sha1-Iw6tNEACmIZEhBqwJEr4xEu+Pvg=", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz", - "integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=", - "dev": true - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/buffer-indexof/download/buffer-indexof-1.1.1.tgz", - "integrity": "sha1-Uvq8xqYG0aADAoAmSO9o9jnaJow=", - "dev": true - }, - "buffer-json": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/buffer-json/download/buffer-json-2.0.0.tgz", - "integrity": "sha1-9z4TseQvGW/i/WfQAcfXEH7dfCM=", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/buffer-xor/download/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/builtin-status-codes/download/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz", - "integrity": "sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY=", - "dev": true - }, - "cacache": { - "version": "12.0.3", - "resolved": "https://registry.npm.taobao.org/cacache/download/cacache-12.0.3.tgz?cache=0&sync_timestamp=1569877543868&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcacache%2Fdownload%2Fcacache-12.0.3.tgz", - "integrity": "sha1-vpmruk4b9d9GHNWiwQcfxDJXM5A=", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npm.taobao.org/ssri/download/ssri-6.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fssri%2Fdownload%2Fssri-6.0.1.tgz", - "integrity": "sha1-KjxBso3UW2K2Nnbst0ABJlrp7dg=", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/cache-base/download/cache-base-1.0.1.tgz", - "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cache-loader": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/cache-loader/download/cache-loader-4.1.0.tgz", - "integrity": "sha1-mUjK41OuwKH8ser9ojAIFuyFOH4=", - "dev": true, - "requires": { - "buffer-json": "^2.0.0", - "find-cache-dir": "^3.0.0", - "loader-utils": "^1.2.3", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "schema-utils": "^2.0.0" - }, - "dependencies": { - "find-cache-dir": { - "version": "3.2.0", - "resolved": "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-3.2.0.tgz", - "integrity": "sha1-5/5EwavBKZ9RYUblYxCP0QBsGHQ=", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.0", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz", - "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz", - "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "make-dir": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/make-dir/download/make-dir-3.0.0.tgz", - "integrity": "sha1-G1859rknDtM/nwVMXA+EMEmJ+AE=", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz", - "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz", - "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-4.2.0.tgz", - "integrity": "sha1-8JkTPfft5CLoHR2ESCcO6z5CYfM=", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "schema-utils": { - "version": "2.6.1", - "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.6.1.tgz?cache=0&sync_timestamp=1574946754916&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.6.1.tgz", - "integrity": "sha1-63jwuUXHvPoggrNWXo2zVIAR3E8=", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz", - "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=", - "dev": true - } - } - }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/call-me-maybe/download/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", - "dev": true - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/caller-callsite/download/caller-callsite-2.0.0.tgz?cache=0&sync_timestamp=1562668966653&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcaller-callsite%2Fdownload%2Fcaller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, - "requires": { - "callsites": "^2.0.0" - }, - "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/callsites/download/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true - } - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/caller-path/download/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/callsites/download/callsites-3.1.0.tgz", - "integrity": "sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M=", - "dev": true - }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/camel-case/download/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz", - "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=", - "dev": true - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/caniuse-api/download/caniuse-api-3.0.0.tgz", - "integrity": "sha1-Xk2Q4idJYdRikZl99Znj7QCO5MA=", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001017", - "resolved": "https://registry.npm.taobao.org/caniuse-lite/download/caniuse-lite-1.0.30001017.tgz?cache=0&sync_timestamp=1577471591500&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcaniuse-lite%2Fdownload%2Fcaniuse-lite-1.0.30001017.tgz", - "integrity": "sha1-061uwYFIub2ZGCmVjZ1+Viu3jNY=", - "dev": true - }, - "case-sensitive-paths-webpack-plugin": { - "version": "2.2.0", - "resolved": "https://registry.npm.taobao.org/case-sensitive-paths-webpack-plugin/download/case-sensitive-paths-webpack-plugin-2.2.0.tgz", - "integrity": "sha1-M3HvY2XvnCX6S4HBas4OnH3FjD4=", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npm.taobao.org/caseless/download/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz?cache=0&sync_timestamp=1573282918610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-2.4.2.tgz", - "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&sync_timestamp=1569557271992&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz", - "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npm.taobao.org/chardet/download/chardet-0.7.0.tgz", - "integrity": "sha1-kAlISfCTfy7twkJdDSip5fDLrZ4=", - "dev": true - }, - "check-types": { - "version": "8.0.3", - "resolved": "https://registry.npm.taobao.org/check-types/download/check-types-8.0.3.tgz?cache=0&sync_timestamp=1577112099852&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcheck-types%2Fdownload%2Fcheck-types-8.0.3.tgz", - "integrity": "sha1-M1bMoZyIlUTy16le1JzlCKDs9VI=", - "dev": true - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npm.taobao.org/chokidar/download/chokidar-2.1.8.tgz", - "integrity": "sha1-gEs6e2qZNYw8XGHnHYco8EHP+Rc=", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "chownr": { - "version": "1.1.3", - "resolved": "https://registry.npm.taobao.org/chownr/download/chownr-1.1.3.tgz", - "integrity": "sha1-Qtg31SOWiNVfMDADpQgjD6ZycUI=", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/chrome-trace-event/download/chrome-trace-event-1.0.2.tgz", - "integrity": "sha1-I0CQ7pfH1K0aLEvq4nUF3v/GCKQ=", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npm.taobao.org/ci-info/download/ci-info-1.6.0.tgz", - "integrity": "sha1-LKINu5zrMtRSSmgzAzE/AwSx5Jc=", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/cipher-base/download/cipher-base-1.0.4.tgz", - "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npm.taobao.org/class-utils/download/class-utils-0.3.6.tgz", - "integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "classnames": { - "version": "2.2.6", - "resolved": "https://registry.npm.taobao.org/classnames/download/classnames-2.2.6.tgz", - "integrity": "sha1-Q5Nb/90pHzJtrQogUwmzjQD2UM4=" - }, - "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npm.taobao.org/clean-css/download/clean-css-4.2.1.tgz", - "integrity": "sha1-LUEe92uFabbQyEBo2r6FsKpeXBc=", - "dev": true, - "requires": { - "source-map": "~0.6.0" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npm.taobao.org/clean-stack/download/clean-stack-2.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fclean-stack%2Fdownload%2Fclean-stack-2.2.0.tgz", - "integrity": "sha1-7oRy27Ep5yezHooQpCfe6d/kAIs=", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/cli-cursor/download/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-highlight": { - "version": "2.1.4", - "resolved": "https://registry.npm.taobao.org/cli-highlight/download/cli-highlight-2.1.4.tgz?cache=0&sync_timestamp=1573949240542&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcli-highlight%2Fdownload%2Fcli-highlight-2.1.4.tgz", - "integrity": "sha1-CYy2Qs8X9CrcHBFF4H+WDsTXUis=", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "highlight.js": "^9.6.0", - "mz": "^2.4.0", - "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^5.1.1", - "yargs": "^15.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.2.1.tgz", - "integrity": "sha1-kK51xCTQCNJiTFvynq0xd+v881k=", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-3.0.0.tgz?cache=0&sync_timestamp=1573282918610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-3.0.0.tgz", - "integrity": "sha1-P3PCv1JlkfV0zEksUeJFY0n4ROQ=", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz", - "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz", - "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.1.0.tgz?cache=0&sync_timestamp=1569557271992&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.1.0.tgz", - "integrity": "sha1-aOMlkd9z4lrRxLSRCKLsUHliv9E=", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "cli-spinners": { - "version": "2.2.0", - "resolved": "https://registry.npm.taobao.org/cli-spinners/download/cli-spinners-2.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcli-spinners%2Fdownload%2Fcli-spinners-2.2.0.tgz", - "integrity": "sha1-6LmI2SBsaSMC2O6DTnqFwBRNj3c=", - "dev": true - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npm.taobao.org/cli-width/download/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "clipboardy": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/clipboardy/download/clipboardy-2.1.0.tgz", - "integrity": "sha1-ASOgyPrJLyVtxWM14LuL6XpJCaU=", - "dev": true, - "requires": { - "arch": "^2.1.1", - "execa": "^1.0.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npm.taobao.org/cliui/download/cliui-5.0.0.tgz?cache=0&sync_timestamp=1573942320052&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcliui%2Fdownload%2Fcliui-5.0.0.tgz", - "integrity": "sha1-3u/P2y6AB4SqNPRvoI4GhRx7u8U=", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz", - "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-3.1.0.tgz", - "integrity": "sha1-InZ74htirxCBV0MG9prFG2IgOWE=", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz?cache=0&sync_timestamp=1573280549549&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-5.2.0.tgz", - "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-5.1.0.tgz?cache=0&sync_timestamp=1573488719878&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwrap-ansi%2Fdownload%2Fwrap-ansi-5.1.0.tgz", - "integrity": "sha1-H9H2cjXVttD+54EFYAG/tpTAOwk=", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - } - } - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/clone/download/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "coa": { - "version": "2.0.2", - "resolved": "https://registry.npm.taobao.org/coa/download/coa-2.0.2.tgz", - "integrity": "sha1-Q/bCEVG07yv1cYfbDXPeIp4+fsM=", - "dev": true, - "requires": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/code-point-at/download/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/collection-visit/download/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color": { - "version": "3.1.2", - "resolved": "https://registry.npm.taobao.org/color/download/color-3.1.2.tgz", - "integrity": "sha1-aBSOf4XUGtdknF+oyBBvCY0inhA=", - "dev": true, - "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz", - "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=", - "dev": true, - "requires": { - "color-name": "1.1.3" - }, - "dependencies": { - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - } - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz", - "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=", - "dev": true - }, - "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npm.taobao.org/color-string/download/color-string-1.5.3.tgz", - "integrity": "sha1-ybvF8BtYtUkvPWhXRZy2WQziBMw=", - "dev": true, - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz", - "integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npm.taobao.org/commander/download/commander-2.20.3.tgz", - "integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/commondir/download/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-classes": { - "version": "1.2.6", - "resolved": "https://registry.npm.taobao.org/component-classes/download/component-classes-1.2.6.tgz", - "integrity": "sha1-xkI5TDYYpNiwuJGe/Mu9kw5c1pE=", - "requires": { - "component-indexof": "0.0.3" - } - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz", - "integrity": "sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A=", - "dev": true - }, - "component-indexof": { - "version": "0.0.3", - "resolved": "https://registry.npm.taobao.org/component-indexof/download/component-indexof-0.0.3.tgz", - "integrity": "sha1-EdCRMSI5648yyPJa6csAL/6NPCQ=" - }, - "compressible": { - "version": "2.0.17", - "resolved": "https://registry.npm.taobao.org/compressible/download/compressible-2.0.17.tgz", - "integrity": "sha1-bowQihatWDhKl386SCyiC/8vOME=", - "dev": true, - "requires": { - "mime-db": ">= 1.40.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npm.taobao.org/compression/download/compression-1.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcompression%2Fdownload%2Fcompression-1.7.4.tgz", - "integrity": "sha1-lVI+/xcMpXwpoMpB5v4TH0Hlu48=", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/bytes/download/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz", - "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", - "dev": true - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npm.taobao.org/concat-stream/download/concat-stream-1.6.2.tgz", - "integrity": "sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ=", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npm.taobao.org/connect-history-api-fallback/download/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha1-izIIk1kwjRERFdgcrT/Oq4iPl7w=", - "dev": true - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/console-browserify/download/console-browserify-1.2.0.tgz", - "integrity": "sha1-ZwY871fOts9Jk6KrOlWECujEkzY=", - "dev": true - }, - "consolidate": { - "version": "0.15.1", - "resolved": "https://registry.npm.taobao.org/consolidate/download/consolidate-0.15.1.tgz", - "integrity": "sha1-IasEMjXHGgfUXZqtmFk7DbpWurc=", - "dev": true, - "requires": { - "bluebird": "^3.1.1" - } - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/constants-browserify/download/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz", - "integrity": "sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70=", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz", - "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", - "dev": true - } - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz", - "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npm.taobao.org/convert-source-map/download/convert-source-map-1.7.0.tgz", - "integrity": "sha1-F6LLiC1/d9NJBYXizmxSRCSjpEI=", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz", - "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", - "dev": true - } - } - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npm.taobao.org/cookie/download/cookie-0.4.0.tgz", - "integrity": "sha1-vrQ35wIrO21JAZ0IhmUwPr6cFLo=", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npm.taobao.org/copy-concurrently/download/copy-concurrently-1.0.5.tgz", - "integrity": "sha1-kilzmMrjSTf8r9bsgTnBgFHwteA=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npm.taobao.org/copy-descriptor/download/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "copy-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npm.taobao.org/copy-webpack-plugin/download/copy-webpack-plugin-5.1.1.tgz", - "integrity": "sha1-VIGgPeoRI9iKmIxv+LeCRyFPC4g=", - "dev": true, - "requires": { - "cacache": "^12.0.3", - "find-cache-dir": "^2.1.0", - "glob-parent": "^3.1.0", - "globby": "^7.1.1", - "is-glob": "^4.0.1", - "loader-utils": "^1.2.3", - "minimatch": "^3.0.4", - "normalize-path": "^3.0.0", - "p-limit": "^2.2.1", - "schema-utils": "^1.0.0", - "serialize-javascript": "^2.1.2", - "webpack-log": "^2.0.0" - }, - "dependencies": { - "globby": { - "version": "7.1.1", - "resolved": "https://registry.npm.taobao.org/globby/download/globby-7.1.1.tgz?cache=0&sync_timestamp=1562335642755&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglobby%2Fdownload%2Fglobby-7.1.1.tgz", - "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "dir-glob": "^2.0.0", - "glob": "^7.1.2", - "ignore": "^3.3.5", - "pify": "^3.0.0", - "slash": "^1.0.0" - } - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npm.taobao.org/ignore/download/ignore-3.3.10.tgz", - "integrity": "sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM=", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/slash/download/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - } - } - }, - "core-js-compat": { - "version": "3.6.1", - "resolved": "https://registry.npm.taobao.org/core-js-compat/download/core-js-compat-3.6.1.tgz?cache=0&sync_timestamp=1577253986957&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js-compat%2Fdownload%2Fcore-js-compat-3.6.1.tgz", - "integrity": "sha1-OWOMk1yDyTp5OrtiiyUuxD6FeDo=", - "dev": true, - "requires": { - "browserslist": "^4.8.2", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npm.taobao.org/semver/download/semver-7.0.0.tgz", - "integrity": "sha1-XzyjV2HkfgWyBsba/yz4FPAxa44=", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npm.taobao.org/cosmiconfig/download/cosmiconfig-5.2.1.tgz?cache=0&sync_timestamp=1572710769619&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcosmiconfig%2Fdownload%2Fcosmiconfig-5.2.1.tgz", - "integrity": "sha1-BA9yaAnFked6F8CjYmykW08Wixo=", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "dependencies": { - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/import-fresh/download/import-fresh-2.0.0.tgz?cache=0&sync_timestamp=1573664960772&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimport-fresh%2Fdownload%2Fimport-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - } - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npm.taobao.org/create-ecdh/download/create-ecdh-4.0.3.tgz", - "integrity": "sha1-yREbbzMEXEaX8UR4f5JUzcd8Rf8=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/create-hash/download/create-hash-1.2.0.tgz", - "integrity": "sha1-iJB4rxGmN1a8+1m9IhmWvjqe8ZY=", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npm.taobao.org/create-hmac/download/create-hmac-1.1.7.tgz", - "integrity": "sha1-aRcMeLOrlXFHsriwRXLkfq0iQ/8=", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-6.0.5.tgz?cache=0&sync_timestamp=1570508303786&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcross-spawn%2Fdownload%2Fcross-spawn-6.0.5.tgz", - "integrity": "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q=", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npm.taobao.org/crypto-browserify/download/crypto-browserify-3.12.0.tgz", - "integrity": "sha1-OWz58xN/A+S45TLFj2mCVOAPgOw=", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npm.taobao.org/css-color-names/download/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "dev": true - }, - "css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/css-declaration-sorter/download/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha1-wZiUD2OnbX42wecQGLABchBUyyI=", - "dev": true, - "requires": { - "postcss": "^7.0.1", - "timsort": "^0.3.0" - } - }, - "css-loader": { - "version": "3.4.0", - "resolved": "https://registry.npm.taobao.org/css-loader/download/css-loader-3.4.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-3.4.0.tgz", - "integrity": "sha1-n7JjQ2eDEXpB0BTkXo6uulTdZnA=", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "cssesc": "^3.0.0", - "icss-utils": "^4.1.1", - "loader-utils": "^1.2.3", - "normalize-path": "^3.0.0", - "postcss": "^7.0.23", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^3.0.2", - "postcss-modules-scope": "^2.1.1", - "postcss-modules-values": "^3.0.0", - "postcss-value-parser": "^4.0.2", - "schema-utils": "^2.6.0" - }, - "dependencies": { - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/cssesc/download/cssesc-3.0.0.tgz", - "integrity": "sha1-N3QZGZA7hoVl4cCep0dEXNGJg+4=", - "dev": true - }, - "postcss-value-parser": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-4.0.2.tgz", - "integrity": "sha1-SCKCwJpCcG0fyaBptz9E7Ag5Hck=", - "dev": true - }, - "schema-utils": { - "version": "2.6.1", - "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.6.1.tgz?cache=0&sync_timestamp=1574946754916&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.6.1.tgz", - "integrity": "sha1-63jwuUXHvPoggrNWXo2zVIAR3E8=", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1" - } - } - } - }, - "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/css-select/download/css-select-2.1.0.tgz", - "integrity": "sha1-ajRlM1ZjWTSoG6ymjQJVQyEF2+8=", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npm.taobao.org/css-select-base-adapter/download/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha1-Oy/0lyzDYquIVhUHqVQIoUMhNdc=", - "dev": true - }, - "css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npm.taobao.org/css-tree/download/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha1-mL69YsTB2flg7DQM+fdSLjBwmiI=", - "dev": true, - "requires": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - } - }, - "css-unit-converter": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/css-unit-converter/download/css-unit-converter-1.1.1.tgz", - "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=", - "dev": true - }, - "css-what": { - "version": "3.2.1", - "resolved": "https://registry.npm.taobao.org/css-what/download/css-what-3.2.1.tgz?cache=0&sync_timestamp=1573341698559&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-what%2Fdownload%2Fcss-what-3.2.1.tgz", - "integrity": "sha1-9KjxJCEGRiG0VnVeNKA6LCLfXaE=", - "dev": true - }, - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/cssesc/download/cssesc-2.0.0.tgz", - "integrity": "sha1-OxO9G7HLNuG8taTc0n9UxdyzVwM=", - "dev": true - }, - "cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npm.taobao.org/cssnano/download/cssnano-4.1.10.tgz", - "integrity": "sha1-CsQfCxPRPUZUh+ERt3jULaYxuLI=", - "dev": true, - "requires": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" - } - }, - "cssnano-preset-default": { - "version": "4.0.7", - "resolved": "https://registry.npm.taobao.org/cssnano-preset-default/download/cssnano-preset-default-4.0.7.tgz", - "integrity": "sha1-UexmLM/KD4izltzZZ5zbkxvhf3Y=", - "dev": true, - "requires": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.2", - "postcss-unique-selectors": "^4.0.1" - } - }, - "cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/cssnano-util-get-arguments/download/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", - "dev": true - }, - "cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/cssnano-util-get-match/download/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", - "dev": true - }, - "cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/cssnano-util-raw-cache/download/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha1-sm1f1fcqEd/np4RvtMZyYPlr8oI=", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/cssnano-util-same-parent/download/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha1-V0CC+yhZ0ttDOFWDXZqEVuoYu/M=", - "dev": true - }, - "csso": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/csso/download/csso-4.0.2.tgz", - "integrity": "sha1-5fgas6Vrju+38Aks5yeTKfRU3j0=", - "dev": true, - "requires": { - "css-tree": "1.0.0-alpha.37" - } - }, - "current-script-polyfill": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/current-script-polyfill/download/current-script-polyfill-1.0.0.tgz", - "integrity": "sha1-8xz35PPiGLBybnOMqSoC00iO9hU=", - "dev": true - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/cyclist/download/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npm.taobao.org/dashdash/download/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz", - "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", - "dev": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/decamelize/download/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npm.taobao.org/decode-uri-component/download/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/deep-equal/download/deep-equal-1.1.1.tgz", - "integrity": "sha1-tcmMlCzv+vfLBR4k4UNKJaLmB2o=", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npm.taobao.org/deep-is/download/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "deepmerge": { - "version": "1.5.2", - "resolved": "https://registry.npm.taobao.org/deepmerge/download/deepmerge-1.5.2.tgz", - "integrity": "sha1-EEmdhohEza1P7ghC34x/bwyVp1M=", - "dev": true - }, - "default-gateway": { - "version": "5.0.5", - "resolved": "https://registry.npm.taobao.org/default-gateway/download/default-gateway-5.0.5.tgz?cache=0&sync_timestamp=1573764719154&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdefault-gateway%2Fdownload%2Fdefault-gateway-5.0.5.tgz", - "integrity": "sha1-T9a9XShV05s0zFpZUFSG6ar8mxA=", - "dev": true, - "requires": { - "execa": "^3.3.0" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.1.tgz?cache=0&sync_timestamp=1570508303786&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcross-spawn%2Fdownload%2Fcross-spawn-7.0.1.tgz", - "integrity": "sha1-CrVihuD3wk4VPQTMKqAn5DqaXRQ=", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "execa": { - "version": "3.4.0", - "resolved": "https://registry.npm.taobao.org/execa/download/execa-3.4.0.tgz?cache=0&sync_timestamp=1576749001049&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-3.4.0.tgz", - "integrity": "sha1-wI7UVQ72XYWPrCaf/IVyRG8364k=", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "p-finally": "^2.0.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-5.1.0.tgz", - "integrity": "sha1-ASA83JJZf5uQkGfD5lbMH008Tck=", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/is-stream/download/is-stream-2.0.0.tgz", - "integrity": "sha1-venDJoDW+uBBKdasnZIc54FfeOM=", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-4.0.1.tgz?cache=0&sync_timestamp=1577053500910&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnpm-run-path%2Fdownload%2Fnpm-run-path-4.0.1.tgz", - "integrity": "sha1-t+zR5e1T2o43pV4cImnguX7XSOo=", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/p-finally/download/p-finally-2.0.1.tgz", - "integrity": "sha1-vW/KqcVZoJa2gIBvTWV7Pw8kBWE=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npm.taobao.org/path-key/download/path-key-3.1.1.tgz?cache=0&sync_timestamp=1574441431664&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-key%2Fdownload%2Fpath-key-3.1.1.tgz", - "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz", - "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-3.0.0.tgz", - "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npm.taobao.org/which/download/which-2.0.2.tgz?cache=0&sync_timestamp=1574116898193&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-2.0.2.tgz", - "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/defaults/download/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "requires": { - "clone": "^1.0.2" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npm.taobao.org/define-properties/download/define-properties-1.1.3.tgz", - "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-2.0.2.tgz", - "integrity": "sha1-1Flono1lS6d+AqgX+HENcCyxbp0=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-1.0.0.tgz", - "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-1.0.2.tgz", - "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/del/download/del-4.1.1.tgz?cache=0&sync_timestamp=1566558736172&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdel%2Fdownload%2Fdel-4.1.1.tgz", - "integrity": "sha1-no8RciLqRKMf86FWwEm5kFKp8LQ=", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npm.taobao.org/globby/download/globby-6.1.0.tgz?cache=0&sync_timestamp=1562335642755&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglobby%2Fdownload%2Fglobby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npm.taobao.org/pify/download/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/p-map/download/p-map-2.1.0.tgz", - "integrity": "sha1-MQko/u+cnsxltosXaTAYpmXOoXU=", - "dev": true - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/des.js/download/des.js-1.0.1.tgz", - "integrity": "sha1-U4IULhvcU/hdhtU+X0qn3rkeCEM=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npm.taobao.org/detect-node/download/detect-node-2.0.4.tgz", - "integrity": "sha1-AU7o+PZpxcWAI9pkuBecCDooxGw=", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npm.taobao.org/diffie-hellman/download/diffie-hellman-5.0.3.tgz", - "integrity": "sha1-QOjumPVaIUlgcUaSHGPhrl89KHU=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npm.taobao.org/dir-glob/download/dir-glob-2.2.2.tgz", - "integrity": "sha1-+gnwaUFTyJGLGLoN6vrpR2n8UMQ=", - "dev": true, - "requires": { - "path-type": "^3.0.0" - } - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/dns-equal/download/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npm.taobao.org/dns-packet/download/dns-packet-1.3.1.tgz", - "integrity": "sha1-EqpCaYEHW+UAuRDu3NC0fdfe2lo=", - "dev": true, - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npm.taobao.org/dns-txt/download/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dev": true, - "requires": { - "buffer-indexof": "^1.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/doctrine/download/doctrine-3.0.0.tgz", - "integrity": "sha1-rd6+rXKmV023g2OdyHoSF3OXOWE=", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-align": { - "version": "1.10.2", - "resolved": "https://registry.npm.taobao.org/dom-align/download/dom-align-1.10.2.tgz", - "integrity": "sha1-VA6hyeIEYr0RufwoxWHcg1Hs5MY=" - }, - "dom-closest": { - "version": "0.2.0", - "resolved": "https://registry.npm.taobao.org/dom-closest/download/dom-closest-0.2.0.tgz", - "integrity": "sha1-69n5HRvyLo1vR3h2u80+yQIWwM8=", - "requires": { - "dom-matches": ">=1.0.1" - } - }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npm.taobao.org/dom-converter/download/dom-converter-0.2.0.tgz", - "integrity": "sha1-ZyGp2u4uKTaClVtq/kFncWJ7t2g=", - "dev": true, - "requires": { - "utila": "~0.4" - } - }, - "dom-matches": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/dom-matches/download/dom-matches-2.0.0.tgz", - "integrity": "sha1-0nKLQWqHUzmA6wibhI0lPPI6dYw=" - }, - "dom-scroll-into-view": { - "version": "1.2.1", - "resolved": "https://registry.npm.taobao.org/dom-scroll-into-view/download/dom-scroll-into-view-1.2.1.tgz", - "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=" - }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npm.taobao.org/dom-serializer/download/dom-serializer-0.2.2.tgz", - "integrity": "sha1-GvuB9TNxcXXUeGVd68XjMtn5u1E=", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/domelementtype/download/domelementtype-2.0.1.tgz", - "integrity": "sha1-H4vf6R9aeAYydOgDtL3O326U+U0=", - "dev": true - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/domain-browser/download/domain-browser-1.2.0.tgz?cache=0&sync_timestamp=1575879334171&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdomain-browser%2Fdownload%2Fdomain-browser-1.2.0.tgz", - "integrity": "sha1-PTH1AZGmdJ3RN1p/Ui6CPULlTto=", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npm.taobao.org/domelementtype/download/domelementtype-1.3.1.tgz", - "integrity": "sha1-0EjESzew0Qp/Kj1f7j9DM9eQSB8=", - "dev": true - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npm.taobao.org/domhandler/download/domhandler-2.4.2.tgz", - "integrity": "sha1-iAUJfpM9ZehVRvcm1g9euItE+AM=", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npm.taobao.org/domutils/download/domutils-1.7.0.tgz", - "integrity": "sha1-Vuo0HoNOBuZ0ivehyyXaZ+qfjCo=", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npm.taobao.org/dot-prop/download/dot-prop-4.2.0.tgz?cache=0&sync_timestamp=1572621117377&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdot-prop%2Fdownload%2Fdot-prop-4.2.0.tgz", - "integrity": "sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc=", - "dev": true, - "requires": { - "is-obj": "^1.0.0" - } - }, - "dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npm.taobao.org/dotenv/download/dotenv-8.2.0.tgz?cache=0&sync_timestamp=1571190685588&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdotenv%2Fdownload%2Fdotenv-8.2.0.tgz", - "integrity": "sha1-l+YZJZradQ7qPk6j4mvO6lQksWo=", - "dev": true - }, - "dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npm.taobao.org/dotenv-expand/download/dotenv-expand-5.1.0.tgz", - "integrity": "sha1-P7rwIL/XlIhAcuomsel5HUWmKfA=", - "dev": true - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npm.taobao.org/duplexer/download/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", - "dev": true - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npm.taobao.org/duplexify/download/duplexify-3.7.1.tgz", - "integrity": "sha1-Kk31MX9sz9kfhtb9JdjYoQO4gwk=", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "easy-stack": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/easy-stack/download/easy-stack-1.0.0.tgz", - "integrity": "sha1-EskbMIWjfwuqM26UhurEv5Tj54g=", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npm.taobao.org/ecc-jsbn/download/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "ejs": { - "version": "2.7.4", - "resolved": "https://registry.npm.taobao.org/ejs/download/ejs-2.7.4.tgz?cache=0&sync_timestamp=1574560333790&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fejs%2Fdownload%2Fejs-2.7.4.tgz", - "integrity": "sha1-SGYSh1c9zFPjZsehrlLDoSDuybo=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.322", - "resolved": "https://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.322.tgz", - "integrity": "sha1-pvfhx5AlwrBYOOjjRPbonrgyE6g=", - "dev": true - }, - "elliptic": { - "version": "6.5.2", - "resolved": "https://registry.npm.taobao.org/elliptic/download/elliptic-6.5.2.tgz", - "integrity": "sha1-BcVnjXFzwEnYykM1UiJKSV0ON2I=", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-7.0.3.tgz", - "integrity": "sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY=", - "dev": true - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/emojis-list/download/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npm.taobao.org/end-of-stream/download/end-of-stream-1.4.4.tgz", - "integrity": "sha1-WuZKX0UFe682JuwU2gyl5LJDHrA=", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/enhanced-resolve/download/enhanced-resolve-4.1.1.tgz?cache=0&sync_timestamp=1572991764265&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-4.1.1.tgz", - "integrity": "sha1-KTfiuAZs0P584JkKmPDXGjUYn2Y=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "dependencies": { - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npm.taobao.org/memory-fs/download/memory-fs-0.5.0.tgz?cache=0&sync_timestamp=1570537491040&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.5.0.tgz", - "integrity": "sha1-MkwBKIuIZSlm0WHbd4OHIIRajjw=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - } - } - }, - "enquire.js": { - "version": "2.1.6", - "resolved": "https://registry.npm.taobao.org/enquire.js/download/enquire.js-2.1.6.tgz", - "integrity": "sha1-PoeAybi4NQhMP2DhZtvDwqPImBQ=" - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/entities/download/entities-2.0.0.tgz", - "integrity": "sha1-aNYITKsbB5dnVA2A5Wo5tCPkq/Q=", - "dev": true - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npm.taobao.org/errno/download/errno-0.1.7.tgz", - "integrity": "sha1-RoTXF3mtOa8Xfj8AeZb3xnyFJhg=", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npm.taobao.org/error-ex/download/error-ex-1.3.2.tgz", - "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "error-stack-parser": { - "version": "2.0.4", - "resolved": "https://registry.npm.taobao.org/error-stack-parser/download/error-stack-parser-2.0.4.tgz?cache=0&sync_timestamp=1568768368147&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ferror-stack-parser%2Fdownload%2Ferror-stack-parser-2.0.4.tgz", - "integrity": "sha1-p1c5fcXZ3pc6yaXX1Oit58+ukQE=", - "dev": true, - "requires": { - "stackframe": "^1.1.0" - } - }, - "es-abstract": { - "version": "1.17.0", - "resolved": "https://registry.npm.taobao.org/es-abstract/download/es-abstract-1.17.0.tgz?cache=0&sync_timestamp=1576883746863&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fes-abstract%2Fdownload%2Fes-abstract-1.17.0.tgz", - "integrity": "sha1-9CpRfQA2pVkduyxGNZHci7UDCbE=", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npm.taobao.org/es-to-primitive/download/es-to-primitive-1.2.1.tgz", - "integrity": "sha1-5VzUyc3BiLzvsDs2bHNjI/xciYo=", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "5.16.0", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz", - "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-4.0.0.tgz?cache=0&sync_timestamp=1573280549549&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "eslint-loader": { - "version": "2.2.1", - "resolved": "https://registry.npm.taobao.org/eslint-loader/download/eslint-loader-2.2.1.tgz", - "integrity": "sha1-KLnBLaVAV68IReKmEScBova/gzc=", - "dev": true, - "requires": { - "loader-fs-cache": "^1.0.0", - "loader-utils": "^1.0.2", - "object-assign": "^4.0.1", - "object-hash": "^1.1.4", - "rimraf": "^2.6.1" - } - }, - "eslint-plugin-vue": { - "version": "5.2.3", - "dev": true, - "requires": { - "vue-eslint-parser": "^5.0.0" - } - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npm.taobao.org/eslint-scope/download/eslint-scope-4.0.3.tgz", - "integrity": "sha1-ygODMxD2iJoyZHgaqC5j65z+eEg=", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npm.taobao.org/eslint-utils/download/eslint-utils-1.4.3.tgz", - "integrity": "sha1-dP7HxU0Hdrb2fgJRBAtYBlZOmB8=", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/eslint-visitor-keys/download/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha1-4qgs6oT/JGrW+1f5veW0ZiFFnsI=", - "dev": true - }, - "espree": { - "version": "5.0.1", - "resolved": "https://registry.npm.taobao.org/espree/download/espree-5.0.1.tgz?cache=0&sync_timestamp=1571624368510&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fespree%2Fdownload%2Fespree-5.0.1.tgz", - "integrity": "sha1-XWUm+k/H8HiKXPdbFfMDI+L4H3o=", - "dev": true, - "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/esprima/download/esprima-4.0.1.tgz", - "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=", - "dev": true - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/esquery/download/esquery-1.0.1.tgz", - "integrity": "sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg=", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npm.taobao.org/esrecurse/download/esrecurse-4.2.1.tgz", - "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npm.taobao.org/estraverse/download/estraverse-4.3.0.tgz", - "integrity": "sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0=", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npm.taobao.org/esutils/download/esutils-2.0.3.tgz", - "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npm.taobao.org/etag/download/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "event-pubsub": { - "version": "4.3.0", - "resolved": "https://registry.npm.taobao.org/event-pubsub/download/event-pubsub-4.3.0.tgz", - "integrity": "sha1-9o2Ba8KfHsAsU53FjI3UDOcss24=", - "dev": true - }, - "eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/eventemitter3/download/eventemitter3-4.0.0.tgz?cache=0&sync_timestamp=1560950873670&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feventemitter3%2Fdownload%2Feventemitter3-4.0.0.tgz", - "integrity": "sha1-1lF2FjiH7lnzhtZMgmELaWpKdOs=", - "dev": true - }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/events/download/events-3.0.0.tgz", - "integrity": "sha1-mgoN+vYok9krh1uPJpjKQRSXPog=", - "dev": true - }, - "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npm.taobao.org/eventsource/download/eventsource-1.0.7.tgz", - "integrity": "sha1-j7xyyT/NNAiAkLwKTmT0tc7m2NA=", - "dev": true, - "requires": { - "original": "^1.0.0" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/evp_bytestokey/download/evp_bytestokey-1.0.3.tgz", - "integrity": "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/execa/download/execa-1.0.0.tgz?cache=0&sync_timestamp=1576749001049&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-1.0.0.tgz", - "integrity": "sha1-xiNqW7TfbW8V6I5/AXeYIWdJ3dg=", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npm.taobao.org/expand-brackets/download/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz", - "integrity": "sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ=", - "dev": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz", - "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz", - "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/is-extendable/download/is-extendable-1.0.1.tgz", - "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/external-editor/download/external-editor-3.1.0.tgz", - "integrity": "sha1-ywP3QL764D6k0oPK7SdBqD8zVJU=", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npm.taobao.org/extglob/download/extglob-2.0.4.tgz", - "integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-1.0.0.tgz", - "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-1.0.2.tgz", - "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npm.taobao.org/extsprintf/download/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npm.taobao.org/fast-glob/download/fast-glob-2.2.7.tgz?cache=0&sync_timestamp=1575197566634&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-glob%2Fdownload%2Ffast-glob-2.2.7.tgz", - "integrity": "sha1-aVOFfDr6R1//ku5gFdUtpwpM050=", - "dev": true, - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.1.0.tgz?cache=0&sync_timestamp=1576340291001&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-json-stable-stringify%2Fdownload%2Ffast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npm.taobao.org/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npm.taobao.org/faye-websocket/download/faye-websocket-0.10.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffaye-websocket%2Fdownload%2Ffaye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "figgy-pudding": { - "version": "3.5.1", - "resolved": "https://registry.npm.taobao.org/figgy-pudding/download/figgy-pudding-3.5.1.tgz", - "integrity": "sha1-hiRwESkBxyeg5JWoB0S9W6odZ5A=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/figures/download/figures-2.0.0.tgz?cache=0&sync_timestamp=1571715625804&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffigures%2Fdownload%2Ffigures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npm.taobao.org/file-entry-cache/download/file-entry-cache-5.0.1.tgz", - "integrity": "sha1-yg9u+m3T1WEzP7FFFQZcL6/fQ5w=", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } - }, - "file-loader": { - "version": "4.3.0", - "resolved": "https://registry.npm.taobao.org/file-loader/download/file-loader-4.3.0.tgz?cache=0&sync_timestamp=1574689264559&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffile-loader%2Fdownload%2Ffile-loader-4.3.0.tgz", - "integrity": "sha1-eA8ED3KbPRgBnyBgX3I+hEuKWK8=", - "dev": true, - "requires": { - "loader-utils": "^1.2.3", - "schema-utils": "^2.5.0" - }, - "dependencies": { - "schema-utils": { - "version": "2.6.1", - "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.6.1.tgz?cache=0&sync_timestamp=1574946754916&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.6.1.tgz", - "integrity": "sha1-63jwuUXHvPoggrNWXo2zVIAR3E8=", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1" - } - } - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/file-uri-to-path/download/file-uri-to-path-1.0.0.tgz", - "integrity": "sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90=", - "dev": true, - "optional": true - }, - "filesize": { - "version": "3.6.1", - "resolved": "https://registry.npm.taobao.org/filesize/download/filesize-3.6.1.tgz", - "integrity": "sha1-CQuz7gG2+AGoqL6Z0xcQs0Irsxc=", - "dev": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/finalhandler/download/finalhandler-1.1.2.tgz", - "integrity": "sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0=", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-2.1.0.tgz", - "integrity": "sha1-jQ+UzRP+Q8bHwmGg2GEVypGMBfc=", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-3.0.0.tgz", - "integrity": "sha1-SRafHXmTQwZG2mHsxa41XCHJe3M=", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/flat-cache/download/flat-cache-2.0.1.tgz", - "integrity": "sha1-XSltbwS9pEpGMKMBQTvbwuwIXsA=", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npm.taobao.org/rimraf/download/rimraf-2.6.3.tgz?cache=0&sync_timestamp=1569343496458&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frimraf%2Fdownload%2Frimraf-2.6.3.tgz", - "integrity": "sha1-stEE/g2Psnz54KHNqCYt04M8bKs=", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/flatted/download/flatted-2.0.1.tgz", - "integrity": "sha1-aeV8qo8OrLwoHS4stFjUb9tEngg=", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/flush-write-stream/download/flush-write-stream-1.1.1.tgz", - "integrity": "sha1-jdfYc6G6vCB9lOrQwuDkQnbr8ug=", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "follow-redirects": { - "version": "1.9.0", - "resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.9.0.tgz", - "integrity": "sha1-jVvNxltxCP4VCGScecEtcy3O208=", - "dev": true, - "requires": { - "debug": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-3.2.6.tgz", - "integrity": "sha1-6D0X3hbYp++3cX7b5fsQE17uYps=", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/for-in/download/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npm.taobao.org/forever-agent/download/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npm.taobao.org/form-data/download/form-data-2.3.3.tgz", - "integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npm.taobao.org/forwarded/download/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npm.taobao.org/fragment-cache/download/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npm.taobao.org/from2/download/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npm.taobao.org/fs-extra/download/fs-extra-7.0.1.tgz", - "integrity": "sha1-TxicRKoSO4lfcigE9V6iPq3DSOk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/fs-minipass/download/fs-minipass-2.0.0.tgz?cache=0&sync_timestamp=1569875077546&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffs-minipass%2Fdownload%2Ffs-minipass-2.0.0.tgz", - "integrity": "sha1-pkFe2rAvrkuekjC8h+4uRHIAPNE=", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npm.taobao.org/fs-write-stream-atomic/download/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npm.taobao.org/fsevents/download/fsevents-1.2.11.tgz", - "integrity": "sha1-Z79X9HWPAu3oj7KhcS/vTRU1i+M=", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "3.1.1", - "bundled": true, - "dev": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz", - "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/functional-red-black-tree/download/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npm.taobao.org/get-caller-file/download/get-caller-file-2.0.5.tgz", - "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-4.1.0.tgz", - "integrity": "sha1-wbJVV189wh1Zv8ec09K0axw6VLU=", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npm.taobao.org/get-value/download/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npm.taobao.org/getpass/download/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npm.taobao.org/glob/download/glob-7.1.6.tgz?cache=0&sync_timestamp=1573078302562&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglob%2Fdownload%2Fglob-7.1.6.tgz", - "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/glob-parent/download/glob-parent-3.1.0.tgz?cache=0&sync_timestamp=1569136652060&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglob-parent%2Fdownload%2Fglob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/is-glob/download/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npm.taobao.org/glob-to-regexp/download/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", - "dev": true - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npm.taobao.org/globals/download/globals-11.12.0.tgz", - "integrity": "sha1-q4eVM4hooLq9hSV1gBjCp+uVxC4=", - "dev": true - }, - "globby": { - "version": "9.2.0", - "resolved": "https://registry.npm.taobao.org/globby/download/globby-9.2.0.tgz?cache=0&sync_timestamp=1562335642755&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglobby%2Fdownload%2Fglobby-9.2.0.tgz", - "integrity": "sha1-/QKacGxwPSm90XD0tts6P3p8tj0=", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.3.tgz", - "integrity": "sha1-ShL/G2A3bvCYYsIJPt2Qgyi+hCM=", - "dev": true - }, - "gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npm.taobao.org/gzip-size/download/gzip-size-5.1.1.tgz", - "integrity": "sha1-y5vuaS+HwGErIyhAqHOQTkwTUnQ=", - "dev": true, - "requires": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" - } - }, - "handle-thing": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/handle-thing/download/handle-thing-2.0.0.tgz", - "integrity": "sha1-DgOWlf9QyT/CiFV9aW88HcZ3Z1Q=", - "dev": true - }, - "handlebars": { - "version": "4.5.3", - "resolved": "https://registry.npm.taobao.org/handlebars/download/handlebars-4.5.3.tgz?cache=0&sync_timestamp=1574061065936&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhandlebars%2Fdownload%2Fhandlebars-4.5.3.tgz", - "integrity": "sha1-XPdb2HFPdgVxNRGla+fDSb7LBII=", - "dev": true, - "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/har-schema/download/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npm.taobao.org/har-validator/download/har-validator-5.1.3.tgz", - "integrity": "sha1-HvievT5JllV2de7ZiTEQ3DUPoIA=", - "dev": true, - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/has/download/has-1.0.3.tgz", - "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/has-ansi/download/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/has-symbols/download/has-symbols-1.0.1.tgz?cache=0&sync_timestamp=1573950719586&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-symbols%2Fdownload%2Fhas-symbols-1.0.1.tgz", - "integrity": "sha1-n1IUdYpEGWxAbZvXbOv4HsLdMeg=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/has-value/download/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/has-values/download/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npm.taobao.org/hash-base/download/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/hash-sum/download/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", - "dev": true - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npm.taobao.org/hash.js/download/hash.js-1.1.7.tgz", - "integrity": "sha1-C6vKU46NTuSg+JiNaIZlN6ADz0I=", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/he/download/he-1.2.0.tgz", - "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=", - "dev": true - }, - "hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/hex-color-regex/download/hex-color-regex-1.1.0.tgz", - "integrity": "sha1-TAb8y0YC/iYCs8k9+C1+fb8aio4=", - "dev": true - }, - "highlight.js": { - "version": "9.17.1", - "resolved": "https://registry.npm.taobao.org/highlight.js/download/highlight.js-9.17.1.tgz", - "integrity": "sha1-FKTt7SP9MUsFiGdYu5BuOd1if5o=", - "dev": true, - "requires": { - "handlebars": "^4.5.3" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/hmac-drbg/download/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npm.taobao.org/hoopy/download/hoopy-0.1.4.tgz", - "integrity": "sha1-YJIH1mEQADOpqUAq096mdzgcGx0=", - "dev": true - }, - "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npm.taobao.org/hosted-git-info/download/hosted-git-info-2.8.5.tgz", - "integrity": "sha1-dZz88sTRVq3lmwst+r3cQqa5xww=", - "dev": true - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npm.taobao.org/hpack.js/download/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/hsl-regex/download/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", - "dev": true - }, - "hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/hsla-regex/download/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", - "dev": true - }, - "html-comment-regex": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/html-comment-regex/download/html-comment-regex-1.1.2.tgz", - "integrity": "sha1-l9RoiutcgYhqNk+qDK0d2hTUM6c=", - "dev": true - }, - "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npm.taobao.org/html-entities/download/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", - "dev": true - }, - "html-minifier": { - "version": "3.5.21", - "resolved": "https://registry.npm.taobao.org/html-minifier/download/html-minifier-3.5.21.tgz", - "integrity": "sha1-0AQOBUcw41TbAIRjWTGUAVIS0gw=", - "dev": true, - "requires": { - "camel-case": "3.0.x", - "clean-css": "4.2.x", - "commander": "2.17.x", - "he": "1.2.x", - "param-case": "2.1.x", - "relateurl": "0.2.x", - "uglify-js": "3.4.x" - }, - "dependencies": { - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npm.taobao.org/commander/download/commander-2.17.1.tgz", - "integrity": "sha1-vXerfebelCBc6sxy8XFtKfIKd78=", - "dev": true - }, - "uglify-js": { - "version": "3.4.10", - "resolved": "https://registry.npm.taobao.org/uglify-js/download/uglify-js-3.4.10.tgz?cache=0&sync_timestamp=1577407920190&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.4.10.tgz", - "integrity": "sha1-mtlWPY6zrN+404WX0q8dgV9qdV8=", - "dev": true, - "requires": { - "commander": "~2.19.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npm.taobao.org/commander/download/commander-2.19.0.tgz", - "integrity": "sha1-9hmKqE5bg8RgVLlN3tv+1e6f8So=", - "dev": true - } - } - } - } - }, - "html-tags": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/html-tags/download/html-tags-2.0.0.tgz?cache=0&sync_timestamp=1566122004262&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-tags%2Fdownload%2Fhtml-tags-2.0.0.tgz", - "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", - "dev": true - }, - "html-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npm.taobao.org/html-webpack-plugin/download/html-webpack-plugin-3.2.0.tgz", - "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", - "dev": true, - "requires": { - "html-minifier": "^3.2.3", - "loader-utils": "^0.2.16", - "lodash": "^4.17.3", - "pretty-error": "^2.0.2", - "tapable": "^1.0.0", - "toposort": "^1.0.0", - "util.promisify": "1.0.0" - }, - "dependencies": { - "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npm.taobao.org/big.js/download/big.js-3.2.0.tgz", - "integrity": "sha1-pfwpi4G54Nyi5FiCR4S2XFK6WI4=", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npm.taobao.org/json5/download/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - } - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npm.taobao.org/htmlparser2/download/htmlparser2-3.10.1.tgz", - "integrity": "sha1-vWedw/WYl7ajS7EHSchVu1OpOS8=", - "dev": true, - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/entities/download/entities-1.1.2.tgz", - "integrity": "sha1-vfpzUplmTfr9NFKe1PhSKidf6lY=", - "dev": true - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.4.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-3.4.0.tgz", - "integrity": "sha1-pRwmdUZY4KPCHb9ZFjvUW6b0R/w=", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npm.taobao.org/http-deceiver/download/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.2.tgz?cache=0&sync_timestamp=1561418493658&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.7.2.tgz", - "integrity": "sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz?cache=0&sync_timestamp=1560975547815&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Finherits%2Fdownload%2Finherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npm.taobao.org/http-parser-js/download/http-parser-js-0.4.10.tgz?cache=0&sync_timestamp=1572714627611&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-parser-js%2Fdownload%2Fhttp-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", - "dev": true - }, - "http-proxy": { - "version": "1.18.0", - "resolved": "https://registry.npm.taobao.org/http-proxy/download/http-proxy-1.18.0.tgz?cache=0&sync_timestamp=1568770896103&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-proxy%2Fdownload%2Fhttp-proxy-1.18.0.tgz", - "integrity": "sha1-2+VfY+daNH2389mZdPJpKjFKajo=", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npm.taobao.org/http-proxy-middleware/download/http-proxy-middleware-0.19.1.tgz?cache=0&sync_timestamp=1577317759023&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-proxy-middleware%2Fdownload%2Fhttp-proxy-middleware-0.19.1.tgz", - "integrity": "sha1-GDx9xKoUeRUDBkmMIQza+WCApDo=", - "dev": true, - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/http-signature/download/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/https-browserify/download/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/human-signals/download/human-signals-1.1.1.tgz?cache=0&sync_timestamp=1577290400756&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhuman-signals%2Fdownload%2Fhuman-signals-1.1.1.tgz", - "integrity": "sha1-xbHNFPUK6uCatsWf5jujOV/k36M=", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz", - "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/icss-utils/download/icss-utils-4.1.1.tgz", - "integrity": "sha1-IRcLU3ie4nRHwvR91oMIFAP5pGc=", - "dev": true, - "requires": { - "postcss": "^7.0.14" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npm.taobao.org/ieee754/download/ieee754-1.1.13.tgz", - "integrity": "sha1-7BaFWOlaoYH9h9N/VcMrvLZwi4Q=", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npm.taobao.org/iferr/download/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npm.taobao.org/ignore/download/ignore-4.0.6.tgz", - "integrity": "sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=", - "dev": true - }, - "import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/import-cwd/download/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "dev": true, - "requires": { - "import-from": "^2.1.0" - } - }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npm.taobao.org/import-fresh/download/import-fresh-3.2.1.tgz?cache=0&sync_timestamp=1573664960772&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimport-fresh%2Fdownload%2Fimport-fresh-3.2.1.tgz", - "integrity": "sha1-Yz/2GFBueTr1rJG/SLcmd+FcvmY=", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/resolve-from/download/resolve-from-4.0.0.tgz", - "integrity": "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=", - "dev": true - } - } - }, - "import-from": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/import-from/download/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/import-local/download/import-local-2.0.0.tgz", - "integrity": "sha1-VQcL44pZk88Y72236WH1vuXFoJ0=", - "dev": true, - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npm.taobao.org/imurmurhash/download/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/indent-string/download/indent-string-4.0.0.tgz", - "integrity": "sha1-Yk+PRJfWGbLZdoUx1Y9BIoVNclE=", - "dev": true - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/indexes-of/download/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/infer-owner/download/infer-owner-1.0.4.tgz", - "integrity": "sha1-xM78qo5RBRwqQLos6KPScpWvlGc=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz?cache=0&sync_timestamp=1560975547815&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Finherits%2Fdownload%2Finherits-2.0.4.tgz", - "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=", - "dev": true - }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npm.taobao.org/inquirer/download/inquirer-6.5.2.tgz", - "integrity": "sha1-rVCUI3XQNtMn/1KMCL1fqwiZKMo=", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz", - "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz?cache=0&sync_timestamp=1573280549549&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-5.2.0.tgz", - "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npm.taobao.org/internal-ip/download/internal-ip-4.3.0.tgz", - "integrity": "sha1-hFRSuq2dLKO2nGNaE3rLmg2tCQc=", - "dev": true, - "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - }, - "dependencies": { - "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npm.taobao.org/default-gateway/download/default-gateway-4.2.0.tgz?cache=0&sync_timestamp=1573764719154&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdefault-gateway%2Fdownload%2Fdefault-gateway-4.2.0.tgz", - "integrity": "sha1-FnEEx1AMIRX23WmwpTa7jtcgVSs=", - "dev": true, - "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - } - } - } - }, - "intersperse": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/intersperse/download/intersperse-1.0.0.tgz", - "integrity": "sha1-8lYfsc/vn1J3zDNHoiiGtDUaUYE=" - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npm.taobao.org/invariant/download/invariant-2.2.4.tgz", - "integrity": "sha1-YQ88ksk1nOHbYW5TgAjSP/NRWOY=", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/invert-kv/download/invert-kv-2.0.0.tgz", - "integrity": "sha1-c5P1r6Weyf9fZ6J2INEcIm4+7AI=", - "dev": true - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npm.taobao.org/ip/download/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/ip-regex/download/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, - "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.9.0.tgz", - "integrity": "sha1-N9905DCg5HVQ/lSi3v4w2KzZX2U=", - "dev": true - }, - "is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/is-absolute-url/download/is-absolute-url-2.1.0.tgz?cache=0&sync_timestamp=1569736493122&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-absolute-url%2Fdownload%2Fis-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/is-arguments/download/is-arguments-1.0.4.tgz", - "integrity": "sha1-P6+WbHy6D/Q3+zH2JQCC/PBEjPM=", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npm.taobao.org/is-arrayish/download/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/is-binary-path/download/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npm.taobao.org/is-buffer/download/is-buffer-1.1.6.tgz", - "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=", - "dev": true - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npm.taobao.org/is-callable/download/is-callable-1.1.5.tgz", - "integrity": "sha1-9+RrWWiQRW23Tn9ul2yzJz0G+qs=", - "dev": true - }, - "is-ci": { - "version": "1.2.1", - "resolved": "https://registry.npm.taobao.org/is-ci/download/is-ci-1.2.1.tgz", - "integrity": "sha1-43ecjuF/zPQoSI9uKBGH8uYyhBw=", - "dev": true, - "requires": { - "ci-info": "^1.5.0" - } - }, - "is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/is-color-stop/download/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "dev": true, - "requires": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/is-date-object/download/is-date-object-1.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-date-object%2Fdownload%2Fis-date-object-1.0.2.tgz", - "integrity": "sha1-vac28s2P0G0yhE53Q7+nSUw7/X4=", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-0.1.6.tgz", - "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-5.1.0.tgz", - "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", - "dev": true - } - } - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npm.taobao.org/is-directory/download/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npm.taobao.org/is-extendable/download/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/is-glob/download/is-glob-4.0.1.tgz", - "integrity": "sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw=", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/is-negative-zero/download/is-negative-zero-2.0.0.tgz", - "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=" - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/is-obj/download/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npm.taobao.org/is-path-cwd/download/is-path-cwd-2.2.0.tgz?cache=0&sync_timestamp=1562347283002&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-path-cwd%2Fdownload%2Fis-path-cwd-2.2.0.tgz", - "integrity": "sha1-Z9Q7gmZKe1GR/ZEZEn6zAASKn9s=", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/is-path-in-cwd/download/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha1-v+Lcomxp85cmWkAJljYCk1oFOss=", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/is-path-inside/download/is-path-inside-2.1.0.tgz", - "integrity": "sha1-fJgQWH1lmkDSe8201WFuqwWUlLI=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/is-plain-obj/download/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npm.taobao.org/is-plain-object/download/is-plain-object-2.0.4.tgz", - "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/is-promise/download/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npm.taobao.org/is-regex/download/is-regex-1.0.5.tgz?cache=0&sync_timestamp=1576454688491&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-regex%2Fdownload%2Fis-regex-1.0.5.tgz", - "integrity": "sha1-OdWJo1i/GJZ/cmlnEguPwa7XTq4=", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/is-resolvable/download/is-resolvable-1.1.0.tgz", - "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/is-stream/download/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-svg": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/is-svg/download/is-svg-3.0.0.tgz", - "integrity": "sha1-kyHb0pwhLlypnE+peUxxS8r6L3U=", - "dev": true, - "requires": { - "html-comment-regex": "^1.1.0" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/is-symbol/download/is-symbol-1.0.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-symbol%2Fdownload%2Fis-symbol-1.0.3.tgz", - "integrity": "sha1-OOEBS55jKb4N6dJKQU/XRB7GGTc=", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/is-windows/download/is-windows-1.0.2.tgz", - "integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/is-wsl/download/is-wsl-1.1.0.tgz?cache=0&sync_timestamp=1569219566107&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-wsl%2Fdownload%2Fis-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz?cache=0&sync_timestamp=1562592096220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisarray%2Fdownload%2Fisarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "ismobilejs": { - "version": "0.5.2", - "resolved": "https://registry.npm.taobao.org/ismobilejs/download/ismobilejs-0.5.2.tgz?cache=0&sync_timestamp=1568180544676&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fismobilejs%2Fdownload%2Fismobilejs-0.5.2.tgz", - "integrity": "sha1-6Bus9hh8UyrYNINV9P7Nbmrf3OE=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npm.taobao.org/isobject/download/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npm.taobao.org/isstream/download/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "javascript-stringify": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/javascript-stringify/download/javascript-stringify-2.0.1.tgz?cache=0&sync_timestamp=1572948916758&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjavascript-stringify%2Fdownload%2Fjavascript-stringify-2.0.1.tgz", - "integrity": "sha1-bvNYA1MQ411mfGde1j0+t8GqGeU=", - "dev": true - }, - "jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npm.taobao.org/jest-worker/download/jest-worker-24.9.0.tgz", - "integrity": "sha1-Xb/bWy0yLphWeJgjipaXvM5ns+U=", - "dev": true, - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" - } - }, - "js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npm.taobao.org/js-levenshtein/download/js-levenshtein-1.1.6.tgz", - "integrity": "sha1-xs7ljrNVA3LfjeuF+tXOZs4B1Z0=", - "dev": true - }, - "js-message": { - "version": "1.0.5", - "resolved": "https://registry.npm.taobao.org/js-message/download/js-message-1.0.5.tgz?cache=0&sync_timestamp=1575284593568&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjs-message%2Fdownload%2Fjs-message-1.0.5.tgz", - "integrity": "sha1-IwDSSxrwjondCVvBpMnJz8uJLRU=", - "dev": true - }, - "js-queue": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/js-queue/download/js-queue-2.0.0.tgz", - "integrity": "sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug=", - "dev": true, - "requires": { - "easy-stack": "^1.0.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/js-tokens/download/js-tokens-4.0.0.tgz", - "integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npm.taobao.org/js-yaml/download/js-yaml-3.13.1.tgz", - "integrity": "sha1-r/FRswv9+o5J4F2iLnQV6d+jeEc=", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npm.taobao.org/jsbn/download/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npm.taobao.org/jsesc/download/jsesc-2.5.2.tgz", - "integrity": "sha1-gFZNLkg9rPbo7yCWUKZ98/DCg6Q=", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/json-parse-better-errors/download/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk=", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npm.taobao.org/json-schema/download/json-schema-0.2.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson-schema%2Fdownload%2Fjson-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npm.taobao.org/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz", - "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/json-stable-stringify-without-jsonify/download/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json2mq": { - "version": "0.2.0", - "resolved": "https://registry.npm.taobao.org/json2mq/download/json2mq-0.2.0.tgz", - "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=", - "requires": { - "string-convert": "^0.2.0" - } - }, - "json3": { - "version": "3.3.3", - "resolved": "https://registry.npm.taobao.org/json3/download/json3-3.3.3.tgz", - "integrity": "sha1-f8EON1/FrkLEcFpcwKpvYr4wW4E=", - "dev": true - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/json5/download/json5-1.0.1.tgz", - "integrity": "sha1-d5+wAYYE+oVOrL9iUhgNg1Q+Pb4=", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npm.taobao.org/jsprim/download/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "killable": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/killable/download/killable-1.0.1.tgz", - "integrity": "sha1-TIzkQRh6Bhx0dPuHygjipjgZSJI=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz", - "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", - "dev": true - }, - "launch-editor": { - "version": "2.2.1", - "resolved": "https://registry.npm.taobao.org/launch-editor/download/launch-editor-2.2.1.tgz", - "integrity": "sha1-hxtaPuOdZoD8wm03kwtu7aidsMo=", - "dev": true, - "requires": { - "chalk": "^2.3.0", - "shell-quote": "^1.6.1" - } - }, - "launch-editor-middleware": { - "version": "2.2.1", - "resolved": "https://registry.npm.taobao.org/launch-editor-middleware/download/launch-editor-middleware-2.2.1.tgz", - "integrity": "sha1-4UsH5scVSwpLhqD9NFeE5FgEwVc=", - "dev": true, - "requires": { - "launch-editor": "^2.2.1" - } - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/lcid/download/lcid-2.0.0.tgz", - "integrity": "sha1-bvXS32DlL4LrIopMNz6NHzlyU88=", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npm.taobao.org/levn/download/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npm.taobao.org/lines-and-columns/download/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, - "loader-fs-cache": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/loader-fs-cache/download/loader-fs-cache-1.0.2.tgz", - "integrity": "sha1-VM7fa3J+F3n9jwEgXwX26IcG8IY=", - "dev": true, - "requires": { - "find-cache-dir": "^0.1.1", - "mkdirp": "0.5.1" - }, - "dependencies": { - "find-cache-dir": { - "version": "0.1.1", - "resolved": "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-0.1.1.tgz", - "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "mkdirp": "^0.5.1", - "pkg-dir": "^1.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "dev": true, - "requires": { - "find-up": "^1.0.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npm.taobao.org/loader-runner/download/loader-runner-2.4.0.tgz", - "integrity": "sha1-7UcGa/5TTX6ExMe5mYwqdWB9k1c=", - "dev": true - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-1.2.3.tgz", - "integrity": "sha1-H/XcaRHJ8KBiUxpMBLYJQGEIwsc=", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-3.0.0.tgz", - "integrity": "sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4=", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npm.taobao.org/lodash/download/lodash-4.17.15.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.15.tgz", - "integrity": "sha1-tEf2ZwoEVbv+7dETku/zMOoJdUg=" - }, - "lodash.defaultsdeep": { - "version": "4.6.1", - "resolved": "https://registry.npm.taobao.org/lodash.defaultsdeep/download/lodash.defaultsdeep-4.6.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash.defaultsdeep%2Fdownload%2Flodash.defaultsdeep-4.6.1.tgz", - "integrity": "sha1-US6b1yHSctlOPTpjZT+hdRZ0HKY=", - "dev": true - }, - "lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/lodash.kebabcase/download/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", - "dev": true - }, - "lodash.mapvalues": { - "version": "4.6.0", - "resolved": "https://registry.npm.taobao.org/lodash.mapvalues/download/lodash.mapvalues-4.6.0.tgz", - "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", - "dev": true - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npm.taobao.org/lodash.memoize/download/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, - "lodash.toarray": { - "version": "4.4.0", - "resolved": "https://registry.npm.taobao.org/lodash.toarray/download/lodash.toarray-4.4.0.tgz", - "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" - }, - "lodash.transform": { - "version": "4.6.0", - "resolved": "https://registry.npm.taobao.org/lodash.transform/download/lodash.transform-4.6.0.tgz", - "integrity": "sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A=", - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npm.taobao.org/log-symbols/download/log-symbols-2.2.0.tgz", - "integrity": "sha1-V0Dhxdbw39pK2TI7UzIQfva0xAo=", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "loglevel": { - "version": "1.6.6", - "resolved": "https://registry.npm.taobao.org/loglevel/download/loglevel-1.6.6.tgz", - "integrity": "sha1-DuYwDMBY22s1UfocS/c7g7t3ExI=", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npm.taobao.org/loose-envify/download/loose-envify-1.4.0.tgz", - "integrity": "sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8=", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npm.taobao.org/lower-case/download/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-5.1.1.tgz", - "integrity": "sha1-HaJ+ZxAnGUdpXa9oSOhH8B2EuSA=", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/make-dir/download/make-dir-2.1.0.tgz", - "integrity": "sha1-XwMQ4YuL6JjMBwCSlaMK5B6R5vU=", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "mamacro": { - "version": "0.0.3", - "resolved": "https://registry.npm.taobao.org/mamacro/download/mamacro-0.0.3.tgz", - "integrity": "sha1-rSyVdhl8nxq/MI0Hh4Zb2XWj8+Q=", - "dev": true - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npm.taobao.org/map-age-cleaner/download/map-age-cleaner-0.1.3.tgz", - "integrity": "sha1-fVg6cwZDTAVf5HSw9FB45uG0uSo=", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npm.taobao.org/map-cache/download/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/map-visit/download/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npm.taobao.org/md5.js/download/md5.js-1.3.5.tgz", - "integrity": "sha1-tdB7jjIW4+J81yjXL3DR5qNCAF8=", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npm.taobao.org/mdn-data/download/mdn-data-2.0.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmdn-data%2Fdownload%2Fmdn-data-2.0.4.tgz", - "integrity": "sha1-aZs8OKxvHXKAkaZGULZdOIUC/Vs=", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npm.taobao.org/mem/download/mem-4.3.0.tgz", - "integrity": "sha1-Rhr0l7xK4JYIzbLmDu+2m/90QXg=", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npm.taobao.org/memory-fs/download/memory-fs-0.4.1.tgz?cache=0&sync_timestamp=1570537491040&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/merge-source-map/download/merge-source-map-1.1.0.tgz", - "integrity": "sha1-L93n5gIJOfcJBqaPLXrmheTIxkY=", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/merge-stream/download/merge-stream-2.0.0.tgz", - "integrity": "sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A=", - "dev": true - }, - "merge2": { - "version": "1.3.0", - "resolved": "https://registry.npm.taobao.org/merge2/download/merge2-1.3.0.tgz", - "integrity": "sha1-WzZu6DsvFYLEj4fkfPGpNSEDyoE=", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npm.taobao.org/micromatch/download/micromatch-3.1.10.tgz", - "integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/miller-rabin/download/miller-rabin-4.0.1.tgz", - "integrity": "sha1-8IA1HIZbDcViqEYpZtqlNUPHik0=", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npm.taobao.org/mime/download/mime-2.4.4.tgz?cache=0&sync_timestamp=1560034758817&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime%2Fdownload%2Fmime-2.4.4.tgz", - "integrity": "sha1-vXuRE1/GsBzePpuuM9ZZtj2IV+U=", - "dev": true - }, - "mime-db": { - "version": "1.42.0", - "resolved": "https://registry.npm.taobao.org/mime-db/download/mime-db-1.42.0.tgz", - "integrity": "sha1-PiUpB7THrbkGWXtLZWNics+ee6w=", - "dev": true - }, - "mime-types": { - "version": "2.1.25", - "resolved": "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.25.tgz", - "integrity": "sha1-OXctRmIfk+KoCoVsU7hqYhVqZDc=", - "dev": true, - "requires": { - "mime-db": "1.42.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/mimic-fn/download/mimic-fn-2.1.0.tgz", - "integrity": "sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs=", - "dev": true - }, - "mini-css-extract-plugin": { - "version": "0.8.2", - "resolved": "https://registry.npm.taobao.org/mini-css-extract-plugin/download/mini-css-extract-plugin-0.8.2.tgz?cache=0&sync_timestamp=1576856580721&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmini-css-extract-plugin%2Fdownload%2Fmini-css-extract-plugin-0.8.2.tgz", - "integrity": "sha1-qHXhab6yfIivd92WJ3HJ7tw9oWE=", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "normalize-url": "1.9.1", - "schema-utils": "^1.0.0", - "webpack-sources": "^1.1.0" - }, - "dependencies": { - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npm.taobao.org/normalize-url/download/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - } - } - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/minimalistic-assert/download/minimalistic-assert-1.0.1.tgz", - "integrity": "sha1-LhlN4ERibUoQ5/f7wAznPoPk1cc=", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/minimalistic-crypto-utils/download/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npm.taobao.org/minimist/download/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "minipass": { - "version": "3.1.1", - "resolved": "https://registry.npm.taobao.org/minipass/download/minipass-3.1.1.tgz", - "integrity": "sha1-dgfOd4RyoYWtbYkIKqIHD3nO3NU=", - "dev": true, - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz", - "integrity": "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI=", - "dev": true - } - } - }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/minipass-collect/download/minipass-collect-1.0.2.tgz", - "integrity": "sha1-IrgTv3Rdxu26JXa5QAIq1u3Ixhc=", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npm.taobao.org/minipass-flush/download/minipass-flush-1.0.5.tgz", - "integrity": "sha1-gucTXX6JpQ/+ZGEKeHlTxMTLs3M=", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-pipeline": { - "version": "1.2.2", - "resolved": "https://registry.npm.taobao.org/minipass-pipeline/download/minipass-pipeline-1.2.2.tgz", - "integrity": "sha1-PctrtKVG4ylpx61xDyx5qGq7qTo=", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/mississippi/download/mississippi-3.0.0.tgz", - "integrity": "sha1-6goykfl+C16HdrNj1fChLZTGcCI=", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npm.taobao.org/mixin-deep/download/mixin-deep-1.3.2.tgz?cache=0&sync_timestamp=1561436244196&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmixin-deep%2Fdownload%2Fmixin-deep-1.3.2.tgz", - "integrity": "sha1-ESC0PcNZp4Xc5ltVuC4lfM9HlWY=", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/is-extendable/download/is-extendable-1.0.1.tgz", - "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npm.taobao.org/moment/download/moment-2.24.0.tgz", - "integrity": "sha1-DQVdU/UFKqZTyfbraLtdEr9cK1s=" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.2.tgz", - "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", - "dev": true - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npm.taobao.org/multicast-dns/download/multicast-dns-6.2.3.tgz", - "integrity": "sha1-oOx72QVcQoL3kMPIL04o2zsxsik=", - "dev": true, - "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - } - }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/multicast-dns-service-types/download/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true - }, - "mutationobserver-shim": { - "version": "0.3.3", - "resolved": "https://registry.npm.taobao.org/mutationobserver-shim/download/mutationobserver-shim-0.3.3.tgz", - "integrity": "sha1-ZYaWMLyJ17+MnNnLghiM2VWqzSs=" - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npm.taobao.org/mute-stream/download/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npm.taobao.org/mz/download/mz-2.7.0.tgz", - "integrity": "sha1-lQCAV6Vsr63CvGPd5/n/aVWUjjI=", - "dev": true, - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npm.taobao.org/nan/download/nan-2.14.0.tgz", - "integrity": "sha1-eBj3IgJ7JFmobwKV1DTR/CM2xSw=", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npm.taobao.org/nanomatch/download/nanomatch-1.2.13.tgz", - "integrity": "sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk=", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npm.taobao.org/natural-compare/download/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz", - "integrity": "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npm.taobao.org/neo-async/download/neo-async-2.6.1.tgz", - "integrity": "sha1-rCetpmFn+ohJpq3dg39rGJrSCBw=", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npm.taobao.org/nice-try/download/nice-try-1.0.5.tgz", - "integrity": "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y=", - "dev": true - }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npm.taobao.org/no-case/download/no-case-2.3.2.tgz?cache=0&sync_timestamp=1576721505371&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-2.3.2.tgz", - "integrity": "sha1-YLgTOWvjmz8SiKTB7V0efSi0ZKw=", - "dev": true, - "requires": { - "lower-case": "^1.1.1" - } - }, - "node-emoji": { - "version": "1.10.0", - "resolved": "https://registry.npm.taobao.org/node-emoji/download/node-emoji-1.10.0.tgz", - "integrity": "sha1-iIar0l2ce7YYAqZYUj0fjSqJsto=", - "requires": { - "lodash.toarray": "^4.4.0" - } - }, - "node-forge": { - "version": "0.9.0", - "resolved": "https://registry.npm.taobao.org/node-forge/download/node-forge-0.9.0.tgz?cache=0&sync_timestamp=1569524669712&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-forge%2Fdownload%2Fnode-forge-0.9.0.tgz", - "integrity": "sha1-1iQFDtu0SHStyhK7mlLsY8t4JXk=", - "dev": true - }, - "node-ipc": { - "version": "9.1.1", - "resolved": "https://registry.npm.taobao.org/node-ipc/download/node-ipc-9.1.1.tgz", - "integrity": "sha1-TiRe1pOOZRAOWV68XcNLFujdXWk=", - "dev": true, - "requires": { - "event-pubsub": "4.3.0", - "js-message": "1.0.5", - "js-queue": "2.0.0" - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npm.taobao.org/node-libs-browser/download/node-libs-browser-2.2.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-libs-browser%2Fdownload%2Fnode-libs-browser-2.2.1.tgz", - "integrity": "sha1-tk9RPRgzhiX5A0bSew0jXmMfZCU=", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npm.taobao.org/punycode/download/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "node-releases": { - "version": "1.1.44", - "resolved": "https://registry.npm.taobao.org/node-releases/download/node-releases-1.1.44.tgz?cache=0&sync_timestamp=1577231700151&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-releases%2Fdownload%2Fnode-releases-1.1.44.tgz", - "integrity": "sha1-zWZDim64dePrAStqEuSNn0Mm/9c=", - "dev": true, - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz", - "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=", - "dev": true - } - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npm.taobao.org/normalize-package-data/download/normalize-package-data-2.5.0.tgz", - "integrity": "sha1-5m2xg4sgDB38IzIl0SyzZSDiNKg=", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/normalize-path/download/normalize-path-3.0.0.tgz", - "integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=", - "dev": true - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npm.taobao.org/normalize-range/download/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true - }, - "normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npm.taobao.org/normalize-url/download/normalize-url-3.3.0.tgz", - "integrity": "sha1-suHE3E98bVd0PfczpPWXjRhlBVk=", - "dev": true - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-2.0.2.tgz?cache=0&sync_timestamp=1577053500910&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnpm-run-path%2Fdownload%2Fnpm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/nth-check/download/nth-check-1.0.2.tgz", - "integrity": "sha1-sr0pXDfj3VijvwcAN2Zjuk2c8Fw=", - "dev": true, - "requires": { - "boolbase": "~1.0.0" - } - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npm.taobao.org/num2fraction/download/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/number-is-nan/download/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npm.taobao.org/oauth-sign/download/oauth-sign-0.9.0.tgz", - "integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npm.taobao.org/object-copy/download/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-hash": { - "version": "1.3.1", - "resolved": "https://registry.npm.taobao.org/object-hash/download/object-hash-1.3.1.tgz", - "integrity": "sha1-/eRSCYqVHLFF8Dm7fUVUSd3BJt8=", - "dev": true - }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npm.taobao.org/object-inspect/download/object-inspect-1.7.0.tgz?cache=0&sync_timestamp=1573451929207&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject-inspect%2Fdownload%2Fobject-inspect-1.7.0.tgz", - "integrity": "sha1-9Pa9GBrXfwBrXs5gvQtvOY/3Smc=", - "dev": true - }, - "object-is": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/object-is/download/object-is-1.0.2.tgz?cache=0&sync_timestamp=1576479714417&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject-is%2Fdownload%2Fobject-is-1.0.2.tgz", - "integrity": "sha1-a4DrhP5FFJj2UAeYLwNaW0Re3sQ=", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/object-keys/download/object-keys-1.1.1.tgz", - "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4=", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/object-visit/download/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/object.assign/download/object.assign-4.1.0.tgz", - "integrity": "sha1-lovxEA15Vrs8oIbwBvhGs7xACNo=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/object.getownpropertydescriptors/download/object.getownpropertydescriptors-2.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject.getownpropertydescriptors%2Fdownload%2Fobject.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha1-Npvx+VktiridcS3O1cuBx8U1Jkk=", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npm.taobao.org/object.pick/download/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/object.values/download/object.values-1.1.1.tgz", - "integrity": "sha1-aKmezeNWt+kpWjxeDOMdyMlT3l4=", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/obuf/download/obuf-1.1.2.tgz", - "integrity": "sha1-Cb6jND1BhZ69RGKS0RydTbYZCE4=", - "dev": true - }, - "omit.js": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/omit.js/download/omit.js-1.0.2.tgz", - "integrity": "sha1-kaFPDrqEBm36AVvzDkdMR/MLyFg=", - "requires": { - "babel-runtime": "^6.23.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/on-headers/download/on-headers-1.0.2.tgz", - "integrity": "sha1-dysK5qqlJcOZ5Imt+tkMQD6zwo8=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npm.taobao.org/onetime/download/onetime-5.1.0.tgz", - "integrity": "sha1-//DzyRYX/mK7UBiWNumayKbfe+U=", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "6.4.0", - "resolved": "https://registry.npm.taobao.org/open/download/open-6.4.0.tgz", - "integrity": "sha1-XBPpbQ3IlGhhZPGJZez+iJ7PyKk=", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "opener": { - "version": "1.5.1", - "resolved": "https://registry.npm.taobao.org/opener/download/opener-1.5.1.tgz", - "integrity": "sha1-bS8Od/GgrwAyrKcWwsH7uOfoq+0=", - "dev": true - }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npm.taobao.org/opn/download/opn-5.5.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fopn%2Fdownload%2Fopn-5.5.0.tgz", - "integrity": "sha1-/HFk+rVtI1kExRw7J9pnWMo7m/w=", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npm.taobao.org/optimist/download/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npm.taobao.org/optionator/download/optionator-0.8.3.tgz?cache=0&sync_timestamp=1573077968812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Foptionator%2Fdownload%2Foptionator-0.8.3.tgz", - "integrity": "sha1-hPodA2/p08fiHZmIS2ARZ+yPtJU=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "ora": { - "version": "3.4.0", - "resolved": "https://registry.npm.taobao.org/ora/download/ora-3.4.0.tgz?cache=0&sync_timestamp=1573640943103&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fora%2Fdownload%2Fora-3.4.0.tgz", - "integrity": "sha1-vwdSSRBZo+8+1MhQl1Md6f280xg=", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-spinners": "^2.0.0", - "log-symbols": "^2.2.0", - "strip-ansi": "^5.2.0", - "wcwidth": "^1.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz", - "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz?cache=0&sync_timestamp=1573280549549&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-5.2.0.tgz", - "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/original/download/original-1.0.2.tgz", - "integrity": "sha1-5EKmHP/hxf0gpl8yYcJmY7MD8l8=", - "dev": true, - "requires": { - "url-parse": "^1.4.3" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npm.taobao.org/os-browserify/download/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/os-locale/download/os-locale-3.1.0.tgz?cache=0&sync_timestamp=1560274285880&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fos-locale%2Fdownload%2Fos-locale-3.1.0.tgz", - "integrity": "sha1-qAKm7hfyTBBIOrmTVxnO9O0Wvxo=", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/os-tmpdir/download/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/p-defer/download/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/p-finally/download/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/p-is-promise/download/p-is-promise-2.1.0.tgz", - "integrity": "sha1-kYzrrqJIpiz3/6uOO8qMX4gvxC4=", - "dev": true - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npm.taobao.org/p-limit/download/p-limit-2.2.2.tgz", - "integrity": "sha1-YSebZ3IfUoeqHBOpp/u8SMkpGx4=", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-3.0.0.tgz", - "integrity": "sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ=", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/p-map/download/p-map-3.0.0.tgz", - "integrity": "sha1-1wTZr4orpoTiYA2aIVmD1BQal50=", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npm.taobao.org/p-retry/download/p-retry-3.0.1.tgz", - "integrity": "sha1-MWtMiJPiyNwc+okfQGxLQivr8yg=", - "dev": true, - "requires": { - "retry": "^0.12.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz", - "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=", - "dev": true - }, - "pako": { - "version": "1.0.10", - "resolved": "https://registry.npm.taobao.org/pako/download/pako-1.0.10.tgz", - "integrity": "sha1-Qyi621CGpCaqkPVBl31JVdpclzI=", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/parallel-transform/download/parallel-transform-1.2.0.tgz", - "integrity": "sha1-kEnKN9bLIYLDsdLHIL6U0UpYFPw=", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/param-case/download/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/parent-module/download/parent-module-1.0.1.tgz", - "integrity": "sha1-aR0nCeeMefrjoVZiJFLQB2LKqqI=", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npm.taobao.org/parse-asn1/download/parse-asn1-5.1.5.tgz", - "integrity": "sha1-ADJxND2ljclMrOSU+u89IUfs6g4=", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/parse-json/download/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse5": { - "version": "5.1.1", - "resolved": "https://registry.npm.taobao.org/parse5/download/parse5-5.1.1.tgz?cache=0&sync_timestamp=1573036827948&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse5%2Fdownload%2Fparse5-5.1.1.tgz", - "integrity": "sha1-9o5OW6GFKsLK3AD0VV//bCq7YXg=", - "dev": true - }, - "parse5-htmlparser2-tree-adapter": { - "version": "5.1.1", - "resolved": "https://registry.npm.taobao.org/parse5-htmlparser2-tree-adapter/download/parse5-htmlparser2-tree-adapter-5.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse5-htmlparser2-tree-adapter%2Fdownload%2Fparse5-htmlparser2-tree-adapter-5.1.1.tgz", - "integrity": "sha1-6MdD1OkhlNUpPs3isIvjHmdGHLw=", - "dev": true, - "requires": { - "parse5": "^5.1.1" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz", - "integrity": "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ=", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npm.taobao.org/pascalcase/download/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npm.taobao.org/path-browserify/download/path-browserify-0.0.1.tgz", - "integrity": "sha1-5sTd1+06onxoogzE5Q4aTug7vEo=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/path-dirname/download/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/path-is-inside/download/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/path-key/download/path-key-2.0.1.tgz?cache=0&sync_timestamp=1574441431664&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-key%2Fdownload%2Fpath-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npm.taobao.org/path-parse/download/path-parse-1.0.6.tgz", - "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/path-type/download/path-type-3.0.0.tgz", - "integrity": "sha1-zvMdyOCho7sNEFwM2Xzzv0f0428=", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npm.taobao.org/pbkdf2/download/pbkdf2-3.0.17.tgz", - "integrity": "sha1-l2wgZTBhexTrsyEUI597CTNuk6Y=", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/pify/download/pify-4.0.1.tgz", - "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npm.taobao.org/pinkie/download/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/pinkie-promise/download/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-3.0.0.tgz", - "integrity": "sha1-J0kCDyOe2ZCIGx9xIQ1R62UjvqM=", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "portfinder": { - "version": "1.0.25", - "resolved": "https://registry.npm.taobao.org/portfinder/download/portfinder-1.0.25.tgz", - "integrity": "sha1-JU/TN/+6hp9LnTftwpgFnLTTXso=", - "dev": true, - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.1" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-3.2.6.tgz", - "integrity": "sha1-6D0X3hbYp++3cX7b5fsQE17uYps=", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npm.taobao.org/posix-character-classes/download/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "postcss": { - "version": "7.0.26", - "resolved": "https://registry.npm.taobao.org/postcss/download/postcss-7.0.26.tgz?cache=0&sync_timestamp=1577751206655&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss%2Fdownload%2Fpostcss-7.0.26.tgz", - "integrity": "sha1-XtYVz8qzW6m7uCQUpPqI6hBClYc=", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "postcss-calc": { - "version": "7.0.1", - "resolved": "https://registry.npm.taobao.org/postcss-calc/download/postcss-calc-7.0.1.tgz", - "integrity": "sha1-Ntd7qwI7Dsu5eJ2E3LI8SUEUVDY=", - "dev": true, - "requires": { - "css-unit-converter": "^1.1.1", - "postcss": "^7.0.5", - "postcss-selector-parser": "^5.0.0-rc.4", - "postcss-value-parser": "^3.3.1" - } - }, - "postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npm.taobao.org/postcss-colormin/download/postcss-colormin-4.0.3.tgz", - "integrity": "sha1-rgYLzpPteUrHEmTwgTLVUJVr04E=", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/postcss-convert-values/download/postcss-convert-values-4.0.1.tgz", - "integrity": "sha1-yjgT7U2g+BL51DcDWE5Enr4Ymn8=", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-discard-comments/download/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha1-H7q9LCRr/2qq15l7KwkY9NevQDM=", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-discard-duplicates/download/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha1-P+EzzTyCKC5VD8myORdqkge3hOs=", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/postcss-discard-empty/download/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha1-yMlR6fc+2UKAGUWERKAq2Qu592U=", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/postcss-discard-overridden/download/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha1-ZSrvipZybwKfXj4AFG7npOdV/1c=", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-load-config": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/postcss-load-config/download/postcss-load-config-2.1.0.tgz", - "integrity": "sha1-yE1pK3u3tB3c7ZTuYuirMbQXsAM=", - "dev": true, - "requires": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" - } - }, - "postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/postcss-loader/download/postcss-loader-3.0.0.tgz", - "integrity": "sha1-a5eUPkfHLYRfqeA/Jzdz1OjdbC0=", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" - } - }, - "postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npm.taobao.org/postcss-merge-longhand/download/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha1-YvSaE+Sg7gTnuY9CuxYGLKJUniQ=", - "dev": true, - "requires": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" - } - }, - "postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npm.taobao.org/postcss-merge-rules/download/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha1-NivqT/Wh+Y5AdacTxsslrv75plA=", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.1", - "resolved": "https://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-3.1.1.tgz", - "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", - "dev": true, - "requires": { - "dot-prop": "^4.1.1", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-minify-font-values/download/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha1-zUw0TM5HQ0P6xdgiBqssvLiv1aY=", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-minify-gradients/download/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha1-k7KcL/UJnFNe7NpWxKpuZlpmNHE=", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-minify-params/download/postcss-minify-params-4.0.2.tgz", - "integrity": "sha1-a5zvAwwR41Jh+V9hjJADbWgNuHQ=", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "uniqs": "^2.0.0" - } - }, - "postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-minify-selectors/download/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha1-4uXrQL/uUA0M2SQ1APX46kJi+9g=", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.1", - "resolved": "https://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-3.1.1.tgz", - "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", - "dev": true, - "requires": { - "dot-prop": "^4.1.1", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/postcss-modules-extract-imports/download/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha1-gYcZoa4doyX5gyRGsBE27rSTzX4=", - "dev": true, - "requires": { - "postcss": "^7.0.5" - } - }, - "postcss-modules-local-by-default": { - "version": "3.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-modules-local-by-default/download/postcss-modules-local-by-default-3.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-local-by-default%2Fdownload%2Fpostcss-modules-local-by-default-3.0.2.tgz", - "integrity": "sha1-6KZWG+kUqvPAUodjd1JMqQ27eRU=", - "dev": true, - "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.16", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.0" - }, - "dependencies": { - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/cssesc/download/cssesc-3.0.0.tgz", - "integrity": "sha1-N3QZGZA7hoVl4cCep0dEXNGJg+4=", - "dev": true - }, - "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha1-k0z3mdAWyDQRhZ4J3Oyt4BKG7Fw=", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "postcss-value-parser": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-4.0.2.tgz", - "integrity": "sha1-SCKCwJpCcG0fyaBptz9E7Ag5Hck=", - "dev": true - } - } - }, - "postcss-modules-scope": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/postcss-modules-scope/download/postcss-modules-scope-2.1.1.tgz", - "integrity": "sha1-M9T8lGYC616TVcQWXWihBydonbo=", - "dev": true, - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" - }, - "dependencies": { - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/cssesc/download/cssesc-3.0.0.tgz", - "integrity": "sha1-N3QZGZA7hoVl4cCep0dEXNGJg+4=", - "dev": true - }, - "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha1-k0z3mdAWyDQRhZ4J3Oyt4BKG7Fw=", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/postcss-modules-values/download/postcss-modules-values-3.0.0.tgz", - "integrity": "sha1-W1AA1uuuKbQlUwG0o6VFdEI+fxA=", - "dev": true, - "requires": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" - } - }, - "postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/postcss-normalize-charset/download/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha1-izWt067oOhNrBHHg1ZvlilAoXdQ=", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-normalize-display-values/download/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha1-Db4EpM6QY9RmftK+R2u4MMglk1o=", - "dev": true, - "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-normalize-positions/download/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha1-BfdX+E8mBDc3g2ipH4ky1LECkX8=", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-normalize-repeat-style/download/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha1-xOu8KJ85kaAo1EdRy90RkYsXkQw=", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-normalize-string/download/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha1-zUTECrB6DHo23F6Zqs4eyk7CaQw=", - "dev": true, - "requires": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-normalize-timing-functions/download/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha1-jgCcoqOUnNr4rSPmtquZy159KNk=", - "dev": true, - "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/postcss-normalize-unicode/download/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha1-hBvUj9zzAZrUuqdJOj02O1KuHPs=", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/postcss-normalize-url/download/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha1-EOQ3+GvHx+WPe5ZS7YeNqqlfquE=", - "dev": true, - "requires": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-normalize-whitespace/download/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha1-vx1AcP5Pzqh9E0joJdjMDF+qfYI=", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npm.taobao.org/postcss-ordered-values/download/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha1-DPdcgg7H1cTSgBiVWeC1ceusDu4=", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npm.taobao.org/postcss-reduce-initial/download/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha1-f9QuvqXpyBRgljniwuhK4nC6SN8=", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-reduce-transforms/download/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha1-F++kBerMbge+NBSlyi0QdGgdTik=", - "dev": true, - "requires": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha1-JJBENWaXsztk8aj3yAki3d7nGVw=", - "dev": true, - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "postcss-svgo": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/postcss-svgo/download/postcss-svgo-4.0.2.tgz", - "integrity": "sha1-F7mXvHEbMzurFDqu07jT1uPTglg=", - "dev": true, - "requires": { - "is-svg": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" - } - }, - "postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/postcss-unique-selectors/download/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha1-lEaRHzKJv9ZMbWgPBzwDsfnuS6w=", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", - "uniqs": "^2.0.0" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-3.3.1.tgz", - "integrity": "sha1-n/giVH4okyE88cMO+lGsX9G6goE=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/prelude-ls/download/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/prepend-http/download/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npm.taobao.org/prettier/download/prettier-1.19.1.tgz?cache=0&sync_timestamp=1573302169507&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-1.19.1.tgz", - "integrity": "sha1-99f1/4qc2HKnvkyhQglZVqYHl8s=", - "dev": true - }, - "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/pretty-error/download/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", - "dev": true, - "requires": { - "renderkid": "^2.0.1", - "utila": "~0.4" - } - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npm.taobao.org/private/download/private-0.1.8.tgz", - "integrity": "sha1-I4Hts2ifelPWUxkAYPz4ItLzaP8=", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npm.taobao.org/process/download/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz", - "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npm.taobao.org/progress/download/progress-2.0.3.tgz", - "integrity": "sha1-foz42PW48jnBvGi+tOt4Vn1XLvg=", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/promise-inflight/download/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npm.taobao.org/proxy-addr/download/proxy-addr-2.0.5.tgz", - "integrity": "sha1-NMvWSi2B9LH9IedvnwbIpFKZ7jQ=", - "dev": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/prr/download/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/pseudomap/download/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.7.0", - "resolved": "https://registry.npm.taobao.org/psl/download/psl-1.7.0.tgz?cache=0&sync_timestamp=1577538558975&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpsl%2Fdownload%2Fpsl-1.7.0.tgz", - "integrity": "sha1-8cTEeo75cWfepda79IFtc26ISjw=", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npm.taobao.org/public-encrypt/download/public-encrypt-4.0.3.tgz", - "integrity": "sha1-T8ydd6B+SLp1J+fL4N4z0HATMeA=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/pump/download/pump-3.0.0.tgz", - "integrity": "sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ=", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npm.taobao.org/pumpify/download/pumpify-1.5.1.tgz?cache=0&sync_timestamp=1569938200736&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpumpify%2Fdownload%2Fpumpify-1.5.1.tgz", - "integrity": "sha1-NlE74karJ1cLGjdKXOJ4v9dDcM4=", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/pump/download/pump-2.0.1.tgz", - "integrity": "sha1-Ejma3W5M91Jtlzy8i1zi4pCLOQk=", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz", - "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=", - "dev": true - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npm.taobao.org/q/download/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.7.0.tgz", - "integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw=", - "dev": true - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npm.taobao.org/query-string/download/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "dev": true, - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npm.taobao.org/querystring/download/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npm.taobao.org/querystring-es3/download/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/querystringify/download/querystringify-2.1.1.tgz", - "integrity": "sha1-YOWl/WSn+L+k0qsu1v30yFutFU4=", - "dev": true - }, - "raf": { - "version": "3.4.1", - "resolved": "https://registry.npm.taobao.org/raf/download/raf-3.4.1.tgz", - "integrity": "sha1-B0LpmkplUvRF1z4+4DKK8P8e3jk=", - "requires": { - "performance-now": "^2.1.0" - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/randombytes/download/randombytes-2.1.0.tgz", - "integrity": "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo=", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/randomfill/download/randomfill-1.0.4.tgz", - "integrity": "sha1-ySGW/IarQr6YPxvzF3giSTHWFFg=", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npm.taobao.org/range-parser/download/range-parser-1.2.1.tgz", - "integrity": "sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE=", - "dev": true - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npm.taobao.org/raw-body/download/raw-body-2.4.0.tgz", - "integrity": "sha1-oc5vucm8NWylLoklarWQWeE9AzI=", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npm.taobao.org/read-pkg/download/read-pkg-5.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg%2Fdownload%2Fread-pkg-5.2.0.tgz", - "integrity": "sha1-e/KVQ4yloz5WzTDgU7NO5yUMk8w=", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npm.taobao.org/parse-json/download/parse-json-5.0.0.tgz", - "integrity": "sha1-c+URTJhtFD76NxLU6iTbmkJm9g8=", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.6.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-2.3.6.tgz", - "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz", - "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz?cache=0&sync_timestamp=1565170823020&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring_decoder%2Fdownload%2Fstring_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npm.taobao.org/readdirp/download/readdirp-2.2.1.tgz?cache=0&sync_timestamp=1575629920252&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freaddirp%2Fdownload%2Freaddirp-2.2.1.tgz", - "integrity": "sha1-DodiKjMlqjPokihcr4tOhGUppSU=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npm.taobao.org/regenerate/download/regenerate-1.4.0.tgz", - "integrity": "sha1-SoVuxLVuQHfFV1icroXnpMiGmhE=", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "8.1.0", - "resolved": "https://registry.npm.taobao.org/regenerate-unicode-properties/download/regenerate-unicode-properties-8.1.0.tgz", - "integrity": "sha1-71Hg8OpK1CS3e/fLQfPgFccKPw4=", - "dev": true, - "requires": { - "regenerate": "^1.4.0" - } - }, - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.13.3.tgz", - "integrity": "sha1-fPanfY9cb2Drc8X8GVWyzrAea/U=", - "dev": true - }, - "regenerator-transform": { - "version": "0.14.1", - "resolved": "https://registry.npm.taobao.org/regenerator-transform/download/regenerator-transform-0.14.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-transform%2Fdownload%2Fregenerator-transform-0.14.1.tgz", - "integrity": "sha1-Oy/OThq3cywI9mXf2zFHScfd0vs=", - "dev": true, - "requires": { - "private": "^0.1.6" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/regex-not/download/regex-not-1.0.2.tgz", - "integrity": "sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw=", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npm.taobao.org/regexp.prototype.flags/download/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha1-erqJs8E6ZFCdq888qNn7ub31y3U=", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/regexpp/download/regexpp-2.0.1.tgz", - "integrity": "sha1-jRnTHPYySCtYkEn4KB+T28uk0H8=", - "dev": true - }, - "regexpu-core": { - "version": "4.6.0", - "resolved": "https://registry.npm.taobao.org/regexpu-core/download/regexpu-core-4.6.0.tgz?cache=0&sync_timestamp=1568375270709&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregexpu-core%2Fdownload%2Fregexpu-core-4.6.0.tgz", - "integrity": "sha1-IDfBizJ8/Oim/qKk7EQfJDKvuLY=", - "dev": true, - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.1.0", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.1.0" - } - }, - "regjsgen": { - "version": "0.5.1", - "resolved": "https://registry.npm.taobao.org/regjsgen/download/regjsgen-0.5.1.tgz?cache=0&sync_timestamp=1571560340910&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregjsgen%2Fdownload%2Fregjsgen-0.5.1.tgz", - "integrity": "sha1-SPC/Gl6iBRlpKcDZeYtC0e2YRDw=", - "dev": true - }, - "regjsparser": { - "version": "0.6.2", - "resolved": "https://registry.npm.taobao.org/regjsparser/download/regjsparser-0.6.2.tgz", - "integrity": "sha1-/WLHU5kUZ9nR/+Cp9n8npSkCS5Y=", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npm.taobao.org/jsesc/download/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npm.taobao.org/relateurl/download/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/remove-trailing-separator/download/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "renderkid": { - "version": "2.0.3", - "resolved": "https://registry.npm.taobao.org/renderkid/download/renderkid-2.0.3.tgz", - "integrity": "sha1-OAF5wv9a4TZcUivy/Pz/AcW3QUk=", - "dev": true, - "requires": { - "css-select": "^1.1.0", - "dom-converter": "^0.2", - "htmlparser2": "^3.3.0", - "strip-ansi": "^3.0.0", - "utila": "^0.4.0" - }, - "dependencies": { - "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/css-select/download/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, - "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, - "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npm.taobao.org/css-what/download/css-what-2.1.3.tgz?cache=0&sync_timestamp=1573341698559&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-what%2Fdownload%2Fcss-what-2.1.3.tgz", - "integrity": "sha1-ptdgRXM2X+dGhsPzEcVlE9iChfI=", - "dev": true - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npm.taobao.org/domutils/download/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - } - } - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npm.taobao.org/repeat-element/download/repeat-element-1.1.3.tgz", - "integrity": "sha1-eC4NglwMWjuzlzH4Tv7mt0Lmsc4=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npm.taobao.org/repeat-string/download/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npm.taobao.org/request/download/request-2.88.0.tgz", - "integrity": "sha1-nC/KT301tZLv5Xx/ClXoEFIST+8=", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.5.2.tgz", - "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=", - "dev": true - } - } - }, - "request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npm.taobao.org/request-promise-core/download/request-promise-core-1.1.3.tgz", - "integrity": "sha1-6aPAgbUTgN/qZ3M2Bh/qh5qCnuk=", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npm.taobao.org/request-promise-native/download/request-promise-native-1.0.8.tgz?cache=0&sync_timestamp=1572829683581&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frequest-promise-native%2Fdownload%2Frequest-promise-native-1.0.8.tgz", - "integrity": "sha1-pFW5YLgm5E4r+Jma9k3/K/5YyzY=", - "dev": true, - "requires": { - "request-promise-core": "1.1.3", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/require-directory/download/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/require-main-filename/download/require-main-filename-2.0.0.tgz", - "integrity": "sha1-0LMp7MfMD2Fkn2IhW+aa9UqomJs=", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/requires-port/download/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resize-observer-polyfill": { - "version": "1.5.1", - "resolved": "https://registry.npm.taobao.org/resize-observer-polyfill/download/resize-observer-polyfill-1.5.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fresize-observer-polyfill%2Fdownload%2Fresize-observer-polyfill-1.5.1.tgz", - "integrity": "sha1-DpAg3T0hAkRY1OvSfiPkAmmBBGQ=" - }, - "resolve": { - "version": "1.14.1", - "resolved": "https://registry.npm.taobao.org/resolve/download/resolve-1.14.1.tgz?cache=0&sync_timestamp=1577139902451&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fresolve%2Fdownload%2Fresolve-1.14.1.tgz", - "integrity": "sha1-ngGMVA/PDEJ9Z4uZMcv0XphLyv8=", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/resolve-cwd/download/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/resolve-from/download/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npm.taobao.org/resolve-url/download/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/restore-cursor/download/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "dependencies": { - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/mimic-fn/download/mimic-fn-1.2.0.tgz", - "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/onetime/download/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - } - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npm.taobao.org/ret/download/ret-0.1.15.tgz", - "integrity": "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w=", - "dev": true - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npm.taobao.org/retry/download/retry-0.12.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fretry%2Fdownload%2Fretry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - }, - "rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/rgb-regex/download/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", - "dev": true - }, - "rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/rgba-regex/download/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npm.taobao.org/rimraf/download/rimraf-2.7.1.tgz?cache=0&sync_timestamp=1569343496458&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frimraf%2Fdownload%2Frimraf-2.7.1.tgz", - "integrity": "sha1-NXl/E6f9rcVmFCwp1PB8ytSD4+w=", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npm.taobao.org/ripemd160/download/ripemd160-2.0.2.tgz", - "integrity": "sha1-ocGm9iR1FXe6XQeRTLyShQWFiQw=", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npm.taobao.org/run-async/download/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/run-queue/download/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npm.taobao.org/rxjs/download/rxjs-6.5.4.tgz?cache=0&sync_timestamp=1577464542639&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.5.4.tgz", - "integrity": "sha1-4Hd/4NGEzseHLfFH8wNXLUFOIRw=", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.0.tgz", - "integrity": "sha1-t02uxJsRSPiMZLaNSbHoFcHy9Rk=", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/safe-regex/download/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz", - "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=", - "dev": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npm.taobao.org/sax/download/sax-1.2.4.tgz", - "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", - "dev": true - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-1.0.0.tgz?cache=0&sync_timestamp=1574946754916&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-1.0.0.tgz", - "integrity": "sha1-C3mpMgTXtgDUsoUNH2bCo0lRx3A=", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/select-hose/download/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selfsigned": { - "version": "1.10.7", - "resolved": "https://registry.npm.taobao.org/selfsigned/download/selfsigned-1.10.7.tgz?cache=0&sync_timestamp=1569952074772&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fselfsigned%2Fdownload%2Fselfsigned-1.10.7.tgz", - "integrity": "sha1-2lgZ/QSdVXTyjoipvMbbxubzkGs=", - "dev": true, - "requires": { - "node-forge": "0.9.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", - "dev": true - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npm.taobao.org/send/download/send-0.17.1.tgz", - "integrity": "sha1-wdiwWfeQD3Rm3Uk4vcROEd2zdsg=", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npm.taobao.org/mime/download/mime-1.6.0.tgz?cache=0&sync_timestamp=1560034758817&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime%2Fdownload%2Fmime-1.6.0.tgz", - "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", - "dev": true - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.1.tgz", - "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo=", - "dev": true - } - } - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npm.taobao.org/serialize-javascript/download/serialize-javascript-2.1.2.tgz?cache=0&sync_timestamp=1575910505665&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-javascript%2Fdownload%2Fserialize-javascript-2.1.2.tgz", - "integrity": "sha1-7OxTsOAxe9yV73arcHS3OEeF+mE=", - "dev": true - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npm.taobao.org/serve-index/download/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.6.3.tgz?cache=0&sync_timestamp=1561418493658&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz?cache=0&sync_timestamp=1560975547815&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Finherits%2Fdownload%2Finherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsetprototypeof%2Fdownload%2Fsetprototypeof-1.1.0.tgz", - "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=", - "dev": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npm.taobao.org/serve-static/download/serve-static-1.14.1.tgz", - "integrity": "sha1-Zm5jbcTwEPfvKZcKiKZ0MgiYsvk=", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/set-blocking/download/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/set-value/download/set-value-2.0.1.tgz", - "integrity": "sha1-oY1AUw5vB95CKMfe/kInr4ytAFs=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npm.taobao.org/setimmediate/download/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsetprototypeof%2Fdownload%2Fsetprototypeof-1.1.1.tgz", - "integrity": "sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npm.taobao.org/sha.js/download/sha.js-2.4.11.tgz", - "integrity": "sha1-N6XPC4HsvGlD3hCbopYNGyZYSuc=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-equal": { - "version": "1.2.1", - "resolved": "https://registry.npm.taobao.org/shallow-equal/download/shallow-equal-1.2.1.tgz?cache=0&sync_timestamp=1575627899561&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fshallow-equal%2Fdownload%2Fshallow-equal-1.2.1.tgz", - "integrity": "sha1-TBar+lYEOqINBQMk76aJQLDaedo=" - }, - "shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/shallowequal/download/shallowequal-1.1.0.tgz", - "integrity": "sha1-GI1SHelbkIdAT9TctosT3wrk5/g=" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npm.taobao.org/shell-quote/download/shell-quote-1.7.2.tgz", - "integrity": "sha1-Z6fQLHbJ2iT5nSCAj8re0ODgS+I=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npm.taobao.org/simple-swizzle/download/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dev": true, - "requires": { - "is-arrayish": "^0.3.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npm.taobao.org/is-arrayish/download/is-arrayish-0.3.2.tgz", - "integrity": "sha1-RXSirlb3qyBolvtDHq7tBm/fjwM=", - "dev": true - } - } - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/slash/download/slash-2.0.0.tgz", - "integrity": "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=", - "dev": true - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/slice-ansi/download/slice-ansi-2.1.0.tgz", - "integrity": "sha1-ys12k0YaY3pXiNkqfdT7oGjoFjY=", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npm.taobao.org/snapdragon/download/snapdragon-0.8.2.tgz", - "integrity": "sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0=", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/snapdragon-node/download/snapdragon-node-2.1.1.tgz", - "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-1.0.0.tgz", - "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-1.0.2.tgz", - "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npm.taobao.org/snapdragon-util/download/snapdragon-util-3.0.1.tgz", - "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "sockjs": { - "version": "0.3.19", - "resolved": "https://registry.npm.taobao.org/sockjs/download/sockjs-0.3.19.tgz", - "integrity": "sha1-2Xa76ACve9IK4IWY1YI5NQiZPA0=", - "dev": true, - "requires": { - "faye-websocket": "^0.10.0", - "uuid": "^3.0.1" - } - }, - "sockjs-client": { - "version": "1.4.0", - "resolved": "https://registry.npm.taobao.org/sockjs-client/download/sockjs-client-1.4.0.tgz", - "integrity": "sha1-yfJWjhnI/YFztJl+o0IOC7MGx9U=", - "dev": true, - "requires": { - "debug": "^3.2.5", - "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-3.2.6.tgz", - "integrity": "sha1-6D0X3hbYp++3cX7b5fsQE17uYps=", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npm.taobao.org/faye-websocket/download/faye-websocket-0.11.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffaye-websocket%2Fdownload%2Ffaye-websocket-0.11.3.tgz", - "integrity": "sha1-XA6aiWjokSwoZjn96XeosgnyUI4=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - } - } - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/sort-keys/download/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/source-list-map/download/source-list-map-2.0.1.tgz", - "integrity": "sha1-OZO9hzv8SEecyp6jpUeDXHwVSzQ=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npm.taobao.org/source-map-resolve/download/source-map-resolve-0.5.3.tgz", - "integrity": "sha1-GQhmvs51U+H48mei7oLGBrVQmho=", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npm.taobao.org/source-map-support/download/source-map-support-0.5.16.tgz", - "integrity": "sha1-CuBp5/47p1OMZMmFFeNTOerFoEI=", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npm.taobao.org/source-map-url/download/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/spdx-correct/download/spdx-correct-3.1.0.tgz", - "integrity": "sha1-+4PlBERSaPFUsHTiGMh8ADzTHfQ=", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npm.taobao.org/spdx-exceptions/download/spdx-exceptions-2.2.0.tgz", - "integrity": "sha1-LqRQrudPKom/uUUZwH/Nb0EyKXc=", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/spdx-expression-parse/download/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npm.taobao.org/spdx-license-ids/download/spdx-license-ids-3.0.5.tgz?cache=0&sync_timestamp=1562834220236&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz", - "integrity": "sha1-NpS1gEVnpFjTyARYQqY1hjL2JlQ=", - "dev": true - }, - "spdy": { - "version": "4.0.1", - "resolved": "https://registry.npm.taobao.org/spdy/download/spdy-4.0.1.tgz", - "integrity": "sha1-bxLtHF236k8k67i4m6WMh8CCV/I=", - "dev": true, - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz", - "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/spdy-transport/download/spdy-transport-3.0.0.tgz", - "integrity": "sha1-ANSGOmQArXXfkzYaFghgXl3NzzE=", - "dev": true, - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz", - "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.4.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-3.4.0.tgz", - "integrity": "sha1-pRwmdUZY4KPCHb9ZFjvUW6b0R/w=", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/split-string/download/split-string-3.1.0.tgz", - "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npm.taobao.org/sshpk/download/sshpk-1.16.1.tgz", - "integrity": "sha1-+2YcC+8ps520B2nuOfpwCT1vaHc=", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "7.1.0", - "resolved": "https://registry.npm.taobao.org/ssri/download/ssri-7.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fssri%2Fdownload%2Fssri-7.1.0.tgz", - "integrity": "sha1-ksJBv23oI2W1x/tL126XVSLhKU0=", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1", - "minipass": "^3.1.1" - } - }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npm.taobao.org/stable/download/stable-0.1.8.tgz", - "integrity": "sha1-g26zyDgv4pNv6vVEYxAXzn1Ho88=", - "dev": true - }, - "stackframe": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/stackframe/download/stackframe-1.1.0.tgz", - "integrity": "sha1-4/wuuRIllHnJgi99Hx/zZb1cvIM=", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npm.taobao.org/static-extend/download/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npm.taobao.org/statuses/download/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/stealthy-require/download/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npm.taobao.org/stream-browserify/download/stream-browserify-2.0.2.tgz", - "integrity": "sha1-h1IdOKRKp+6RzhzSpH3wy0ndZgs=", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npm.taobao.org/stream-each/download/stream-each-1.2.3.tgz", - "integrity": "sha1-6+J6DDibBPvMIzZClS4Qcxr6m64=", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npm.taobao.org/stream-http/download/stream-http-2.8.3.tgz", - "integrity": "sha1-stJCRpKIpaJ+xP6JM6z2I95lFPw=", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/stream-shift/download/stream-shift-1.0.1.tgz?cache=0&sync_timestamp=1576147178936&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstream-shift%2Fdownload%2Fstream-shift-1.0.1.tgz", - "integrity": "sha1-1wiCgVWasneEJCebCHfaPDktWj0=", - "dev": true - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/strict-uri-encode/download/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true - }, - "string-convert": { - "version": "0.2.1", - "resolved": "https://registry.npm.taobao.org/string-convert/download/string-convert-0.2.1.tgz", - "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-4.0.0.tgz?cache=0&sync_timestamp=1573280549549&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string.prototype.trimleft": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/string.prototype.trimleft/download/string.prototype.trimleft-2.1.1.tgz", - "integrity": "sha1-m9uKxqvW1gKxek7TIYcNL43O/HQ=", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/string.prototype.trimright/download/string.prototype.trimright-2.1.1.tgz?cache=0&sync_timestamp=1576706898686&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimright%2Fdownload%2Fstring.prototype.trimright-2.1.1.tgz", - "integrity": "sha1-RAMUsVmWyGbOigNBiU1FGGIAxdk=", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.3.0.tgz?cache=0&sync_timestamp=1565170823020&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring_decoder%2Fdownload%2Fstring_decoder-1.3.0.tgz", - "integrity": "sha1-QvEUWUpGzxqOMLCoT1bHjD7awh4=", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-3.0.1.tgz?cache=0&sync_timestamp=1573280549549&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/strip-eof/download/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/strip-final-newline/download/strip-final-newline-2.0.0.tgz", - "integrity": "sha1-ibhS+y/L6Tb29LMYevsKEsGrWK0=", - "dev": true - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/strip-indent/download/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/strip-json-comments/download/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npm.taobao.org/stylehacks/download/stylehacks-4.0.3.tgz", - "integrity": "sha1-Zxj8r00eB9ihMYaQiB6NlnJqcdU=", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.1", - "resolved": "https://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-3.1.1.tgz", - "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", - "dev": true, - "requires": { - "dot-prop": "^4.1.1", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-6.1.0.tgz?cache=0&sync_timestamp=1569557271992&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-6.1.0.tgz", - "integrity": "sha1-B2Srxpxj1ayELdSGfo0CXogN+PM=", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/svg-tags/download/svg-tags-1.0.0.tgz", - "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", - "dev": true - }, - "svgo": { - "version": "1.3.2", - "resolved": "https://registry.npm.taobao.org/svgo/download/svgo-1.3.2.tgz?cache=0&sync_timestamp=1572433264480&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsvgo%2Fdownload%2Fsvgo-1.3.2.tgz", - "integrity": "sha1-ttxRHAYzRsnkFbgeQ0ARRbltQWc=", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - } - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npm.taobao.org/table/download/table-5.4.6.tgz", - "integrity": "sha1-EpLRlQDOP4YFOwXw6Ofko7shB54=", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz", - "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-3.1.0.tgz", - "integrity": "sha1-InZ74htirxCBV0MG9prFG2IgOWE=", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz?cache=0&sync_timestamp=1573280549549&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-5.2.0.tgz", - "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npm.taobao.org/tapable/download/tapable-1.1.3.tgz", - "integrity": "sha1-ofzMBrWNth/XpF2i2kT186Pme6I=", - "dev": true - }, - "terser": { - "version": "4.5.1", - "resolved": "https://registry.npm.taobao.org/terser/download/terser-4.5.1.tgz", - "integrity": "sha1-Y7Uta2zjRKpv7c0O4GppV5nrUL0=", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - } - }, - "terser-webpack-plugin": { - "version": "2.3.1", - "resolved": "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-2.3.1.tgz?cache=0&sync_timestamp=1576580692685&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-2.3.1.tgz", - "integrity": "sha1-amPCfevBWyX/0liFYu4u6r3KuSM=", - "dev": true, - "requires": { - "cacache": "^13.0.1", - "find-cache-dir": "^3.2.0", - "jest-worker": "^24.9.0", - "schema-utils": "^2.6.1", - "serialize-javascript": "^2.1.2", - "source-map": "^0.6.1", - "terser": "^4.4.3", - "webpack-sources": "^1.4.3" - }, - "dependencies": { - "cacache": { - "version": "13.0.1", - "resolved": "https://registry.npm.taobao.org/cacache/download/cacache-13.0.1.tgz?cache=0&sync_timestamp=1569877543868&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcacache%2Fdownload%2Fcacache-13.0.1.tgz", - "integrity": "sha1-qAAMIWlwiQgvhSh6GuxuOCAkpxw=", - "dev": true, - "requires": { - "chownr": "^1.1.2", - "figgy-pudding": "^3.5.1", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.2", - "infer-owner": "^1.0.4", - "lru-cache": "^5.1.1", - "minipass": "^3.0.0", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "p-map": "^3.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^2.7.1", - "ssri": "^7.0.0", - "unique-filename": "^1.1.1" - } - }, - "find-cache-dir": { - "version": "3.2.0", - "resolved": "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-3.2.0.tgz", - "integrity": "sha1-5/5EwavBKZ9RYUblYxCP0QBsGHQ=", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.0", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz", - "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz", - "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "make-dir": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/make-dir/download/make-dir-3.0.0.tgz", - "integrity": "sha1-G1859rknDtM/nwVMXA+EMEmJ+AE=", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz", - "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz", - "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-4.2.0.tgz", - "integrity": "sha1-8JkTPfft5CLoHR2ESCcO6z5CYfM=", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "schema-utils": { - "version": "2.6.1", - "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.6.1.tgz?cache=0&sync_timestamp=1574946754916&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.6.1.tgz", - "integrity": "sha1-63jwuUXHvPoggrNWXo2zVIAR3E8=", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz", - "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=", - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npm.taobao.org/text-table/download/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "thenify": { - "version": "3.3.0", - "resolved": "https://registry.npm.taobao.org/thenify/download/thenify-3.3.0.tgz", - "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", - "dev": true, - "requires": { - "any-promise": "^1.0.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npm.taobao.org/thenify-all/download/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", - "dev": true, - "requires": { - "thenify": ">= 3.1.0 < 4" - } - }, - "thread-loader": { - "version": "2.1.3", - "resolved": "https://registry.npm.taobao.org/thread-loader/download/thread-loader-2.1.3.tgz?cache=0&sync_timestamp=1565261083321&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fthread-loader%2Fdownload%2Fthread-loader-2.1.3.tgz", - "integrity": "sha1-y9LBOfwrLebp0o9iKGq3cMGsvdo=", - "dev": true, - "requires": { - "loader-runner": "^2.3.1", - "loader-utils": "^1.1.0", - "neo-async": "^2.6.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npm.taobao.org/through/download/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npm.taobao.org/through2/download/through2-2.0.5.tgz", - "integrity": "sha1-AcHjnrMdB8t9A6lqcIIyYLIxMs0=", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/thunky/download/thunky-1.1.0.tgz", - "integrity": "sha1-Wrr3FKlAXbBQRzK7zNLO3Z75U30=", - "dev": true - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npm.taobao.org/timers-browserify/download/timers-browserify-2.0.11.tgz", - "integrity": "sha1-gAsfPu4nLlvFPuRloE0OgEwxIR8=", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npm.taobao.org/timsort/download/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", - "dev": true - }, - "tinycolor2": { - "version": "1.4.1", - "resolved": "https://registry.npm.taobao.org/tinycolor2/download/tinycolor2-1.4.1.tgz", - "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npm.taobao.org/tmp/download/tmp-0.0.33.tgz", - "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/to-arraybuffer/download/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/to-fast-properties/download/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npm.taobao.org/to-object-path/download/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npm.taobao.org/to-regex/download/to-regex-3.0.2.tgz", - "integrity": "sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4=", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz", - "integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM=", - "dev": true - }, - "toposort": { - "version": "1.0.7", - "resolved": "https://registry.npm.taobao.org/toposort/download/toposort-1.0.7.tgz", - "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", - "dev": true - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npm.taobao.org/tough-cookie/download/tough-cookie-2.4.3.tgz", - "integrity": "sha1-U/Nto/R3g7CSWvoG/587FlKA94E=", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npm.taobao.org/punycode/download/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "tryer": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/tryer/download/tryer-1.0.1.tgz", - "integrity": "sha1-8shUBoALmw90yfdGW4HqrSQSUvg=", - "dev": true - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npm.taobao.org/tslib/download/tslib-1.10.0.tgz", - "integrity": "sha1-w8GflZc/sKYpc/sJ2Q2WHuQ+XIo=", - "dev": true - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npm.taobao.org/tty-browserify/download/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npm.taobao.org/tunnel-agent/download/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npm.taobao.org/tweetnacl/download/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npm.taobao.org/type-check/download/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npm.taobao.org/type-fest/download/type-fest-0.6.0.tgz", - "integrity": "sha1-jSojcNPfiG61yQraHFv2GIrPg4s=", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npm.taobao.org/type-is/download/type-is-1.6.18.tgz", - "integrity": "sha1-TlUs0F3wlGfcvE73Od6J8s83wTE=", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npm.taobao.org/typedarray/download/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "uglify-js": { - "version": "3.7.3", - "resolved": "https://registry.npm.taobao.org/uglify-js/download/uglify-js-3.7.3.tgz?cache=0&sync_timestamp=1577407920190&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.7.3.tgz", - "integrity": "sha1-+Rj86RgvRm1RQPJLsP81wtMtzGo=", - "dev": true, - "optional": true, - "requires": { - "commander": "~2.20.3", - "source-map": "~0.6.1" - } - }, - "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/unicode-canonical-property-names-ecmascript/download/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha1-JhmADEyCWADv3YNDr33Zkzy+KBg=", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npm.taobao.org/unicode-match-property-ecmascript/download/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha1-jtKjJWmWG86SJ9Cc0/+7j+1fAgw=", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npm.taobao.org/unicode-match-property-value-ecmascript/download/unicode-match-property-value-ecmascript-1.1.0.tgz", - "integrity": "sha1-W0tCbgjROoA2Xg1lesemwexGonc=", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "1.0.5", - "resolved": "https://registry.npm.taobao.org/unicode-property-aliases-ecmascript/download/unicode-property-aliases-ecmascript-1.0.5.tgz", - "integrity": "sha1-qcxsx85joKMCP8meNBuUQx1AWlc=", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/union-value/download/union-value-1.0.1.tgz", - "integrity": "sha1-C2/nuDWuzaYcbqTU8CwUIh4QmEc=", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/uniq/download/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/uniqs/download/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", - "dev": true - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/unique-filename/download/unique-filename-1.1.1.tgz", - "integrity": "sha1-HWl2k2mtoFgxA6HmrodoG1ZXMjA=", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npm.taobao.org/unique-slug/download/unique-slug-2.0.2.tgz", - "integrity": "sha1-uqvOkQg/xk6UWw861hPiZPfNTmw=", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz", - "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unquote": { - "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/unquote/download/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/unset-value/download/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npm.taobao.org/has-value/download/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/isobject/download/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npm.taobao.org/has-values/download/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npm.taobao.org/upath/download/upath-1.2.0.tgz?cache=0&sync_timestamp=1567457281208&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fupath%2Fdownload%2Fupath-1.2.0.tgz", - "integrity": "sha1-j2bbzVWog6za5ECK+LA1pQRMGJQ=", - "dev": true - }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npm.taobao.org/upper-case/download/upper-case-1.1.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fupper-case%2Fdownload%2Fupper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npm.taobao.org/uri-js/download/uri-js-4.2.2.tgz", - "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npm.taobao.org/urix/download/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npm.taobao.org/url/download/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npm.taobao.org/punycode/download/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-loader": { - "version": "2.3.0", - "resolved": "https://registry.npm.taobao.org/url-loader/download/url-loader-2.3.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Furl-loader%2Fdownload%2Furl-loader-2.3.0.tgz", - "integrity": "sha1-4OLvZY8APvuMpBsPP/v3a6uIZYs=", - "dev": true, - "requires": { - "loader-utils": "^1.2.3", - "mime": "^2.4.4", - "schema-utils": "^2.5.0" - }, - "dependencies": { - "schema-utils": { - "version": "2.6.1", - "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.6.1.tgz?cache=0&sync_timestamp=1574946754916&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-2.6.1.tgz", - "integrity": "sha1-63jwuUXHvPoggrNWXo2zVIAR3E8=", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1" - } - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npm.taobao.org/url-parse/download/url-parse-1.4.7.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Furl-parse%2Fdownload%2Furl-parse-1.4.7.tgz", - "integrity": "sha1-qKg1NejACjFuQDpdtKwbm4U64ng=", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npm.taobao.org/use/download/use-3.1.1.tgz", - "integrity": "sha1-1QyMrHmhn7wg8pEfVuuXP04QBw8=", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npm.taobao.org/util/download/util-0.11.1.tgz", - "integrity": "sha1-MjZzNyDsZLsn9uJvQhqqLhtYjWE=", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz?cache=0&sync_timestamp=1560975547815&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Finherits%2Fdownload%2Finherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/util.promisify/download/util.promisify-1.0.0.tgz", - "integrity": "sha1-RA9xZaRZyaFtwUXrjnLzVocJcDA=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npm.taobao.org/utila/download/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npm.taobao.org/uuid/download/uuid-3.3.3.tgz?cache=0&sync_timestamp=1566221202613&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuuid%2Fdownload%2Fuuid-3.3.3.tgz", - "integrity": "sha1-RWjwIW54dg7h2/Ok0s9T4iQRKGY=", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npm.taobao.org/validate-npm-package-license/download/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha1-/JH2uce6FchX9MssXe/uw51PQQo=", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "vendors": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/vendors/download/vendors-1.0.3.tgz", - "integrity": "sha1-pkZ3gavTZiF8BQ+CAuflDMnu+MA=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npm.taobao.org/verror/download/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz?cache=0&sync_timestamp=1572870772154&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvm-browserify%2Fdownload%2Fvm-browserify-1.1.2.tgz", - "integrity": "sha1-eGQcSIuObKkadfUR56OzKobl3aA=", - "dev": true - }, - "vue": { - "version": "2.6.11" - }, - "vue-eslint-parser": { - "version": "5.0.0", - "resolved": "https://registry.npm.taobao.org/vue-eslint-parser/download/vue-eslint-parser-5.0.0.tgz", - "integrity": "sha1-APTk2pTsl0uCGib/DtD3p4QCuKE=", - "dev": true, - "requires": { - "debug": "^4.1.0", - "eslint-scope": "^4.0.0", - "eslint-visitor-keys": "^1.0.0", - "espree": "^4.1.0", - "esquery": "^1.0.1", - "lodash": "^4.17.11" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz", - "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "espree": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/espree/download/espree-4.1.0.tgz?cache=0&sync_timestamp=1571624368510&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fespree%2Fdownload%2Fespree-4.1.0.tgz", - "integrity": "sha1-co1UUeD9FWwEOEp62J7VH/VOsl8=", - "dev": true, - "requires": { - "acorn": "^6.0.2", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - } - } - }, - "vue-hot-reload-api": { - "version": "2.3.4", - "resolved": "https://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.3.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-hot-reload-api%2Fdownload%2Fvue-hot-reload-api-2.3.4.tgz", - "integrity": "sha1-UylVzB6yCKPZkLOp+acFdGV+CPI=", - "dev": true - }, - "vue-loader": { - "version": "15.8.3", - "resolved": "https://registry.npm.taobao.org/vue-loader/download/vue-loader-15.8.3.tgz?cache=0&sync_timestamp=1578008466541&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-15.8.3.tgz", - "integrity": "sha1-hXy54w61/CXmbbSNzn5PdoYCojw=", - "dev": true, - "requires": { - "@vue/component-compiler-utils": "^3.1.0", - "hash-sum": "^1.0.2", - "loader-utils": "^1.1.0", - "vue-hot-reload-api": "^2.3.0", - "vue-style-loader": "^4.1.0" - } - }, - "vue-ref": { - "version": "1.0.6", - "resolved": "https://registry.npm.taobao.org/vue-ref/download/vue-ref-1.0.6.tgz", - "integrity": "sha1-ubPX0OKQ7i/T1Q1de9rFIIBssmU=" - }, - "vue-style-loader": { - "version": "4.1.2", - "resolved": "https://registry.npm.taobao.org/vue-style-loader/download/vue-style-loader-4.1.2.tgz", - "integrity": "sha1-3t80mAbyXOtOZPOtfApE+6c1/Pg=", - "dev": true, - "requires": { - "hash-sum": "^1.0.2", - "loader-utils": "^1.0.2" - } - }, - "vue-template-compiler": { - "version": "2.6.11", - "dev": true, - "requires": { - "de-indent": "^1.0.2", - "he": "^1.1.0" - } - }, - "vue-template-es2015-compiler": { - "version": "1.9.1", - "resolved": "https://registry.npm.taobao.org/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.9.1.tgz", - "integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=", - "dev": true - }, - "warning": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/warning/download/warning-3.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwarning%2Fdownload%2Fwarning-3.0.0.tgz", - "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npm.taobao.org/watchpack/download/watchpack-1.6.0.tgz", - "integrity": "sha1-S8EsLr6KonenHx0/FNaFx7RGzQA=", - "dev": true, - "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npm.taobao.org/wbuf/download/wbuf-1.7.3.tgz", - "integrity": "sha1-wdjRSTFtPqhShIiVy2oL/oh7h98=", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/wcwidth/download/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "webpack": { - "version": "4.41.5", - "resolved": "https://registry.npm.taobao.org/webpack/download/webpack-4.41.5.tgz", - "integrity": "sha1-MhDxiGvOUxDmK7lyBNGMJjNBt3w=", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/wasm-edit": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "acorn": "^6.2.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.6.0", - "webpack-sources": "^1.4.1" - }, - "dependencies": { - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-1.4.3.tgz?cache=0&sync_timestamp=1576580692685&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-1.4.3.tgz", - "integrity": "sha1-Xsry29xfuZdF/QZ5H0b8ndscmnw=", - "dev": true, - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^2.1.2", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - } - } - }, - "webpack-bundle-analyzer": { - "version": "3.6.0", - "resolved": "https://registry.npm.taobao.org/webpack-bundle-analyzer/download/webpack-bundle-analyzer-3.6.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-bundle-analyzer%2Fdownload%2Fwebpack-bundle-analyzer-3.6.0.tgz", - "integrity": "sha1-ObOo+CnKBEaCvG+eARyV3rVUrv0=", - "dev": true, - "requires": { - "acorn": "^6.0.7", - "acorn-walk": "^6.1.1", - "bfj": "^6.1.1", - "chalk": "^2.4.1", - "commander": "^2.18.0", - "ejs": "^2.6.1", - "express": "^4.16.3", - "filesize": "^3.6.1", - "gzip-size": "^5.0.0", - "lodash": "^4.17.15", - "mkdirp": "^0.5.1", - "opener": "^1.5.1", - "ws": "^6.0.0" - } - }, - "webpack-chain": { - "version": "6.3.0", - "resolved": "https://registry.npm.taobao.org/webpack-chain/download/webpack-chain-6.3.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-chain%2Fdownload%2Fwebpack-chain-6.3.0.tgz", - "integrity": "sha1-pgmOuJpD2+ZTNTj0ZHsoO5m/Zu0=", - "dev": true, - "requires": { - "deepmerge": "^1.5.2", - "javascript-stringify": "^2.0.1" - } - }, - "webpack-dev-middleware": { - "version": "3.7.2", - "resolved": "https://registry.npm.taobao.org/webpack-dev-middleware/download/webpack-dev-middleware-3.7.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-dev-middleware%2Fdownload%2Fwebpack-dev-middleware-3.7.2.tgz", - "integrity": "sha1-ABnD23FuP6XOy/ZPKriKdLqzMfM=", - "dev": true, - "requires": { - "memory-fs": "^0.4.1", - "mime": "^2.4.4", - "mkdirp": "^0.5.1", - "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" - } - }, - "webpack-dev-server": { - "version": "3.10.1", - "resolved": "https://registry.npm.taobao.org/webpack-dev-server/download/webpack-dev-server-3.10.1.tgz?cache=0&sync_timestamp=1576754491231&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-dev-server%2Fdownload%2Fwebpack-dev-server-3.10.1.tgz", - "integrity": "sha1-H/PlzM+OCJeqP1kJxlTmI/abHA4=", - "dev": true, - "requires": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.8", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.2.1", - "http-proxy-middleware": "0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "is-absolute-url": "^3.0.3", - "killable": "^1.0.1", - "loglevel": "^1.6.6", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.25", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.7", - "semver": "^6.3.0", - "serve-index": "^1.9.1", - "sockjs": "0.3.19", - "sockjs-client": "1.4.0", - "spdy": "^4.0.1", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.2", - "webpack-log": "^2.0.0", - "ws": "^6.2.1", - "yargs": "12.0.5" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/cliui/download/cliui-4.1.0.tgz?cache=0&sync_timestamp=1573942320052&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcliui%2Fdownload%2Fcliui-4.1.0.tgz", - "integrity": "sha1-NIQi2+gtgAswIu709qwQvy5NG0k=", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-4.0.0.tgz?cache=0&sync_timestamp=1573280549549&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz", - "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/get-caller-file/download/get-caller-file-1.0.3.tgz", - "integrity": "sha1-+Xj6TJDR3+f/LWvtoqUV5xO9z0o=", - "dev": true - }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npm.taobao.org/is-absolute-url/download/is-absolute-url-3.0.3.tgz?cache=0&sync_timestamp=1569736493122&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-absolute-url%2Fdownload%2Fis-absolute-url-3.0.3.tgz", - "integrity": "sha1-lsaiK2ojkpsR6gr7GDbDatSl1pg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npm.taobao.org/require-main-filename/download/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz", - "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-2.1.0.tgz?cache=0&sync_timestamp=1573488719878&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwrap-ansi%2Fdownload%2Fwrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npm.taobao.org/yargs/download/yargs-12.0.5.tgz?cache=0&sync_timestamp=1577940973312&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs%2Fdownload%2Fyargs-12.0.5.tgz", - "integrity": "sha1-BfWZe2CWR7ZPZrgeO0sQo2jnrRM=", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-11.1.1.tgz", - "integrity": "sha1-h5oIZZc7yp9rq1y987HGfsfTvPQ=", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/webpack-log/download/webpack-log-2.0.0.tgz?cache=0&sync_timestamp=1564684394562&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-log%2Fdownload%2Fwebpack-log-2.0.0.tgz", - "integrity": "sha1-W3ko4GN1k/EZ0y9iJ8HgrDHhtH8=", - "dev": true, - "requires": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - } - }, - "webpack-merge": { - "version": "4.2.2", - "resolved": "https://registry.npm.taobao.org/webpack-merge/download/webpack-merge-4.2.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-merge%2Fdownload%2Fwebpack-merge-4.2.2.tgz", - "integrity": "sha1-onxS6ng9E5iv0gh/VH17nS9DY00=", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npm.taobao.org/webpack-sources/download/webpack-sources-1.4.3.tgz", - "integrity": "sha1-7t2OwLko+/HL/plOItLYkPMwqTM=", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npm.taobao.org/websocket-driver/download/websocket-driver-0.7.3.tgz", - "integrity": "sha1-otTg1PTxFvHmKX66WLBdQwEA6fk=", - "dev": true, - "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npm.taobao.org/websocket-extensions/download/websocket-extensions-0.1.3.tgz", - "integrity": "sha1-XS/yKXcAPsaHpLhwc9+7rBRszyk=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npm.taobao.org/which/download/which-1.3.1.tgz?cache=0&sync_timestamp=1574116898193&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-1.3.1.tgz", - "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/which-module/download/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npm.taobao.org/word-wrap/download/word-wrap-1.2.3.tgz", - "integrity": "sha1-YQY29rH3A4kb00dxzLF/uTtHB5w=", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npm.taobao.org/wordwrap/download/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npm.taobao.org/worker-farm/download/worker-farm-1.7.0.tgz", - "integrity": "sha1-JqlMU5G7ypJhUgAvabhKS/dy5ag=", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-6.2.0.tgz?cache=0&sync_timestamp=1573488719878&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwrap-ansi%2Fdownload%2Fwrap-ansi-6.2.0.tgz", - "integrity": "sha1-6Tk7oHEC5skaOyIUePAlfNKFblM=", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz", - "integrity": "sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=", - "dev": true - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.2.1.tgz", - "integrity": "sha1-kK51xCTQCNJiTFvynq0xd+v881k=", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz", - "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz", - "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-4.2.0.tgz", - "integrity": "sha1-lSGCxGzHssMT0VluYjmSvRY7crU=", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz?cache=0&sync_timestamp=1573280549549&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-6.0.0.tgz", - "integrity": "sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI=", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npm.taobao.org/wrappy/download/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npm.taobao.org/write/download/write-1.0.3.tgz", - "integrity": "sha1-CADhRSO5I6OH5BUSPIZWFqrg9cM=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npm.taobao.org/ws/download/ws-6.2.1.tgz?cache=0&sync_timestamp=1576314828024&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fws%2Fdownload%2Fws-6.2.1.tgz", - "integrity": "sha1-RC/fCkftZPWbal2P8TD0dI7VJPs=", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npm.taobao.org/xtend/download/xtend-4.0.2.tgz", - "integrity": "sha1-u3J3n1+kZRhrH0OPZ0+jR/2121Q=", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/y18n/download/y18n-4.0.0.tgz", - "integrity": "sha1-le+U+F7MgdAHwmThkKEg8KPIVms=", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-3.1.1.tgz", - "integrity": "sha1-27fa+b/YusmrRev2ArjLrQ1dCP0=", - "dev": true - }, - "yargs": { - "version": "15.1.0", - "resolved": "https://registry.npm.taobao.org/yargs/download/yargs-15.1.0.tgz?cache=0&sync_timestamp=1577940973312&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs%2Fdownload%2Fyargs-15.1.0.tgz", - "integrity": "sha1-4RE4H1gw6GOolVC9SxNrtqXzchk=", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^16.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz", - "integrity": "sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=", - "dev": true - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npm.taobao.org/cliui/download/cliui-6.0.0.tgz?cache=0&sync_timestamp=1573942320052&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcliui%2Fdownload%2Fcliui-6.0.0.tgz", - "integrity": "sha1-UR1wLAxOQcoVbX0OlgIfI+EyJbE=", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz", - "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=", - "dev": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz", - "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz", - "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz", - "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz", - "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-4.2.0.tgz", - "integrity": "sha1-lSGCxGzHssMT0VluYjmSvRY7crU=", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz?cache=0&sync_timestamp=1573280549549&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-6.0.0.tgz", - "integrity": "sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI=", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "yargs-parser": { - "version": "16.1.0", - "resolved": "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-16.1.0.tgz", - "integrity": "sha1-c3R9U64YfnuNvjM/lXFMduoA7PE=", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yorkie": { - "version": "2.0.0", - "resolved": "https://registry.npm.taobao.org/yorkie/download/yorkie-2.0.0.tgz", - "integrity": "sha1-kkEZEtQ1IU4SxRwq4Qk+VLa7g9k=", - "dev": true, - "requires": { - "execa": "^0.8.0", - "is-ci": "^1.0.10", - "normalize-path": "^1.0.0", - "strip-indent": "^2.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-5.1.0.tgz?cache=0&sync_timestamp=1570508303786&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcross-spawn%2Fdownload%2Fcross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.8.0", - "resolved": "https://registry.npm.taobao.org/execa/download/execa-0.8.0.tgz?cache=0&sync_timestamp=1576749001049&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-0.8.0.tgz", - "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-4.1.5.tgz", - "integrity": "sha1-i75Q6oW+1ZvJ4z3KuCNe6bz0Q80=", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "normalize-path": { - "version": "1.0.0", - "resolved": "https://registry.npm.taobao.org/normalize-path/download/normalize-path-1.0.0.tgz", - "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } - } - } -} diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/package.json" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/package.json" deleted file mode 100644 index 37a26a04f169077039f00d25ee899b0178d834c6..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/package.json" +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "antd-demo", - "version": "0.1.0", - "private": true, - "scripts": { - "serve": "vue-cli-service serve", - "build": "vue-cli-service build", - "lint": "vue-cli-service lint" - }, - "dependencies": { - "@antv/g2": "^3.5.11", - "ant-design-vue": "^1.4.10", - "core-js": "^3.4.4", - "vue": "^2.6.10", - "vue-router": "^3.1.3" - }, - "devDependencies": { - "@vue/cli-plugin-babel": "^4.1.0", - "@vue/cli-plugin-eslint": "^4.1.0", - "@vue/cli-service": "^4.1.0", - "babel-eslint": "^10.0.3", - "eslint": "^5.16.0", - "eslint-plugin-vue": "^5.0.0", - "vue-template-compiler": "^2.6.10", - "vuex": "^3.1.2" - }, - "eslintConfig": { - "root": true, - "env": { - "node": true - }, - "extends": [ - "plugin:vue/essential", - "eslint:recommended" - ], - "rules": { - "no-console":"off" - }, - "parserOptions": { - "parser": "babel-eslint" - } - }, - "browserslist": [ - "> 1%", - "last 2 versions" - ] -} diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/public/index.html" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/public/index.html" deleted file mode 100644 index e0e48347ff4b8e19e1e822f36cb6bd3ce781c5db..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/public/index.html" +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - antd-demo - - - -
- - - diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/App.vue" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/App.vue" deleted file mode 100644 index 0885506f535b00e0fd0a083ba13e808a0b72f859..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/App.vue" +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/assets/logo.png" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/assets/logo.png" deleted file mode 100644 index f3d2503fc2a44b5053b0837ebea6e87a2d339a43..0000000000000000000000000000000000000000 Binary files "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/assets/logo.png" and /dev/null differ diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/components/CommentBox.vue" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/components/CommentBox.vue" deleted file mode 100644 index 7609530a9f8593763f3b99fd4dd31759226c8495..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/components/CommentBox.vue" +++ /dev/null @@ -1,58 +0,0 @@ - - diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/components/CommentList.vue" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/components/CommentList.vue" deleted file mode 100644 index d831257e8b26303306bfb4bdbbea80c598be0116..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/components/CommentList.vue" +++ /dev/null @@ -1,155 +0,0 @@ - - - diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/components/HelloWorld.vue" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/components/HelloWorld.vue" deleted file mode 100644 index 879051a29739fdfb17ae82ed23b53fac251c2b7e..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/components/HelloWorld.vue" +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/main.js" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/main.js" deleted file mode 100644 index 213b3050ea3697e5b8d0c491d241c1daad46bcf5..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/main.js" +++ /dev/null @@ -1,19 +0,0 @@ -import Vue from 'vue' -import App from './App.vue' -import store from './store' -import Router from 'vue-router' -import 'ant-design-vue/dist/antd.css'; -import Antd from 'ant-design-vue'; -import router from './router/index.js' - -Vue.use(Router) -Vue.config.productionTip = false - -Vue.use(Antd); - -new Vue({ - render: h => h(App), - router, - //需要将store和vue实例进行关联,这里将其传递进去 - store -}).$mount('#app') diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/router/index.js" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/router/index.js" deleted file mode 100644 index 07038b60c0062d5787c4df987ac7bfa2b6da11b4..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/router/index.js" +++ /dev/null @@ -1,38 +0,0 @@ -import HelloWorld from '../components/HelloWorld' -import index from '../view/index' -import about from '../view/about' -import comment from '../view/comment' -import heatMap from '../view/heatMap' - -import Router from 'vue-router' - -export default new Router({ - routes: [ - - { - path: '/', - name: 'HelloWorld', - component: HelloWorld - }, - { - path: '/index', - name: 'index', - component: index - }, - { - path: '/about', - name: 'about', - component: about - }, - { - path: '/comment', - name: 'comment', - component: comment - }, - { - path: '/heatMap', - name: 'heatMap', - component: heatMap - }, - ] -}) diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/store/app.js" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/store/app.js" deleted file mode 100644 index 66856ef467bd700489a7cdafa09a3ad4fd802964..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/store/app.js" +++ /dev/null @@ -1,38 +0,0 @@ -import {SET_COMMENT_LIST, INCREMENT, DECREMENT} from "./mutation-types"; - -const app = { - // 全局状态 - state: { - commentList: [], - id: 100, - }, - // getters是对数据的包装,例如对数据进行拼接,或者过滤 - getters: { - //类似于计算属性 - getCommentList(state) { - return state.commentList - }, - // 增加的方法 - [INCREMENT](state) { - state.id += 1 - }, - // 减少的方法 - [DECREMENT](state) { - state.id -= 1 - }, - }, - // 如果我们需要更改store中的状态,一定要通过mutations来进行操作 - mutations: { - - // 传入自定义参数 - [SET_COMMENT_LIST](state, commentList) { - state.commentList = commentList - }, - }, - - // actions是我们定义的一些操作,正常情况下,我们很少会直接调用mutation方法来改变state - actions: { - - } -} -export default app diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/store/index.js" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/store/index.js" deleted file mode 100644 index 6f0aa1a3cba8d0ef9069041b29c5c0b4e6c89ed1..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/store/index.js" +++ /dev/null @@ -1,16 +0,0 @@ -import Vue from 'vue' -import Vuex from 'vuex' -import app from './app' - -//让vuex生效 -Vue.use(Vuex) - -const store = new Vuex.Store({ - - // 将app和user放在store中 - modules: { - app - } -}) - -export default store diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/store/mutation-types.js" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/store/mutation-types.js" deleted file mode 100644 index a38fba89ce1c247989e9f550de82cfab67698628..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/store/mutation-types.js" +++ /dev/null @@ -1,3 +0,0 @@ -export const SET_COMMENT_LIST = "setCommentList" -export const INCREMENT = "increment" -export const DECREMENT = "decrement" diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/view/about.vue" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/view/about.vue" deleted file mode 100644 index e6ba8b6035a583a3ca450bdb1c33e5169f3a903b..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/view/about.vue" +++ /dev/null @@ -1,79 +0,0 @@ - - diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/view/comment.vue" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/view/comment.vue" deleted file mode 100644 index 689cb2981ad24b9be50f8779791c7a713f64b7ff..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/view/comment.vue" +++ /dev/null @@ -1,125 +0,0 @@ - - diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/view/heatMap.vue" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/view/heatMap.vue" deleted file mode 100644 index 783875ea228132962bf4c0c984b866250b25d5d5..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/view/heatMap.vue" +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/view/index.vue" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/view/index.vue" deleted file mode 100644 index 689cb2981ad24b9be50f8779791c7a713f64b7ff..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/src/view/index.vue" +++ /dev/null @@ -1,125 +0,0 @@ - - diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/yarn.lock" "b/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/yarn.lock" deleted file mode 100644 index 30a3ed97e195834b930eda8677768f2374ac4e58..0000000000000000000000000000000000000000 --- "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/yarn.lock" +++ /dev/null @@ -1,8640 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@ant-design/colors@^3.1.0": - version "3.2.2" - resolved "https://registry.npm.taobao.org/@ant-design/colors/download/@ant-design/colors-3.2.2.tgz#5ad43d619e911f3488ebac303d606e66a8423903" - integrity sha1-WtQ9YZ6RHzSI66wwPWBuZqhCOQM= - dependencies: - tinycolor2 "^1.4.1" - -"@ant-design/icons-vue@^2.0.0": - version "2.0.0" - resolved "https://registry.npm.taobao.org/@ant-design/icons-vue/download/@ant-design/icons-vue-2.0.0.tgz#0357f5010a404e9f34a87a4b41b2a08df691dbce" - integrity sha1-A1f1AQpATp80qHpLQbKgjfaR284= - dependencies: - "@ant-design/colors" "^3.1.0" - babel-runtime "^6.26.0" - -"@ant-design/icons@^2.1.1": - version "2.1.1" - resolved "https://registry.npm.taobao.org/@ant-design/icons/download/@ant-design/icons-2.1.1.tgz#7b9c08dffd4f5d41db667d9dbe5e0107d0bd9a4a" - integrity sha1-e5wI3/1PXUHbZn2dvl4BB9C9mko= - -"@antv/adjust@~0.1.0": - version "0.1.1" - resolved "https://registry.npm.taobao.org/@antv/adjust/download/@antv/adjust-0.1.1.tgz#e263ab0e1a1941a648842fc086cf65a7e3b75e98" - integrity sha1-4mOrDhoZQaZIhC/Ahs9lp+O3Xpg= - dependencies: - "@antv/util" "~1.3.1" - -"@antv/attr@~0.1.2": - version "0.1.2" - resolved "https://registry.npm.taobao.org/@antv/attr/download/@antv/attr-0.1.2.tgz#2eeb122fcaaf851a2d8749abc7c60519d3f77e37" - integrity sha1-LusSL8qvhRoth0mrx8YFGdP3fjc= - dependencies: - "@antv/util" "~1.3.1" - -"@antv/component@~0.3.3": - version "0.3.8" - resolved "https://registry.npm.taobao.org/@antv/component/download/@antv/component-0.3.8.tgz#677ecd3b5026907d4cb70d9082951d7c3c2b5434" - integrity sha1-Z37NO1AmkH1Mtw2QgpUdfDwrVDQ= - dependencies: - "@antv/attr" "~0.1.2" - "@antv/g" "~3.3.5" - "@antv/util" "~1.3.1" - wolfy87-eventemitter "~5.1.0" - -"@antv/coord@~0.1.0": - version "0.1.0" - resolved "https://registry.npm.taobao.org/@antv/coord/download/@antv/coord-0.1.0.tgz?cache=0&sync_timestamp=1577785100964&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40antv%2Fcoord%2Fdownload%2F%40antv%2Fcoord-0.1.0.tgz#48a80ae36d07552f96657e7f8095227c63f0c0a9" - integrity sha1-SKgK420HVS+WZX5/gJUifGPwwKk= - dependencies: - "@antv/util" "~1.3.1" - -"@antv/g2@^3.5.11": - version "3.5.11" - resolved "https://registry.npm.taobao.org/@antv/g2/download/@antv/g2-3.5.11.tgz#bd17f4911618671f115a249af410d3bb1c932e5e" - integrity sha1-vRf0kRYYZx8RWiSa9BDTuxyTLl4= - dependencies: - "@antv/adjust" "~0.1.0" - "@antv/attr" "~0.1.2" - "@antv/component" "~0.3.3" - "@antv/coord" "~0.1.0" - "@antv/g" "~3.3.6" - "@antv/scale" "~0.1.1" - "@antv/util" "~1.3.1" - venn.js "~0.2.20" - wolfy87-eventemitter "~5.1.0" - -"@antv/g@~3.3.5", "@antv/g@~3.3.6": - version "3.3.6" - resolved "https://registry.npm.taobao.org/@antv/g/download/@antv/g-3.3.6.tgz#11fed9ddc9ed4e5a2aa244b7c8abb982a003f201" - integrity sha1-Ef7Z3cntTloqokS3yKu5gqAD8gE= - dependencies: - "@antv/gl-matrix" "~2.7.1" - "@antv/util" "~1.3.1" - d3-ease "~1.0.3" - d3-interpolate "~1.1.5" - d3-timer "~1.0.6" - wolfy87-eventemitter "~5.1.0" - -"@antv/gl-matrix@^2.7.1", "@antv/gl-matrix@~2.7.1": - version "2.7.1" - resolved "https://registry.npm.taobao.org/@antv/gl-matrix/download/@antv/gl-matrix-2.7.1.tgz#acb8e37f7ab3df01345aba4372d7942be42eba14" - integrity sha1-rLjjf3qz3wE0WrpDcteUK+QuuhQ= - -"@antv/scale@~0.1.1": - version "0.1.3" - resolved "https://registry.npm.taobao.org/@antv/scale/download/@antv/scale-0.1.3.tgz#4876e6140cb7dcda190e7fe2e780882dcac6b09d" - integrity sha1-SHbmFAy33NoZDn/i54CILcrGsJ0= - dependencies: - "@antv/util" "~1.3.1" - fecha "~2.3.3" - -"@antv/util@~1.3.1": - version "1.3.1" - resolved "https://registry.npm.taobao.org/@antv/util/download/@antv/util-1.3.1.tgz#30a34b201ff9126ec0d58c72c8166a9c3e644ccd" - integrity sha1-MKNLIB/5Em7A1YxyyBZqnD5kTM0= - dependencies: - "@antv/gl-matrix" "^2.7.1" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": - version "7.5.5" - resolved "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" - integrity sha1-vAeC9tafe31JUxIZaZuYj2aaj50= - dependencies: - "@babel/highlight" "^7.0.0" - -"@babel/core@^7.7.4": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/core/download/@babel/core-7.7.7.tgz#ee155d2e12300bcc0cff6a8ad46f2af5063803e9" - integrity sha1-7hVdLhIwC8wM/2qK1G8q9QY4A+k= - dependencies: - "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.7" - "@babel/helpers" "^7.7.4" - "@babel/parser" "^7.7.7" - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - convert-source-map "^1.7.0" - debug "^4.1.0" - json5 "^2.1.0" - lodash "^4.17.13" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/generator@^7.7.4", "@babel/generator@^7.7.7": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/generator/download/@babel/generator-7.7.7.tgz#859ac733c44c74148e1a72980a64ec84b85f4f45" - integrity sha1-hZrHM8RMdBSOGnKYCmTshLhfT0U= - dependencies: - "@babel/types" "^7.7.4" - jsesc "^2.5.1" - lodash "^4.17.13" - source-map "^0.5.0" - -"@babel/helper-annotate-as-pure@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-annotate-as-pure/download/@babel/helper-annotate-as-pure-7.7.4.tgz?cache=0&sync_timestamp=1574466005922&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.7.4.tgz#bb3faf1e74b74bd547e867e48f551fa6b098b6ce" - integrity sha1-uz+vHnS3S9VH6Gfkj1UfprCYts4= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-builder-binary-assignment-operator-visitor/download/@babel/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz?cache=0&sync_timestamp=1574465920635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-builder-binary-assignment-operator-visitor%2Fdownload%2F%40babel%2Fhelper-builder-binary-assignment-operator-visitor-7.7.4.tgz#5f73f2b28580e224b5b9bd03146a4015d6217f5f" - integrity sha1-X3PysoWA4iS1ub0DFGpAFdYhf18= - dependencies: - "@babel/helper-explode-assignable-expression" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-call-delegate@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-call-delegate/download/@babel/helper-call-delegate-7.7.4.tgz?cache=0&sync_timestamp=1574465922326&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-call-delegate%2Fdownload%2F%40babel%2Fhelper-call-delegate-7.7.4.tgz#621b83e596722b50c0066f9dc37d3232e461b801" - integrity sha1-YhuD5ZZyK1DABm+dw30yMuRhuAE= - dependencies: - "@babel/helper-hoist-variables" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-create-class-features-plugin@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-create-class-features-plugin/download/@babel/helper-create-class-features-plugin-7.7.4.tgz#fce60939fd50618610942320a8d951b3b639da2d" - integrity sha1-/OYJOf1QYYYQlCMgqNlRs7Y52i0= - dependencies: - "@babel/helper-function-name" "^7.7.4" - "@babel/helper-member-expression-to-functions" "^7.7.4" - "@babel/helper-optimise-call-expression" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.7.4" - "@babel/helper-split-export-declaration" "^7.7.4" - -"@babel/helper-create-regexp-features-plugin@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-create-regexp-features-plugin/download/@babel/helper-create-regexp-features-plugin-7.7.4.tgz#6d5762359fd34f4da1500e4cff9955b5299aaf59" - integrity sha1-bVdiNZ/TT02hUA5M/5lVtSmar1k= - dependencies: - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.6.0" - -"@babel/helper-define-map@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-define-map/download/@babel/helper-define-map-7.7.4.tgz#2841bf92eb8bd9c906851546fe6b9d45e162f176" - integrity sha1-KEG/kuuL2ckGhRVG/mudReFi8XY= - dependencies: - "@babel/helper-function-name" "^7.7.4" - "@babel/types" "^7.7.4" - lodash "^4.17.13" - -"@babel/helper-explode-assignable-expression@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-explode-assignable-expression/download/@babel/helper-explode-assignable-expression-7.7.4.tgz#fa700878e008d85dc51ba43e9fb835cddfe05c84" - integrity sha1-+nAIeOAI2F3FG6Q+n7g1zd/gXIQ= - dependencies: - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-function-name@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-function-name/download/@babel/helper-function-name-7.7.4.tgz?cache=0&sync_timestamp=1574465630791&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.7.4.tgz#ab6e041e7135d436d8f0a3eca15de5b67a341a2e" - integrity sha1-q24EHnE11DbY8KPsoV3ltno0Gi4= - dependencies: - "@babel/helper-get-function-arity" "^7.7.4" - "@babel/template" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-get-function-arity@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-get-function-arity/download/@babel/helper-get-function-arity-7.7.4.tgz#cb46348d2f8808e632f0ab048172130e636005f0" - integrity sha1-y0Y0jS+ICOYy8KsEgXITDmNgBfA= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-hoist-variables@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-hoist-variables/download/@babel/helper-hoist-variables-7.7.4.tgz?cache=0&sync_timestamp=1574466005056&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-hoist-variables%2Fdownload%2F%40babel%2Fhelper-hoist-variables-7.7.4.tgz#612384e3d823fdfaaf9fce31550fe5d4db0f3d12" - integrity sha1-YSOE49gj/fqvn84xVQ/l1NsPPRI= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-member-expression-to-functions@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-member-expression-to-functions/download/@babel/helper-member-expression-to-functions-7.7.4.tgz#356438e2569df7321a8326644d4b790d2122cb74" - integrity sha1-NWQ44lad9zIagyZkTUt5DSEiy3Q= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-module-imports/download/@babel/helper-module-imports-7.7.4.tgz#e5a92529f8888bf319a6376abfbd1cebc491ad91" - integrity sha1-5aklKfiIi/MZpjdqv70c68SRrZE= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-module-transforms@^7.7.4", "@babel/helper-module-transforms@^7.7.5": - version "7.7.5" - resolved "https://registry.npm.taobao.org/@babel/helper-module-transforms/download/@babel/helper-module-transforms-7.7.5.tgz#d044da7ffd91ec967db25cd6748f704b6b244835" - integrity sha1-0ETaf/2R7JZ9slzWdI9wS2skSDU= - dependencies: - "@babel/helper-module-imports" "^7.7.4" - "@babel/helper-simple-access" "^7.7.4" - "@babel/helper-split-export-declaration" "^7.7.4" - "@babel/template" "^7.7.4" - "@babel/types" "^7.7.4" - lodash "^4.17.13" - -"@babel/helper-optimise-call-expression@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-optimise-call-expression/download/@babel/helper-optimise-call-expression-7.7.4.tgz?cache=0&sync_timestamp=1574465630779&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-optimise-call-expression%2Fdownload%2F%40babel%2Fhelper-optimise-call-expression-7.7.4.tgz#034af31370d2995242aa4df402c3b7794b2dcdf2" - integrity sha1-A0rzE3DSmVJCqk30AsO3eUstzfI= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-plugin-utils@^7.0.0": - version "7.0.0" - resolved "https://registry.npm.taobao.org/@babel/helper-plugin-utils/download/@babel/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" - integrity sha1-u7P77phmHFaQNCN8wDlnupm08lA= - -"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": - version "7.5.5" - resolved "https://registry.npm.taobao.org/@babel/helper-regex/download/@babel/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351" - integrity sha1-CqaCT3EAouDonBUnwjk2wVLKs1E= - dependencies: - lodash "^4.17.13" - -"@babel/helper-remap-async-to-generator@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-remap-async-to-generator/download/@babel/helper-remap-async-to-generator-7.7.4.tgz#c68c2407350d9af0e061ed6726afb4fff16d0234" - integrity sha1-xowkBzUNmvDgYe1nJq+0//FtAjQ= - dependencies: - "@babel/helper-annotate-as-pure" "^7.7.4" - "@babel/helper-wrap-function" "^7.7.4" - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-replace-supers@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-replace-supers/download/@babel/helper-replace-supers-7.7.4.tgz?cache=0&sync_timestamp=1574465645820&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-replace-supers%2Fdownload%2F%40babel%2Fhelper-replace-supers-7.7.4.tgz#3c881a6a6a7571275a72d82e6107126ec9e2cdd2" - integrity sha1-PIgaamp1cSdactguYQcSbsnizdI= - dependencies: - "@babel/helper-member-expression-to-functions" "^7.7.4" - "@babel/helper-optimise-call-expression" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-simple-access@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-simple-access/download/@babel/helper-simple-access-7.7.4.tgz#a169a0adb1b5f418cfc19f22586b2ebf58a9a294" - integrity sha1-oWmgrbG19BjPwZ8iWGsuv1ipopQ= - dependencies: - "@babel/template" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-split-export-declaration@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-split-export-declaration/download/@babel/helper-split-export-declaration-7.7.4.tgz#57292af60443c4a3622cf74040ddc28e68336fd8" - integrity sha1-Vykq9gRDxKNiLPdAQN3Cjmgzb9g= - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-wrap-function@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helper-wrap-function/download/@babel/helper-wrap-function-7.7.4.tgz#37ab7fed5150e22d9d7266e830072c0cdd8baace" - integrity sha1-N6t/7VFQ4i2dcmboMAcsDN2Lqs4= - dependencies: - "@babel/helper-function-name" "^7.7.4" - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helpers@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/helpers/download/@babel/helpers-7.7.4.tgz#62c215b9e6c712dadc15a9a0dcab76c92a940302" - integrity sha1-YsIVuebHEtrcFamg3Kt2ySqUAwI= - dependencies: - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/highlight@^7.0.0": - version "7.5.0" - resolved "https://registry.npm.taobao.org/@babel/highlight/download/@babel/highlight-7.5.0.tgz?cache=0&sync_timestamp=1562245140883&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhighlight%2Fdownload%2F%40babel%2Fhighlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" - integrity sha1-VtETEr2SSPphlZHQJHK+boyzJUA= - dependencies: - chalk "^2.0.0" - esutils "^2.0.2" - js-tokens "^4.0.0" - -"@babel/parser@^7.0.0", "@babel/parser@^7.7.4", "@babel/parser@^7.7.7": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/parser/download/@babel/parser-7.7.7.tgz#1b886595419cf92d811316d5b715a53ff38b4937" - integrity sha1-G4hllUGc+S2BExbVtxWlP/OLSTc= - -"@babel/plugin-proposal-async-generator-functions@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-async-generator-functions/download/@babel/plugin-proposal-async-generator-functions-7.7.4.tgz?cache=0&sync_timestamp=1574465892135&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.7.4.tgz#0351c5ac0a9e927845fffd5b82af476947b7ce6d" - integrity sha1-A1HFrAqeknhF//1bgq9HaUe3zm0= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.7.4" - "@babel/plugin-syntax-async-generators" "^7.7.4" - -"@babel/plugin-proposal-class-properties@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-class-properties/download/@babel/plugin-proposal-class-properties-7.7.4.tgz#2f964f0cb18b948450362742e33e15211e77c2ba" - integrity sha1-L5ZPDLGLlIRQNidC4z4VIR53wro= - dependencies: - "@babel/helper-create-class-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-proposal-decorators@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-decorators/download/@babel/plugin-proposal-decorators-7.7.4.tgz?cache=0&sync_timestamp=1574466411881&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-decorators%2Fdownload%2F%40babel%2Fplugin-proposal-decorators-7.7.4.tgz#58c1e21d21ea12f9f5f0a757e46e687b94a7ab2b" - integrity sha1-WMHiHSHqEvn18KdX5G5oe5Snqys= - dependencies: - "@babel/helper-create-class-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-decorators" "^7.7.4" - -"@babel/plugin-proposal-dynamic-import@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-dynamic-import/download/@babel/plugin-proposal-dynamic-import-7.7.4.tgz?cache=0&sync_timestamp=1574465998853&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-dynamic-import%2Fdownload%2F%40babel%2Fplugin-proposal-dynamic-import-7.7.4.tgz#dde64a7f127691758cbfed6cf70de0fa5879d52d" - integrity sha1-3eZKfxJ2kXWMv+1s9w3g+lh51S0= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.7.4" - -"@babel/plugin-proposal-json-strings@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-json-strings/download/@babel/plugin-proposal-json-strings-7.7.4.tgz?cache=0&sync_timestamp=1574466003110&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-json-strings%2Fdownload%2F%40babel%2Fplugin-proposal-json-strings-7.7.4.tgz#7700a6bfda771d8dc81973249eac416c6b4c697d" - integrity sha1-dwCmv9p3HY3IGXMknqxBbGtMaX0= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.7.4" - -"@babel/plugin-proposal-object-rest-spread@^7.7.7": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-object-rest-spread/download/@babel/plugin-proposal-object-rest-spread-7.7.7.tgz?cache=0&sync_timestamp=1576716808008&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-object-rest-spread%2Fdownload%2F%40babel%2Fplugin-proposal-object-rest-spread-7.7.7.tgz#9f27075004ab99be08c5c1bd653a2985813cb370" - integrity sha1-nycHUASrmb4IxcG9ZTophYE8s3A= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.7.4" - -"@babel/plugin-proposal-optional-catch-binding@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-optional-catch-binding/download/@babel/plugin-proposal-optional-catch-binding-7.7.4.tgz?cache=0&sync_timestamp=1574466000999&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-optional-catch-binding%2Fdownload%2F%40babel%2Fplugin-proposal-optional-catch-binding-7.7.4.tgz#ec21e8aeb09ec6711bc0a39ca49520abee1de379" - integrity sha1-7CHorrCexnEbwKOcpJUgq+4d43k= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" - -"@babel/plugin-proposal-unicode-property-regex@^7.7.7": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/plugin-proposal-unicode-property-regex/download/@babel/plugin-proposal-unicode-property-regex-7.7.7.tgz#433fa9dac64f953c12578b29633f456b68831c4e" - integrity sha1-Qz+p2sZPlTwSV4spYz9Fa2iDHE4= - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-async-generators@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-async-generators/download/@babel/plugin-syntax-async-generators-7.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-async-generators%2Fdownload%2F%40babel%2Fplugin-syntax-async-generators-7.7.4.tgz#331aaf310a10c80c44a66b238b6e49132bd3c889" - integrity sha1-MxqvMQoQyAxEpmsji25JEyvTyIk= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-decorators@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-decorators/download/@babel/plugin-syntax-decorators-7.7.4.tgz#3c91cfee2a111663ff3ac21b851140f5a52a4e0b" - integrity sha1-PJHP7ioRFmP/OsIbhRFA9aUqTgs= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-dynamic-import@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-dynamic-import/download/@babel/plugin-syntax-dynamic-import-7.7.4.tgz#29ca3b4415abfe4a5ec381e903862ad1a54c3aec" - integrity sha1-Kco7RBWr/kpew4HpA4Yq0aVMOuw= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-json-strings@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-json-strings/download/@babel/plugin-syntax-json-strings-7.7.4.tgz#86e63f7d2e22f9e27129ac4e83ea989a382e86cc" - integrity sha1-huY/fS4i+eJxKaxOg+qYmjguhsw= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-jsx@^7.2.0", "@babel/plugin-syntax-jsx@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-jsx/download/@babel/plugin-syntax-jsx-7.7.4.tgz?cache=0&sync_timestamp=1574466421110&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-jsx%2Fdownload%2F%40babel%2Fplugin-syntax-jsx-7.7.4.tgz#dab2b56a36fb6c3c222a1fbc71f7bf97f327a9ec" - integrity sha1-2rK1ajb7bDwiKh+8cfe/l/Mnqew= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-object-rest-spread@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-object-rest-spread/download/@babel/plugin-syntax-object-rest-spread-7.7.4.tgz#47cf220d19d6d0d7b154304701f468fc1cc6ff46" - integrity sha1-R88iDRnW0NexVDBHAfRo/BzG/0Y= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-optional-catch-binding/download/@babel/plugin-syntax-optional-catch-binding-7.7.4.tgz#a3e38f59f4b6233867b4a92dcb0ee05b2c334aa6" - integrity sha1-o+OPWfS2IzhntKktyw7gWywzSqY= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-top-level-await@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-syntax-top-level-await/download/@babel/plugin-syntax-top-level-await-7.7.4.tgz#bd7d8fa7b9fee793a36e4027fd6dd1aa32f946da" - integrity sha1-vX2Pp7n+55OjbkAn/W3RqjL5Rto= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-arrow-functions@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-arrow-functions/download/@babel/plugin-transform-arrow-functions-7.7.4.tgz?cache=0&sync_timestamp=1574465864396&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-arrow-functions%2Fdownload%2F%40babel%2Fplugin-transform-arrow-functions-7.7.4.tgz#76309bd578addd8aee3b379d809c802305a98a12" - integrity sha1-djCb1Xit3YruOzedgJyAIwWpihI= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-async-to-generator@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-async-to-generator/download/@babel/plugin-transform-async-to-generator-7.7.4.tgz?cache=0&sync_timestamp=1574465889738&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.7.4.tgz#694cbeae6d613a34ef0292713fa42fb45c4470ba" - integrity sha1-aUy+rm1hOjTvApJxP6QvtFxEcLo= - dependencies: - "@babel/helper-module-imports" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.7.4" - -"@babel/plugin-transform-block-scoped-functions@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoped-functions/download/@babel/plugin-transform-block-scoped-functions-7.7.4.tgz#d0d9d5c269c78eaea76227ace214b8d01e4d837b" - integrity sha1-0NnVwmnHjq6nYies4hS40B5Ng3s= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-block-scoping@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoping/download/@babel/plugin-transform-block-scoping-7.7.4.tgz#200aad0dcd6bb80372f94d9e628ea062c58bf224" - integrity sha1-IAqtDc1ruANy+U2eYo6gYsWL8iQ= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.13" - -"@babel/plugin-transform-classes@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-classes/download/@babel/plugin-transform-classes-7.7.4.tgz#c92c14be0a1399e15df72667067a8f510c9400ec" - integrity sha1-ySwUvgoTmeFd9yZnBnqPUQyUAOw= - dependencies: - "@babel/helper-annotate-as-pure" "^7.7.4" - "@babel/helper-define-map" "^7.7.4" - "@babel/helper-function-name" "^7.7.4" - "@babel/helper-optimise-call-expression" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.7.4" - "@babel/helper-split-export-declaration" "^7.7.4" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-computed-properties/download/@babel/plugin-transform-computed-properties-7.7.4.tgz#e856c1628d3238ffe12d668eb42559f79a81910d" - integrity sha1-6FbBYo0yOP/hLWaOtCVZ95qBkQ0= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-destructuring@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-destructuring/download/@babel/plugin-transform-destructuring-7.7.4.tgz#2b713729e5054a1135097b6a67da1b6fe8789267" - integrity sha1-K3E3KeUFShE1CXtqZ9obb+h4kmc= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-dotall-regex@^7.7.7": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-dotall-regex/download/@babel/plugin-transform-dotall-regex-7.7.7.tgz#3e9713f1b69f339e87fa796b097d73ded16b937b" - integrity sha1-PpcT8bafM56H+nlrCX1z3tFrk3s= - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-duplicate-keys@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-duplicate-keys/download/@babel/plugin-transform-duplicate-keys-7.7.4.tgz#3d21731a42e3f598a73835299dd0169c3b90ac91" - integrity sha1-PSFzGkLj9ZinODUpndAWnDuQrJE= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-exponentiation-operator@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-exponentiation-operator/download/@babel/plugin-transform-exponentiation-operator-7.7.4.tgz#dd30c0191e3a1ba19bcc7e389bdfddc0729d5db9" - integrity sha1-3TDAGR46G6GbzH44m9/dwHKdXbk= - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-for-of@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-for-of/download/@babel/plugin-transform-for-of-7.7.4.tgz#248800e3a5e507b1f103d8b4ca998e77c63932bc" - integrity sha1-JIgA46XlB7HxA9i0ypmOd8Y5Mrw= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-function-name@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-function-name/download/@babel/plugin-transform-function-name-7.7.4.tgz#75a6d3303d50db638ff8b5385d12451c865025b1" - integrity sha1-dabTMD1Q22OP+LU4XRJFHIZQJbE= - dependencies: - "@babel/helper-function-name" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-literals@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-literals/download/@babel/plugin-transform-literals-7.7.4.tgz#27fe87d2b5017a2a5a34d1c41a6b9f6a6262643e" - integrity sha1-J/6H0rUBeipaNNHEGmufamJiZD4= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-member-expression-literals@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-member-expression-literals/download/@babel/plugin-transform-member-expression-literals-7.7.4.tgz#aee127f2f3339fc34ce5e3055d7ffbf7aa26f19a" - integrity sha1-ruEn8vMzn8NM5eMFXX/796om8Zo= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-modules-amd@^7.7.5": - version "7.7.5" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-modules-amd/download/@babel/plugin-transform-modules-amd-7.7.5.tgz#39e0fb717224b59475b306402bb8eedab01e729c" - integrity sha1-OeD7cXIktZR1swZAK7ju2rAecpw= - dependencies: - "@babel/helper-module-transforms" "^7.7.5" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-commonjs@^7.7.5": - version "7.7.5" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-modules-commonjs/download/@babel/plugin-transform-modules-commonjs-7.7.5.tgz#1d27f5eb0bcf7543e774950e5b2fa782e637b345" - integrity sha1-HSf16wvPdUPndJUOWy+nguY3s0U= - dependencies: - "@babel/helper-module-transforms" "^7.7.5" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.7.4" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-systemjs@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-modules-systemjs/download/@babel/plugin-transform-modules-systemjs-7.7.4.tgz#cd98152339d3e763dfe838b7d4273edaf520bb30" - integrity sha1-zZgVIznT52Pf6Di31Cc+2vUguzA= - dependencies: - "@babel/helper-hoist-variables" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-umd@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-modules-umd/download/@babel/plugin-transform-modules-umd-7.7.4.tgz#1027c355a118de0aae9fee00ad7813c584d9061f" - integrity sha1-ECfDVaEY3gqun+4ArXgTxYTZBh8= - dependencies: - "@babel/helper-module-transforms" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-named-capturing-groups-regex/download/@babel/plugin-transform-named-capturing-groups-regex-7.7.4.tgz?cache=0&sync_timestamp=1574465998388&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.7.4.tgz#fb3bcc4ee4198e7385805007373d6b6f42c98220" - integrity sha1-+zvMTuQZjnOFgFAHNz1rb0LJgiA= - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.4" - -"@babel/plugin-transform-new-target@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-new-target/download/@babel/plugin-transform-new-target-7.7.4.tgz#4a0753d2d60639437be07b592a9e58ee00720167" - integrity sha1-SgdT0tYGOUN74HtZKp5Y7gByAWc= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-object-super@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-object-super/download/@babel/plugin-transform-object-super-7.7.4.tgz#48488937a2d586c0148451bf51af9d7dda567262" - integrity sha1-SEiJN6LVhsAUhFG/Ua+dfdpWcmI= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.7.4" - -"@babel/plugin-transform-parameters@^7.7.7": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-parameters/download/@babel/plugin-transform-parameters-7.7.7.tgz#7a884b2460164dc5f194f668332736584c760007" - integrity sha1-eohLJGAWTcXxlPZoMyc2WEx2AAc= - dependencies: - "@babel/helper-call-delegate" "^7.7.4" - "@babel/helper-get-function-arity" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-property-literals@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-property-literals/download/@babel/plugin-transform-property-literals-7.7.4.tgz#2388d6505ef89b266103f450f9167e6bd73f98c2" - integrity sha1-I4jWUF74myZhA/RQ+RZ+a9c/mMI= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-regenerator@^7.7.5": - version "7.7.5" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-regenerator/download/@babel/plugin-transform-regenerator-7.7.5.tgz#3a8757ee1a2780f390e89f246065ecf59c26fce9" - integrity sha1-OodX7hongPOQ6J8kYGXs9Zwm/Ok= - dependencies: - regenerator-transform "^0.14.0" - -"@babel/plugin-transform-reserved-words@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-reserved-words/download/@babel/plugin-transform-reserved-words-7.7.4.tgz#6a7cf123ad175bb5c69aec8f6f0770387ed3f1eb" - integrity sha1-anzxI60XW7XGmuyPbwdwOH7T8es= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-runtime@^7.7.4": - version "7.7.6" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-runtime/download/@babel/plugin-transform-runtime-7.7.6.tgz#4f2b548c88922fb98ec1c242afd4733ee3e12f61" - integrity sha1-TytUjIiSL7mOwcJCr9RzPuPhL2E= - dependencies: - "@babel/helper-module-imports" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - resolve "^1.8.1" - semver "^5.5.1" - -"@babel/plugin-transform-shorthand-properties@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-shorthand-properties/download/@babel/plugin-transform-shorthand-properties-7.7.4.tgz#74a0a9b2f6d67a684c6fbfd5f0458eb7ba99891e" - integrity sha1-dKCpsvbWemhMb7/V8EWOt7qZiR4= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-spread@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-spread/download/@babel/plugin-transform-spread-7.7.4.tgz#aa673b356fe6b7e70d69b6e33a17fef641008578" - integrity sha1-qmc7NW/mt+cNabbjOhf+9kEAhXg= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-sticky-regex@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-sticky-regex/download/@babel/plugin-transform-sticky-regex-7.7.4.tgz#ffb68c05090c30732076b1285dc1401b404a123c" - integrity sha1-/7aMBQkMMHMgdrEoXcFAG0BKEjw= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" - -"@babel/plugin-transform-template-literals@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-template-literals/download/@babel/plugin-transform-template-literals-7.7.4.tgz#1eb6411736dd3fe87dbd20cc6668e5121c17d604" - integrity sha1-HrZBFzbdP+h9vSDMZmjlEhwX1gQ= - dependencies: - "@babel/helper-annotate-as-pure" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-typeof-symbol@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-typeof-symbol/download/@babel/plugin-transform-typeof-symbol-7.7.4.tgz#3174626214f2d6de322882e498a38e8371b2140e" - integrity sha1-MXRiYhTy1t4yKILkmKOOg3GyFA4= - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-unicode-regex@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/plugin-transform-unicode-regex/download/@babel/plugin-transform-unicode-regex-7.7.4.tgz?cache=0&sync_timestamp=1574465997106&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.7.4.tgz#a3c0f65b117c4c81c5b6484f2a5e7b95346b83ae" - integrity sha1-o8D2WxF8TIHFtkhPKl57lTRrg64= - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/preset-env@^7.7.4": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/preset-env/download/@babel/preset-env-7.7.7.tgz#c294167b91e53e7e36d820e943ece8d0c7fe46ac" - integrity sha1-wpQWe5HlPn422CDpQ+zo0Mf+Rqw= - dependencies: - "@babel/helper-module-imports" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.7.4" - "@babel/plugin-proposal-dynamic-import" "^7.7.4" - "@babel/plugin-proposal-json-strings" "^7.7.4" - "@babel/plugin-proposal-object-rest-spread" "^7.7.7" - "@babel/plugin-proposal-optional-catch-binding" "^7.7.4" - "@babel/plugin-proposal-unicode-property-regex" "^7.7.7" - "@babel/plugin-syntax-async-generators" "^7.7.4" - "@babel/plugin-syntax-dynamic-import" "^7.7.4" - "@babel/plugin-syntax-json-strings" "^7.7.4" - "@babel/plugin-syntax-object-rest-spread" "^7.7.4" - "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" - "@babel/plugin-syntax-top-level-await" "^7.7.4" - "@babel/plugin-transform-arrow-functions" "^7.7.4" - "@babel/plugin-transform-async-to-generator" "^7.7.4" - "@babel/plugin-transform-block-scoped-functions" "^7.7.4" - "@babel/plugin-transform-block-scoping" "^7.7.4" - "@babel/plugin-transform-classes" "^7.7.4" - "@babel/plugin-transform-computed-properties" "^7.7.4" - "@babel/plugin-transform-destructuring" "^7.7.4" - "@babel/plugin-transform-dotall-regex" "^7.7.7" - "@babel/plugin-transform-duplicate-keys" "^7.7.4" - "@babel/plugin-transform-exponentiation-operator" "^7.7.4" - "@babel/plugin-transform-for-of" "^7.7.4" - "@babel/plugin-transform-function-name" "^7.7.4" - "@babel/plugin-transform-literals" "^7.7.4" - "@babel/plugin-transform-member-expression-literals" "^7.7.4" - "@babel/plugin-transform-modules-amd" "^7.7.5" - "@babel/plugin-transform-modules-commonjs" "^7.7.5" - "@babel/plugin-transform-modules-systemjs" "^7.7.4" - "@babel/plugin-transform-modules-umd" "^7.7.4" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.7.4" - "@babel/plugin-transform-new-target" "^7.7.4" - "@babel/plugin-transform-object-super" "^7.7.4" - "@babel/plugin-transform-parameters" "^7.7.7" - "@babel/plugin-transform-property-literals" "^7.7.4" - "@babel/plugin-transform-regenerator" "^7.7.5" - "@babel/plugin-transform-reserved-words" "^7.7.4" - "@babel/plugin-transform-shorthand-properties" "^7.7.4" - "@babel/plugin-transform-spread" "^7.7.4" - "@babel/plugin-transform-sticky-regex" "^7.7.4" - "@babel/plugin-transform-template-literals" "^7.7.4" - "@babel/plugin-transform-typeof-symbol" "^7.7.4" - "@babel/plugin-transform-unicode-regex" "^7.7.4" - "@babel/types" "^7.7.4" - browserslist "^4.6.0" - core-js-compat "^3.6.0" - invariant "^2.2.2" - js-levenshtein "^1.1.3" - semver "^5.5.0" - -"@babel/runtime@^7.7.4": - version "7.7.7" - resolved "https://registry.npm.taobao.org/@babel/runtime/download/@babel/runtime-7.7.7.tgz#194769ca8d6d7790ec23605af9ee3e42a0aa79cf" - integrity sha1-GUdpyo1td5DsI2Ba+e4+QqCqec8= - dependencies: - regenerator-runtime "^0.13.2" - -"@babel/template@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/template/download/@babel/template-7.7.4.tgz?cache=0&sync_timestamp=1574465630781&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftemplate%2Fdownload%2F%40babel%2Ftemplate-7.7.4.tgz#428a7d9eecffe27deac0a98e23bf8e3675d2a77b" - integrity sha1-Qop9nuz/4n3qwKmOI7+ONnXSp3s= - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/traverse@^7.0.0", "@babel/traverse@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/traverse/download/@babel/traverse-7.7.4.tgz?cache=0&sync_timestamp=1574465640801&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftraverse%2Fdownload%2F%40babel%2Ftraverse-7.7.4.tgz#9c1e7c60fb679fe4fcfaa42500833333c2058558" - integrity sha1-nB58YPtnn+T8+qQlAIMzM8IFhVg= - dependencies: - "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.4" - "@babel/helper-function-name" "^7.7.4" - "@babel/helper-split-export-declaration" "^7.7.4" - "@babel/parser" "^7.7.4" - "@babel/types" "^7.7.4" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.13" - -"@babel/types@^7.0.0", "@babel/types@^7.7.4": - version "7.7.4" - resolved "https://registry.npm.taobao.org/@babel/types/download/@babel/types-7.7.4.tgz?cache=0&sync_timestamp=1574465636802&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.7.4.tgz#516570d539e44ddf308c07569c258ff94fde9193" - integrity sha1-UWVw1TnkTd8wjAdWnCWP+U/ekZM= - dependencies: - esutils "^2.0.2" - lodash "^4.17.13" - to-fast-properties "^2.0.0" - -"@hapi/address@2.x.x": - version "2.1.4" - resolved "https://registry.npm.taobao.org/@hapi/address/download/@hapi/address-2.1.4.tgz?cache=0&sync_timestamp=1573979090690&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40hapi%2Faddress%2Fdownload%2F%40hapi%2Faddress-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" - integrity sha1-XWftQ/P9QaadS5/3tW58DR0KgeU= - -"@hapi/bourne@1.x.x": - version "1.3.2" - resolved "https://registry.npm.taobao.org/@hapi/bourne/download/@hapi/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" - integrity sha1-CnCVreoGckPOMoPhtWuKj0U7JCo= - -"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": - version "8.5.0" - resolved "https://registry.npm.taobao.org/@hapi/hoek/download/@hapi/hoek-8.5.0.tgz#2f9ce301c8898e1c3248b0a8564696b24d1a9a5a" - integrity sha1-L5zjAciJjhwySLCoVkaWsk0amlo= - -"@hapi/joi@^15.0.1": - version "15.1.1" - resolved "https://registry.npm.taobao.org/@hapi/joi/download/@hapi/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" - integrity sha1-xnW4pxKW8Cgz+NbSQ7NMV7jOGdc= - dependencies: - "@hapi/address" "2.x.x" - "@hapi/bourne" "1.x.x" - "@hapi/hoek" "8.x.x" - "@hapi/topo" "3.x.x" - -"@hapi/topo@3.x.x": - version "3.1.6" - resolved "https://registry.npm.taobao.org/@hapi/topo/download/@hapi/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" - integrity sha1-aNk1+j6uf91asNf5U/MgXYsr/Ck= - dependencies: - "@hapi/hoek" "^8.3.0" - -"@intervolga/optimize-cssnano-plugin@^1.0.5": - version "1.0.6" - resolved "https://registry.npm.taobao.org/@intervolga/optimize-cssnano-plugin/download/@intervolga/optimize-cssnano-plugin-1.0.6.tgz#be7c7846128b88f6a9b1d1261a0ad06eb5c0fdf8" - integrity sha1-vnx4RhKLiPapsdEmGgrQbrXA/fg= - dependencies: - cssnano "^4.0.0" - cssnano-preset-default "^4.0.0" - postcss "^7.0.0" - -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.npm.taobao.org/@mrmlnc/readdir-enhanced/download/@mrmlnc/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - integrity sha1-UkryQNGjYFJ7cwR17PoTRKpUDd4= - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" - integrity sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs= - -"@soda/friendly-errors-webpack-plugin@^1.7.1": - version "1.7.1" - resolved "https://registry.npm.taobao.org/@soda/friendly-errors-webpack-plugin/download/@soda/friendly-errors-webpack-plugin-1.7.1.tgz#706f64bcb4a8b9642b48ae3ace444c70334d615d" - integrity sha1-cG9kvLSouWQrSK46zkRMcDNNYV0= - dependencies: - chalk "^1.1.3" - error-stack-parser "^2.0.0" - string-width "^2.0.0" - -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.npm.taobao.org/@types/color-name/download/@types/color-name-1.1.1.tgz?cache=0&sync_timestamp=1572460951965&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fcolor-name%2Fdownload%2F%40types%2Fcolor-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha1-HBJhu+qhCoBVu8XYq4S3sq/IRqA= - -"@types/events@*": - version "3.0.0" - resolved "https://registry.npm.taobao.org/@types/events/download/@types/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" - integrity sha1-KGLz9Yqaf3w+eNefEw3U1xwlwqc= - -"@types/glob@^7.1.1": - version "7.1.1" - resolved "https://registry.npm.taobao.org/@types/glob/download/@types/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" - integrity sha1-qlmhxuP7xCHgfM0xqUTDDrpSFXU= - dependencies: - "@types/events" "*" - "@types/minimatch" "*" - "@types/node" "*" - -"@types/minimatch@*": - version "3.0.3" - resolved "https://registry.npm.taobao.org/@types/minimatch/download/@types/minimatch-3.0.3.tgz?cache=0&sync_timestamp=1572463171410&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fminimatch%2Fdownload%2F%40types%2Fminimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha1-PcoOPzOyAPx9ETnAzZbBJoyt/Z0= - -"@types/node@*": - version "13.1.2" - resolved "https://registry.npm.taobao.org/@types/node/download/@types/node-13.1.2.tgz?cache=0&sync_timestamp=1577727780099&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-13.1.2.tgz#fe94285bf5e0782e1a9e5a8c482b1c34465fa385" - integrity sha1-/pQoW/XgeC4anlqMSCscNEZfo4U= - -"@types/normalize-package-data@^2.4.0": - version "2.4.0" - resolved "https://registry.npm.taobao.org/@types/normalize-package-data/download/@types/normalize-package-data-2.4.0.tgz?cache=0&sync_timestamp=1572463173738&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnormalize-package-data%2Fdownload%2F%40types%2Fnormalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" - integrity sha1-5IbQ2XOW15vu3QpuM/RTT/a0lz4= - -"@types/q@^1.5.1": - version "1.5.2" - resolved "https://registry.npm.taobao.org/@types/q/download/@types/q-1.5.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fq%2Fdownload%2F%40types%2Fq-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" - integrity sha1-aQoUdbhPKohP0HzXl8APXzE1bqg= - -"@vue/babel-helper-vue-jsx-merge-props@^1.0.0": - version "1.0.0" - resolved "https://registry.npm.taobao.org/@vue/babel-helper-vue-jsx-merge-props/download/@vue/babel-helper-vue-jsx-merge-props-1.0.0.tgz#048fe579958da408fb7a8b2a3ec050b50a661040" - integrity sha1-BI/leZWNpAj7eosqPsBQtQpmEEA= - -"@vue/babel-plugin-transform-vue-jsx@^1.1.2": - version "1.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-plugin-transform-vue-jsx/download/@vue/babel-plugin-transform-vue-jsx-1.1.2.tgz#c0a3e6efc022e75e4247b448a8fc6b86f03e91c0" - integrity sha1-wKPm78Ai515CR7RIqPxrhvA+kcA= - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" - html-tags "^2.0.0" - lodash.kebabcase "^4.1.1" - svg-tags "^1.0.0" - -"@vue/babel-preset-app@^4.1.2": - version "4.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-preset-app/download/@vue/babel-preset-app-4.1.2.tgz?cache=0&sync_timestamp=1577537773193&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-preset-app%2Fdownload%2F%40vue%2Fbabel-preset-app-4.1.2.tgz#dc52559b3fc34c2f444dabb8e3bb0aa03840e8db" - integrity sha1-3FJVmz/DTC9ETau447sKoDhA6Ns= - dependencies: - "@babel/core" "^7.7.4" - "@babel/helper-module-imports" "^7.7.4" - "@babel/plugin-proposal-class-properties" "^7.7.4" - "@babel/plugin-proposal-decorators" "^7.7.4" - "@babel/plugin-syntax-dynamic-import" "^7.7.4" - "@babel/plugin-syntax-jsx" "^7.7.4" - "@babel/plugin-transform-runtime" "^7.7.4" - "@babel/preset-env" "^7.7.4" - "@babel/runtime" "^7.7.4" - "@vue/babel-preset-jsx" "^1.1.2" - babel-plugin-dynamic-import-node "^2.2.0" - core-js "^3.4.4" - core-js-compat "^3.4.4" - -"@vue/babel-preset-jsx@^1.1.2": - version "1.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-preset-jsx/download/@vue/babel-preset-jsx-1.1.2.tgz?cache=0&sync_timestamp=1573270721644&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-preset-jsx%2Fdownload%2F%40vue%2Fbabel-preset-jsx-1.1.2.tgz#2e169eb4c204ea37ca66c2ea85a880bfc99d4f20" - integrity sha1-LhaetMIE6jfKZsLqhaiAv8mdTyA= - dependencies: - "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" - "@vue/babel-plugin-transform-vue-jsx" "^1.1.2" - "@vue/babel-sugar-functional-vue" "^1.1.2" - "@vue/babel-sugar-inject-h" "^1.1.2" - "@vue/babel-sugar-v-model" "^1.1.2" - "@vue/babel-sugar-v-on" "^1.1.2" - -"@vue/babel-sugar-functional-vue@^1.1.2": - version "1.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-sugar-functional-vue/download/@vue/babel-sugar-functional-vue-1.1.2.tgz#f7e24fba09e6f1ee70104560a8808057555f1a9a" - integrity sha1-9+JPugnm8e5wEEVgqICAV1VfGpo= - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - -"@vue/babel-sugar-inject-h@^1.1.2": - version "1.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-sugar-inject-h/download/@vue/babel-sugar-inject-h-1.1.2.tgz#8a5276b6d8e2ed16ffc8078aad94236274e6edf0" - integrity sha1-ilJ2ttji7Rb/yAeKrZQjYnTm7fA= - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - -"@vue/babel-sugar-v-model@^1.1.2": - version "1.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-sugar-v-model/download/@vue/babel-sugar-v-model-1.1.2.tgz#1ff6fd1b800223fc9cb1e84dceb5e52d737a8192" - integrity sha1-H/b9G4ACI/ycsehNzrXlLXN6gZI= - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" - "@vue/babel-plugin-transform-vue-jsx" "^1.1.2" - camelcase "^5.0.0" - html-tags "^2.0.0" - svg-tags "^1.0.0" - -"@vue/babel-sugar-v-on@^1.1.2": - version "1.1.2" - resolved "https://registry.npm.taobao.org/@vue/babel-sugar-v-on/download/@vue/babel-sugar-v-on-1.1.2.tgz?cache=0&sync_timestamp=1573270721318&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-sugar-v-on%2Fdownload%2F%40vue%2Fbabel-sugar-v-on-1.1.2.tgz#b2ef99b8f2fab09fbead25aad70ef42e1cf5b13b" - integrity sha1-su+ZuPL6sJ++rSWq1w70Lhz1sTs= - dependencies: - "@babel/plugin-syntax-jsx" "^7.2.0" - "@vue/babel-plugin-transform-vue-jsx" "^1.1.2" - camelcase "^5.0.0" - -"@vue/cli-overlay@^4.1.2": - version "4.1.2" - resolved "https://registry.npm.taobao.org/@vue/cli-overlay/download/@vue/cli-overlay-4.1.2.tgz#d5da88139a522d98a60edcc6f61c0a06cdfa97f1" - integrity sha1-1dqIE5pSLZimDtzG9hwKBs36l/E= - -"@vue/cli-plugin-babel@^4.1.0": - version "4.1.2" - resolved "https://registry.npm.taobao.org/@vue/cli-plugin-babel/download/@vue/cli-plugin-babel-4.1.2.tgz?cache=0&sync_timestamp=1577537783017&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-plugin-babel%2Fdownload%2F%40vue%2Fcli-plugin-babel-4.1.2.tgz#b03880617727fe786b28cef43ef53d47b83b0c28" - integrity sha1-sDiAYXcn/nhrKM70PvU9R7g7DCg= - dependencies: - "@babel/core" "^7.7.4" - "@vue/babel-preset-app" "^4.1.2" - "@vue/cli-shared-utils" "^4.1.2" - babel-loader "^8.0.6" - cache-loader "^4.1.0" - thread-loader "^2.1.3" - webpack "^4.0.0" - -"@vue/cli-plugin-eslint@^4.1.0": - version "4.1.2" - resolved "https://registry.npm.taobao.org/@vue/cli-plugin-eslint/download/@vue/cli-plugin-eslint-4.1.2.tgz?cache=0&sync_timestamp=1577537782821&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-plugin-eslint%2Fdownload%2F%40vue%2Fcli-plugin-eslint-4.1.2.tgz#173d2a40beb7debc03a217db3bb4c67cbf255bd6" - integrity sha1-Fz0qQL633rwDohfbO7TGfL8lW9Y= - dependencies: - "@vue/cli-shared-utils" "^4.1.2" - eslint-loader "^2.1.2" - globby "^9.2.0" - webpack "^4.0.0" - yorkie "^2.0.0" - -"@vue/cli-plugin-router@^4.1.2": - version "4.1.2" - resolved "https://registry.npm.taobao.org/@vue/cli-plugin-router/download/@vue/cli-plugin-router-4.1.2.tgz#dc0fddfa4b8812f8a81746ac5beffb9168dcc81f" - integrity sha1-3A/d+kuIEvioF0asW+/7kWjcyB8= - dependencies: - "@vue/cli-shared-utils" "^4.1.2" - -"@vue/cli-plugin-vuex@^4.1.2": - version "4.1.2" - resolved "https://registry.npm.taobao.org/@vue/cli-plugin-vuex/download/@vue/cli-plugin-vuex-4.1.2.tgz#5e728b56ad9de2f062a8944f838affa0297ccb99" - integrity sha1-XnKLVq2d4vBiqJRPg4r/oCl8y5k= - -"@vue/cli-service@^4.1.0": - version "4.1.2" - resolved "https://registry.npm.taobao.org/@vue/cli-service/download/@vue/cli-service-4.1.2.tgz?cache=0&sync_timestamp=1577537787566&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-service%2Fdownload%2F%40vue%2Fcli-service-4.1.2.tgz#005f1dbd4626237eec79b256f3d928081884c325" - integrity sha1-AF8dvUYmI37sebJW89koCBiEwyU= - dependencies: - "@intervolga/optimize-cssnano-plugin" "^1.0.5" - "@soda/friendly-errors-webpack-plugin" "^1.7.1" - "@vue/cli-overlay" "^4.1.2" - "@vue/cli-plugin-router" "^4.1.2" - "@vue/cli-plugin-vuex" "^4.1.2" - "@vue/cli-shared-utils" "^4.1.2" - "@vue/component-compiler-utils" "^3.0.2" - "@vue/preload-webpack-plugin" "^1.1.0" - "@vue/web-component-wrapper" "^1.2.0" - acorn "^6.1.1" - acorn-walk "^6.1.1" - address "^1.1.2" - autoprefixer "^9.7.2" - browserslist "^4.7.3" - cache-loader "^4.1.0" - case-sensitive-paths-webpack-plugin "^2.2.0" - cli-highlight "^2.1.4" - clipboardy "^2.0.0" - cliui "^5.0.0" - copy-webpack-plugin "^5.0.5" - css-loader "^3.1.0" - cssnano "^4.1.10" - current-script-polyfill "^1.0.0" - debug "^4.1.1" - default-gateway "^5.0.5" - dotenv "^8.2.0" - dotenv-expand "^5.1.0" - file-loader "^4.2.0" - fs-extra "^7.0.1" - globby "^9.2.0" - hash-sum "^1.0.2" - html-webpack-plugin "^3.2.0" - launch-editor-middleware "^2.2.1" - lodash.defaultsdeep "^4.6.1" - lodash.mapvalues "^4.6.0" - lodash.transform "^4.6.0" - mini-css-extract-plugin "^0.8.0" - minimist "^1.2.0" - portfinder "^1.0.25" - postcss-loader "^3.0.0" - read-pkg "^5.1.1" - ssri "^7.1.0" - terser-webpack-plugin "^2.2.1" - thread-loader "^2.1.3" - url-loader "^2.2.0" - vue-loader "^15.7.2" - vue-style-loader "^4.1.0" - webpack "^4.0.0" - webpack-bundle-analyzer "^3.6.0" - webpack-chain "^6.0.0" - webpack-dev-server "^3.9.0" - webpack-merge "^4.2.2" - -"@vue/cli-shared-utils@^4.1.2": - version "4.1.2" - resolved "https://registry.npm.taobao.org/@vue/cli-shared-utils/download/@vue/cli-shared-utils-4.1.2.tgz?cache=0&sync_timestamp=1577537777874&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-shared-utils%2Fdownload%2F%40vue%2Fcli-shared-utils-4.1.2.tgz#d33984c8790ad869ef77f5229abd3e8e584fe58b" - integrity sha1-0zmEyHkK2Gnvd/Uimr0+jlhP5Ys= - dependencies: - "@hapi/joi" "^15.0.1" - chalk "^2.4.2" - execa "^1.0.0" - launch-editor "^2.2.1" - lru-cache "^5.1.1" - node-ipc "^9.1.1" - open "^6.3.0" - ora "^3.4.0" - request "^2.87.0" - request-promise-native "^1.0.8" - semver "^6.1.0" - strip-ansi "^6.0.0" - -"@vue/component-compiler-utils@^3.0.2", "@vue/component-compiler-utils@^3.1.0": - version "3.1.0" - resolved "https://registry.npm.taobao.org/@vue/component-compiler-utils/download/@vue/component-compiler-utils-3.1.0.tgz#64cd394925f5af1f9c3228c66e954536f5311857" - integrity sha1-ZM05SSX1rx+cMijGbpVFNvUxGFc= - dependencies: - consolidate "^0.15.1" - hash-sum "^1.0.2" - lru-cache "^4.1.2" - merge-source-map "^1.1.0" - postcss "^7.0.14" - postcss-selector-parser "^5.0.0" - prettier "^1.18.2" - source-map "~0.6.1" - vue-template-es2015-compiler "^1.9.0" - -"@vue/preload-webpack-plugin@^1.1.0": - version "1.1.1" - resolved "https://registry.npm.taobao.org/@vue/preload-webpack-plugin/download/@vue/preload-webpack-plugin-1.1.1.tgz#18723530d304f443021da2292d6ec9502826104a" - integrity sha1-GHI1MNME9EMCHaIpLW7JUCgmEEo= - -"@vue/web-component-wrapper@^1.2.0": - version "1.2.0" - resolved "https://registry.npm.taobao.org/@vue/web-component-wrapper/download/@vue/web-component-wrapper-1.2.0.tgz#bb0e46f1585a7e289b4ee6067dcc5a6ae62f1dd1" - integrity sha1-uw5G8VhafiibTuYGfcxaauYvHdE= - -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/ast/download/@webassemblyjs/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha1-UbHF/mV2o0lTv0slPfnw1JDZ41k= - dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/floating-point-hex-parser/download/@webassemblyjs/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha1-G6kmopI2E+3OSW/VsC6M6KX0lyE= - -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-api-error/download/@webassemblyjs/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha1-xJ2tIvZFInxe22EL25aX8aq3Ifc= - -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-buffer/download/@webassemblyjs/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha1-/qk+Qphj3V5DOFVfQikjhaZT8gQ= - -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-code-frame/download/@webassemblyjs/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha1-mnQP9I4/qjAisd/1RCPfmqKTwl4= - dependencies: - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-fsm/download/@webassemblyjs/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha1-ugt9Oz9+RzPaYFnJMyJ12GBwJFI= - -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-module-context/download/@webassemblyjs/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha1-3vS5knsBAdyMu9jR7bW3ucguskU= - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-wasm-bytecode/download/@webassemblyjs/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha1-U3p1Dt31weky83RCBlUckcG5PmE= - -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/helper-wasm-section/download/@webassemblyjs/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha1-dMpqa8vhnlCjtrRihH5pUD5r/L8= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/ieee754/download/@webassemblyjs/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha1-cSMp2+8kDza/V70ve4+5v0FUQh4= - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/leb128/download/@webassemblyjs/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha1-BE7es06mefPgTNT9mCTV41dnrhA= - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/utf8/download/@webassemblyjs/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha1-qL87XY/+mGx8Hjc8y9wqCRXwztw= - -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/wasm-edit/download/@webassemblyjs/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha1-li2hKqWswcExyBxCMpkcgs5W4Bo= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/wasm-gen/download/@webassemblyjs/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha1-VIQHZsLBAC62TtGr5yCt7XFPmLw= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/wasm-opt/download/@webassemblyjs/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha1-sk2fa6UDlK8TSfUQr6j/y4pj0mQ= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/wasm-parser/download/@webassemblyjs/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha1-IVdvDsiLkUJzV7hTY4NmjvfGa40= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/wast-parser/download/@webassemblyjs/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha1-4Q7s1ULQ5705T2gnxJ899tTu+4w= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.npm.taobao.org/@webassemblyjs/wast-printer/download/@webassemblyjs/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha1-EUu8SB/RDKDiOzVg+oEnSLC65bw= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - "@xtuc/long" "4.2.2" - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.npm.taobao.org/@xtuc/ieee754/download/@xtuc/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha1-7vAUoxRa5Hehy8AM0eVSM23Ot5A= - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.npm.taobao.org/@xtuc/long/download/@xtuc/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha1-0pHGpOl5ibXGHZrPOWrk/hM6cY0= - -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha1-UxvHJlF6OytB+FACHGzBXqq1B80= - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn-jsx@^5.0.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/acorn-jsx/download/acorn-jsx-5.1.0.tgz?cache=0&sync_timestamp=1570991888898&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Facorn-jsx%2Fdownload%2Facorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384" - integrity sha1-KUrbcbVzmLBoABXwo4xWPuHbU4Q= - -acorn-walk@^6.1.1: - version "6.2.0" - resolved "https://registry.npm.taobao.org/acorn-walk/download/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" - integrity sha1-Ejy487hMIXHx9/slJhWxx4prGow= - -acorn@^6.0.2, acorn@^6.0.7, acorn@^6.1.1, acorn@^6.2.1: - version "6.4.0" - resolved "https://registry.npm.taobao.org/acorn/download/acorn-6.4.0.tgz?cache=0&sync_timestamp=1574806921127&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Facorn%2Fdownload%2Facorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" - integrity sha1-tlnS/7r6JLr12xzbsslKmD7NJ4Q= - -add-dom-event-listener@^1.0.2: - version "1.1.0" - resolved "https://registry.npm.taobao.org/add-dom-event-listener/download/add-dom-event-listener-1.1.0.tgz#6a92db3a0dd0abc254e095c0f1dc14acbbaae310" - integrity sha1-apLbOg3Qq8JU4JXA8dwUrLuq4xA= - dependencies: - object-assign "4.x" - -address@^1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/address/download/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" - integrity sha1-vxEWycdYxRt6kz0pa3LCIe2UKLY= - -aggregate-error@^3.0.0: - version "3.0.1" - resolved "https://registry.npm.taobao.org/aggregate-error/download/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0" - integrity sha1-2y/nJG5Tb0DZtUQqOeEX191qJOA= - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv-errors@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/ajv-errors/download/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" - integrity sha1-81mGrOuRr63sQQL72FAUlQzvpk0= - -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: - version "3.4.1" - resolved "https://registry.npm.taobao.org/ajv-keywords/download/ajv-keywords-3.4.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-keywords%2Fdownload%2Fajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha1-75FuJxxkrBIXH9g4TqrmsjRYVNo= - -ajv@^6.1.0, ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1: - version "6.10.2" - resolved "https://registry.npm.taobao.org/ajv/download/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" - integrity sha1-086gTWsBeyiUrWkED+yLYj60vVI= - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.npm.taobao.org/align-text/download/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - integrity sha1-DNkKVhCT810KmSVsIrcGlDP60Rc= - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - -alphanum-sort@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/alphanum-sort/download/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" - integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.npm.taobao.org/amdefine/download/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= - -ansi-colors@^3.0.0: - version "3.2.4" - resolved "https://registry.npm.taobao.org/ansi-colors/download/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" - integrity sha1-46PaS/uubIapwoViXeEkojQCb78= - -ansi-escapes@^3.2.0: - version "3.2.0" - resolved "https://registry.npm.taobao.org/ansi-escapes/download/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha1-h4C5j/nb9WOBUtHx/lwde0RCl2s= - -ansi-html@0.0.7: - version "0.0.7" - resolved "https://registry.npm.taobao.org/ansi-html/download/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" - integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-2.1.1.tgz?cache=0&sync_timestamp=1570188663907&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-regex%2Fdownload%2Fansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-3.0.0.tgz?cache=0&sync_timestamp=1570188663907&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-regex%2Fdownload%2Fansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz?cache=0&sync_timestamp=1570188663907&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-regex%2Fdownload%2Fansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc= - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz?cache=0&sync_timestamp=1570188663907&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-regex%2Fdownload%2Fansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U= - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0= - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.2.1" - resolved "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" - integrity sha1-kK51xCTQCNJiTFvynq0xd+v881k= - dependencies: - "@types/color-name" "^1.1.1" - color-convert "^2.0.1" - -ant-design-vue@^1.4.10: - version "1.4.10" - resolved "https://registry.npm.taobao.org/ant-design-vue/download/ant-design-vue-1.4.10.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fant-design-vue%2Fdownload%2Fant-design-vue-1.4.10.tgz#26bf3570a3c93d54bae571e98f29457b0fd116d8" - integrity sha1-Jr81cKPJPVS65XHpjylFew/RFtg= - dependencies: - "@ant-design/icons" "^2.1.1" - "@ant-design/icons-vue" "^2.0.0" - add-dom-event-listener "^1.0.2" - array-tree-filter "^2.1.0" - async-validator "^3.0.3" - babel-helper-vue-jsx-merge-props "^2.0.3" - babel-runtime "6.x" - classnames "^2.2.5" - component-classes "^1.2.6" - dom-align "^1.7.0" - dom-closest "^0.2.0" - dom-scroll-into-view "^1.2.1" - enquire.js "^2.1.6" - intersperse "^1.0.0" - is-negative-zero "^2.0.0" - ismobilejs "^0.5.1" - json2mq "^0.2.0" - lodash "^4.17.5" - moment "^2.21.0" - mutationobserver-shim "^0.3.2" - node-emoji "^1.10.0" - omit.js "^1.0.0" - raf "^3.4.0" - resize-observer-polyfill "^1.5.1" - shallow-equal "^1.0.0" - shallowequal "^1.0.2" - vue-ref "^1.0.4" - warning "^3.0.0" - -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.npm.taobao.org/any-promise/download/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/anymatch/download/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha1-vLJLTzeTTZqnrBe0ra+J58du8us= - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.npm.taobao.org/aproba/download/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha1-aALmJk79GMeQobDVF/DyYnvyyUo= - -arch@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/arch/download/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e" - integrity sha1-j1wnMao1owkpIhuwZA7tZRdeyE4= - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.npm.taobao.org/argparse/download/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE= - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/arr-diff/download/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/arr-flatten/download/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha1-NgSLv/TntH4TZkQxbJlmnqWukfE= - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/arr-union/download/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz?cache=0&sync_timestamp=1574313384951&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-flatten@^2.1.0: - version "2.1.2" - resolved "https://registry.npm.taobao.org/array-flatten/download/array-flatten-2.1.2.tgz?cache=0&sync_timestamp=1574313384951&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha1-JO+AoowaiTYX4hSbDG0NeIKTsJk= - -array-tree-filter@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/array-tree-filter/download/array-tree-filter-2.1.0.tgz#873ac00fec83749f255ac8dd083814b4f6329190" - integrity sha1-hzrAD+yDdJ8lWsjdCDgUtPYykZA= - -array-union@^1.0.1, array-union@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/array-union/download/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.npm.taobao.org/array-uniq/download/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.npm.taobao.org/array-unique/download/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.npm.taobao.org/asn1.js/download/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha1-ucK/WAXx5kqt7tbfOiv6+1pz9aA= - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha1-jSR136tVO7M+d7VOWeiAu4ziMTY= - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/assert-plus/download/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assert@^1.1.1: - version "1.5.0" - resolved "https://registry.npm.taobao.org/assert/download/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" - integrity sha1-VcEJqvbgrv2z3EtxJAxwv1dLGOs= - dependencies: - object-assign "^4.1.1" - util "0.10.3" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/assign-symbols/download/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/astral-regex/download/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha1-bIw/uCfdQ+45GPJ7gngqt2WKb9k= - -async-each@^1.0.1: - version "1.0.3" - resolved "https://registry.npm.taobao.org/async-each/download/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" - integrity sha1-tyfb+H12UWAvBvTUrDh/R9kbDL8= - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/async-limiter/download/async-limiter-1.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fasync-limiter%2Fdownload%2Fasync-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha1-3TeelPDbgxCwgpH51kwyCXZmF/0= - -async-validator@^3.0.3: - version "3.2.3" - resolved "https://registry.npm.taobao.org/async-validator/download/async-validator-3.2.3.tgz#b38b72f9c08c1d28548df13bb260b6908448ca49" - integrity sha1-s4ty+cCMHShUjfE7smC2kIRIykk= - -async@^2.6.2: - version "2.6.3" - resolved "https://registry.npm.taobao.org/async/download/async-2.6.3.tgz?cache=0&sync_timestamp=1563385399810&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fasync%2Fdownload%2Fasync-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha1-1yYl4jRKNlbjo61Pp0n6gymdgv8= - dependencies: - lodash "^4.17.14" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.npm.taobao.org/atob/download/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k= - -autoprefixer@^9.7.2: - version "9.7.3" - resolved "https://registry.npm.taobao.org/autoprefixer/download/autoprefixer-9.7.3.tgz#fd42ed03f53de9beb4ca0d61fb4f7268a9bb50b4" - integrity sha1-/ULtA/U96b60yg1h+09yaKm7ULQ= - dependencies: - browserslist "^4.8.0" - caniuse-lite "^1.0.30001012" - chalk "^2.4.2" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^7.0.23" - postcss-value-parser "^4.0.2" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.npm.taobao.org/aws-sign2/download/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.9.0" - resolved "https://registry.npm.taobao.org/aws4/download/aws4-1.9.0.tgz?cache=0&sync_timestamp=1574807521525&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faws4%2Fdownload%2Faws4-1.9.0.tgz#24390e6ad61386b0a747265754d2a17219de862c" - integrity sha1-JDkOatYThrCnRyZXVNKhchnehiw= - -babel-eslint@^10.0.3: - version "10.0.3" - resolved "https://registry.npm.taobao.org/babel-eslint/download/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a" - integrity sha1-gaLGab4PIF4ZRi/tJILTPkaHqIo= - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - eslint-visitor-keys "^1.0.0" - resolve "^1.12.0" - -babel-helper-vue-jsx-merge-props@^2.0.3: - version "2.0.3" - resolved "https://registry.npm.taobao.org/babel-helper-vue-jsx-merge-props/download/babel-helper-vue-jsx-merge-props-2.0.3.tgz#22aebd3b33902328e513293a8e4992b384f9f1b6" - integrity sha1-Iq69OzOQIyjlEyk6jkmSs4T58bY= - -babel-loader@^8.0.6: - version "8.0.6" - resolved "https://registry.npm.taobao.org/babel-loader/download/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb" - integrity sha1-4zvbbzYrA/S7FBoMIauHxQG3Dfs= - dependencies: - find-cache-dir "^2.0.0" - loader-utils "^1.0.2" - mkdirp "^0.5.1" - pify "^4.0.1" - -babel-plugin-dynamic-import-node@^2.2.0, babel-plugin-dynamic-import-node@^2.3.0: - version "2.3.0" - resolved "https://registry.npm.taobao.org/babel-plugin-dynamic-import-node/download/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" - integrity sha1-8A9Qe9qjw+P/bn5emNkKesq5b38= - dependencies: - object.assign "^4.1.0" - -babel-runtime@6.x, babel-runtime@^6.23.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.npm.taobao.org/babel-runtime/download/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.npm.taobao.org/base64-js/download/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha1-WOzoy3XdB+ce0IxzarxfrE2/jfE= - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.npm.taobao.org/base/download/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha1-e95c7RRbbVUakNuH+DxVi060io8= - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.npm.taobao.org/batch/download/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/bcrypt-pbkdf/download/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -bfj@^6.1.1: - version "6.1.2" - resolved "https://registry.npm.taobao.org/bfj/download/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" - integrity sha1-MlyGGoIryzWKQceKM7jm4ght3n8= - dependencies: - bluebird "^3.5.5" - check-types "^8.0.3" - hoopy "^0.1.4" - tryer "^1.0.1" - -big.js@^3.1.3: - version "3.2.0" - resolved "https://registry.npm.taobao.org/big.js/download/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" - integrity sha1-pfwpi4G54Nyi5FiCR4S2XFK6WI4= - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.npm.taobao.org/big.js/download/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha1-ZfCvOC9Xi83HQr2cKB6cstd2gyg= - -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.npm.taobao.org/binary-extensions/download/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha1-WYr+VHVbKGilMw0q/51Ou1Mgm2U= - -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.npm.taobao.org/bindings/download/bindings-1.5.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbindings%2Fdownload%2Fbindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha1-EDU8npRTNLwFEabZCzj7x8nFBN8= - dependencies: - file-uri-to-path "1.0.0" - -bluebird@^3.1.1, bluebird@^3.5.5: - version "3.7.2" - resolved "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha1-nyKcFb4nJFT/qXOs4NvueaGww28= - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.npm.taobao.org/bn.js/download/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha1-LN4J617jQfSEdGuwMJsyU7GxRC8= - -body-parser@1.19.0: - version "1.19.0" - resolved "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io= - dependencies: - bytes "3.1.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" - -bonjour@^3.5.0: - version "3.5.0" - resolved "https://registry.npm.taobao.org/bonjour/download/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= - dependencies: - array-flatten "^2.1.0" - deep-equal "^1.0.1" - dns-equal "^1.0.0" - dns-txt "^2.0.2" - multicast-dns "^6.0.1" - multicast-dns-service-types "^1.1.0" - -boolbase@^1.0.0, boolbase@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/boolbase/download/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0= - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.npm.taobao.org/braces/download/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha1-WXn9PxTNUxVl5fot8av/8d+u5yk= - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.npm.taobao.org/brorand/download/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.2.0" - resolved "https://registry.npm.taobao.org/browserify-aes/download/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha1-Mmc0ZC9APavDADIJhTu3CtQo70g= - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/browserify-cipher/download/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha1-jWR0wbhwv9q807z8wZNKEOlPFfA= - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/browserify-des/download/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha1-OvTx9Zg5QDVy8cZiBDdfen9wPpw= - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.npm.taobao.org/browserify-rsa/download/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= - dependencies: - bn.js "^4.1.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.npm.taobao.org/browserify-sign/download/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.npm.taobao.org/browserify-zlib/download/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha1-KGlFnZqjviRf6P4sofRuLn9U1z8= - dependencies: - pako "~1.0.5" - -browserslist@^4.0.0, browserslist@^4.6.0, browserslist@^4.7.3, browserslist@^4.8.0, browserslist@^4.8.2: - version "4.8.3" - resolved "https://registry.npm.taobao.org/browserslist/download/browserslist-4.8.3.tgz#65802fcd77177c878e015f0e3189f2c4f627ba44" - integrity sha1-ZYAvzXcXfIeOAV8OMYnyxPYnukQ= - dependencies: - caniuse-lite "^1.0.30001017" - electron-to-chromium "^1.3.322" - node-releases "^1.1.44" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8= - -buffer-indexof@^1.0.0: - version "1.1.1" - resolved "https://registry.npm.taobao.org/buffer-indexof/download/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" - integrity sha1-Uvq8xqYG0aADAoAmSO9o9jnaJow= - -buffer-json@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/buffer-json/download/buffer-json-2.0.0.tgz#f73e13b1e42f196fe2fd67d001c7d7107edd7c23" - integrity sha1-9z4TseQvGW/i/WfQAcfXEH7dfCM= - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/buffer-xor/download/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= - -buffer@^4.3.0: - version "4.9.2" - resolved "https://registry.npm.taobao.org/buffer/download/buffer-4.9.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbuffer%2Fdownload%2Fbuffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha1-Iw6tNEACmIZEhBqwJEr4xEu+Pvg= - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/builtin-status-codes/download/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/bytes/download/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= - -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY= - -cacache@^12.0.2, cacache@^12.0.3: - version "12.0.3" - resolved "https://registry.npm.taobao.org/cacache/download/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" - integrity sha1-vpmruk4b9d9GHNWiwQcfxDJXM5A= - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cacache@^13.0.1: - version "13.0.1" - resolved "https://registry.npm.taobao.org/cacache/download/cacache-13.0.1.tgz#a8000c21697089082f85287a1aec6e382024a71c" - integrity sha1-qAAMIWlwiQgvhSh6GuxuOCAkpxw= - dependencies: - chownr "^1.1.2" - figgy-pudding "^3.5.1" - fs-minipass "^2.0.0" - glob "^7.1.4" - graceful-fs "^4.2.2" - infer-owner "^1.0.4" - lru-cache "^5.1.1" - minipass "^3.0.0" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - p-map "^3.0.0" - promise-inflight "^1.0.1" - rimraf "^2.7.1" - ssri "^7.0.0" - unique-filename "^1.1.1" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/cache-base/download/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha1-Cn9GQWgxyLZi7jb+TnxZ129marI= - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cache-loader@^4.1.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/cache-loader/download/cache-loader-4.1.0.tgz#9948cae353aec0a1fcb1eafda2300816ec85387e" - integrity sha1-mUjK41OuwKH8ser9ojAIFuyFOH4= - dependencies: - buffer-json "^2.0.0" - find-cache-dir "^3.0.0" - loader-utils "^1.2.3" - mkdirp "^0.5.1" - neo-async "^2.6.1" - schema-utils "^2.0.0" - -call-me-maybe@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/call-me-maybe/download/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" - integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= - -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/caller-callsite/download/caller-callsite-2.0.0.tgz?cache=0&sync_timestamp=1562668933683&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcaller-callsite%2Fdownload%2Fcaller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/caller-path/download/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/callsites/download/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/callsites/download/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M= - -camel-case@3.0.x: - version "3.0.0" - resolved "https://registry.npm.taobao.org/camel-case/download/camel-case-3.0.0.tgz?cache=0&sync_timestamp=1576748709736&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamel-case%2Fdownload%2Fcamel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" - integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= - dependencies: - no-case "^2.2.0" - upper-case "^1.1.1" - -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.npm.taobao.org/camelcase/download/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= - -camelcase@^5.0.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA= - -caniuse-api@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/caniuse-api/download/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" - integrity sha1-Xk2Q4idJYdRikZl99Znj7QCO5MA= - dependencies: - browserslist "^4.0.0" - caniuse-lite "^1.0.0" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" - -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001012, caniuse-lite@^1.0.30001017: - version "1.0.30001017" - resolved "https://registry.npm.taobao.org/caniuse-lite/download/caniuse-lite-1.0.30001017.tgz?cache=0&sync_timestamp=1577471591500&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcaniuse-lite%2Fdownload%2Fcaniuse-lite-1.0.30001017.tgz#d3ad6ec18148b9bd991829958d9d7e562bb78cd6" - integrity sha1-061uwYFIub2ZGCmVjZ1+Viu3jNY= - -case-sensitive-paths-webpack-plugin@^2.2.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/case-sensitive-paths-webpack-plugin/download/case-sensitive-paths-webpack-plugin-2.2.0.tgz#3371ef6365ef9c25fa4b81c16ace0e9c7dc58c3e" - integrity sha1-M3HvY2XvnCX6S4HBas4OnH3FjD4= - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.npm.taobao.org/caseless/download/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.npm.taobao.org/center-align/download/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - integrity sha1-qg0yYptu6XIgBBHL1EYckHvCt60= - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - -chalk@^1.1.1, chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.npm.taobao.org/chalk/download/chalk-1.1.3.tgz?cache=0&sync_timestamp=1573282918610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.npm.taobao.org/chalk/download/chalk-2.4.2.tgz?cache=0&sync_timestamp=1573282918610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ= - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/chalk/download/chalk-3.0.0.tgz?cache=0&sync_timestamp=1573282918610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha1-P3PCv1JlkfV0zEksUeJFY0n4ROQ= - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.npm.taobao.org/chardet/download/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha1-kAlISfCTfy7twkJdDSip5fDLrZ4= - -check-types@^8.0.3: - version "8.0.3" - resolved "https://registry.npm.taobao.org/check-types/download/check-types-8.0.3.tgz?cache=0&sync_timestamp=1577112099852&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcheck-types%2Fdownload%2Fcheck-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" - integrity sha1-M1bMoZyIlUTy16le1JzlCKDs9VI= - -chokidar@^2.0.2, chokidar@^2.1.8: - version "2.1.8" - resolved "https://registry.npm.taobao.org/chokidar/download/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha1-gEs6e2qZNYw8XGHnHYco8EHP+Rc= - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" - -chownr@^1.1.1, chownr@^1.1.2: - version "1.1.3" - resolved "https://registry.npm.taobao.org/chownr/download/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" - integrity sha1-Qtg31SOWiNVfMDADpQgjD6ZycUI= - -chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/chrome-trace-event/download/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha1-I0CQ7pfH1K0aLEvq4nUF3v/GCKQ= - dependencies: - tslib "^1.9.0" - -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.npm.taobao.org/ci-info/download/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha1-LKINu5zrMtRSSmgzAzE/AwSx5Jc= - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.npm.taobao.org/cipher-base/download/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.npm.taobao.org/class-utils/download/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha1-+TNprouafOAv1B+q0MqDAzGQxGM= - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -classnames@^2.2.5: - version "2.2.6" - resolved "https://registry.npm.taobao.org/classnames/download/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" - integrity sha1-Q5Nb/90pHzJtrQogUwmzjQD2UM4= - -clean-css@4.2.x: - version "4.2.1" - resolved "https://registry.npm.taobao.org/clean-css/download/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" - integrity sha1-LUEe92uFabbQyEBo2r6FsKpeXBc= - dependencies: - source-map "~0.6.0" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/clean-stack/download/clean-stack-2.2.0.tgz?cache=0&sync_timestamp=1564586594378&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fclean-stack%2Fdownload%2Fclean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha1-7oRy27Ep5yezHooQpCfe6d/kAIs= - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/cli-cursor/download/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= - dependencies: - restore-cursor "^2.0.0" - -cli-highlight@^2.1.4: - version "2.1.4" - resolved "https://registry.npm.taobao.org/cli-highlight/download/cli-highlight-2.1.4.tgz?cache=0&sync_timestamp=1573948719956&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcli-highlight%2Fdownload%2Fcli-highlight-2.1.4.tgz#098cb642cf17f42adc1c1145e07f960ec4d7522b" - integrity sha1-CYy2Qs8X9CrcHBFF4H+WDsTXUis= - dependencies: - chalk "^3.0.0" - highlight.js "^9.6.0" - mz "^2.4.0" - parse5 "^5.1.1" - parse5-htmlparser2-tree-adapter "^5.1.1" - yargs "^15.0.0" - -cli-spinners@^2.0.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/cli-spinners/download/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" - integrity sha1-6LmI2SBsaSMC2O6DTnqFwBRNj3c= - -cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/cli-width/download/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= - -clipboardy@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/clipboardy/download/clipboardy-2.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fclipboardy%2Fdownload%2Fclipboardy-2.1.0.tgz#0123a0c8fac92f256dc56335e0bb8be97a4909a5" - integrity sha1-ASOgyPrJLyVtxWM14LuL6XpJCaU= - dependencies: - arch "^2.1.1" - execa "^1.0.0" - -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/cliui/download/cliui-2.1.0.tgz?cache=0&sync_timestamp=1573943292170&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcliui%2Fdownload%2Fcliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - integrity sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE= - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/cliui/download/cliui-4.1.0.tgz?cache=0&sync_timestamp=1573943292170&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcliui%2Fdownload%2Fcliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha1-NIQi2+gtgAswIu709qwQvy5NG0k= - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.npm.taobao.org/cliui/download/cliui-5.0.0.tgz?cache=0&sync_timestamp=1573943292170&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcliui%2Fdownload%2Fcliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha1-3u/P2y6AB4SqNPRvoI4GhRx7u8U= - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -cliui@^6.0.0: - version "6.0.0" - resolved "https://registry.npm.taobao.org/cliui/download/cliui-6.0.0.tgz?cache=0&sync_timestamp=1573943292170&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcliui%2Fdownload%2Fcliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" - integrity sha1-UR1wLAxOQcoVbX0OlgIfI+EyJbE= - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^6.2.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.npm.taobao.org/clone/download/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= - -coa@^2.0.2: - version "2.0.2" - resolved "https://registry.npm.taobao.org/coa/download/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" - integrity sha1-Q/bCEVG07yv1cYfbDXPeIp4+fsM= - dependencies: - "@types/q" "^1.5.1" - chalk "^2.4.1" - q "^1.1.2" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/code-point-at/download/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/collection-visit/download/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0, color-convert@^1.9.1: - version "1.9.3" - resolved "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz?cache=0&sync_timestamp=1566248870121&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcolor-convert%2Fdownload%2Fcolor-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg= - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz?cache=0&sync_timestamp=1566248870121&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcolor-convert%2Fdownload%2Fcolor-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM= - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha1-wqCah6y95pVD3m9j+jmVyCbFNqI= - -color-string@^1.5.2: - version "1.5.3" - resolved "https://registry.npm.taobao.org/color-string/download/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha1-ybvF8BtYtUkvPWhXRZy2WQziBMw= - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@^3.0.0: - version "3.1.2" - resolved "https://registry.npm.taobao.org/color/download/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" - integrity sha1-aBSOf4XUGtdknF+oyBBvCY0inhA= - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha1-w9RaizT9cwYxoRCoolIGgrMdWn8= - dependencies: - delayed-stream "~1.0.0" - -commander@2.17.x: - version "2.17.1" - resolved "https://registry.npm.taobao.org/commander/download/commander-2.17.1.tgz?cache=0&sync_timestamp=1573464028535&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - integrity sha1-vXerfebelCBc6sxy8XFtKfIKd78= - -commander@^2.18.0, commander@^2.20.0, commander@~2.20.3: - version "2.20.3" - resolved "https://registry.npm.taobao.org/commander/download/commander-2.20.3.tgz?cache=0&sync_timestamp=1573464028535&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha1-/UhehMA+tIgcIHIrpIA16FMa6zM= - -commander@~2.19.0: - version "2.19.0" - resolved "https://registry.npm.taobao.org/commander/download/commander-2.19.0.tgz?cache=0&sync_timestamp=1573464028535&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha1-9hmKqE5bg8RgVLlN3tv+1e6f8So= - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/commondir/download/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -component-classes@^1.2.6: - version "1.2.6" - resolved "https://registry.npm.taobao.org/component-classes/download/component-classes-1.2.6.tgz#c642394c3618a4d8b0b8919efccbbd930e5cd691" - integrity sha1-xkI5TDYYpNiwuJGe/Mu9kw5c1pE= - dependencies: - component-indexof "0.0.3" - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A= - -component-indexof@0.0.3: - version "0.0.3" - resolved "https://registry.npm.taobao.org/component-indexof/download/component-indexof-0.0.3.tgz#11d091312239eb8f32c8f25ae9cb002ffe8d3c24" - integrity sha1-EdCRMSI5648yyPJa6csAL/6NPCQ= - -compressible@~2.0.16: - version "2.0.17" - resolved "https://registry.npm.taobao.org/compressible/download/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" - integrity sha1-bowQihatWDhKl386SCyiC/8vOME= - dependencies: - mime-db ">= 1.40.0 < 2" - -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.npm.taobao.org/compression/download/compression-1.7.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcompression%2Fdownload%2Fcompression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha1-lVI+/xcMpXwpoMpB5v4TH0Hlu48= - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.npm.taobao.org/concat-stream/download/concat-stream-1.6.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconcat-stream%2Fdownload%2Fconcat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ= - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -connect-history-api-fallback@^1.6.0: - version "1.6.0" - resolved "https://registry.npm.taobao.org/connect-history-api-fallback/download/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" - integrity sha1-izIIk1kwjRERFdgcrT/Oq4iPl7w= - -console-browserify@^1.1.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/console-browserify/download/console-browserify-1.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconsole-browserify%2Fdownload%2Fconsole-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" - integrity sha1-ZwY871fOts9Jk6KrOlWECujEkzY= - -consolidate@^0.15.1: - version "0.15.1" - resolved "https://registry.npm.taobao.org/consolidate/download/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" - integrity sha1-IasEMjXHGgfUXZqtmFk7DbpWurc= - dependencies: - bluebird "^3.1.1" - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/constants-browserify/download/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= - -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70= - dependencies: - safe-buffer "5.1.2" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha1-4TjMdeBAxyexlm/l5fjJruJW/js= - -contour_plot@^0.0.1: - version "0.0.1" - resolved "https://registry.npm.taobao.org/contour_plot/download/contour_plot-0.0.1.tgz#475870f032b8e338412aa5fc507880f0bf495c77" - integrity sha1-R1hw8DK44zhBKqX8UHiA8L9JXHc= - -convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.npm.taobao.org/convert-source-map/download/convert-source-map-1.7.0.tgz?cache=0&sync_timestamp=1573003637425&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconvert-source-map%2Fdownload%2Fconvert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha1-F6LLiC1/d9NJBYXizmxSRCSjpEI= - dependencies: - safe-buffer "~5.1.1" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.npm.taobao.org/cookie/download/cookie-0.4.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcookie%2Fdownload%2Fcookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha1-vrQ35wIrO21JAZ0IhmUwPr6cFLo= - -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.npm.taobao.org/copy-concurrently/download/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha1-kilzmMrjSTf8r9bsgTnBgFHwteA= - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.npm.taobao.org/copy-descriptor/download/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -copy-webpack-plugin@^5.0.5: - version "5.1.1" - resolved "https://registry.npm.taobao.org/copy-webpack-plugin/download/copy-webpack-plugin-5.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcopy-webpack-plugin%2Fdownload%2Fcopy-webpack-plugin-5.1.1.tgz#5481a03dea1123d88a988c6ff8b78247214f0b88" - integrity sha1-VIGgPeoRI9iKmIxv+LeCRyFPC4g= - dependencies: - cacache "^12.0.3" - find-cache-dir "^2.1.0" - glob-parent "^3.1.0" - globby "^7.1.1" - is-glob "^4.0.1" - loader-utils "^1.2.3" - minimatch "^3.0.4" - normalize-path "^3.0.0" - p-limit "^2.2.1" - schema-utils "^1.0.0" - serialize-javascript "^2.1.2" - webpack-log "^2.0.0" - -core-js-compat@^3.4.4, core-js-compat@^3.6.0: - version "3.6.1" - resolved "https://registry.npm.taobao.org/core-js-compat/download/core-js-compat-3.6.1.tgz?cache=0&sync_timestamp=1577253986957&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js-compat%2Fdownload%2Fcore-js-compat-3.6.1.tgz#39638c935c83c93a793abb628b252ec43e85783a" - integrity sha1-OWOMk1yDyTp5OrtiiyUuxD6FeDo= - dependencies: - browserslist "^4.8.2" - semver "7.0.0" - -core-js@^2.4.0: - version "2.6.11" - resolved "https://registry.npm.taobao.org/core-js/download/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" - integrity sha1-OIMUafmSK97Y7iHJ3EaYXgOZMIw= - -core-js@^3.4.4: - version "3.6.1" - resolved "https://registry.npm.taobao.org/core-js/download/core-js-3.6.1.tgz#39d5e2e346258cc01eb7d44345b1c3c014ca3f05" - integrity sha1-OdXi40YljMAet9RDRbHDwBTKPwU= - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cosmiconfig@^5.0.0: - version "5.2.1" - resolved "https://registry.npm.taobao.org/cosmiconfig/download/cosmiconfig-5.2.1.tgz?cache=0&sync_timestamp=1572710682964&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcosmiconfig%2Fdownload%2Fcosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - integrity sha1-BA9yaAnFked6F8CjYmykW08Wixo= - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - -create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.npm.taobao.org/create-ecdh/download/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha1-yREbbzMEXEaX8UR4f5JUzcd8Rf8= - dependencies: - bn.js "^4.1.0" - elliptic "^6.0.0" - -create-hash@^1.1.0, create-hash@^1.1.2: - version "1.2.0" - resolved "https://registry.npm.taobao.org/create-hash/download/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha1-iJB4rxGmN1a8+1m9IhmWvjqe8ZY= - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: - version "1.1.7" - resolved "https://registry.npm.taobao.org/create-hmac/download/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha1-aRcMeLOrlXFHsriwRXLkfq0iQ/8= - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q= - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^7.0.0: - version "7.0.1" - resolved "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" - integrity sha1-CrVihuD3wk4VPQTMKqAn5DqaXRQ= - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-browserify@^3.11.0: - version "3.12.0" - resolved "https://registry.npm.taobao.org/crypto-browserify/download/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha1-OWz58xN/A+S45TLFj2mCVOAPgOw= - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -css-color-names@0.0.4, css-color-names@^0.0.4: - version "0.0.4" - resolved "https://registry.npm.taobao.org/css-color-names/download/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= - -css-declaration-sorter@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/css-declaration-sorter/download/css-declaration-sorter-4.0.1.tgz?cache=0&sync_timestamp=1576525913209&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-declaration-sorter%2Fdownload%2Fcss-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" - integrity sha1-wZiUD2OnbX42wecQGLABchBUyyI= - dependencies: - postcss "^7.0.1" - timsort "^0.3.0" - -css-loader@^3.1.0: - version "3.4.0" - resolved "https://registry.npm.taobao.org/css-loader/download/css-loader-3.4.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-3.4.0.tgz#9fb263436783117a41d014e45e8eaeba54dd6670" - integrity sha1-n7JjQ2eDEXpB0BTkXo6uulTdZnA= - dependencies: - camelcase "^5.3.1" - cssesc "^3.0.0" - icss-utils "^4.1.1" - loader-utils "^1.2.3" - normalize-path "^3.0.0" - postcss "^7.0.23" - postcss-modules-extract-imports "^2.0.0" - postcss-modules-local-by-default "^3.0.2" - postcss-modules-scope "^2.1.1" - postcss-modules-values "^3.0.0" - postcss-value-parser "^4.0.2" - schema-utils "^2.6.0" - -css-select-base-adapter@^0.1.1: - version "0.1.1" - resolved "https://registry.npm.taobao.org/css-select-base-adapter/download/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" - integrity sha1-Oy/0lyzDYquIVhUHqVQIoUMhNdc= - -css-select@^1.1.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/css-select/download/css-select-1.2.0.tgz?cache=0&sync_timestamp=1573341911322&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-select%2Fdownload%2Fcss-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= - dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" - -css-select@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/css-select/download/css-select-2.1.0.tgz?cache=0&sync_timestamp=1573341911322&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-select%2Fdownload%2Fcss-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" - integrity sha1-ajRlM1ZjWTSoG6ymjQJVQyEF2+8= - dependencies: - boolbase "^1.0.0" - css-what "^3.2.1" - domutils "^1.7.0" - nth-check "^1.0.2" - -css-tree@1.0.0-alpha.37: - version "1.0.0-alpha.37" - resolved "https://registry.npm.taobao.org/css-tree/download/css-tree-1.0.0-alpha.37.tgz?cache=0&sync_timestamp=1575583846685&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-tree%2Fdownload%2Fcss-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" - integrity sha1-mL69YsTB2flg7DQM+fdSLjBwmiI= - dependencies: - mdn-data "2.0.4" - source-map "^0.6.1" - -css-unit-converter@^1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/css-unit-converter/download/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996" - integrity sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY= - -css-what@2.1: - version "2.1.3" - resolved "https://registry.npm.taobao.org/css-what/download/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha1-ptdgRXM2X+dGhsPzEcVlE9iChfI= - -css-what@^3.2.1: - version "3.2.1" - resolved "https://registry.npm.taobao.org/css-what/download/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" - integrity sha1-9KjxJCEGRiG0VnVeNKA6LCLfXaE= - -cssesc@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/cssesc/download/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" - integrity sha1-OxO9G7HLNuG8taTc0n9UxdyzVwM= - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/cssesc/download/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha1-N3QZGZA7hoVl4cCep0dEXNGJg+4= - -cssnano-preset-default@^4.0.0, cssnano-preset-default@^4.0.7: - version "4.0.7" - resolved "https://registry.npm.taobao.org/cssnano-preset-default/download/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" - integrity sha1-UexmLM/KD4izltzZZ5zbkxvhf3Y= - dependencies: - css-declaration-sorter "^4.0.1" - cssnano-util-raw-cache "^4.0.1" - postcss "^7.0.0" - postcss-calc "^7.0.1" - postcss-colormin "^4.0.3" - postcss-convert-values "^4.0.1" - postcss-discard-comments "^4.0.2" - postcss-discard-duplicates "^4.0.2" - postcss-discard-empty "^4.0.1" - postcss-discard-overridden "^4.0.1" - postcss-merge-longhand "^4.0.11" - postcss-merge-rules "^4.0.3" - postcss-minify-font-values "^4.0.2" - postcss-minify-gradients "^4.0.2" - postcss-minify-params "^4.0.2" - postcss-minify-selectors "^4.0.2" - postcss-normalize-charset "^4.0.1" - postcss-normalize-display-values "^4.0.2" - postcss-normalize-positions "^4.0.2" - postcss-normalize-repeat-style "^4.0.2" - postcss-normalize-string "^4.0.2" - postcss-normalize-timing-functions "^4.0.2" - postcss-normalize-unicode "^4.0.1" - postcss-normalize-url "^4.0.1" - postcss-normalize-whitespace "^4.0.2" - postcss-ordered-values "^4.1.2" - postcss-reduce-initial "^4.0.3" - postcss-reduce-transforms "^4.0.2" - postcss-svgo "^4.0.2" - postcss-unique-selectors "^4.0.1" - -cssnano-util-get-arguments@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/cssnano-util-get-arguments/download/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" - integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= - -cssnano-util-get-match@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/cssnano-util-get-match/download/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" - integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= - -cssnano-util-raw-cache@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/cssnano-util-raw-cache/download/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" - integrity sha1-sm1f1fcqEd/np4RvtMZyYPlr8oI= - dependencies: - postcss "^7.0.0" - -cssnano-util-same-parent@^4.0.0: - version "4.0.1" - resolved "https://registry.npm.taobao.org/cssnano-util-same-parent/download/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" - integrity sha1-V0CC+yhZ0ttDOFWDXZqEVuoYu/M= - -cssnano@^4.0.0, cssnano@^4.1.10: - version "4.1.10" - resolved "https://registry.npm.taobao.org/cssnano/download/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" - integrity sha1-CsQfCxPRPUZUh+ERt3jULaYxuLI= - dependencies: - cosmiconfig "^5.0.0" - cssnano-preset-default "^4.0.7" - is-resolvable "^1.0.0" - postcss "^7.0.0" - -csso@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/csso/download/csso-4.0.2.tgz#e5f81ab3a56b8eefb7f0092ce7279329f454de3d" - integrity sha1-5fgas6Vrju+38Aks5yeTKfRU3j0= - dependencies: - css-tree "1.0.0-alpha.37" - -current-script-polyfill@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/current-script-polyfill/download/current-script-polyfill-1.0.0.tgz#f31cf7e4f3e218b0726e738ca92a02d3488ef615" - integrity sha1-8xz35PPiGLBybnOMqSoC00iO9hU= - -cyclist@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/cyclist/download/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" - integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= - -d3-color@1: - version "1.4.0" - resolved "https://registry.npm.taobao.org/d3-color/download/d3-color-1.4.0.tgz#89c45a995ed773b13314f06460df26d60ba0ecaf" - integrity sha1-icRamV7Xc7EzFPBkYN8m1gug7K8= - -d3-dispatch@1: - version "1.0.6" - resolved "https://registry.npm.taobao.org/d3-dispatch/download/d3-dispatch-1.0.6.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fd3-dispatch%2Fdownload%2Fd3-dispatch-1.0.6.tgz#00d37bcee4dd8cd97729dd893a0ac29caaba5d58" - integrity sha1-ANN7zuTdjNl3Kd2JOgrCnKq6XVg= - -d3-ease@1, d3-ease@~1.0.3: - version "1.0.6" - resolved "https://registry.npm.taobao.org/d3-ease/download/d3-ease-1.0.6.tgz#ebdb6da22dfac0a22222f2d4da06f66c416a0ec0" - integrity sha1-69ttoi36wKIiIvLU2gb2bEFqDsA= - -d3-interpolate@1: - version "1.4.0" - resolved "https://registry.npm.taobao.org/d3-interpolate/download/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" - integrity sha1-Um554tgNqjg/ngwcHH3MDwWD6Yc= - dependencies: - d3-color "1" - -d3-interpolate@~1.1.5: - version "1.1.6" - resolved "https://registry.npm.taobao.org/d3-interpolate/download/d3-interpolate-1.1.6.tgz#2cf395ae2381804df08aa1bf766b7f97b5f68fb6" - integrity sha1-LPOVriOBgE3wiqG/dmt/l7X2j7Y= - dependencies: - d3-color "1" - -d3-selection@^1.0.2, d3-selection@^1.1.0: - version "1.4.1" - resolved "https://registry.npm.taobao.org/d3-selection/download/d3-selection-1.4.1.tgz?cache=0&sync_timestamp=1573957585177&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fd3-selection%2Fdownload%2Fd3-selection-1.4.1.tgz#98eedbbe085fbda5bafa2f9e3f3a2f4d7d622a98" - integrity sha1-mO7bvghfvaW6+i+ePzovTX1iKpg= - -d3-timer@1, d3-timer@~1.0.6: - version "1.0.10" - resolved "https://registry.npm.taobao.org/d3-timer/download/d3-timer-1.0.10.tgz?cache=0&sync_timestamp=1573938297645&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fd3-timer%2Fdownload%2Fd3-timer-1.0.10.tgz#dfe76b8a91748831b13b6d9c793ffbd508dd9de5" - integrity sha1-3+dripF0iDGxO22ceT/71QjdneU= - -d3-transition@^1.0.1: - version "1.3.2" - resolved "https://registry.npm.taobao.org/d3-transition/download/d3-transition-1.3.2.tgz#a98ef2151be8d8600543434c1ca80140ae23b398" - integrity sha1-qY7yFRvo2GAFQ0NMHKgBQK4js5g= - dependencies: - d3-color "1" - d3-dispatch "1" - d3-ease "1" - d3-interpolate "1" - d3-selection "^1.1.0" - d3-timer "1" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.npm.taobao.org/dashdash/download/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -de-indent@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" - integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= - -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8= - dependencies: - ms "2.0.0" - -debug@^3.0.0, debug@^3.1.1, debug@^3.2.5: - version "3.2.6" - resolved "https://registry.npm.taobao.org/debug/download/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha1-6D0X3hbYp++3cX7b5fsQE17uYps= - dependencies: - ms "^2.1.1" - -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.1.1" - resolved "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E= - dependencies: - ms "^2.1.1" - -decamelize@^1.0.0, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/decamelize/download/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.npm.taobao.org/decode-uri-component/download/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -deep-equal@^1.0.1, deep-equal@~1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/deep-equal/download/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha1-tcmMlCzv+vfLBR4k4UNKJaLmB2o= - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.npm.taobao.org/deep-is/download/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -deepmerge@^1.5.2: - version "1.5.2" - resolved "https://registry.npm.taobao.org/deepmerge/download/deepmerge-1.5.2.tgz?cache=0&sync_timestamp=1572279720382&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdeepmerge%2Fdownload%2Fdeepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753" - integrity sha1-EEmdhohEza1P7ghC34x/bwyVp1M= - -default-gateway@^4.2.0: - version "4.2.0" - resolved "https://registry.npm.taobao.org/default-gateway/download/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" - integrity sha1-FnEEx1AMIRX23WmwpTa7jtcgVSs= - dependencies: - execa "^1.0.0" - ip-regex "^2.1.0" - -default-gateway@^5.0.5: - version "5.0.5" - resolved "https://registry.npm.taobao.org/default-gateway/download/default-gateway-5.0.5.tgz#4fd6bd5d2855d39b34cc5a59505486e9aafc9b10" - integrity sha1-T9a9XShV05s0zFpZUFSG6ar8mxA= - dependencies: - execa "^3.3.0" - -defaults@^1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/defaults/download/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= - dependencies: - clone "^1.0.2" - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.npm.taobao.org/define-properties/download/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE= - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.npm.taobao.org/define-property/download/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/define-property/download/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.npm.taobao.org/define-property/download/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha1-1Flono1lS6d+AqgX+HENcCyxbp0= - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -defined@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/defined/download/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= - -del@^4.1.1: - version "4.1.1" - resolved "https://registry.npm.taobao.org/del/download/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" - integrity sha1-no8RciLqRKMf86FWwEm5kFKp8LQ= - dependencies: - "@types/glob" "^7.1.1" - globby "^6.1.0" - is-path-cwd "^2.0.0" - is-path-in-cwd "^2.0.0" - p-map "^2.0.0" - pify "^4.0.1" - rimraf "^2.6.3" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/des.js/download/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha1-U4IULhvcU/hdhtU+X0qn3rkeCEM= - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detect-node@^2.0.4: - version "2.0.4" - resolved "https://registry.npm.taobao.org/detect-node/download/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" - integrity sha1-AU7o+PZpxcWAI9pkuBecCDooxGw= - -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.npm.taobao.org/diffie-hellman/download/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha1-QOjumPVaIUlgcUaSHGPhrl89KHU= - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -dir-glob@^2.0.0, dir-glob@^2.2.2: - version "2.2.2" - resolved "https://registry.npm.taobao.org/dir-glob/download/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" - integrity sha1-+gnwaUFTyJGLGLoN6vrpR2n8UMQ= - dependencies: - path-type "^3.0.0" - -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/dns-equal/download/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= - -dns-packet@^1.3.1: - version "1.3.1" - resolved "https://registry.npm.taobao.org/dns-packet/download/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" - integrity sha1-EqpCaYEHW+UAuRDu3NC0fdfe2lo= - dependencies: - ip "^1.1.0" - safe-buffer "^5.0.1" - -dns-txt@^2.0.2: - version "2.0.2" - resolved "https://registry.npm.taobao.org/dns-txt/download/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= - dependencies: - buffer-indexof "^1.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/doctrine/download/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha1-rd6+rXKmV023g2OdyHoSF3OXOWE= - dependencies: - esutils "^2.0.2" - -dom-align@^1.7.0: - version "1.10.2" - resolved "https://registry.npm.taobao.org/dom-align/download/dom-align-1.10.2.tgz#540ea1c9e20462bd11b9fc28c561dc8351ece4c6" - integrity sha1-VA6hyeIEYr0RufwoxWHcg1Hs5MY= - -dom-closest@^0.2.0: - version "0.2.0" - resolved "https://registry.npm.taobao.org/dom-closest/download/dom-closest-0.2.0.tgz#ebd9f91d1bf22e8d6f477876bbcd3ec90216c0cf" - integrity sha1-69n5HRvyLo1vR3h2u80+yQIWwM8= - dependencies: - dom-matches ">=1.0.1" - -dom-converter@^0.2: - version "0.2.0" - resolved "https://registry.npm.taobao.org/dom-converter/download/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" - integrity sha1-ZyGp2u4uKTaClVtq/kFncWJ7t2g= - dependencies: - utila "~0.4" - -dom-matches@>=1.0.1: - version "2.0.0" - resolved "https://registry.npm.taobao.org/dom-matches/download/dom-matches-2.0.0.tgz#d2728b416a87533980eb089b848d253cf23a758c" - integrity sha1-0nKLQWqHUzmA6wibhI0lPPI6dYw= - -dom-scroll-into-view@^1.2.1: - version "1.2.1" - resolved "https://registry.npm.taobao.org/dom-scroll-into-view/download/dom-scroll-into-view-1.2.1.tgz#e8f36732dd089b0201a88d7815dc3f88e6d66c7e" - integrity sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4= - -dom-serializer@0: - version "0.2.2" - resolved "https://registry.npm.taobao.org/dom-serializer/download/dom-serializer-0.2.2.tgz?cache=0&sync_timestamp=1573447907918&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdom-serializer%2Fdownload%2Fdom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" - integrity sha1-GvuB9TNxcXXUeGVd68XjMtn5u1E= - dependencies: - domelementtype "^2.0.1" - entities "^2.0.0" - -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.npm.taobao.org/domain-browser/download/domain-browser-1.2.0.tgz?cache=0&sync_timestamp=1575879298649&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdomain-browser%2Fdownload%2Fdomain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - integrity sha1-PTH1AZGmdJ3RN1p/Ui6CPULlTto= - -domelementtype@1, domelementtype@^1.3.1: - version "1.3.1" - resolved "https://registry.npm.taobao.org/domelementtype/download/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha1-0EjESzew0Qp/Kj1f7j9DM9eQSB8= - -domelementtype@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/domelementtype/download/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" - integrity sha1-H4vf6R9aeAYydOgDtL3O326U+U0= - -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.npm.taobao.org/domhandler/download/domhandler-2.4.2.tgz?cache=0&sync_timestamp=1564708909977&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdomhandler%2Fdownload%2Fdomhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha1-iAUJfpM9ZehVRvcm1g9euItE+AM= - dependencies: - domelementtype "1" - -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.npm.taobao.org/domutils/download/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= - dependencies: - dom-serializer "0" - domelementtype "1" - -domutils@^1.5.1, domutils@^1.7.0: - version "1.7.0" - resolved "https://registry.npm.taobao.org/domutils/download/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha1-Vuo0HoNOBuZ0ivehyyXaZ+qfjCo= - dependencies: - dom-serializer "0" - domelementtype "1" - -dot-prop@^4.1.1: - version "4.2.0" - resolved "https://registry.npm.taobao.org/dot-prop/download/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" - integrity sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc= - dependencies: - is-obj "^1.0.0" - -dotenv-expand@^5.1.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/dotenv-expand/download/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" - integrity sha1-P7rwIL/XlIhAcuomsel5HUWmKfA= - -dotenv@^8.2.0: - version "8.2.0" - resolved "https://registry.npm.taobao.org/dotenv/download/dotenv-8.2.0.tgz?cache=0&sync_timestamp=1571190696472&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdotenv%2Fdownload%2Fdotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" - integrity sha1-l+YZJZradQ7qPk6j4mvO6lQksWo= - -duplexer@^0.1.1: - version "0.1.1" - resolved "https://registry.npm.taobao.org/duplexer/download/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= - -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.npm.taobao.org/duplexify/download/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha1-Kk31MX9sz9kfhtb9JdjYoQO4gwk= - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -easy-stack@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/easy-stack/download/easy-stack-1.0.0.tgz#12c91b3085a37f0baa336e9486eac4bf94e3e788" - integrity sha1-EskbMIWjfwuqM26UhurEv5Tj54g= - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.npm.taobao.org/ecc-jsbn/download/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -ejs@^2.6.1: - version "2.7.4" - resolved "https://registry.npm.taobao.org/ejs/download/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" - integrity sha1-SGYSh1c9zFPjZsehrlLDoSDuybo= - -electron-to-chromium@^1.3.322: - version "1.3.322" - resolved "https://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.322.tgz#a6f7e1c79025c2b05838e8e344f6e89eb83213a8" - integrity sha1-pvfhx5AlwrBYOOjjRPbonrgyE6g= - -elliptic@^6.0.0: - version "6.5.2" - resolved "https://registry.npm.taobao.org/elliptic/download/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" - integrity sha1-BcVnjXFzwEnYykM1UiJKSV0ON2I= - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY= - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc= - -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/emojis-list/download/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.npm.taobao.org/end-of-stream/download/end-of-stream-1.4.4.tgz?cache=0&sync_timestamp=1569416367473&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fend-of-stream%2Fdownload%2Fend-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha1-WuZKX0UFe682JuwU2gyl5LJDHrA= - dependencies: - once "^1.4.0" - -enhanced-resolve@^4.1.0: - version "4.1.1" - resolved "https://registry.npm.taobao.org/enhanced-resolve/download/enhanced-resolve-4.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" - integrity sha1-KTfiuAZs0P584JkKmPDXGjUYn2Y= - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.5.0" - tapable "^1.0.0" - -enquire.js@^2.1.6: - version "2.1.6" - resolved "https://registry.npm.taobao.org/enquire.js/download/enquire.js-2.1.6.tgz#3e8780c9b8b835084c3f60e166dbc3c2a3c89814" - integrity sha1-PoeAybi4NQhMP2DhZtvDwqPImBQ= - -entities@^1.1.1: - version "1.1.2" - resolved "https://registry.npm.taobao.org/entities/download/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha1-vfpzUplmTfr9NFKe1PhSKidf6lY= - -entities@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/entities/download/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" - integrity sha1-aNYITKsbB5dnVA2A5Wo5tCPkq/Q= - -errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.npm.taobao.org/errno/download/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha1-RoTXF3mtOa8Xfj8AeZb3xnyFJhg= - dependencies: - prr "~1.0.1" - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.npm.taobao.org/error-ex/download/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha1-tKxAZIEH/c3PriQvQovqihTU8b8= - dependencies: - is-arrayish "^0.2.1" - -error-stack-parser@^2.0.0: - version "2.0.4" - resolved "https://registry.npm.taobao.org/error-stack-parser/download/error-stack-parser-2.0.4.tgz#a757397dc5d9de973ac9a5d7d4e8ade7cfae9101" - integrity sha1-p1c5fcXZ3pc6yaXX1Oit58+ukQE= - dependencies: - stackframe "^1.1.0" - -es-abstract@^1.17.0-next.1: - version "1.17.0" - resolved "https://registry.npm.taobao.org/es-abstract/download/es-abstract-1.17.0.tgz?cache=0&sync_timestamp=1576883946566&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fes-abstract%2Fdownload%2Fes-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1" - integrity sha1-9CpRfQA2pVkduyxGNZHci7UDCbE= - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.1.5" - is-regex "^1.0.5" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimleft "^2.1.1" - string.prototype.trimright "^2.1.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.npm.taobao.org/es-to-primitive/download/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha1-5VzUyc3BiLzvsDs2bHNjI/xciYo= - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-loader@^2.1.2: - version "2.2.1" - resolved "https://registry.npm.taobao.org/eslint-loader/download/eslint-loader-2.2.1.tgz#28b9c12da54057af0845e2a6112701a2f6bf8337" - integrity sha1-KLnBLaVAV68IReKmEScBova/gzc= - dependencies: - loader-fs-cache "^1.0.0" - loader-utils "^1.0.2" - object-assign "^4.0.1" - object-hash "^1.1.4" - rimraf "^2.6.1" - -eslint-plugin-vue@^5.0.0: - version "5.2.3" - resolved "https://registry.npm.taobao.org/eslint-plugin-vue/download/eslint-plugin-vue-5.2.3.tgz?cache=0&sync_timestamp=1577727030399&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-vue%2Fdownload%2Feslint-plugin-vue-5.2.3.tgz#3ee7597d823b5478804b2feba9863b1b74273961" - integrity sha1-PudZfYI7VHiASy/rqYY7G3QnOWE= - dependencies: - vue-eslint-parser "^5.0.0" - -eslint-scope@^4.0.0, eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.npm.taobao.org/eslint-scope/download/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha1-ygODMxD2iJoyZHgaqC5j65z+eEg= - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-utils@^1.3.1: - version "1.4.3" - resolved "https://registry.npm.taobao.org/eslint-utils/download/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha1-dP7HxU0Hdrb2fgJRBAtYBlZOmB8= - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/eslint-visitor-keys/download/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" - integrity sha1-4qgs6oT/JGrW+1f5veW0ZiFFnsI= - -eslint@^5.16.0: - version "5.16.0" - resolved "https://registry.npm.taobao.org/eslint/download/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" - integrity sha1-oeOsGq5KP72Clvz496tzFMu2q+o= - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.9.1" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^4.0.3" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^5.0.1" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob "^7.1.2" - globals "^11.7.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^6.2.2" - js-yaml "^3.13.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.11" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.2" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^5.5.1" - strip-ansi "^4.0.0" - strip-json-comments "^2.0.1" - table "^5.2.3" - text-table "^0.2.0" - -espree@^4.1.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/espree/download/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" - integrity sha1-co1UUeD9FWwEOEp62J7VH/VOsl8= - dependencies: - acorn "^6.0.2" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" - -espree@^5.0.1: - version "5.0.1" - resolved "https://registry.npm.taobao.org/espree/download/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" - integrity sha1-XWUm+k/H8HiKXPdbFfMDI+L4H3o= - dependencies: - acorn "^6.0.7" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.npm.taobao.org/esprima/download/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha1-E7BM2z5sXRnfkatph6hpVhmwqnE= - -esquery@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/esquery/download/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" - integrity sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg= - dependencies: - estraverse "^4.0.0" - -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.npm.taobao.org/esrecurse/download/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8= - dependencies: - estraverse "^4.1.0" - -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.npm.taobao.org/estraverse/download/estraverse-4.3.0.tgz?cache=0&sync_timestamp=1565734335990&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0= - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.npm.taobao.org/esutils/download/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q= - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.npm.taobao.org/etag/download/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -event-pubsub@4.3.0: - version "4.3.0" - resolved "https://registry.npm.taobao.org/event-pubsub/download/event-pubsub-4.3.0.tgz#f68d816bc29f1ec02c539dc58c8dd40ce72cb36e" - integrity sha1-9o2Ba8KfHsAsU53FjI3UDOcss24= - -eventemitter3@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/eventemitter3/download/eventemitter3-4.0.0.tgz?cache=0&sync_timestamp=1560950873670&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feventemitter3%2Fdownload%2Feventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" - integrity sha1-1lF2FjiH7lnzhtZMgmELaWpKdOs= - -events@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/events/download/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" - integrity sha1-mgoN+vYok9krh1uPJpjKQRSXPog= - -eventsource@^1.0.7: - version "1.0.7" - resolved "https://registry.npm.taobao.org/eventsource/download/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" - integrity sha1-j7xyyT/NNAiAkLwKTmT0tc7m2NA= - dependencies: - original "^1.0.0" - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/evp_bytestokey/download/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI= - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@^0.8.0: - version "0.8.0" - resolved "https://registry.npm.taobao.org/execa/download/execa-0.8.0.tgz?cache=0&sync_timestamp=1576749091315&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" - integrity sha1-2NdrvBtVIX7RkP1t1J08d07PyNo= - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/execa/download/execa-1.0.0.tgz?cache=0&sync_timestamp=1576749091315&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha1-xiNqW7TfbW8V6I5/AXeYIWdJ3dg= - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^3.3.0: - version "3.4.0" - resolved "https://registry.npm.taobao.org/execa/download/execa-3.4.0.tgz?cache=0&sync_timestamp=1576749091315&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" - integrity sha1-wI7UVQ72XYWPrCaf/IVyRG8364k= - dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - p-finally "^2.0.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.npm.taobao.org/expand-brackets/download/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -express@^4.16.3, express@^4.17.1: - version "4.17.1" - resolved "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ= - dependencies: - accepts "~1.3.7" - array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" - content-type "~1.0.4" - cookie "0.4.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" - range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo= - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.npm.taobao.org/external-editor/download/external-editor-3.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexternal-editor%2Fdownload%2Fexternal-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha1-ywP3QL764D6k0oPK7SdBqD8zVJU= - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.npm.taobao.org/extglob/download/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM= - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.npm.taobao.org/extsprintf/download/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.npm.taobao.org/extsprintf/download/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= - -fast-glob@^2.2.6: - version "2.2.7" - resolved "https://registry.npm.taobao.org/fast-glob/download/fast-glob-2.2.7.tgz?cache=0&sync_timestamp=1575197566634&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-glob%2Fdownload%2Ffast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" - integrity sha1-aVOFfDr6R1//ku5gFdUtpwpM050= - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.1.0.tgz?cache=0&sync_timestamp=1576340291001&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-json-stable-stringify%2Fdownload%2Ffast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM= - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.npm.taobao.org/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -faye-websocket@^0.10.0: - version "0.10.0" - resolved "https://registry.npm.taobao.org/faye-websocket/download/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" - integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= - dependencies: - websocket-driver ">=0.5.1" - -faye-websocket@~0.11.1: - version "0.11.3" - resolved "https://registry.npm.taobao.org/faye-websocket/download/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" - integrity sha1-XA6aiWjokSwoZjn96XeosgnyUI4= - dependencies: - websocket-driver ">=0.5.1" - -fecha@~2.3.3: - version "2.3.3" - resolved "https://registry.npm.taobao.org/fecha/download/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" - integrity sha1-lI50FX3xoy/RsSw6PDzctuydls0= - -figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.npm.taobao.org/figgy-pudding/download/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - integrity sha1-hiRwESkBxyeg5JWoB0S9W6odZ5A= - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/figures/download/figures-2.0.0.tgz?cache=0&sync_timestamp=1571715625804&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffigures%2Fdownload%2Ffigures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.npm.taobao.org/file-entry-cache/download/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha1-yg9u+m3T1WEzP7FFFQZcL6/fQ5w= - dependencies: - flat-cache "^2.0.1" - -file-loader@^4.2.0: - version "4.3.0" - resolved "https://registry.npm.taobao.org/file-loader/download/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af" - integrity sha1-eA8ED3KbPRgBnyBgX3I+hEuKWK8= - dependencies: - loader-utils "^1.2.3" - schema-utils "^2.5.0" - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/file-uri-to-path/download/file-uri-to-path-1.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffile-uri-to-path%2Fdownload%2Ffile-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90= - -filesize@^3.6.1: - version "3.6.1" - resolved "https://registry.npm.taobao.org/filesize/download/filesize-3.6.1.tgz?cache=0&sync_timestamp=1573255715350&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffilesize%2Fdownload%2Ffilesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" - integrity sha1-CQuz7gG2+AGoqL6Z0xcQs0Irsxc= - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/fill-range/download/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/finalhandler/download/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0= - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -find-cache-dir@^0.1.1: - version "0.1.1" - resolved "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" - integrity sha1-yN765XyKUqinhPnjHFfHQumToLk= - dependencies: - commondir "^1.0.1" - mkdirp "^0.5.1" - pkg-dir "^1.0.0" - -find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha1-jQ+UzRP+Q8bHwmGg2GEVypGMBfc= - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-cache-dir@^3.0.0, find-cache-dir@^3.2.0: - version "3.2.0" - resolved "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-3.2.0.tgz#e7fe44c1abc1299f516146e563108fd1006c1874" - integrity sha1-5/5EwavBKZ9RYUblYxCP0QBsGHQ= - dependencies: - commondir "^1.0.1" - make-dir "^3.0.0" - pkg-dir "^4.1.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.npm.taobao.org/find-up/download/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/find-up/download/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha1-SRafHXmTQwZG2mHsxa41XCHJe3M= - dependencies: - locate-path "^3.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk= - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/flat-cache/download/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha1-XSltbwS9pEpGMKMBQTvbwuwIXsA= - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flatted@^2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/flatted/download/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" - integrity sha1-aeV8qo8OrLwoHS4stFjUb9tEngg= - -flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.npm.taobao.org/flush-write-stream/download/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha1-jdfYc6G6vCB9lOrQwuDkQnbr8ug= - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - -fmin@0.0.2: - version "0.0.2" - resolved "https://registry.npm.taobao.org/fmin/download/fmin-0.0.2.tgz#59bbb40d43ffdc1c94cd00a568c41f95f1973017" - integrity sha1-Wbu0DUP/3ByUzQClaMQflfGXMBc= - dependencies: - contour_plot "^0.0.1" - json2module "^0.0.3" - rollup "^0.25.8" - tape "^4.5.1" - uglify-js "^2.6.2" - -follow-redirects@^1.0.0: - version "1.9.0" - resolved "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.9.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.9.0.tgz#8d5bcdc65b7108fe1508649c79c12d732dcedb4f" - integrity sha1-jVvNxltxCP4VCGScecEtcy3O208= - dependencies: - debug "^3.0.0" - -for-each@~0.3.3: - version "0.3.3" - resolved "https://registry.npm.taobao.org/for-each/download/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha1-abRH6IoKXTLD5whPPxcQA0shN24= - dependencies: - is-callable "^1.1.3" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/for-in/download/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.npm.taobao.org/forever-agent/download/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.npm.taobao.org/form-data/download/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha1-3M5SwF9kTymManq5Nr1yTO/786Y= - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.npm.taobao.org/forwarded/download/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.npm.taobao.org/fragment-cache/download/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.npm.taobao.org/from2/download/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.npm.taobao.org/fs-extra/download/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha1-TxicRKoSO4lfcigE9V6iPq3DSOk= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-minipass@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/fs-minipass/download/fs-minipass-2.0.0.tgz#a6415edab02fae4b9e9230bc87ee2e4472003cd1" - integrity sha1-pkFe2rAvrkuekjC8h+4uRHIAPNE= - dependencies: - minipass "^3.0.0" - -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.npm.taobao.org/fs-write-stream-atomic/download/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.7: - version "1.2.11" - resolved "https://registry.npm.taobao.org/fsevents/download/fsevents-1.2.11.tgz?cache=0&sync_timestamp=1576322865545&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffsevents%2Fdownload%2Ffsevents-1.2.11.tgz#67bf57f4758f02ede88fb2a1712fef4d15358be3" - integrity sha1-Z79X9HWPAu3oj7KhcS/vTRU1i+M= - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - -function-bind@^1.1.1, function-bind@~1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0= - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/functional-red-black-tree/download/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.npm.taobao.org/get-caller-file/download/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha1-+Xj6TJDR3+f/LWvtoqUV5xO9z0o= - -get-caller-file@^2.0.1: - version "2.0.5" - resolved "https://registry.npm.taobao.org/get-caller-file/download/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha1-T5RBKoLbMvNuOwuXQfipf+sDH34= - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/get-stream/download/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/get-stream/download/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha1-wbJVV189wh1Zv8ec09K0axw6VLU= - dependencies: - pump "^3.0.0" - -get-stream@^5.0.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/get-stream/download/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" - integrity sha1-ASA83JJZf5uQkGfD5lbMH008Tck= - dependencies: - pump "^3.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.npm.taobao.org/get-value/download/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.npm.taobao.org/getpass/download/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/glob-parent/download/glob-parent-3.1.0.tgz?cache=0&sync_timestamp=1569108917227&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglob-parent%2Fdownload%2Fglob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.npm.taobao.org/glob-to-regexp/download/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= - -glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.6: - version "7.1.6" - resolved "https://registry.npm.taobao.org/glob/download/glob-7.1.6.tgz?cache=0&sync_timestamp=1573078121947&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglob%2Fdownload%2Fglob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY= - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0, globals@^11.7.0: - version "11.12.0" - resolved "https://registry.npm.taobao.org/globals/download/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha1-q4eVM4hooLq9hSV1gBjCp+uVxC4= - -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.npm.taobao.org/globby/download/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -globby@^7.1.1: - version "7.1.1" - resolved "https://registry.npm.taobao.org/globby/download/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" - integrity sha1-+yzP+UAfhgCUXfral0QMypcrhoA= - dependencies: - array-union "^1.0.1" - dir-glob "^2.0.0" - glob "^7.1.2" - ignore "^3.3.5" - pify "^3.0.0" - slash "^1.0.0" - -globby@^9.2.0: - version "9.2.0" - resolved "https://registry.npm.taobao.org/globby/download/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" - integrity sha1-/QKacGxwPSm90XD0tts6P3p8tj0= - dependencies: - "@types/glob" "^7.1.1" - array-union "^1.0.2" - dir-glob "^2.2.2" - fast-glob "^2.2.6" - glob "^7.1.3" - ignore "^4.0.3" - pify "^4.0.1" - slash "^2.0.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.2: - version "4.2.3" - resolved "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha1-ShL/G2A3bvCYYsIJPt2Qgyi+hCM= - -gzip-size@^5.0.0: - version "5.1.1" - resolved "https://registry.npm.taobao.org/gzip-size/download/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" - integrity sha1-y5vuaS+HwGErIyhAqHOQTkwTUnQ= - dependencies: - duplexer "^0.1.1" - pify "^4.0.1" - -handle-thing@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/handle-thing/download/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" - integrity sha1-DgOWlf9QyT/CiFV9aW88HcZ3Z1Q= - -handlebars@^4.5.3: - version "4.5.3" - resolved "https://registry.npm.taobao.org/handlebars/download/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482" - integrity sha1-XPdb2HFPdgVxNRGla+fDSb7LBII= - dependencies: - neo-async "^2.6.0" - optimist "^0.6.1" - source-map "^0.6.1" - optionalDependencies: - uglify-js "^3.1.4" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/har-schema/download/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.0: - version "5.1.3" - resolved "https://registry.npm.taobao.org/har-validator/download/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha1-HvievT5JllV2de7ZiTEQ3DUPoIA= - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/has-ansi/download/has-ansi-2.0.0.tgz?cache=0&sync_timestamp=1568144533484&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-ansi%2Fdownload%2Fhas-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s= - -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/has-symbols/download/has-symbols-1.0.1.tgz?cache=0&sync_timestamp=1573950719586&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-symbols%2Fdownload%2Fhas-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha1-n1IUdYpEGWxAbZvXbOv4HsLdMeg= - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.npm.taobao.org/has-value/download/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/has-value/download/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.npm.taobao.org/has-values/download/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/has-values/download/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.0, has@^1.0.3, has@~1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/has/download/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y= - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.npm.taobao.org/hash-base/download/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -hash-sum@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/hash-sum/download/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" - integrity sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ= - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.npm.taobao.org/hash.js/download/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha1-C6vKU46NTuSg+JiNaIZlN6ADz0I= - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -he@1.2.x, he@^1.1.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/he/download/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha1-hK5l+n6vsWX922FWauFLrwVmTw8= - -hex-color-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/hex-color-regex/download/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" - integrity sha1-TAb8y0YC/iYCs8k9+C1+fb8aio4= - -highlight.js@^9.6.0: - version "9.17.1" - resolved "https://registry.npm.taobao.org/highlight.js/download/highlight.js-9.17.1.tgz?cache=0&sync_timestamp=1576163806990&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhighlight.js%2Fdownload%2Fhighlight.js-9.17.1.tgz#14a4eded23fd314b05886758bb906e39dd627f9a" - integrity sha1-FKTt7SP9MUsFiGdYu5BuOd1if5o= - dependencies: - handlebars "^4.5.3" - -hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/hmac-drbg/download/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -hoopy@^0.1.4: - version "0.1.4" - resolved "https://registry.npm.taobao.org/hoopy/download/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" - integrity sha1-YJIH1mEQADOpqUAq096mdzgcGx0= - -hosted-git-info@^2.1.4: - version "2.8.5" - resolved "https://registry.npm.taobao.org/hosted-git-info/download/hosted-git-info-2.8.5.tgz?cache=0&sync_timestamp=1570493686863&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhosted-git-info%2Fdownload%2Fhosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" - integrity sha1-dZz88sTRVq3lmwst+r3cQqa5xww= - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.npm.taobao.org/hpack.js/download/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -hsl-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/hsl-regex/download/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" - integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= - -hsla-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/hsla-regex/download/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" - integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= - -html-comment-regex@^1.1.0: - version "1.1.2" - resolved "https://registry.npm.taobao.org/html-comment-regex/download/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" - integrity sha1-l9RoiutcgYhqNk+qDK0d2hTUM6c= - -html-entities@^1.2.1: - version "1.2.1" - resolved "https://registry.npm.taobao.org/html-entities/download/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" - integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= - -html-minifier@^3.2.3: - version "3.5.21" - resolved "https://registry.npm.taobao.org/html-minifier/download/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" - integrity sha1-0AQOBUcw41TbAIRjWTGUAVIS0gw= - dependencies: - camel-case "3.0.x" - clean-css "4.2.x" - commander "2.17.x" - he "1.2.x" - param-case "2.1.x" - relateurl "0.2.x" - uglify-js "3.4.x" - -html-tags@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/html-tags/download/html-tags-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-tags%2Fdownload%2Fhtml-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b" - integrity sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos= - -html-webpack-plugin@^3.2.0: - version "3.2.0" - resolved "https://registry.npm.taobao.org/html-webpack-plugin/download/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" - integrity sha1-sBq71yOsqqeze2r0SS69oD2d03s= - dependencies: - html-minifier "^3.2.3" - loader-utils "^0.2.16" - lodash "^4.17.3" - pretty-error "^2.0.2" - tapable "^1.0.0" - toposort "^1.0.0" - util.promisify "1.0.0" - -htmlparser2@^3.3.0: - version "3.10.1" - resolved "https://registry.npm.taobao.org/htmlparser2/download/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha1-vWedw/WYl7ajS7EHSchVu1OpOS8= - dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.npm.taobao.org/http-deceiver/download/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= - -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha1-bGGeT5xgMIw4UZSYwU+7EKrOuwY= - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -"http-parser-js@>=0.4.0 <0.4.11": - version "0.4.10" - resolved "https://registry.npm.taobao.org/http-parser-js/download/http-parser-js-0.4.10.tgz?cache=0&sync_timestamp=1572714277347&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-parser-js%2Fdownload%2Fhttp-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" - integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= - -http-proxy-middleware@0.19.1: - version "0.19.1" - resolved "https://registry.npm.taobao.org/http-proxy-middleware/download/http-proxy-middleware-0.19.1.tgz?cache=0&sync_timestamp=1577317759023&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-proxy-middleware%2Fdownload%2Fhttp-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" - integrity sha1-GDx9xKoUeRUDBkmMIQza+WCApDo= - dependencies: - http-proxy "^1.17.0" - is-glob "^4.0.0" - lodash "^4.17.11" - micromatch "^3.1.10" - -http-proxy@^1.17.0: - version "1.18.0" - resolved "https://registry.npm.taobao.org/http-proxy/download/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a" - integrity sha1-2+VfY+daNH2389mZdPJpKjFKajo= - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/http-signature/download/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/https-browserify/download/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= - -human-signals@^1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/human-signals/download/human-signals-1.1.1.tgz?cache=0&sync_timestamp=1577290400756&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhuman-signals%2Fdownload%2Fhuman-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" - integrity sha1-xbHNFPUK6uCatsWf5jujOV/k36M= - -iconv-lite@0.4.24, iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha1-ICK0sl+93CHS9SSXSkdKr+czkIs= - dependencies: - safer-buffer ">= 2.1.2 < 3" - -icss-utils@^4.0.0, icss-utils@^4.1.1: - version "4.1.1" - resolved "https://registry.npm.taobao.org/icss-utils/download/icss-utils-4.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ficss-utils%2Fdownload%2Ficss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" - integrity sha1-IRcLU3ie4nRHwvR91oMIFAP5pGc= - dependencies: - postcss "^7.0.14" - -ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.npm.taobao.org/ieee754/download/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha1-7BaFWOlaoYH9h9N/VcMrvLZwi4Q= - -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.npm.taobao.org/iferr/download/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= - -ignore@^3.3.5: - version "3.3.10" - resolved "https://registry.npm.taobao.org/ignore/download/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" - integrity sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM= - -ignore@^4.0.3, ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.npm.taobao.org/ignore/download/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw= - -import-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/import-cwd/download/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" - integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= - dependencies: - import-from "^2.1.0" - -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/import-fresh/download/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - -import-fresh@^3.0.0: - version "3.2.1" - resolved "https://registry.npm.taobao.org/import-fresh/download/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha1-Yz/2GFBueTr1rJG/SLcmd+FcvmY= - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-from@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/import-from/download/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" - integrity sha1-M1238qev/VOqpHHUuAId7ja387E= - dependencies: - resolve-from "^3.0.0" - -import-local@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/import-local/download/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha1-VQcL44pZk88Y72236WH1vuXFoJ0= - dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npm.taobao.org/imurmurhash/download/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/indent-string/download/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha1-Yk+PRJfWGbLZdoUx1Y9BIoVNclE= - -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/indexes-of/download/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= - -infer-owner@^1.0.3, infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.npm.taobao.org/infer-owner/download/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha1-xM78qo5RBRwqQLos6KPScpWvlGc= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: - version "2.0.4" - resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w= - -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -inquirer@^6.2.2: - version "6.5.2" - resolved "https://registry.npm.taobao.org/inquirer/download/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" - integrity sha1-rVCUI3XQNtMn/1KMCL1fqwiZKMo= - dependencies: - ansi-escapes "^3.2.0" - chalk "^2.4.2" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.12" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.4.0" - string-width "^2.1.0" - strip-ansi "^5.1.0" - through "^2.3.6" - -internal-ip@^4.3.0: - version "4.3.0" - resolved "https://registry.npm.taobao.org/internal-ip/download/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" - integrity sha1-hFRSuq2dLKO2nGNaE3rLmg2tCQc= - dependencies: - default-gateway "^4.2.0" - ipaddr.js "^1.9.0" - -intersperse@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/intersperse/download/intersperse-1.0.0.tgz#f2561fb1cfef9f5277cc3347a22886b4351a5181" - integrity sha1-8lYfsc/vn1J3zDNHoiiGtDUaUYE= - -invariant@^2.2.2: - version "2.2.4" - resolved "https://registry.npm.taobao.org/invariant/download/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha1-YQ88ksk1nOHbYW5TgAjSP/NRWOY= - dependencies: - loose-envify "^1.0.0" - -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/invert-kv/download/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha1-c5P1r6Weyf9fZ6J2INEcIm4+7AI= - -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/ip-regex/download/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= - -ip@^1.1.0, ip@^1.1.5: - version "1.1.5" - resolved "https://registry.npm.taobao.org/ip/download/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -ipaddr.js@1.9.0: - version "1.9.0" - resolved "https://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" - integrity sha1-N9905DCg5HVQ/lSi3v4w2KzZX2U= - -ipaddr.js@^1.9.0: - version "1.9.1" - resolved "https://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha1-v/OFQ+64mEglB5/zoqjmy9RngbM= - -is-absolute-url@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/is-absolute-url/download/is-absolute-url-2.1.0.tgz?cache=0&sync_timestamp=1569736493122&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-absolute-url%2Fdownload%2Fis-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" - integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= - -is-absolute-url@^3.0.3: - version "3.0.3" - resolved "https://registry.npm.taobao.org/is-absolute-url/download/is-absolute-url-3.0.3.tgz?cache=0&sync_timestamp=1569736493122&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-absolute-url%2Fdownload%2Fis-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" - integrity sha1-lsaiK2ojkpsR6gr7GDbDatSl1pg= - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY= - dependencies: - kind-of "^6.0.0" - -is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.npm.taobao.org/is-arguments/download/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha1-P6+WbHy6D/Q3+zH2JQCC/PBEjPM= - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.npm.taobao.org/is-arrayish/download/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.npm.taobao.org/is-arrayish/download/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha1-RXSirlb3qyBolvtDHq7tBm/fjwM= - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/is-binary-path/download/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.npm.taobao.org/is-buffer/download/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha1-76ouqdqg16suoTqXsritUf776L4= - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.npm.taobao.org/is-callable/download/is-callable-1.1.5.tgz?cache=0&sync_timestamp=1576778381051&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-callable%2Fdownload%2Fis-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha1-9+RrWWiQRW23Tn9ul2yzJz0G+qs= - -is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.npm.taobao.org/is-ci/download/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha1-43ecjuF/zPQoSI9uKBGH8uYyhBw= - dependencies: - ci-info "^1.5.0" - -is-color-stop@^1.0.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/is-color-stop/download/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" - integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= - dependencies: - css-color-names "^0.0.4" - hex-color-regex "^1.1.0" - hsl-regex "^1.0.0" - hsla-regex "^1.0.0" - rgb-regex "^1.0.1" - rgba-regex "^1.0.0" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc= - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.npm.taobao.org/is-date-object/download/is-date-object-1.0.2.tgz?cache=0&sync_timestamp=1576729165697&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-date-object%2Fdownload%2Fis-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha1-vac28s2P0G0yhE53Q7+nSUw7/X4= - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco= - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw= - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.npm.taobao.org/is-directory/download/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.npm.taobao.org/is-extendable/download/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/is-extendable/download/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ= - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0= - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/is-glob/download/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0, is-glob@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/is-glob/download/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw= - dependencies: - is-extglob "^2.1.1" - -is-negative-zero@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/is-negative-zero/download/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" - integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/is-number/download/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/is-obj/download/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - -is-path-cwd@^2.0.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/is-path-cwd/download/is-path-cwd-2.2.0.tgz?cache=0&sync_timestamp=1562347283002&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-path-cwd%2Fdownload%2Fis-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha1-Z9Q7gmZKe1GR/ZEZEn6zAASKn9s= - -is-path-in-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/is-path-in-cwd/download/is-path-in-cwd-2.1.0.tgz?cache=0&sync_timestamp=1562347183080&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-path-in-cwd%2Fdownload%2Fis-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" - integrity sha1-v+Lcomxp85cmWkAJljYCk1oFOss= - dependencies: - is-path-inside "^2.1.0" - -is-path-inside@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/is-path-inside/download/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" - integrity sha1-fJgQWH1lmkDSe8201WFuqwWUlLI= - dependencies: - path-is-inside "^1.0.2" - -is-plain-obj@^1.0.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/is-plain-obj/download/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.npm.taobao.org/is-plain-object/download/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc= - dependencies: - isobject "^3.0.1" - -is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/is-promise/download/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= - -is-regex@^1.0.4, is-regex@^1.0.5, is-regex@~1.0.5: - version "1.0.5" - resolved "https://registry.npm.taobao.org/is-regex/download/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha1-OdWJo1i/GJZ/cmlnEguPwa7XTq4= - dependencies: - has "^1.0.3" - -is-resolvable@^1.0.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/is-resolvable/download/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - integrity sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg= - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/is-stream/download/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/is-stream/download/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha1-venDJoDW+uBBKdasnZIc54FfeOM= - -is-svg@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/is-svg/download/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" - integrity sha1-kyHb0pwhLlypnE+peUxxS8r6L3U= - dependencies: - html-comment-regex "^1.1.0" - -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.npm.taobao.org/is-symbol/download/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha1-OOEBS55jKb4N6dJKQU/XRB7GGTc= - dependencies: - has-symbols "^1.0.1" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/is-windows/download/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0= - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/is-wsl/download/is-wsl-1.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-wsl%2Fdownload%2Fis-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz?cache=0&sync_timestamp=1562592096220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisarray%2Fdownload%2Fisarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisexe%2Fdownload%2Fisexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -ismobilejs@^0.5.1: - version "0.5.2" - resolved "https://registry.npm.taobao.org/ismobilejs/download/ismobilejs-0.5.2.tgz#e81bacf6187c532ad8348355f4fecd6e6adfdce1" - integrity sha1-6Bus9hh8UyrYNINV9P7Nbmrf3OE= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/isobject/download/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.npm.taobao.org/isobject/download/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.npm.taobao.org/isstream/download/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -javascript-stringify@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/javascript-stringify/download/javascript-stringify-2.0.1.tgz?cache=0&sync_timestamp=1572948916758&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjavascript-stringify%2Fdownload%2Fjavascript-stringify-2.0.1.tgz#6ef358035310e35d667c675ed63d3eb7c1aa19e5" - integrity sha1-bvNYA1MQ411mfGde1j0+t8GqGeU= - -jest-worker@^24.9.0: - version "24.9.0" - resolved "https://registry.npm.taobao.org/jest-worker/download/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" - integrity sha1-Xb/bWy0yLphWeJgjipaXvM5ns+U= - dependencies: - merge-stream "^2.0.0" - supports-color "^6.1.0" - -js-levenshtein@^1.1.3: - version "1.1.6" - resolved "https://registry.npm.taobao.org/js-levenshtein/download/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" - integrity sha1-xs7ljrNVA3LfjeuF+tXOZs4B1Z0= - -js-message@1.0.5: - version "1.0.5" - resolved "https://registry.npm.taobao.org/js-message/download/js-message-1.0.5.tgz#2300d24b1af08e89dd095bc1a4c9c9cfcb892d15" - integrity sha1-IwDSSxrwjondCVvBpMnJz8uJLRU= - -js-queue@2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/js-queue/download/js-queue-2.0.0.tgz#362213cf860f468f0125fc6c96abc1742531f948" - integrity sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug= - dependencies: - easy-stack "^1.0.0" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/js-tokens/download/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha1-GSA/tZmR35jjoocFDUZHzerzJJk= - -js-yaml@^3.13.0, js-yaml@^3.13.1: - version "3.13.1" - resolved "https://registry.npm.taobao.org/js-yaml/download/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha1-r/FRswv9+o5J4F2iLnQV6d+jeEc= - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.npm.taobao.org/jsbn/download/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.npm.taobao.org/jsesc/download/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha1-gFZNLkg9rPbo7yCWUKZ98/DCg6Q= - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.npm.taobao.org/jsesc/download/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/json-parse-better-errors/download/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npm.taobao.org/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha1-afaofZUTq4u4/mO9sJecRI5oRmA= - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.npm.taobao.org/json-schema/download/json-schema-0.2.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson-schema%2Fdownload%2Fjson-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/json-stable-stringify-without-jsonify/download/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json2module@^0.0.3: - version "0.0.3" - resolved "https://registry.npm.taobao.org/json2module/download/json2module-0.0.3.tgz#00fb5f4a9b7adfc3f0647c29cb17bcd1979be9b2" - integrity sha1-APtfSpt638PwZHwpyxe80Zeb6bI= - dependencies: - rw "^1.3.2" - -json2mq@^0.2.0: - version "0.2.0" - resolved "https://registry.npm.taobao.org/json2mq/download/json2mq-0.2.0.tgz#b637bd3ba9eabe122c83e9720483aeb10d2c904a" - integrity sha1-tje9O6nqvhIsg+lyBIOusQ0skEo= - dependencies: - string-convert "^0.2.0" - -json3@^3.3.2: - version "3.3.3" - resolved "https://registry.npm.taobao.org/json3/download/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" - integrity sha1-f8EON1/FrkLEcFpcwKpvYr4wW4E= - -json5@^0.5.0: - version "0.5.1" - resolved "https://registry.npm.taobao.org/json5/download/json5-0.5.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/json5/download/json5-1.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha1-d5+wAYYE+oVOrL9iUhgNg1Q+Pb4= - dependencies: - minimist "^1.2.0" - -json5@^2.1.0: - version "2.1.1" - resolved "https://registry.npm.taobao.org/json5/download/json5-2.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" - integrity sha1-gbbLBOm6SW8ccAXQe0NoomOPkLY= - dependencies: - minimist "^1.2.0" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.npm.taobao.org/jsprim/download/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -killable@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/killable/download/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" - integrity sha1-TIzkQRh6Bhx0dPuHygjipjgZSJI= - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha1-cpyR4thXt6QZofmqZWhcTDP1hF0= - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha1-ARRrNqYhjmTljzqNZt5df8b20FE= - -launch-editor-middleware@^2.2.1: - version "2.2.1" - resolved "https://registry.npm.taobao.org/launch-editor-middleware/download/launch-editor-middleware-2.2.1.tgz#e14b07e6c7154b0a4b86a0fd345784e45804c157" - integrity sha1-4UsH5scVSwpLhqD9NFeE5FgEwVc= - dependencies: - launch-editor "^2.2.1" - -launch-editor@^2.2.1: - version "2.2.1" - resolved "https://registry.npm.taobao.org/launch-editor/download/launch-editor-2.2.1.tgz#871b5a3ee39d6680fcc26d37930b6eeda89db0ca" - integrity sha1-hxtaPuOdZoD8wm03kwtu7aidsMo= - dependencies: - chalk "^2.3.0" - shell-quote "^1.6.1" - -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.npm.taobao.org/lazy-cache/download/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= - -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/lcid/download/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha1-bvXS32DlL4LrIopMNz6NHzlyU88= - dependencies: - invert-kv "^2.0.0" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.npm.taobao.org/levn/download/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.npm.taobao.org/lines-and-columns/download/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= - -loader-fs-cache@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/loader-fs-cache/download/loader-fs-cache-1.0.2.tgz#54cedf6b727e1779fd8f01205f05f6e88706f086" - integrity sha1-VM7fa3J+F3n9jwEgXwX26IcG8IY= - dependencies: - find-cache-dir "^0.1.1" - mkdirp "0.5.1" - -loader-runner@^2.3.1, loader-runner@^2.4.0: - version "2.4.0" - resolved "https://registry.npm.taobao.org/loader-runner/download/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" - integrity sha1-7UcGa/5TTX6ExMe5mYwqdWB9k1c= - -loader-utils@^0.2.16: - version "0.2.17" - resolved "https://registry.npm.taobao.org/loader-utils/download/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" - integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - object-assign "^4.0.1" - -loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: - version "1.2.3" - resolved "https://registry.npm.taobao.org/loader-utils/download/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" - integrity sha1-H/XcaRHJ8KBiUxpMBLYJQGEIwsc= - dependencies: - big.js "^5.2.2" - emojis-list "^2.0.0" - json5 "^1.0.1" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/locate-path/download/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4= - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha1-Gvujlq/WdqbUJQTQpno6frn2KqA= - dependencies: - p-locate "^4.1.0" - -lodash.defaultsdeep@^4.6.1: - version "4.6.1" - resolved "https://registry.npm.taobao.org/lodash.defaultsdeep/download/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" - integrity sha1-US6b1yHSctlOPTpjZT+hdRZ0HKY= - -lodash.kebabcase@^4.1.1: - version "4.1.1" - resolved "https://registry.npm.taobao.org/lodash.kebabcase/download/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" - integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= - -lodash.mapvalues@^4.6.0: - version "4.6.0" - resolved "https://registry.npm.taobao.org/lodash.mapvalues/download/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" - integrity sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw= - -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.npm.taobao.org/lodash.memoize/download/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - -lodash.toarray@^4.4.0: - version "4.4.0" - resolved "https://registry.npm.taobao.org/lodash.toarray/download/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" - integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE= - -lodash.transform@^4.6.0: - version "4.6.0" - resolved "https://registry.npm.taobao.org/lodash.transform/download/lodash.transform-4.6.0.tgz#12306422f63324aed8483d3f38332b5f670547a0" - integrity sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A= - -lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= - -lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3, lodash@^4.17.5: - version "4.17.15" - resolved "https://registry.npm.taobao.org/lodash/download/lodash-4.17.15.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha1-tEf2ZwoEVbv+7dETku/zMOoJdUg= - -log-symbols@^2.2.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/log-symbols/download/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - integrity sha1-V0Dhxdbw39pK2TI7UzIQfva0xAo= - dependencies: - chalk "^2.0.1" - -loglevel@^1.6.6: - version "1.6.6" - resolved "https://registry.npm.taobao.org/loglevel/download/loglevel-1.6.6.tgz?cache=0&sync_timestamp=1573147510261&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Floglevel%2Fdownload%2Floglevel-1.6.6.tgz#0ee6300cc058db6b3551fa1c4bf73b83bb771312" - integrity sha1-DuYwDMBY22s1UfocS/c7g7t3ExI= - -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/longest/download/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.npm.taobao.org/loose-envify/download/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8= - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lower-case@^1.1.1: - version "1.1.4" - resolved "https://registry.npm.taobao.org/lower-case/download/lower-case-1.1.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flower-case%2Fdownload%2Flower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" - integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= - -lru-cache@^4.0.1, lru-cache@^4.1.2: - version "4.1.5" - resolved "https://registry.npm.taobao.org/lru-cache/download/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha1-i75Q6oW+1ZvJ4z3KuCNe6bz0Q80= - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.npm.taobao.org/lru-cache/download/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha1-HaJ+ZxAnGUdpXa9oSOhH8B2EuSA= - dependencies: - yallist "^3.0.2" - -make-dir@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/make-dir/download/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha1-XwMQ4YuL6JjMBwCSlaMK5B6R5vU= - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -make-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/make-dir/download/make-dir-3.0.0.tgz#1b5f39f6b9270ed33f9f054c5c0f84304989f801" - integrity sha1-G1859rknDtM/nwVMXA+EMEmJ+AE= - dependencies: - semver "^6.0.0" - -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.npm.taobao.org/mamacro/download/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha1-rSyVdhl8nxq/MI0Hh4Zb2XWj8+Q= - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.npm.taobao.org/map-age-cleaner/download/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha1-fVg6cwZDTAVf5HSw9FB45uG0uSo= - dependencies: - p-defer "^1.0.0" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.npm.taobao.org/map-cache/download/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/map-visit/download/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.npm.taobao.org/md5.js/download/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha1-tdB7jjIW4+J81yjXL3DR5qNCAF8= - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -mdn-data@2.0.4: - version "2.0.4" - resolved "https://registry.npm.taobao.org/mdn-data/download/mdn-data-2.0.4.tgz?cache=0&sync_timestamp=1573816265745&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmdn-data%2Fdownload%2Fmdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" - integrity sha1-aZs8OKxvHXKAkaZGULZdOIUC/Vs= - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.npm.taobao.org/mem/download/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha1-Rhr0l7xK4JYIzbLmDu+2m/90QXg= - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -memory-fs@^0.4.1: - version "0.4.1" - resolved "https://registry.npm.taobao.org/memory-fs/download/memory-fs-0.4.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -memory-fs@^0.5.0: - version "0.5.0" - resolved "https://registry.npm.taobao.org/memory-fs/download/memory-fs-0.5.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" - integrity sha1-MkwBKIuIZSlm0WHbd4OHIIRajjw= - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -merge-source-map@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/merge-source-map/download/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" - integrity sha1-L93n5gIJOfcJBqaPLXrmheTIxkY= - dependencies: - source-map "^0.6.1" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/merge-stream/download/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A= - -merge2@^1.2.3: - version "1.3.0" - resolved "https://registry.npm.taobao.org/merge2/download/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" - integrity sha1-WzZu6DsvFYLEj4fkfPGpNSEDyoE= - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.npm.taobao.org/micromatch/download/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha1-cIWbyVyYQJUvNZoGij/En57PrCM= - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.npm.taobao.org/miller-rabin/download/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha1-8IA1HIZbDcViqEYpZtqlNUPHik0= - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mime-db@1.42.0, "mime-db@>= 1.40.0 < 2": - version "1.42.0" - resolved "https://registry.npm.taobao.org/mime-db/download/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" - integrity sha1-PiUpB7THrbkGWXtLZWNics+ee6w= - -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.25" - resolved "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" - integrity sha1-OXctRmIfk+KoCoVsU7hqYhVqZDc= - dependencies: - mime-db "1.42.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.npm.taobao.org/mime/download/mime-1.6.0.tgz?cache=0&sync_timestamp=1560034758817&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime%2Fdownload%2Fmime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE= - -mime@^2.4.4: - version "2.4.4" - resolved "https://registry.npm.taobao.org/mime/download/mime-2.4.4.tgz?cache=0&sync_timestamp=1560034758817&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime%2Fdownload%2Fmime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" - integrity sha1-vXuRE1/GsBzePpuuM9ZZtj2IV+U= - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/mimic-fn/download/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI= - -mimic-fn@^2.0.0, mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/mimic-fn/download/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs= - -mini-css-extract-plugin@^0.8.0: - version "0.8.2" - resolved "https://registry.npm.taobao.org/mini-css-extract-plugin/download/mini-css-extract-plugin-0.8.2.tgz?cache=0&sync_timestamp=1576856499989&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmini-css-extract-plugin%2Fdownload%2Fmini-css-extract-plugin-0.8.2.tgz#a875e169beb27c88af77dd962771c9eedc3da161" - integrity sha1-qHXhab6yfIivd92WJ3HJ7tw9oWE= - dependencies: - loader-utils "^1.1.0" - normalize-url "1.9.1" - schema-utils "^1.0.0" - webpack-sources "^1.1.0" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/minimalistic-assert/download/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha1-LhlN4ERibUoQ5/f7wAznPoPk1cc= - -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/minimalistic-crypto-utils/download/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM= - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.npm.taobao.org/minimist/download/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.0, minimist@~1.2.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.npm.taobao.org/minimist/download/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= - -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/minipass-collect/download/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha1-IrgTv3Rdxu26JXa5QAIq1u3Ixhc= - dependencies: - minipass "^3.0.0" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.npm.taobao.org/minipass-flush/download/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" - integrity sha1-gucTXX6JpQ/+ZGEKeHlTxMTLs3M= - dependencies: - minipass "^3.0.0" - -minipass-pipeline@^1.2.2: - version "1.2.2" - resolved "https://registry.npm.taobao.org/minipass-pipeline/download/minipass-pipeline-1.2.2.tgz#3dcb6bb4a546e32969c7ad710f2c79a86abba93a" - integrity sha1-PctrtKVG4ylpx61xDyx5qGq7qTo= - dependencies: - minipass "^3.0.0" - -minipass@^3.0.0, minipass@^3.1.1: - version "3.1.1" - resolved "https://registry.npm.taobao.org/minipass/download/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" - integrity sha1-dgfOd4RyoYWtbYkIKqIHD3nO3NU= - dependencies: - yallist "^4.0.0" - -mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/mississippi/download/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - integrity sha1-6goykfl+C16HdrNj1fChLZTGcCI= - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.npm.taobao.org/mixin-deep/download/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha1-ESC0PcNZp4Xc5ltVuC4lfM9HlWY= - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@0.5.1, mkdirp@^0.5.1, mkdirp@~0.5.1: - version "0.5.1" - resolved "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -moment@^2.21.0: - version "2.24.0" - resolved "https://registry.npm.taobao.org/moment/download/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" - integrity sha1-DQVdU/UFKqZTyfbraLtdEr9cK1s= - -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/ms/download/ms-2.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo= - -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk= - -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/multicast-dns-service-types/download/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^6.0.1: - version "6.2.3" - resolved "https://registry.npm.taobao.org/multicast-dns/download/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" - integrity sha1-oOx72QVcQoL3kMPIL04o2zsxsik= - dependencies: - dns-packet "^1.3.1" - thunky "^1.0.2" - -mutationobserver-shim@^0.3.2: - version "0.3.3" - resolved "https://registry.npm.taobao.org/mutationobserver-shim/download/mutationobserver-shim-0.3.3.tgz#65869630bc89d7bf8c9cd9cb82188cd955aacd2b" - integrity sha1-ZYaWMLyJ17+MnNnLghiM2VWqzSs= - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.npm.taobao.org/mute-stream/download/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - -mz@^2.4.0: - version "2.7.0" - resolved "https://registry.npm.taobao.org/mz/download/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha1-lQCAV6Vsr63CvGPd5/n/aVWUjjI= - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -nan@^2.12.1: - version "2.14.0" - resolved "https://registry.npm.taobao.org/nan/download/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha1-eBj3IgJ7JFmobwKV1DTR/CM2xSw= - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.npm.taobao.org/nanomatch/download/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk= - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npm.taobao.org/natural-compare/download/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs= - -neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1: - version "2.6.1" - resolved "https://registry.npm.taobao.org/neo-async/download/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha1-rCetpmFn+ohJpq3dg39rGJrSCBw= - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.npm.taobao.org/nice-try/download/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y= - -no-case@^2.2.0: - version "2.3.2" - resolved "https://registry.npm.taobao.org/no-case/download/no-case-2.3.2.tgz?cache=0&sync_timestamp=1576721537540&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fno-case%2Fdownload%2Fno-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" - integrity sha1-YLgTOWvjmz8SiKTB7V0efSi0ZKw= - dependencies: - lower-case "^1.1.1" - -node-emoji@^1.10.0: - version "1.10.0" - resolved "https://registry.npm.taobao.org/node-emoji/download/node-emoji-1.10.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-emoji%2Fdownload%2Fnode-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" - integrity sha1-iIar0l2ce7YYAqZYUj0fjSqJsto= - dependencies: - lodash.toarray "^4.4.0" - -node-forge@0.9.0: - version "0.9.0" - resolved "https://registry.npm.taobao.org/node-forge/download/node-forge-0.9.0.tgz?cache=0&sync_timestamp=1569524876130&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-forge%2Fdownload%2Fnode-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" - integrity sha1-1iQFDtu0SHStyhK7mlLsY8t4JXk= - -node-ipc@^9.1.1: - version "9.1.1" - resolved "https://registry.npm.taobao.org/node-ipc/download/node-ipc-9.1.1.tgz#4e245ed6938e65100e595ebc5dc34b16e8dd5d69" - integrity sha1-TiRe1pOOZRAOWV68XcNLFujdXWk= - dependencies: - event-pubsub "4.3.0" - js-message "1.0.5" - js-queue "2.0.0" - -node-libs-browser@^2.2.1: - version "2.2.1" - resolved "https://registry.npm.taobao.org/node-libs-browser/download/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" - integrity sha1-tk9RPRgzhiX5A0bSew0jXmMfZCU= - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^3.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.1" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.11.0" - vm-browserify "^1.0.1" - -node-releases@^1.1.44: - version "1.1.44" - resolved "https://registry.npm.taobao.org/node-releases/download/node-releases-1.1.44.tgz?cache=0&sync_timestamp=1577231700151&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-releases%2Fdownload%2Fnode-releases-1.1.44.tgz#cd66438a6eb875e3eb012b6a12e48d9f4326ffd7" - integrity sha1-zWZDim64dePrAStqEuSNn0Mm/9c= - dependencies: - semver "^6.3.0" - -normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.npm.taobao.org/normalize-package-data/download/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha1-5m2xg4sgDB38IzIl0SyzZSDiNKg= - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/normalize-path/download/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" - integrity sha1-MtDkcvkf80VwHBWoMRAY07CpA3k= - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/normalize-path/download/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/normalize-path/download/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU= - -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.npm.taobao.org/normalize-range/download/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= - -normalize-url@1.9.1: - version "1.9.1" - resolved "https://registry.npm.taobao.org/normalize-url/download/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" - integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= - dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" - -normalize-url@^3.0.0: - version "3.3.0" - resolved "https://registry.npm.taobao.org/normalize-url/download/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" - integrity sha1-suHE3E98bVd0PfczpPWXjRhlBVk= - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-2.0.2.tgz?cache=0&sync_timestamp=1577053500910&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnpm-run-path%2Fdownload%2Fnpm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npm-run-path@^4.0.0: - version "4.0.1" - resolved "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-4.0.1.tgz?cache=0&sync_timestamp=1577053500910&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnpm-run-path%2Fdownload%2Fnpm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha1-t+zR5e1T2o43pV4cImnguX7XSOo= - dependencies: - path-key "^3.0.0" - -nth-check@^1.0.2, nth-check@~1.0.1: - version "1.0.2" - resolved "https://registry.npm.taobao.org/nth-check/download/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha1-sr0pXDfj3VijvwcAN2Zjuk2c8Fw= - dependencies: - boolbase "~1.0.0" - -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.npm.taobao.org/num2fraction/download/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/number-is-nan/download/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.npm.taobao.org/oauth-sign/download/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU= - -object-assign@4.x, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.npm.taobao.org/object-copy/download/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-hash@^1.1.4: - version "1.3.1" - resolved "https://registry.npm.taobao.org/object-hash/download/object-hash-1.3.1.tgz?cache=0&sync_timestamp=1575157999857&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject-hash%2Fdownload%2Fobject-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" - integrity sha1-/eRSCYqVHLFF8Dm7fUVUSd3BJt8= - -object-inspect@^1.7.0, object-inspect@~1.7.0: - version "1.7.0" - resolved "https://registry.npm.taobao.org/object-inspect/download/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha1-9Pa9GBrXfwBrXs5gvQtvOY/3Smc= - -object-is@^1.0.1: - version "1.0.2" - resolved "https://registry.npm.taobao.org/object-is/download/object-is-1.0.2.tgz?cache=0&sync_timestamp=1576479681769&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject-is%2Fdownload%2Fobject-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4" - integrity sha1-a4DrhP5FFJj2UAeYLwNaW0Re3sQ= - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/object-keys/download/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha1-HEfyct8nfzsdrwYWd9nILiMixg4= - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/object-visit/download/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/object.assign/download/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha1-lovxEA15Vrs8oIbwBvhGs7xACNo= - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.getownpropertydescriptors@^2.0.3: - version "2.1.0" - resolved "https://registry.npm.taobao.org/object.getownpropertydescriptors/download/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha1-Npvx+VktiridcS3O1cuBx8U1Jkk= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.npm.taobao.org/object.pick/download/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -object.values@^1.1.0: - version "1.1.1" - resolved "https://registry.npm.taobao.org/object.values/download/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha1-aKmezeNWt+kpWjxeDOMdyMlT3l4= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - has "^1.0.3" - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/obuf/download/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha1-Cb6jND1BhZ69RGKS0RydTbYZCE4= - -omit.js@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/omit.js/download/omit.js-1.0.2.tgz#91a14f0eba84066dfa015bf30e474c47f30bc858" - integrity sha1-kaFPDrqEBm36AVvzDkdMR/MLyFg= - dependencies: - babel-runtime "^6.23.0" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/on-headers/download/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha1-dysK5qqlJcOZ5Imt+tkMQD6zwo8= - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/onetime/download/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= - dependencies: - mimic-fn "^1.0.0" - -onetime@^5.1.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/onetime/download/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" - integrity sha1-//DzyRYX/mK7UBiWNumayKbfe+U= - dependencies: - mimic-fn "^2.1.0" - -open@^6.3.0: - version "6.4.0" - resolved "https://registry.npm.taobao.org/open/download/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" - integrity sha1-XBPpbQ3IlGhhZPGJZez+iJ7PyKk= - dependencies: - is-wsl "^1.1.0" - -opener@^1.5.1: - version "1.5.1" - resolved "https://registry.npm.taobao.org/opener/download/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" - integrity sha1-bS8Od/GgrwAyrKcWwsH7uOfoq+0= - -opn@^5.5.0: - version "5.5.0" - resolved "https://registry.npm.taobao.org/opn/download/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" - integrity sha1-/HFk+rVtI1kExRw7J9pnWMo7m/w= - dependencies: - is-wsl "^1.1.0" - -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.npm.taobao.org/optimist/download/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - -optionator@^0.8.2: - version "0.8.3" - resolved "https://registry.npm.taobao.org/optionator/download/optionator-0.8.3.tgz?cache=0&sync_timestamp=1573078174520&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Foptionator%2Fdownload%2Foptionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha1-hPodA2/p08fiHZmIS2ARZ+yPtJU= - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -ora@^3.4.0: - version "3.4.0" - resolved "https://registry.npm.taobao.org/ora/download/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" - integrity sha1-vwdSSRBZo+8+1MhQl1Md6f280xg= - dependencies: - chalk "^2.4.2" - cli-cursor "^2.1.0" - cli-spinners "^2.0.0" - log-symbols "^2.2.0" - strip-ansi "^5.2.0" - wcwidth "^1.0.1" - -original@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/original/download/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" - integrity sha1-5EKmHP/hxf0gpl8yYcJmY7MD8l8= - dependencies: - url-parse "^1.4.3" - -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.npm.taobao.org/os-browserify/download/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= - -os-locale@^3.0.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/os-locale/download/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha1-qAKm7hfyTBBIOrmTVxnO9O0Wvxo= - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/os-tmpdir/download/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/p-defer/download/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/p-finally/download/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-finally@^2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/p-finally/download/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" - integrity sha1-vW/KqcVZoJa2gIBvTWV7Pw8kBWE= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/p-is-promise/download/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha1-kYzrrqJIpiz3/6uOO8qMX4gvxC4= - -p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1: - version "2.2.2" - resolved "https://registry.npm.taobao.org/p-limit/download/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha1-YSebZ3IfUoeqHBOpp/u8SMkpGx4= - dependencies: - p-try "^2.0.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/p-locate/download/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ= - dependencies: - p-limit "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.npm.taobao.org/p-locate/download/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha1-o0KLtwiLOmApL2aRkni3wpetTwc= - dependencies: - p-limit "^2.2.0" - -p-map@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/p-map/download/p-map-2.1.0.tgz?cache=0&sync_timestamp=1563032875018&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-map%2Fdownload%2Fp-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha1-MQko/u+cnsxltosXaTAYpmXOoXU= - -p-map@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/p-map/download/p-map-3.0.0.tgz?cache=0&sync_timestamp=1563032875018&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-map%2Fdownload%2Fp-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" - integrity sha1-1wTZr4orpoTiYA2aIVmD1BQal50= - dependencies: - aggregate-error "^3.0.0" - -p-retry@^3.0.1: - version "3.0.1" - resolved "https://registry.npm.taobao.org/p-retry/download/p-retry-3.0.1.tgz?cache=0&sync_timestamp=1572521210242&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-retry%2Fdownload%2Fp-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" - integrity sha1-MWtMiJPiyNwc+okfQGxLQivr8yg= - dependencies: - retry "^0.12.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha1-yyhoVA4xPWHeWPr741zpAE1VQOY= - -pako@~1.0.5: - version "1.0.10" - resolved "https://registry.npm.taobao.org/pako/download/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" - integrity sha1-Qyi621CGpCaqkPVBl31JVdpclzI= - -parallel-transform@^1.1.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/parallel-transform/download/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" - integrity sha1-kEnKN9bLIYLDsdLHIL6U0UpYFPw= - dependencies: - cyclist "^1.0.1" - inherits "^2.0.3" - readable-stream "^2.1.5" - -param-case@2.1.x: - version "2.1.1" - resolved "https://registry.npm.taobao.org/param-case/download/param-case-2.1.1.tgz?cache=0&sync_timestamp=1576721509342&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparam-case%2Fdownload%2Fparam-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" - integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= - dependencies: - no-case "^2.2.0" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/parent-module/download/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha1-aR0nCeeMefrjoVZiJFLQB2LKqqI= - dependencies: - callsites "^3.0.0" - -parse-asn1@^5.0.0: - version "5.1.5" - resolved "https://registry.npm.taobao.org/parse-asn1/download/parse-asn1-5.1.5.tgz?cache=0&sync_timestamp=1568806095714&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-asn1%2Fdownload%2Fparse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" - integrity sha1-ADJxND2ljclMrOSU+u89IUfs6g4= - dependencies: - asn1.js "^4.0.0" - browserify-aes "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/parse-json/download/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0: - version "5.0.0" - resolved "https://registry.npm.taobao.org/parse-json/download/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" - integrity sha1-c+URTJhtFD76NxLU6iTbmkJm9g8= - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - lines-and-columns "^1.1.6" - -parse5-htmlparser2-tree-adapter@^5.1.1: - version "5.1.1" - resolved "https://registry.npm.taobao.org/parse5-htmlparser2-tree-adapter/download/parse5-htmlparser2-tree-adapter-5.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse5-htmlparser2-tree-adapter%2Fdownload%2Fparse5-htmlparser2-tree-adapter-5.1.1.tgz#e8c743d4e92194d5293ecde2b08be31e67461cbc" - integrity sha1-6MdD1OkhlNUpPs3isIvjHmdGHLw= - dependencies: - parse5 "^5.1.1" - -parse5@^5.1.1: - version "5.1.1" - resolved "https://registry.npm.taobao.org/parse5/download/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" - integrity sha1-9o5OW6GFKsLK3AD0VV//bCq7YXg= - -parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ= - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.npm.taobao.org/pascalcase/download/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.npm.taobao.org/path-browserify/download/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" - integrity sha1-5sTd1+06onxoogzE5Q4aTug7vEo= - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/path-dirname/download/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/path-exists/download/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/path-exists/download/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/path-exists/download/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha1-UTvb4tO5XXdi6METfvoZXGxhtbM= - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/path-is-inside/download/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/path-key/download/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.npm.taobao.org/path-key/download/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.npm.taobao.org/path-parse/download/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha1-1i27VnlAXXLEc37FhgDp3c8G0kw= - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/path-type/download/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha1-zvMdyOCho7sNEFwM2Xzzv0f0428= - dependencies: - pify "^3.0.0" - -pbkdf2@^3.0.3: - version "3.0.17" - resolved "https://registry.npm.taobao.org/pbkdf2/download/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" - integrity sha1-l2wgZTBhexTrsyEUI597CTNuk6Y= - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.npm.taobao.org/pify/download/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/pify/download/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE= - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/pinkie-promise/download/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.npm.taobao.org/pinkie/download/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= - dependencies: - find-up "^1.0.0" - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha1-J0kCDyOe2ZCIGx9xIQ1R62UjvqM= - dependencies: - find-up "^3.0.0" - -pkg-dir@^4.1.0: - version "4.2.0" - resolved "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha1-8JkTPfft5CLoHR2ESCcO6z5CYfM= - dependencies: - find-up "^4.0.0" - -portfinder@^1.0.25: - version "1.0.25" - resolved "https://registry.npm.taobao.org/portfinder/download/portfinder-1.0.25.tgz#254fd337ffba869f4b9d37edc298059cb4d35eca" - integrity sha1-JU/TN/+6hp9LnTftwpgFnLTTXso= - dependencies: - async "^2.6.2" - debug "^3.1.1" - mkdirp "^0.5.1" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.npm.taobao.org/posix-character-classes/download/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -postcss-calc@^7.0.1: - version "7.0.1" - resolved "https://registry.npm.taobao.org/postcss-calc/download/postcss-calc-7.0.1.tgz#36d77bab023b0ecbb9789d84dcb23c4941145436" - integrity sha1-Ntd7qwI7Dsu5eJ2E3LI8SUEUVDY= - dependencies: - css-unit-converter "^1.1.1" - postcss "^7.0.5" - postcss-selector-parser "^5.0.0-rc.4" - postcss-value-parser "^3.3.1" - -postcss-colormin@^4.0.3: - version "4.0.3" - resolved "https://registry.npm.taobao.org/postcss-colormin/download/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" - integrity sha1-rgYLzpPteUrHEmTwgTLVUJVr04E= - dependencies: - browserslist "^4.0.0" - color "^3.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-convert-values@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-convert-values/download/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" - integrity sha1-yjgT7U2g+BL51DcDWE5Enr4Ymn8= - dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-discard-comments@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-discard-comments/download/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" - integrity sha1-H7q9LCRr/2qq15l7KwkY9NevQDM= - dependencies: - postcss "^7.0.0" - -postcss-discard-duplicates@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-discard-duplicates/download/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" - integrity sha1-P+EzzTyCKC5VD8myORdqkge3hOs= - dependencies: - postcss "^7.0.0" - -postcss-discard-empty@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-discard-empty/download/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" - integrity sha1-yMlR6fc+2UKAGUWERKAq2Qu592U= - dependencies: - postcss "^7.0.0" - -postcss-discard-overridden@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-discard-overridden/download/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" - integrity sha1-ZSrvipZybwKfXj4AFG7npOdV/1c= - dependencies: - postcss "^7.0.0" - -postcss-load-config@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/postcss-load-config/download/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003" - integrity sha1-yE1pK3u3tB3c7ZTuYuirMbQXsAM= - dependencies: - cosmiconfig "^5.0.0" - import-cwd "^2.0.0" - -postcss-loader@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/postcss-loader/download/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" - integrity sha1-a5eUPkfHLYRfqeA/Jzdz1OjdbC0= - dependencies: - loader-utils "^1.1.0" - postcss "^7.0.0" - postcss-load-config "^2.0.0" - schema-utils "^1.0.0" - -postcss-merge-longhand@^4.0.11: - version "4.0.11" - resolved "https://registry.npm.taobao.org/postcss-merge-longhand/download/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" - integrity sha1-YvSaE+Sg7gTnuY9CuxYGLKJUniQ= - dependencies: - css-color-names "0.0.4" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - stylehacks "^4.0.0" - -postcss-merge-rules@^4.0.3: - version "4.0.3" - resolved "https://registry.npm.taobao.org/postcss-merge-rules/download/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" - integrity sha1-NivqT/Wh+Y5AdacTxsslrv75plA= - dependencies: - browserslist "^4.0.0" - caniuse-api "^3.0.0" - cssnano-util-same-parent "^4.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - vendors "^1.0.0" - -postcss-minify-font-values@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-minify-font-values/download/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" - integrity sha1-zUw0TM5HQ0P6xdgiBqssvLiv1aY= - dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-minify-gradients@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-minify-gradients/download/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" - integrity sha1-k7KcL/UJnFNe7NpWxKpuZlpmNHE= - dependencies: - cssnano-util-get-arguments "^4.0.0" - is-color-stop "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-minify-params@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-minify-params/download/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" - integrity sha1-a5zvAwwR41Jh+V9hjJADbWgNuHQ= - dependencies: - alphanum-sort "^1.0.0" - browserslist "^4.0.0" - cssnano-util-get-arguments "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - uniqs "^2.0.0" - -postcss-minify-selectors@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-minify-selectors/download/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" - integrity sha1-4uXrQL/uUA0M2SQ1APX46kJi+9g= - dependencies: - alphanum-sort "^1.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - -postcss-modules-extract-imports@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/postcss-modules-extract-imports/download/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" - integrity sha1-gYcZoa4doyX5gyRGsBE27rSTzX4= - dependencies: - postcss "^7.0.5" - -postcss-modules-local-by-default@^3.0.2: - version "3.0.2" - resolved "https://registry.npm.taobao.org/postcss-modules-local-by-default/download/postcss-modules-local-by-default-3.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-local-by-default%2Fdownload%2Fpostcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915" - integrity sha1-6KZWG+kUqvPAUodjd1JMqQ27eRU= - dependencies: - icss-utils "^4.1.1" - postcss "^7.0.16" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.0.0" - -postcss-modules-scope@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/postcss-modules-scope/download/postcss-modules-scope-2.1.1.tgz?cache=0&sync_timestamp=1574936987092&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-modules-scope%2Fdownload%2Fpostcss-modules-scope-2.1.1.tgz#33d4fc946602eb5e9355c4165d68a10727689dba" - integrity sha1-M9T8lGYC616TVcQWXWihBydonbo= - dependencies: - postcss "^7.0.6" - postcss-selector-parser "^6.0.0" - -postcss-modules-values@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/postcss-modules-values/download/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" - integrity sha1-W1AA1uuuKbQlUwG0o6VFdEI+fxA= - dependencies: - icss-utils "^4.0.0" - postcss "^7.0.6" - -postcss-normalize-charset@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-normalize-charset/download/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" - integrity sha1-izWt067oOhNrBHHg1ZvlilAoXdQ= - dependencies: - postcss "^7.0.0" - -postcss-normalize-display-values@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-normalize-display-values/download/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" - integrity sha1-Db4EpM6QY9RmftK+R2u4MMglk1o= - dependencies: - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-positions@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-normalize-positions/download/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" - integrity sha1-BfdX+E8mBDc3g2ipH4ky1LECkX8= - dependencies: - cssnano-util-get-arguments "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-repeat-style@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-normalize-repeat-style/download/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" - integrity sha1-xOu8KJ85kaAo1EdRy90RkYsXkQw= - dependencies: - cssnano-util-get-arguments "^4.0.0" - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-string@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-normalize-string/download/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" - integrity sha1-zUTECrB6DHo23F6Zqs4eyk7CaQw= - dependencies: - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-timing-functions@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-normalize-timing-functions/download/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" - integrity sha1-jgCcoqOUnNr4rSPmtquZy159KNk= - dependencies: - cssnano-util-get-match "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-unicode@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-normalize-unicode/download/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" - integrity sha1-hBvUj9zzAZrUuqdJOj02O1KuHPs= - dependencies: - browserslist "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-url@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-normalize-url/download/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" - integrity sha1-EOQ3+GvHx+WPe5ZS7YeNqqlfquE= - dependencies: - is-absolute-url "^2.0.0" - normalize-url "^3.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-normalize-whitespace@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-normalize-whitespace/download/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" - integrity sha1-vx1AcP5Pzqh9E0joJdjMDF+qfYI= - dependencies: - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-ordered-values@^4.1.2: - version "4.1.2" - resolved "https://registry.npm.taobao.org/postcss-ordered-values/download/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" - integrity sha1-DPdcgg7H1cTSgBiVWeC1ceusDu4= - dependencies: - cssnano-util-get-arguments "^4.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-reduce-initial@^4.0.3: - version "4.0.3" - resolved "https://registry.npm.taobao.org/postcss-reduce-initial/download/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" - integrity sha1-f9QuvqXpyBRgljniwuhK4nC6SN8= - dependencies: - browserslist "^4.0.0" - caniuse-api "^3.0.0" - has "^1.0.0" - postcss "^7.0.0" - -postcss-reduce-transforms@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-reduce-transforms/download/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" - integrity sha1-F++kBerMbge+NBSlyi0QdGgdTik= - dependencies: - cssnano-util-get-match "^4.0.0" - has "^1.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - -postcss-selector-parser@^3.0.0: - version "3.1.1" - resolved "https://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-3.1.1.tgz#4f875f4afb0c96573d5cf4d74011aee250a7e865" - integrity sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU= - dependencies: - dot-prop "^4.1.1" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-selector-parser@^5.0.0, postcss-selector-parser@^5.0.0-rc.4: - version "5.0.0" - resolved "https://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" - integrity sha1-JJBENWaXsztk8aj3yAki3d7nGVw= - dependencies: - cssesc "^2.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: - version "6.0.2" - resolved "https://registry.npm.taobao.org/postcss-selector-parser/download/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" - integrity sha1-k0z3mdAWyDQRhZ4J3Oyt4BKG7Fw= - dependencies: - cssesc "^3.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-svgo@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-svgo/download/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" - integrity sha1-F7mXvHEbMzurFDqu07jT1uPTglg= - dependencies: - is-svg "^3.0.0" - postcss "^7.0.0" - postcss-value-parser "^3.0.0" - svgo "^1.0.0" - -postcss-unique-selectors@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/postcss-unique-selectors/download/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" - integrity sha1-lEaRHzKJv9ZMbWgPBzwDsfnuS6w= - dependencies: - alphanum-sort "^1.0.0" - postcss "^7.0.0" - uniqs "^2.0.0" - -postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.1: - version "3.3.1" - resolved "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" - integrity sha1-n/giVH4okyE88cMO+lGsX9G6goE= - -postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2: - version "4.0.2" - resolved "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" - integrity sha1-SCKCwJpCcG0fyaBptz9E7Ag5Hck= - -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.23, postcss@^7.0.5, postcss@^7.0.6: - version "7.0.26" - resolved "https://registry.npm.taobao.org/postcss/download/postcss-7.0.26.tgz?cache=0&sync_timestamp=1577751206655&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss%2Fdownload%2Fpostcss-7.0.26.tgz#5ed615cfcab35ba9bbb82414a4fa88ea10429587" - integrity sha1-XtYVz8qzW6m7uCQUpPqI6hBClYc= - dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.1.0" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/prelude-ls/download/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -prepend-http@^1.0.0: - version "1.0.4" - resolved "https://registry.npm.taobao.org/prepend-http/download/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - -prettier@^1.18.2: - version "1.19.1" - resolved "https://registry.npm.taobao.org/prettier/download/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha1-99f1/4qc2HKnvkyhQglZVqYHl8s= - -pretty-error@^2.0.2: - version "2.1.1" - resolved "https://registry.npm.taobao.org/pretty-error/download/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" - integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= - dependencies: - renderkid "^2.0.1" - utila "~0.4" - -private@^0.1.6: - version "0.1.8" - resolved "https://registry.npm.taobao.org/private/download/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha1-I4Hts2ifelPWUxkAYPz4ItLzaP8= - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha1-eCDZsWEgzFXKmud5JoCufbptf+I= - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.npm.taobao.org/process/download/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.npm.taobao.org/progress/download/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha1-foz42PW48jnBvGi+tOt4Vn1XLvg= - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/promise-inflight/download/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= - -proxy-addr@~2.0.5: - version "2.0.5" - resolved "https://registry.npm.taobao.org/proxy-addr/download/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" - integrity sha1-NMvWSi2B9LH9IedvnwbIpFKZ7jQ= - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.0" - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/prr/download/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/pseudomap/download/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.24, psl@^1.1.28: - version "1.7.0" - resolved "https://registry.npm.taobao.org/psl/download/psl-1.7.0.tgz?cache=0&sync_timestamp=1577538558975&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpsl%2Fdownload%2Fpsl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" - integrity sha1-8cTEeo75cWfepda79IFtc26ISjw= - -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.npm.taobao.org/public-encrypt/download/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha1-T8ydd6B+SLp1J+fL4N4z0HATMeA= - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/pump/download/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha1-Ejma3W5M91Jtlzy8i1zi4pCLOQk= - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/pump/download/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ= - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.npm.taobao.org/pumpify/download/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha1-NlE74karJ1cLGjdKXOJ4v9dDcM4= - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.npm.taobao.org/punycode/download/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@^1.2.4, punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.npm.taobao.org/punycode/download/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha1-tYsBCsQMIsVldhbI0sLALHv0eew= - -q@^1.1.2: - version "1.5.1" - resolved "https://registry.npm.taobao.org/q/download/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= - -qs@6.7.0: - version "6.7.0" - resolved "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha1-QdwaAV49WB8WIXdr4xr7KHapsbw= - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha1-yzroBuh0BERYTvFUzo7pjUA/PjY= - -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.npm.taobao.org/query-string/download/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" - integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -querystring-es3@^0.2.0: - version "0.2.1" - resolved "https://registry.npm.taobao.org/querystring-es3/download/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.npm.taobao.org/querystring/download/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -querystringify@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/querystringify/download/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" - integrity sha1-YOWl/WSn+L+k0qsu1v30yFutFU4= - -raf@^3.4.0: - version "3.4.1" - resolved "https://registry.npm.taobao.org/raf/download/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" - integrity sha1-B0LpmkplUvRF1z4+4DKK8P8e3jk= - dependencies: - performance-now "^2.1.0" - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.1.0" - resolved "https://registry.npm.taobao.org/randombytes/download/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo= - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.npm.taobao.org/randomfill/download/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha1-ySGW/IarQr6YPxvzF3giSTHWFFg= - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.npm.taobao.org/range-parser/download/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE= - -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.npm.taobao.org/raw-body/download/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha1-oc5vucm8NWylLoklarWQWeE9AzI= - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - -read-pkg@^5.1.1: - version "5.2.0" - resolved "https://registry.npm.taobao.org/read-pkg/download/read-pkg-5.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg%2Fdownload%2Fread-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - integrity sha1-e/KVQ4yloz5WzTDgU7NO5yUMk8w= - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6, readable-stream@^3.1.1: - version "3.4.0" - resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" - integrity sha1-pRwmdUZY4KPCHb9ZFjvUW6b0R/w= - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.npm.taobao.org/readdirp/download/readdirp-2.2.1.tgz?cache=0&sync_timestamp=1575629866543&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freaddirp%2Fdownload%2Freaddirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha1-DodiKjMlqjPokihcr4tOhGUppSU= - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - -regenerate-unicode-properties@^8.1.0: - version "8.1.0" - resolved "https://registry.npm.taobao.org/regenerate-unicode-properties/download/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" - integrity sha1-71Hg8OpK1CS3e/fLQfPgFccKPw4= - dependencies: - regenerate "^1.4.0" - -regenerate@^1.4.0: - version "1.4.0" - resolved "https://registry.npm.taobao.org/regenerate/download/regenerate-1.4.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerate%2Fdownload%2Fregenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - integrity sha1-SoVuxLVuQHfFV1icroXnpMiGmhE= - -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.11.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha1-vgWtf5v30i4Fb5cmzuUBf78Z4uk= - -regenerator-runtime@^0.13.2: - version "0.13.3" - resolved "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.13.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" - integrity sha1-fPanfY9cb2Drc8X8GVWyzrAea/U= - -regenerator-transform@^0.14.0: - version "0.14.1" - resolved "https://registry.npm.taobao.org/regenerator-transform/download/regenerator-transform-0.14.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-transform%2Fdownload%2Fregenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb" - integrity sha1-Oy/OThq3cywI9mXf2zFHScfd0vs= - dependencies: - private "^0.1.6" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.npm.taobao.org/regex-not/download/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw= - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp.prototype.flags@^1.2.0: - version "1.3.0" - resolved "https://registry.npm.taobao.org/regexp.prototype.flags/download/regexp.prototype.flags-1.3.0.tgz?cache=0&sync_timestamp=1576388141321&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregexp.prototype.flags%2Fdownload%2Fregexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha1-erqJs8E6ZFCdq888qNn7ub31y3U= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/regexpp/download/regexpp-2.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregexpp%2Fdownload%2Fregexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha1-jRnTHPYySCtYkEn4KB+T28uk0H8= - -regexpu-core@^4.6.0: - version "4.6.0" - resolved "https://registry.npm.taobao.org/regexpu-core/download/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" - integrity sha1-IDfBizJ8/Oim/qKk7EQfJDKvuLY= - dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.1.0" - regjsgen "^0.5.0" - regjsparser "^0.6.0" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.1.0" - -regjsgen@^0.5.0: - version "0.5.1" - resolved "https://registry.npm.taobao.org/regjsgen/download/regjsgen-0.5.1.tgz?cache=0&sync_timestamp=1571560410206&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregjsgen%2Fdownload%2Fregjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" - integrity sha1-SPC/Gl6iBRlpKcDZeYtC0e2YRDw= - -regjsparser@^0.6.0: - version "0.6.2" - resolved "https://registry.npm.taobao.org/regjsparser/download/regjsparser-0.6.2.tgz?cache=0&sync_timestamp=1576908177912&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregjsparser%2Fdownload%2Fregjsparser-0.6.2.tgz#fd62c753991467d9d1ffe0a9f67f27a529024b96" - integrity sha1-/WLHU5kUZ9nR/+Cp9n8npSkCS5Y= - dependencies: - jsesc "~0.5.0" - -relateurl@0.2.x: - version "0.2.7" - resolved "https://registry.npm.taobao.org/relateurl/download/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.npm.taobao.org/remove-trailing-separator/download/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -renderkid@^2.0.1: - version "2.0.3" - resolved "https://registry.npm.taobao.org/renderkid/download/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" - integrity sha1-OAF5wv9a4TZcUivy/Pz/AcW3QUk= - dependencies: - css-select "^1.1.0" - dom-converter "^0.2" - htmlparser2 "^3.3.0" - strip-ansi "^3.0.0" - utila "^0.4.0" - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.npm.taobao.org/repeat-element/download/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha1-eC4NglwMWjuzlzH4Tv7mt0Lmsc4= - -repeat-string@^1.5.2, repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.npm.taobao.org/repeat-string/download/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -request-promise-core@1.1.3: - version "1.1.3" - resolved "https://registry.npm.taobao.org/request-promise-core/download/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" - integrity sha1-6aPAgbUTgN/qZ3M2Bh/qh5qCnuk= - dependencies: - lodash "^4.17.15" - -request-promise-native@^1.0.8: - version "1.0.8" - resolved "https://registry.npm.taobao.org/request-promise-native/download/request-promise-native-1.0.8.tgz?cache=0&sync_timestamp=1572829683581&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frequest-promise-native%2Fdownload%2Frequest-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" - integrity sha1-pFW5YLgm5E4r+Jma9k3/K/5YyzY= - dependencies: - request-promise-core "1.1.3" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.87.0: - version "2.88.0" - resolved "https://registry.npm.taobao.org/request/download/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha1-nC/KT301tZLv5Xx/ClXoEFIST+8= - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.0" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.4.3" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/require-directory/download/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/require-main-filename/download/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/require-main-filename/download/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha1-0LMp7MfMD2Fkn2IhW+aa9UqomJs= - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/requires-port/download/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= - -resize-observer-polyfill@^1.5.1: - version "1.5.1" - resolved "https://registry.npm.taobao.org/resize-observer-polyfill/download/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" - integrity sha1-DpAg3T0hAkRY1OvSfiPkAmmBBGQ= - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/resolve-cwd/download/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/resolve-from/download/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/resolve-from/download/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY= - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.npm.taobao.org/resolve-url/download/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@^1.10.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.8.1, resolve@~1.14.1: - version "1.14.1" - resolved "https://registry.npm.taobao.org/resolve/download/resolve-1.14.1.tgz?cache=0&sync_timestamp=1577139902451&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fresolve%2Fdownload%2Fresolve-1.14.1.tgz#9e018c540fcf0c427d678b9931cbf45e984bcaff" - integrity sha1-ngGMVA/PDEJ9Z4uZMcv0XphLyv8= - dependencies: - path-parse "^1.0.6" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/restore-cursor/download/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -resumer@~0.0.0: - version "0.0.0" - resolved "https://registry.npm.taobao.org/resumer/download/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" - integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= - dependencies: - through "~2.3.4" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.npm.taobao.org/ret/download/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w= - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.npm.taobao.org/retry/download/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - -rgb-regex@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/rgb-regex/download/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" - integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= - -rgba-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/rgba-regex/download/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" - integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= - -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.npm.taobao.org/right-align/download/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - integrity sha1-YTObci/mo1FWiSENJOFMlhSGE+8= - dependencies: - align-text "^0.1.1" - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.npm.taobao.org/rimraf/download/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha1-stEE/g2Psnz54KHNqCYt04M8bKs= - dependencies: - glob "^7.1.3" - -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1: - version "2.7.1" - resolved "https://registry.npm.taobao.org/rimraf/download/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha1-NXl/E6f9rcVmFCwp1PB8ytSD4+w= - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.npm.taobao.org/ripemd160/download/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha1-ocGm9iR1FXe6XQeRTLyShQWFiQw= - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rollup@^0.25.8: - version "0.25.8" - resolved "https://registry.npm.taobao.org/rollup/download/rollup-0.25.8.tgz?cache=0&sync_timestamp=1577029997952&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frollup%2Fdownload%2Frollup-0.25.8.tgz#bf6ce83b87510d163446eeaa577ed6a6fc5835e0" - integrity sha1-v2zoO4dRDRY0Ru6qV37WpvxYNeA= - dependencies: - chalk "^1.1.1" - minimist "^1.2.0" - source-map-support "^0.3.2" - -run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.npm.taobao.org/run-async/download/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= - dependencies: - is-promise "^2.1.0" - -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/run-queue/download/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= - dependencies: - aproba "^1.1.1" - -rw@^1.3.2: - version "1.3.3" - resolved "https://registry.npm.taobao.org/rw/download/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" - integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q= - -rxjs@^6.4.0: - version "6.5.4" - resolved "https://registry.npm.taobao.org/rxjs/download/rxjs-6.5.4.tgz?cache=0&sync_timestamp=1577464542639&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frxjs%2Fdownload%2Frxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" - integrity sha1-4Hd/4NGEzseHLfFH8wNXLUFOIRw= - dependencies: - tslib "^1.9.0" - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha1-mR7GnSluAxN0fVm9/St0XDX4go0= - -safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha1-t02uxJsRSPiMZLaNSbHoFcHy9Rk= - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/safe-regex/download/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsafer-buffer%2Fdownload%2Fsafer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo= - -sax@~1.2.4: - version "1.2.4" - resolved "https://registry.npm.taobao.org/sax/download/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha1-KBYjTiN4vdxOU1T6tcqold9xANk= - -schema-utils@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/schema-utils/download/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" - integrity sha1-C3mpMgTXtgDUsoUNH2bCo0lRx3A= - dependencies: - ajv "^6.1.0" - ajv-errors "^1.0.0" - ajv-keywords "^3.1.0" - -schema-utils@^2.0.0, schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.1: - version "2.6.1" - resolved "https://registry.npm.taobao.org/schema-utils/download/schema-utils-2.6.1.tgz#eb78f0b945c7bcfa2082b3565e8db3548011dc4f" - integrity sha1-63jwuUXHvPoggrNWXo2zVIAR3E8= - dependencies: - ajv "^6.10.2" - ajv-keywords "^3.4.1" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/select-hose/download/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= - -selfsigned@^1.10.7: - version "1.10.7" - resolved "https://registry.npm.taobao.org/selfsigned/download/selfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b" - integrity sha1-2lgZ/QSdVXTyjoipvMbbxubzkGs= - dependencies: - node-forge "0.9.0" - -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha1-qVT5Ma66UI0we78Gnv8MAclhFvc= - -semver@7.0.0: - version "7.0.0" - resolved "https://registry.npm.taobao.org/semver/download/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha1-XzyjV2HkfgWyBsba/yz4FPAxa44= - -semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.npm.taobao.org/semver/download/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0= - -send@0.17.1: - version "0.17.1" - resolved "https://registry.npm.taobao.org/send/download/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha1-wdiwWfeQD3Rm3Uk4vcROEd2zdsg= - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.7.2" - mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -serialize-javascript@^2.1.2: - version "2.1.2" - resolved "https://registry.npm.taobao.org/serialize-javascript/download/serialize-javascript-2.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-javascript%2Fdownload%2Fserialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" - integrity sha1-7OxTsOAxe9yV73arcHS3OEeF+mE= - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.npm.taobao.org/serve-index/download/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.npm.taobao.org/serve-static/download/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha1-Zm5jbcTwEPfvKZcKiKZ0MgiYsvk= - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/set-blocking/download/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/set-value/download/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha1-oY1AUw5vB95CKMfe/kInr4ytAFs= - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.4: - version "1.0.5" - resolved "https://registry.npm.taobao.org/setimmediate/download/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY= - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM= - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.npm.taobao.org/sha.js/download/sha.js-2.4.11.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsha.js%2Fdownload%2Fsha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha1-N6XPC4HsvGlD3hCbopYNGyZYSuc= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -shallow-equal@^1.0.0: - version "1.2.1" - resolved "https://registry.npm.taobao.org/shallow-equal/download/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da" - integrity sha1-TBar+lYEOqINBQMk76aJQLDaedo= - -shallowequal@^1.0.2: - version "1.1.0" - resolved "https://registry.npm.taobao.org/shallowequal/download/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" - integrity sha1-GI1SHelbkIdAT9TctosT3wrk5/g= - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.npm.taobao.org/shebang-command/download/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo= - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI= - -shell-quote@^1.6.1: - version "1.7.2" - resolved "https://registry.npm.taobao.org/shell-quote/download/shell-quote-1.7.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fshell-quote%2Fdownload%2Fshell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" - integrity sha1-Z6fQLHbJ2iT5nSCAj8re0ODgS+I= - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.npm.taobao.org/simple-swizzle/download/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/slash/download/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/slash/download/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q= - -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/slice-ansi/download/slice-ansi-2.1.0.tgz?cache=0&sync_timestamp=1568743500638&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fslice-ansi%2Fdownload%2Fslice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha1-ys12k0YaY3pXiNkqfdT7oGjoFjY= - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/snapdragon-node/download/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha1-bBdfhv8UvbByRWPo88GwIaKGhTs= - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.npm.taobao.org/snapdragon-util/download/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI= - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.npm.taobao.org/snapdragon/download/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0= - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -sockjs-client@1.4.0: - version "1.4.0" - resolved "https://registry.npm.taobao.org/sockjs-client/download/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5" - integrity sha1-yfJWjhnI/YFztJl+o0IOC7MGx9U= - dependencies: - debug "^3.2.5" - eventsource "^1.0.7" - faye-websocket "~0.11.1" - inherits "^2.0.3" - json3 "^3.3.2" - url-parse "^1.4.3" - -sockjs@0.3.19: - version "0.3.19" - resolved "https://registry.npm.taobao.org/sockjs/download/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" - integrity sha1-2Xa76ACve9IK4IWY1YI5NQiZPA0= - dependencies: - faye-websocket "^0.10.0" - uuid "^3.0.1" - -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.npm.taobao.org/sort-keys/download/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= - dependencies: - is-plain-obj "^1.0.0" - -source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.npm.taobao.org/source-list-map/download/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha1-OZO9hzv8SEecyp6jpUeDXHwVSzQ= - -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.npm.taobao.org/source-map-resolve/download/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha1-GQhmvs51U+H48mei7oLGBrVQmho= - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@^0.3.2: - version "0.3.3" - resolved "https://registry.npm.taobao.org/source-map-support/download/source-map-support-0.3.3.tgz?cache=0&sync_timestamp=1572389965235&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map-support%2Fdownload%2Fsource-map-support-0.3.3.tgz#34900977d5ba3f07c7757ee72e73bb1a9b53754f" - integrity sha1-NJAJd9W6PwfHdX7nLnO7GptTdU8= - dependencies: - source-map "0.1.32" - -source-map-support@~0.5.12: - version "0.5.16" - resolved "https://registry.npm.taobao.org/source-map-support/download/source-map-support-0.5.16.tgz?cache=0&sync_timestamp=1572389965235&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map-support%2Fdownload%2Fsource-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" - integrity sha1-CuBp5/47p1OMZMmFFeNTOerFoEI= - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.npm.taobao.org/source-map-url/download/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@0.1.32: - version "0.1.32" - resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.1.32.tgz#c8b6c167797ba4740a8ea33252162ff08591b266" - integrity sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY= - dependencies: - amdefine ">=0.0.4" - -source-map@^0.5.0, source-map@^0.5.6, source-map@~0.5.1: - version "0.5.7" - resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha1-dHIq8y6WFOnCh6jQu95IteLxomM= - -spdx-correct@^3.0.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/spdx-correct/download/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha1-+4PlBERSaPFUsHTiGMh8ADzTHfQ= - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.npm.taobao.org/spdx-exceptions/download/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha1-LqRQrudPKom/uUUZwH/Nb0EyKXc= - -spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/spdx-expression-parse/download/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha1-meEZt6XaAOBUkcn6M4t5BII7QdA= - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.5" - resolved "https://registry.npm.taobao.org/spdx-license-ids/download/spdx-license-ids-3.0.5.tgz?cache=0&sync_timestamp=1562834220236&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" - integrity sha1-NpS1gEVnpFjTyARYQqY1hjL2JlQ= - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/spdy-transport/download/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha1-ANSGOmQArXXfkzYaFghgXl3NzzE= - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.1: - version "4.0.1" - resolved "https://registry.npm.taobao.org/spdy/download/spdy-4.0.1.tgz#6f12ed1c5db7ea4f24ebb8b89ba58c87c08257f2" - integrity sha1-bxLtHF236k8k67i4m6WMh8CCV/I= - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.npm.taobao.org/split-string/download/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha1-fLCd2jqGWFcFxks5pkZgOGguj+I= - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.0.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsprintf-js%2Fdownload%2Fsprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.npm.taobao.org/sshpk/download/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha1-+2YcC+8ps520B2nuOfpwCT1vaHc= - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.npm.taobao.org/ssri/download/ssri-6.0.1.tgz?cache=0&sync_timestamp=1571961201744&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fssri%2Fdownload%2Fssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - integrity sha1-KjxBso3UW2K2Nnbst0ABJlrp7dg= - dependencies: - figgy-pudding "^3.5.1" - -ssri@^7.0.0, ssri@^7.1.0: - version "7.1.0" - resolved "https://registry.npm.taobao.org/ssri/download/ssri-7.1.0.tgz?cache=0&sync_timestamp=1571961201744&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fssri%2Fdownload%2Fssri-7.1.0.tgz#92c241bf6de82365b5c7fb4bd76e975522e1294d" - integrity sha1-ksJBv23oI2W1x/tL126XVSLhKU0= - dependencies: - figgy-pudding "^3.5.1" - minipass "^3.1.1" - -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.npm.taobao.org/stable/download/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha1-g26zyDgv4pNv6vVEYxAXzn1Ho88= - -stackframe@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/stackframe/download/stackframe-1.1.0.tgz#e3fc2eb912259479c9822f7d1f1ff365bd5cbc83" - integrity sha1-4/wuuRIllHnJgi99Hx/zZb1cvIM= - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.npm.taobao.org/static-extend/download/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.npm.taobao.org/statuses/download/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/stealthy-require/download/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - -stream-browserify@^2.0.1: - version "2.0.2" - resolved "https://registry.npm.taobao.org/stream-browserify/download/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" - integrity sha1-h1IdOKRKp+6RzhzSpH3wy0ndZgs= - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.npm.taobao.org/stream-each/download/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha1-6+J6DDibBPvMIzZClS4Qcxr6m64= - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.npm.taobao.org/stream-http/download/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha1-stJCRpKIpaJ+xP6JM6z2I95lFPw= - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/stream-shift/download/stream-shift-1.0.1.tgz?cache=0&sync_timestamp=1576147168429&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstream-shift%2Fdownload%2Fstream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" - integrity sha1-1wiCgVWasneEJCebCHfaPDktWj0= - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/strict-uri-encode/download/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= - -string-convert@^0.2.0: - version "0.2.1" - resolved "https://registry.npm.taobao.org/string-convert/download/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97" - integrity sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c= - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.npm.taobao.org/string-width/download/string-width-1.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring-width%2Fdownload%2Fstring-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/string-width/download/string-width-2.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring-width%2Fdownload%2Fstring-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4= - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.npm.taobao.org/string-width/download/string-width-3.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring-width%2Fdownload%2Fstring-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha1-InZ74htirxCBV0MG9prFG2IgOWE= - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.npm.taobao.org/string-width/download/string-width-4.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring-width%2Fdownload%2Fstring-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha1-lSGCxGzHssMT0VluYjmSvRY7crU= - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string.prototype.trim@~1.2.1: - version "1.2.1" - resolved "https://registry.npm.taobao.org/string.prototype.trim/download/string.prototype.trim-1.2.1.tgz#141233dff32c82bfad80684d7e5f0869ee0fb782" - integrity sha1-FBIz3/Msgr+tgGhNfl8Iae4Pt4I= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - -string.prototype.trimleft@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/string.prototype.trimleft/download/string.prototype.trimleft-2.1.1.tgz?cache=0&sync_timestamp=1576706744979&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimleft%2Fdownload%2Fstring.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha1-m9uKxqvW1gKxek7TIYcNL43O/HQ= - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string.prototype.trimright@^2.1.1: - version "2.1.1" - resolved "https://registry.npm.taobao.org/string.prototype.trimright/download/string.prototype.trimright-2.1.1.tgz?cache=0&sync_timestamp=1576706745939&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimright%2Fdownload%2Fstring.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha1-RAMUsVmWyGbOigNBiU1FGGIAxdk= - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string_decoder@^1.0.0, string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.3.0.tgz?cache=0&sync_timestamp=1565170823020&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring_decoder%2Fdownload%2Fstring_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha1-QvEUWUpGzxqOMLCoT1bHjD7awh4= - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz?cache=0&sync_timestamp=1565170823020&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring_decoder%2Fdownload%2Fstring_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha1-nPFhG6YmhdcDCunkujQUnDrwP8g= - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-3.0.1.tgz?cache=0&sync_timestamp=1573280518303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-4.0.0.tgz?cache=0&sync_timestamp=1573280518303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz?cache=0&sync_timestamp=1573280518303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4= - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-6.0.0.tgz?cache=0&sync_timestamp=1573280518303&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI= - dependencies: - ansi-regex "^5.0.0" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/strip-eof/download/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/strip-final-newline/download/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha1-ibhS+y/L6Tb29LMYevsKEsGrWK0= - -strip-indent@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/strip-indent/download/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" - integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= - -strip-json-comments@^2.0.1: - version "2.0.1" - resolved "https://registry.npm.taobao.org/strip-json-comments/download/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -stylehacks@^4.0.0: - version "4.0.3" - resolved "https://registry.npm.taobao.org/stylehacks/download/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" - integrity sha1-Zxj8r00eB9ihMYaQiB6NlnJqcdU= - dependencies: - browserslist "^4.0.0" - postcss "^7.0.0" - postcss-selector-parser "^3.0.0" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-5.5.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha1-4uaaRKyHcveKHsCzW2id9lMO/I8= - dependencies: - has-flag "^3.0.0" - -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-6.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha1-B2Srxpxj1ayELdSGfo0CXogN+PM= - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.1.0" - resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-7.1.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" - integrity sha1-aOMlkd9z4lrRxLSRCKLsUHliv9E= - dependencies: - has-flag "^4.0.0" - -svg-tags@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/svg-tags/download/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" - integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= - -svgo@^1.0.0: - version "1.3.2" - resolved "https://registry.npm.taobao.org/svgo/download/svgo-1.3.2.tgz?cache=0&sync_timestamp=1572433263159&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsvgo%2Fdownload%2Fsvgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" - integrity sha1-ttxRHAYzRsnkFbgeQ0ARRbltQWc= - dependencies: - chalk "^2.4.1" - coa "^2.0.2" - css-select "^2.0.0" - css-select-base-adapter "^0.1.1" - css-tree "1.0.0-alpha.37" - csso "^4.0.2" - js-yaml "^3.13.1" - mkdirp "~0.5.1" - object.values "^1.1.0" - sax "~1.2.4" - stable "^0.1.8" - unquote "~1.1.1" - util.promisify "~1.0.0" - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.npm.taobao.org/table/download/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha1-EpLRlQDOP4YFOwXw6Ofko7shB54= - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -tapable@^1.0.0, tapable@^1.1.3: - version "1.1.3" - resolved "https://registry.npm.taobao.org/tapable/download/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha1-ofzMBrWNth/XpF2i2kT186Pme6I= - -tape@^4.5.1: - version "4.12.1" - resolved "https://registry.npm.taobao.org/tape/download/tape-4.12.1.tgz#5fe2f0e2ef09ff0ec6f6d37f38300a6016082d91" - integrity sha1-X+Lw4u8J/w7G9tN/ODAKYBYILZE= - dependencies: - deep-equal "~1.1.1" - defined "~1.0.0" - for-each "~0.3.3" - function-bind "~1.1.1" - glob "~7.1.6" - has "~1.0.3" - inherits "~2.0.4" - is-regex "~1.0.5" - minimist "~1.2.0" - object-inspect "~1.7.0" - resolve "~1.14.1" - resumer "~0.0.0" - string.prototype.trim "~1.2.1" - through "~2.3.8" - -terser-webpack-plugin@^1.4.3: - version "1.4.3" - resolved "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-1.4.3.tgz?cache=0&sync_timestamp=1576580745773&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" - integrity sha1-Xsry29xfuZdF/QZ5H0b8ndscmnw= - dependencies: - cacache "^12.0.2" - find-cache-dir "^2.1.0" - is-wsl "^1.1.0" - schema-utils "^1.0.0" - serialize-javascript "^2.1.2" - source-map "^0.6.1" - terser "^4.1.2" - webpack-sources "^1.4.0" - worker-farm "^1.7.0" - -terser-webpack-plugin@^2.2.1: - version "2.3.1" - resolved "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-2.3.1.tgz?cache=0&sync_timestamp=1576580745773&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-2.3.1.tgz#6a63c27debc15b25ffd2588562ee2eeabdcab923" - integrity sha1-amPCfevBWyX/0liFYu4u6r3KuSM= - dependencies: - cacache "^13.0.1" - find-cache-dir "^3.2.0" - jest-worker "^24.9.0" - schema-utils "^2.6.1" - serialize-javascript "^2.1.2" - source-map "^0.6.1" - terser "^4.4.3" - webpack-sources "^1.4.3" - -terser@^4.1.2, terser@^4.4.3: - version "4.5.1" - resolved "https://registry.npm.taobao.org/terser/download/terser-4.5.1.tgz#63b52d6b6ce344aa6fedcd0ee06a695799eb50bd" - integrity sha1-Y7Uta2zjRKpv7c0O4GppV5nrUL0= - dependencies: - commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npm.taobao.org/text-table/download/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.npm.taobao.org/thenify-all/download/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.0" - resolved "https://registry.npm.taobao.org/thenify/download/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" - integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk= - dependencies: - any-promise "^1.0.0" - -thread-loader@^2.1.3: - version "2.1.3" - resolved "https://registry.npm.taobao.org/thread-loader/download/thread-loader-2.1.3.tgz#cbd2c139fc2b2de6e9d28f62286ab770c1acbdda" - integrity sha1-y9LBOfwrLebp0o9iKGq3cMGsvdo= - dependencies: - loader-runner "^2.3.1" - loader-utils "^1.1.0" - neo-async "^2.6.0" - -through2@^2.0.0: - version "2.0.5" - resolved "https://registry.npm.taobao.org/through2/download/through2-2.0.5.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fthrough2%2Fdownload%2Fthrough2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha1-AcHjnrMdB8t9A6lqcIIyYLIxMs0= - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through@^2.3.6, through@~2.3.4, through@~2.3.8: - version "2.3.8" - resolved "https://registry.npm.taobao.org/through/download/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.npm.taobao.org/thunky/download/thunky-1.1.0.tgz?cache=0&sync_timestamp=1571043401546&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fthunky%2Fdownload%2Fthunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha1-Wrr3FKlAXbBQRzK7zNLO3Z75U30= - -timers-browserify@^2.0.4: - version "2.0.11" - resolved "https://registry.npm.taobao.org/timers-browserify/download/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" - integrity sha1-gAsfPu4nLlvFPuRloE0OgEwxIR8= - dependencies: - setimmediate "^1.0.4" - -timsort@^0.3.0: - version "0.3.0" - resolved "https://registry.npm.taobao.org/timsort/download/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" - integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= - -tinycolor2@^1.4.1: - version "1.4.1" - resolved "https://registry.npm.taobao.org/tinycolor2/download/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" - integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.npm.taobao.org/tmp/download/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha1-bTQzWIl2jSGyvNoKonfO07G/rfk= - dependencies: - os-tmpdir "~1.0.2" - -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/to-arraybuffer/download/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/to-fast-properties/download/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.npm.taobao.org/to-object-path/download/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.npm.taobao.org/to-regex/download/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4= - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM= - -toposort@^1.0.0: - version "1.0.7" - resolved "https://registry.npm.taobao.org/toposort/download/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" - integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk= - -tough-cookie@^2.3.3: - version "2.5.0" - resolved "https://registry.npm.taobao.org/tough-cookie/download/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha1-zZ+yoKodWhK0c72fuW+j3P9lreI= - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.npm.taobao.org/tough-cookie/download/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha1-U/Nto/R3g7CSWvoG/587FlKA94E= - dependencies: - psl "^1.1.24" - punycode "^1.4.1" - -tryer@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/tryer/download/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" - integrity sha1-8shUBoALmw90yfdGW4HqrSQSUvg= - -tslib@^1.9.0: - version "1.10.0" - resolved "https://registry.npm.taobao.org/tslib/download/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha1-w8GflZc/sKYpc/sJ2Q2WHuQ+XIo= - -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.npm.taobao.org/tty-browserify/download/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.npm.taobao.org/tunnel-agent/download/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.npm.taobao.org/tweetnacl/download/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.npm.taobao.org/type-check/download/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.npm.taobao.org/type-fest/download/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha1-jSojcNPfiG61yQraHFv2GIrPg4s= - -type-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.npm.taobao.org/type-is/download/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha1-TlUs0F3wlGfcvE73Od6J8s83wTE= - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.npm.taobao.org/typedarray/download/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -uglify-js@3.4.x: - version "3.4.10" - resolved "https://registry.npm.taobao.org/uglify-js/download/uglify-js-3.4.10.tgz?cache=0&sync_timestamp=1577407920190&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" - integrity sha1-mtlWPY6zrN+404WX0q8dgV9qdV8= - dependencies: - commander "~2.19.0" - source-map "~0.6.1" - -uglify-js@^2.6.2: - version "2.8.29" - resolved "https://registry.npm.taobao.org/uglify-js/download/uglify-js-2.8.29.tgz?cache=0&sync_timestamp=1577407920190&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" - integrity sha1-KcVzMUgFe7Th913zW3qcty5qWd0= - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-js@^3.1.4: - version "3.7.3" - resolved "https://registry.npm.taobao.org/uglify-js/download/uglify-js-3.7.3.tgz?cache=0&sync_timestamp=1577407920190&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.7.3.tgz#f918fce9182f466d5140f24bb0ff35c2d32dcc6a" - integrity sha1-+Rj86RgvRm1RQPJLsP81wtMtzGo= - dependencies: - commander "~2.20.3" - source-map "~0.6.1" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.npm.taobao.org/uglify-to-browserify/download/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc= - -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.npm.taobao.org/unicode-canonical-property-names-ecmascript/download/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha1-JhmADEyCWADv3YNDr33Zkzy+KBg= - -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.npm.taobao.org/unicode-match-property-ecmascript/download/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha1-jtKjJWmWG86SJ9Cc0/+7j+1fAgw= - dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" - -unicode-match-property-value-ecmascript@^1.1.0: - version "1.1.0" - resolved "https://registry.npm.taobao.org/unicode-match-property-value-ecmascript/download/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" - integrity sha1-W0tCbgjROoA2Xg1lesemwexGonc= - -unicode-property-aliases-ecmascript@^1.0.4: - version "1.0.5" - resolved "https://registry.npm.taobao.org/unicode-property-aliases-ecmascript/download/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" - integrity sha1-qcxsx85joKMCP8meNBuUQx1AWlc= - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.npm.taobao.org/union-value/download/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha1-C2/nuDWuzaYcbqTU8CwUIh4QmEc= - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/uniq/download/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= - -uniqs@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/uniqs/download/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" - integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= - -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/unique-filename/download/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha1-HWl2k2mtoFgxA6HmrodoG1ZXMjA= - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.npm.taobao.org/unique-slug/download/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha1-uqvOkQg/xk6UWw861hPiZPfNTmw= - dependencies: - imurmurhash "^0.1.4" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY= - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unquote@~1.1.1: - version "1.1.1" - resolved "https://registry.npm.taobao.org/unquote/download/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" - integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/unset-value/download/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.1: - version "1.2.0" - resolved "https://registry.npm.taobao.org/upath/download/upath-1.2.0.tgz?cache=0&sync_timestamp=1567457281208&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fupath%2Fdownload%2Fupath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha1-j2bbzVWog6za5ECK+LA1pQRMGJQ= - -upper-case@^1.1.1: - version "1.1.3" - resolved "https://registry.npm.taobao.org/upper-case/download/upper-case-1.1.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fupper-case%2Fdownload%2Fupper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" - integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.npm.taobao.org/uri-js/download/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha1-lMVA4f93KVbiKZUHwBCupsiDjrA= - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.npm.taobao.org/urix/download/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -url-loader@^2.2.0: - version "2.3.0" - resolved "https://registry.npm.taobao.org/url-loader/download/url-loader-2.3.0.tgz?cache=0&sync_timestamp=1574768466952&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Furl-loader%2Fdownload%2Furl-loader-2.3.0.tgz#e0e2ef658f003efb8ca41b0f3ffbf76bab88658b" - integrity sha1-4OLvZY8APvuMpBsPP/v3a6uIZYs= - dependencies: - loader-utils "^1.2.3" - mime "^2.4.4" - schema-utils "^2.5.0" - -url-parse@^1.4.3: - version "1.4.7" - resolved "https://registry.npm.taobao.org/url-parse/download/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" - integrity sha1-qKg1NejACjFuQDpdtKwbm4U64ng= - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.npm.taobao.org/url/download/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.npm.taobao.org/use/download/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha1-1QyMrHmhn7wg8pEfVuuXP04QBw8= - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util.promisify@1.0.0, util.promisify@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/util.promisify/download/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha1-RA9xZaRZyaFtwUXrjnLzVocJcDA= - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - -util@0.10.3: - version "0.10.3" - resolved "https://registry.npm.taobao.org/util/download/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= - dependencies: - inherits "2.0.1" - -util@^0.11.0: - version "0.11.1" - resolved "https://registry.npm.taobao.org/util/download/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - integrity sha1-MjZzNyDsZLsn9uJvQhqqLhtYjWE= - dependencies: - inherits "2.0.3" - -utila@^0.4.0, utila@~0.4: - version "0.4.0" - resolved "https://registry.npm.taobao.org/utila/download/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -uuid@^3.0.1, uuid@^3.3.2: - version "3.3.3" - resolved "https://registry.npm.taobao.org/uuid/download/uuid-3.3.3.tgz?cache=0&sync_timestamp=1566221202613&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuuid%2Fdownload%2Fuuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" - integrity sha1-RWjwIW54dg7h2/Ok0s9T4iQRKGY= - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.npm.taobao.org/validate-npm-package-license/download/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha1-/JH2uce6FchX9MssXe/uw51PQQo= - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -vendors@^1.0.0: - version "1.0.3" - resolved "https://registry.npm.taobao.org/vendors/download/vendors-1.0.3.tgz#a6467781abd366217c050f8202e7e50cc9eef8c0" - integrity sha1-pkZ3gavTZiF8BQ+CAuflDMnu+MA= - -venn.js@~0.2.20: - version "0.2.20" - resolved "https://registry.npm.taobao.org/venn.js/download/venn.js-0.2.20.tgz#3f0e50cc75cba1f58692a8a32f67bd7aaf1aa6fa" - integrity sha1-Pw5QzHXLofWGkqijL2e9eq8apvo= - dependencies: - d3-selection "^1.0.2" - d3-transition "^1.0.1" - fmin "0.0.2" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.npm.taobao.org/verror/download/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vm-browserify@^1.0.1: - version "1.1.2" - resolved "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz?cache=0&sync_timestamp=1572870717730&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvm-browserify%2Fdownload%2Fvm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" - integrity sha1-eGQcSIuObKkadfUR56OzKobl3aA= - -vue-eslint-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.npm.taobao.org/vue-eslint-parser/download/vue-eslint-parser-5.0.0.tgz?cache=0&sync_timestamp=1573306368916&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-eslint-parser%2Fdownload%2Fvue-eslint-parser-5.0.0.tgz#00f4e4da94ec974b821a26ff0ed0f7a78402b8a1" - integrity sha1-APTk2pTsl0uCGib/DtD3p4QCuKE= - dependencies: - debug "^4.1.0" - eslint-scope "^4.0.0" - eslint-visitor-keys "^1.0.0" - espree "^4.1.0" - esquery "^1.0.1" - lodash "^4.17.11" - -vue-hot-reload-api@^2.3.0: - version "2.3.4" - resolved "https://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.3.4.tgz?cache=0&sync_timestamp=1568190386192&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-hot-reload-api%2Fdownload%2Fvue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2" - integrity sha1-UylVzB6yCKPZkLOp+acFdGV+CPI= - -vue-loader@^15.7.2: - version "15.8.3" - resolved "https://registry.npm.taobao.org/vue-loader/download/vue-loader-15.8.3.tgz?cache=0&sync_timestamp=1578008466541&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-15.8.3.tgz#857cb9e30eb5fc25e66db48dce7e4f768602a23c" - integrity sha1-hXy54w61/CXmbbSNzn5PdoYCojw= - dependencies: - "@vue/component-compiler-utils" "^3.1.0" - hash-sum "^1.0.2" - loader-utils "^1.1.0" - vue-hot-reload-api "^2.3.0" - vue-style-loader "^4.1.0" - -vue-ref@^1.0.4: - version "1.0.6" - resolved "https://registry.npm.taobao.org/vue-ref/download/vue-ref-1.0.6.tgz#b9b3d7d0e290ee2fd3d50d5d7bdac520806cb265" - integrity sha1-ubPX0OKQ7i/T1Q1de9rFIIBssmU= - -vue-router@^3.1.3: - version "3.1.3" - resolved "https://registry.npm.taobao.org/vue-router/download/vue-router-3.1.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-router%2Fdownload%2Fvue-router-3.1.3.tgz#e6b14fabc0c0ee9fda0e2cbbda74b350e28e412b" - integrity sha1-5rFPq8DA7p/aDiy72nSzUOKOQSs= - -vue-style-loader@^4.1.0: - version "4.1.2" - resolved "https://registry.npm.taobao.org/vue-style-loader/download/vue-style-loader-4.1.2.tgz#dedf349806f25ceb4e64f3ad7c0a44fba735fcf8" - integrity sha1-3t80mAbyXOtOZPOtfApE+6c1/Pg= - dependencies: - hash-sum "^1.0.2" - loader-utils "^1.0.2" - -vue-template-compiler@^2.6.10: - version "2.6.11" - resolved "https://registry.npm.taobao.org/vue-template-compiler/download/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080" - integrity sha1-wEcE749JixUxMAGJk+VjCdRpgIA= - dependencies: - de-indent "^1.0.2" - he "^1.1.0" - -vue-template-es2015-compiler@^1.9.0: - version "1.9.1" - resolved "https://registry.npm.taobao.org/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" - integrity sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU= - -vue@^2.6.10: - version "2.6.11" - resolved "https://registry.npm.taobao.org/vue/download/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5" - integrity sha1-dllNh31LEiNEBuhONSdcbVFBJcU= - -vuex@^3.1.2: - version "3.1.2" - resolved "https://registry.npm.taobao.org/vuex/download/vuex-3.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvuex%2Fdownload%2Fvuex-3.1.2.tgz#a2863f4005aa73f2587e55c3fadf3f01f69c7d4d" - integrity sha1-ooY/QAWqc/JYflXD+t8/AfacfU0= - -warning@^3.0.0: - version "3.0.0" - resolved "https://registry.npm.taobao.org/warning/download/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" - integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w= - dependencies: - loose-envify "^1.0.0" - -watchpack@^1.6.0: - version "1.6.0" - resolved "https://registry.npm.taobao.org/watchpack/download/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha1-S8EsLr6KonenHx0/FNaFx7RGzQA= - dependencies: - chokidar "^2.0.2" - graceful-fs "^4.1.2" - neo-async "^2.5.0" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.npm.taobao.org/wbuf/download/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha1-wdjRSTFtPqhShIiVy2oL/oh7h98= - dependencies: - minimalistic-assert "^1.0.0" - -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.npm.taobao.org/wcwidth/download/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= - dependencies: - defaults "^1.0.3" - -webpack-bundle-analyzer@^3.6.0: - version "3.6.0" - resolved "https://registry.npm.taobao.org/webpack-bundle-analyzer/download/webpack-bundle-analyzer-3.6.0.tgz#39b3a8f829ca044682bc6f9e011c95deb554aefd" - integrity sha1-ObOo+CnKBEaCvG+eARyV3rVUrv0= - dependencies: - acorn "^6.0.7" - acorn-walk "^6.1.1" - bfj "^6.1.1" - chalk "^2.4.1" - commander "^2.18.0" - ejs "^2.6.1" - express "^4.16.3" - filesize "^3.6.1" - gzip-size "^5.0.0" - lodash "^4.17.15" - mkdirp "^0.5.1" - opener "^1.5.1" - ws "^6.0.0" - -webpack-chain@^6.0.0: - version "6.3.0" - resolved "https://registry.npm.taobao.org/webpack-chain/download/webpack-chain-6.3.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-chain%2Fdownload%2Fwebpack-chain-6.3.0.tgz#a6098eb89a43dbe6533538f4647b283b99bf66ed" - integrity sha1-pgmOuJpD2+ZTNTj0ZHsoO5m/Zu0= - dependencies: - deepmerge "^1.5.2" - javascript-stringify "^2.0.1" - -webpack-dev-middleware@^3.7.2: - version "3.7.2" - resolved "https://registry.npm.taobao.org/webpack-dev-middleware/download/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" - integrity sha1-ABnD23FuP6XOy/ZPKriKdLqzMfM= - dependencies: - memory-fs "^0.4.1" - mime "^2.4.4" - mkdirp "^0.5.1" - range-parser "^1.2.1" - webpack-log "^2.0.0" - -webpack-dev-server@^3.9.0: - version "3.10.1" - resolved "https://registry.npm.taobao.org/webpack-dev-server/download/webpack-dev-server-3.10.1.tgz?cache=0&sync_timestamp=1576754522893&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-dev-server%2Fdownload%2Fwebpack-dev-server-3.10.1.tgz#1ff3e5cccf8e0897aa3f5909c654e623f69b1c0e" - integrity sha1-H/PlzM+OCJeqP1kJxlTmI/abHA4= - dependencies: - ansi-html "0.0.7" - bonjour "^3.5.0" - chokidar "^2.1.8" - compression "^1.7.4" - connect-history-api-fallback "^1.6.0" - debug "^4.1.1" - del "^4.1.1" - express "^4.17.1" - html-entities "^1.2.1" - http-proxy-middleware "0.19.1" - import-local "^2.0.0" - internal-ip "^4.3.0" - ip "^1.1.5" - is-absolute-url "^3.0.3" - killable "^1.0.1" - loglevel "^1.6.6" - opn "^5.5.0" - p-retry "^3.0.1" - portfinder "^1.0.25" - schema-utils "^1.0.0" - selfsigned "^1.10.7" - semver "^6.3.0" - serve-index "^1.9.1" - sockjs "0.3.19" - sockjs-client "1.4.0" - spdy "^4.0.1" - strip-ansi "^3.0.1" - supports-color "^6.1.0" - url "^0.11.0" - webpack-dev-middleware "^3.7.2" - webpack-log "^2.0.0" - ws "^6.2.1" - yargs "12.0.5" - -webpack-log@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/webpack-log/download/webpack-log-2.0.0.tgz?cache=0&sync_timestamp=1564684667159&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-log%2Fdownload%2Fwebpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" - integrity sha1-W3ko4GN1k/EZ0y9iJ8HgrDHhtH8= - dependencies: - ansi-colors "^3.0.0" - uuid "^3.3.2" - -webpack-merge@^4.2.2: - version "4.2.2" - resolved "https://registry.npm.taobao.org/webpack-merge/download/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" - integrity sha1-onxS6ng9E5iv0gh/VH17nS9DY00= - dependencies: - lodash "^4.17.15" - -webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: - version "1.4.3" - resolved "https://registry.npm.taobao.org/webpack-sources/download/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha1-7t2OwLko+/HL/plOItLYkPMwqTM= - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -webpack@^4.0.0: - version "4.41.5" - resolved "https://registry.npm.taobao.org/webpack/download/webpack-4.41.5.tgz#3210f1886bce5310e62bb97204d18c263341b77c" - integrity sha1-MhDxiGvOUxDmK7lyBNGMJjNBt3w= - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.1" - ajv "^6.10.2" - ajv-keywords "^3.4.1" - chrome-trace-event "^1.0.2" - enhanced-resolve "^4.1.0" - eslint-scope "^4.0.3" - json-parse-better-errors "^1.0.2" - loader-runner "^2.4.0" - loader-utils "^1.2.3" - memory-fs "^0.4.1" - micromatch "^3.1.10" - mkdirp "^0.5.1" - neo-async "^2.6.1" - node-libs-browser "^2.2.1" - schema-utils "^1.0.0" - tapable "^1.1.3" - terser-webpack-plugin "^1.4.3" - watchpack "^1.6.0" - webpack-sources "^1.4.1" - -websocket-driver@>=0.5.1: - version "0.7.3" - resolved "https://registry.npm.taobao.org/websocket-driver/download/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" - integrity sha1-otTg1PTxFvHmKX66WLBdQwEA6fk= - dependencies: - http-parser-js ">=0.4.0 <0.4.11" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.3" - resolved "https://registry.npm.taobao.org/websocket-extensions/download/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" - integrity sha1-XS/yKXcAPsaHpLhwc9+7rBRszyk= - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/which-module/download/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@^1.2.9: - version "1.3.1" - resolved "https://registry.npm.taobao.org/which/download/which-1.3.1.tgz?cache=0&sync_timestamp=1574116720213&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo= - dependencies: - isexe "^2.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.npm.taobao.org/which/download/which-2.0.2.tgz?cache=0&sync_timestamp=1574116720213&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE= - dependencies: - isexe "^2.0.0" - -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.npm.taobao.org/window-size/download/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0= - -wolfy87-eventemitter@~5.1.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/wolfy87-eventemitter/download/wolfy87-eventemitter-5.1.0.tgz#35c1ac0dd1ac0c15e35d981508fc22084a13a011" - integrity sha1-NcGsDdGsDBXjXZgVCPwiCEoToBE= - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.npm.taobao.org/word-wrap/download/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha1-YQY29rH3A4kb00dxzLF/uTtHB5w= - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.npm.taobao.org/wordwrap/download/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8= - -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.npm.taobao.org/wordwrap/download/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= - -worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.npm.taobao.org/worker-farm/download/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha1-JqlMU5G7ypJhUgAvabhKS/dy5ag= - dependencies: - errno "~0.1.7" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha1-H9H2cjXVttD+54EFYAG/tpTAOwk= - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha1-6Tk7oHEC5skaOyIUePAlfNKFblM= - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.npm.taobao.org/wrappy/download/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write@1.0.3: - version "1.0.3" - resolved "https://registry.npm.taobao.org/write/download/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha1-CADhRSO5I6OH5BUSPIZWFqrg9cM= - dependencies: - mkdirp "^0.5.1" - -ws@^6.0.0, ws@^6.2.1: - version "6.2.1" - resolved "https://registry.npm.taobao.org/ws/download/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" - integrity sha1-RC/fCkftZPWbal2P8TD0dI7VJPs= - dependencies: - async-limiter "~1.0.0" - -xtend@^4.0.0, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.npm.taobao.org/xtend/download/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha1-u3J3n1+kZRhrH0OPZ0+jR/2121Q= - -"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/y18n/download/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha1-le+U+F7MgdAHwmThkKEg8KPIVms= - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.npm.taobao.org/yallist/download/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.npm.taobao.org/yallist/download/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha1-27fa+b/YusmrRev2ArjLrQ1dCP0= - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI= - -yargs-parser@^11.1.1: - version "11.1.1" - resolved "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" - integrity sha1-h5oIZZc7yp9rq1y987HGfsfTvPQ= - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^16.1.0: - version "16.1.0" - resolved "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-16.1.0.tgz#73747d53ae187e7b8dbe333f95714c76ea00ecf1" - integrity sha1-c3R9U64YfnuNvjM/lXFMduoA7PE= - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs@12.0.5: - version "12.0.5" - resolved "https://registry.npm.taobao.org/yargs/download/yargs-12.0.5.tgz?cache=0&sync_timestamp=1577940973312&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs%2Fdownload%2Fyargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha1-BfWZe2CWR7ZPZrgeO0sQo2jnrRM= - dependencies: - cliui "^4.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" - -yargs@^15.0.0: - version "15.1.0" - resolved "https://registry.npm.taobao.org/yargs/download/yargs-15.1.0.tgz?cache=0&sync_timestamp=1577940973312&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs%2Fdownload%2Fyargs-15.1.0.tgz#e111381f5830e863a89550bd4b136bb6a5f37219" - integrity sha1-4RE4H1gw6GOolVC9SxNrtqXzchk= - dependencies: - cliui "^6.0.0" - decamelize "^1.2.0" - find-up "^4.1.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^4.2.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^16.1.0" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.npm.taobao.org/yargs/download/yargs-3.10.0.tgz?cache=0&sync_timestamp=1577940973312&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs%2Fdownload%2Fyargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - integrity sha1-9+572FfdfB0tOMDnTvvWgdFDH9E= - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" - -yorkie@^2.0.0: - version "2.0.0" - resolved "https://registry.npm.taobao.org/yorkie/download/yorkie-2.0.0.tgz#92411912d435214e12c51c2ae1093e54b6bb83d9" - integrity sha1-kkEZEtQ1IU4SxRwq4Qk+VLa7g9k= - dependencies: - execa "^0.8.0" - is-ci "^1.0.10" - normalize-path "^1.0.0" - strip-indent "^2.0.0" diff --git a/CNAME b/CNAME new file mode 100644 index 0000000000000000000000000000000000000000..48f6c6bba8ddd9b50fecfa6c5a6db4947b0f5900 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +note.moguit.cn \ No newline at end of file diff --git a/Docker/DockerCompose/README.md b/Docker/DockerCompose/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1d0b22ad5664d31902e2ce996cc8a9cfdae329e3 --- /dev/null +++ b/Docker/DockerCompose/README.md @@ -0,0 +1,435 @@ +# Docker Compose + +## 简介 + +原来我们的操作是:DockerFile build run 进行手动操作,单个容器,如果假设我们有100个微服务,并行微服务之间还存在依赖关系。 + +这个时候,我们就可以使用Docker Compose来轻松高效的管理容器,定义运行多个容器。 + +官方介绍: + +- 定义、运行多个容器 +- YAML file配置环境 + +> Compose是一个用于定义和运行多容器Docker应用程序的工具。使用Compose,您可以使用YAML文件来配置应用程序的服务。然后,使用一个命令,就可以从配置中创建并启动所有服务。要了解有关Compose的所有特性的更多信息,请参阅[特性列表](https://docs.docker.com/compose/#features)。 +> +> Compose可以在所有环境中工作:生产、阶段、开发、测试,以及CI工作流。您可以在常见用例中了解关于每个用例的更多信息 +> +> 使用Compose基本上有三个步骤: +> +> - 用 Dockerfile 定义你的应用程序的环境,这样它就可以在任何地方复制。 +> - 在 Docker-compose 中定义组成应用程序的服务。这样它们就可以在一个独立的环境中一起运行。 +> - 运行 docker-compose up 和 Compose 启动并运行整个应用程序。 + +作用:批量容器编排 + +> Compose是Docker官方的开源项目,需要安装! +> +> Dockerfile 让程序在任何地方运行,web服务。Redis、MySQL、Nginx。。。多个容器 + +Compose的YAML文件如下所示 + +```yaml +version: '2.0' +services: + web: + build: . + ports: + - "5000:5000" + volumes: + - .:/code + - logvolume01:/var/log + links: + - redis + redis: + image: redis +volumes: + logvolume01: {} +``` + +docker-compose up 100 个服务,也可以一键启动 + +Compose:重要的概念 + +- 服务service,容器,应用(web,redis,mysql) +- 项目project,就是一组关联的容器。 + +## 安装Docker Compose + +官方文档:https://docs.docker.com/compose/install/ + +### 下载 + +首先我们先安装一下Docker + +```bash +# yum安装 +yum -y install docker-ce +#查看docker版本 +docker --version +# 设置开机自启 +systemctl enable docker +# 启动docker +systemctl start docker +``` + +然后下载docker-compose + +```bash +sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +``` + +### 授权 + +下载完成后,我们进入到下面的目录 + +```bash +cd /usr/local/bin +``` + +然后加入执行权限 + +```bash +sudo chmod +x docker-compose +``` + +查看是否安装成功 + +```bash +docker-compose version +``` + +### 创建文件体验 + +在这个页面中,您将构建一个运行在Docker撰写器上的简单Python web应用程序。该应用程序使用了烧瓶框架,并在Redis中维护了一个命中计数器。虽然示例使用Python,但是即使您不熟悉它,这里演示的概念也应该可以理解。 + +确保你已经安装了Docker引擎和Docker组合。你不需要安装Python或Redis,因为它们都是由Docker images提供的。 + +```bash +# 创建文件夹 +mkdir composetest +# 进入该文件夹 +cd composetest +``` + +然后我们需要创建一个 app.py 文件 + +```bash +import time + +import redis +from flask import Flask + +app = Flask(__name__) +cache = redis.Redis(host='redis', port=6379) + + +def get_hit_count(): + retries = 5 + while True: + try: + return cache.incr('hits') + except redis.exceptions.ConnectionError as exc: + if retries == 0: + raise exc + retries -= 1 + time.sleep(0.5) + + +@app.route('/') +def hello(): + count = get_hit_count() + return 'Hello World! I have been seen {} times.\n'.format(count) +``` + +然后创建一个 requirements.txt 文件,里面需要依赖包 + +```py +flask +redis +``` + +### 创建Docker file + +在这个步骤中,您将编写一个构建Docker映像的Dockerfile。该映像包含Python应用程序需要的所有依赖项,包括Python本身。在您的项目目录中,创建一个名为Dockerfile的文件,并粘贴以下内容: + +```bash +FROM python:3.7-alpine +WORKDIR /code +ENV FLASK_APP app.py +ENV FLASK_RUN_HOST 0.0.0.0 +RUN apk add --no-cache gcc musl-dev linux-headers +COPY requirements.txt requirements.txt +RUN pip install -r requirements.txt +EXPOSE 5000 +COPY . . +CMD ["flask", "run"] +``` + +> 上述代码中,是为了告诉Docker +> +> 从Python3.7版本开始构建镜像 +> +> 将当前目录设置为 /code +> +> 安装python依赖项 +> +> 将容器的默认命令设置为 python app.py + +### 定义服务在Compose文件中 + +创建一个名为docker-compose的文件。yml在您的项目目录,并粘贴以下 + +```bash +version: '3' +services: + web: + build: . + ports: + - "5000:5000" + redis: + image: "redis:alpine" +``` + +> 此Compose文件定义了两个服务,web和redis,该web服务使用从Docker file当前目录中构建的镜像 +> +> 将容器上的公开端口5000 + +这个合成文件定义了两个服务:web和redis。 + +#### Web服务 + +web服务使用从当前目录中的Dockerfile构建的映像。然后,它将容器和主机绑定到公开的端口5000。这个示例服务使用了Flask web服务器5000的默认端口 + +#### Redis服务 + +redis服务使用从Docker Hub注册中心提取的公共redis图像 + +### 使用Compose构建和运行应用程序 + +在项目目录中,通过运行启动应用程序 `docker-compose up`. + +```bash +docker-compose up +``` + +运行结果如下 + +```bash +Creating network "composetest_default" with the default driver +Creating composetest_web_1 ... +Creating composetest_redis_1 ... +Creating composetest_web_1 +Creating composetest_redis_1 ... done +Attaching to composetest_web_1, composetest_redis_1 +web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) +redis_1 | 1:C 17 Aug 22:11:10.480 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo +redis_1 | 1:C 17 Aug 22:11:10.480 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1, just started +redis_1 | 1:C 17 Aug 22:11:10.480 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf +web_1 | * Restarting with stat +redis_1 | 1:M 17 Aug 22:11:10.483 * Running mode=standalone, port=6379. +redis_1 | 1:M 17 Aug 22:11:10.483 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. +web_1 | * Debugger is active! +redis_1 | 1:M 17 Aug 22:11:10.483 # Server initialized +redis_1 | 1:M 17 Aug 22:11:10.483 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. +web_1 | * Debugger PIN: 330-787-903 +redis_1 | 1:M 17 Aug 22:11:10.483 * Ready to accept connections +``` + +最后查看服务是否启动成功 + +![image-20200727212451516](images/image-20200727212451516.png) + +使用 docker images命令,我们发现在docker compose中的镜像都已经下载好了 + +![image-20200727212555232](images/image-20200727212555232.png) + +### 网络规则 + +使用下面的命令,就可以查看到docker中的网络 + +```bash +docker network ls +``` + +![image-20200727212932704](images/image-20200727212932704.png) + +通过compose构建的服务,compose帮我们维护了,都会在一个网络下面,就可以通过域名访问 + +我们通过以下命令来进行查看,发现启动的两个服务,就是同处于同一个网络下的 + +```bash +docker network inspect composetest_default +``` + +![image-20200727213527466](images/image-20200727213527466.png) + +### 关闭docker compose + +可以使用一下命令退出 + +```bash +docker-compose down +# 或者 +ctrl + c +``` + +### 总结 + +我们可以对上述的操作,进行一下总结,就可以分为一下几个步骤 + +- 应用 app.py +- Docker file 将应用程序打包成镜像 +- Docker-compose yaml 文件(定义整个服务,需要的环境,web、redis)完整的上线服务 +- 启动compose项目(docker-compose up) +- 流程 + - 创建网络 + - 执行Docker-compose yaml + - 启动服务 + +原来我们没有用到docker-compose的时候,都是需要使用docker run,一个个的运行我们的容器 + +通过docker-compose,我们编写yaml文件,可以通过docker-compose一键启动服务,或者停止。 + +## yaml规则 + +docker-compose.yaml规则 + +```bash +# 三层 +version: "3.8" # 定义版本 +services: # 定义服务 + 服务1:web + images + build + network + ...... + 服务2:redis + ..... + 服务3:nginx + ..... + # 其它配置 网络/卷、全局规则 + volumes: + networks: + configs: +``` + +完整实例如下 + +```yaml +version: "3.8" +services: + redis: + image: redis:latest + deploy: + replicas: 1 + configs: + - my_config + - my_other_config +configs: + my_config: + file: ./my_config.txt + my_other_config: + external: true +``` + +### 依赖关系 + +如果我们的项目还有依赖关系,比如 web 依赖于redis,也就是说项目需要首先启动redis + +```yaml +version: "3.8" +services: + web: + build: . + depends_on: + - db + - redis + redis: + image: redis + db: + image: postgres +``` + +## 快速搭建WordPress + +官网搭建文档:https://docs.docker.com/compose/wordpress/ + +首先创建项目的文件夹 + +```bash +# 创建文件夹 +mkdir my_wordpress +# 进入文件夹 +cd my_wordpress/ +``` + +然后创建一个 docker-compose.yml 文件 + +```yaml +version: '3.3' # 定义版本 + +services: + db: + image: mysql:5.7 + volumes: + - db_data:/var/lib/mysql + restart: always + environment: + MYSQL_ROOT_PASSWORD: somewordpress + MYSQL_DATABASE: wordpress + MYSQL_USER: wordpress + MYSQL_PASSWORD: wordpress + + wordpress: + depends_on: # 依赖于上一个db,也就是需要db启动 + - db + image: wordpress:latest + ports: + - "8000:80" + restart: always + environment: + WORDPRESS_DB_HOST: db:3306 + WORDPRESS_DB_USER: wordpress + WORDPRESS_DB_PASSWORD: wordpress + WORDPRESS_DB_NAME: wordpress +volumes: + db_data: {} +``` + +后台启动项目 + +```bash +docker-compose -d +``` + +到此为止,项目已经成功搭建完毕 + +> 正常的开源项目,可能还需要依赖 build后的jar包,所以我们还需要使用Dockerfile +> +> 当我们的文件准备齐全的时候,就可以一键启动项目 + +未来的趋势:linux、docker、k8s + +掌握:docker基础、原理、网络、服务、集群、错误排查、日志。 + +## docker-compose搭建微服务 + +我们可以使用下面命令 ,创建一个SpringBoot项目:https://start.spring.io/ + +- 编写项目微服务 +- dockerfile构建镜像 +- 创建docker-compose来启动项目,进行服务编排 +- 丢到服务器 docker-compose启动 +- 如果出现了问题:使用docker-compose up --build(重新构建) + +## Docker小结 + +- Docker镜像 -> 通过 run命令启动镜像 +- Dockerfile 构建镜像(服务打包) +- docker-compose 启动项目(编排、多个微服务/ 环境) +- Docker 网络 + +## 参考 + +https://www.bilibili.com/video/BV1kv411q7Qc \ No newline at end of file diff --git a/Docker/DockerCompose/images/image-20200727212451516.png b/Docker/DockerCompose/images/image-20200727212451516.png new file mode 100644 index 0000000000000000000000000000000000000000..b738310ba159b39c624e48ced158db069f87b8f3 Binary files /dev/null and b/Docker/DockerCompose/images/image-20200727212451516.png differ diff --git a/Docker/DockerCompose/images/image-20200727212555232.png b/Docker/DockerCompose/images/image-20200727212555232.png new file mode 100644 index 0000000000000000000000000000000000000000..20863d22936a41de657eae9883c2b5f822f4fc7d Binary files /dev/null and b/Docker/DockerCompose/images/image-20200727212555232.png differ diff --git a/Docker/DockerCompose/images/image-20200727212932704.png b/Docker/DockerCompose/images/image-20200727212932704.png new file mode 100644 index 0000000000000000000000000000000000000000..67b310cd744dcb02cfe14ce8e6a987ed939f21bc Binary files /dev/null and b/Docker/DockerCompose/images/image-20200727212932704.png differ diff --git a/Docker/DockerCompose/images/image-20200727213527466.png b/Docker/DockerCompose/images/image-20200727213527466.png new file mode 100644 index 0000000000000000000000000000000000000000..c88cb883bddf282b6703b5f8b92ffb9b641013ec Binary files /dev/null and b/Docker/DockerCompose/images/image-20200727213527466.png differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/README.md" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..0fd4ab16cda85203ed2cb661d2e78004f3d590d5 --- /dev/null +++ "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/README.md" @@ -0,0 +1,2250 @@ +# ElasticSearch安装与介绍 + +## Elastic Stack简介 + +如果你没有听说过Elastic Stack,那你一定听说过ELK,实际上ELK是三款软件的简称,分别是Elasticsearch、 +Logstash、Kibana组成,在发展的过程中,又有新成员Beats的加入,所以就形成了Elastic Stack。所以说,ELK是旧的称呼,Elastic Stack是新的名字。 + +![image-20200922092403279](images/image-20200922092403279.png) + +全系的Elastic Stack技术栈包括: + +![image-20200922092505011](images/image-20200922092505011.png) + +### Elasticsearch + +Elasticsearch 基于java,是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。 + +### Logstash + +Logstash 基于java,是一个开源的用于收集,分析和存储日志的工具。 + +### Kibana + +Kibana 基于nodejs,也是一个开源和免费的工具,Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的Web 界面,可以汇总、分析和搜索重要数据日志。 + +### Beats + +Beats是elastic公司开源的一款采集系统监控数据的代理agent,是在被监控服务器上以客户端形式运行的数据收集器的统称,可以直接把数据发送给Elasticsearch或者通过Logstash发送给Elasticsearch,然后进行后续的数据分析活动。Beats由如下组成: + +- Packetbeat:是一个网络数据包分析器,用于监控、收集网络流量信息,Packetbeat嗅探服务器之间的流量,解析应用层协议,并关联到消息的处理,其支 持ICMP (v4 and v6)、DNS、HTTP、Mysql、PostgreSQL、Redis、MongoDB、Memcache等协议; +- Filebeat:用于监控、收集服务器日志文件,其已取代 logstash forwarder; +- Metricbeat:可定期获取外部系统的监控指标信息,其可以监控、收集 Apache、HAProxy、MongoDB + MySQL、Nginx、PostgreSQL、Redis、System、Zookeeper等服务; + +> Beats和Logstash其实都可以进行数据的采集,但是目前主流的是使用Beats进行数据采集,然后使用 Logstash进行数据的分割处理等,早期没有Beats的时候,使用的就是Logstash进行数据的采集。 + +## ElasticSearch快速入门 + +### 简介 + +官网:https://www.elastic.co/ + +ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。 + +我们建立一个网站或应用程序,并要添加搜索功能,但是想要完成搜索工作的创建是非常困难的。我们希望搜索解决方案要运行速度快,我们希望能有一个零配置和一个完全免费的搜索模式,我们希望能够简单地使用JSON通过HTTP来索引数据,我们希望我们的搜索服务器始终可用,我们希望能够从一台开始并扩展到数百台,我们要实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案。因此我们利用Elasticsearch来解决所有这些问题及可能出现的更多其它问题。 + +ElasticSearch是Elastic Stack的核心,同时Elasticsearch 是一个分布式、RESTful风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。作为Elastic Stack的核心,它集中存储您的数据,帮助您发现意料之中以及意料之外的情况。 + +### 前言 + +Elasticsearch的发展是非常快速的,所以在ES5.0之前,ELK的各个版本都不统一,出现了版本号混乱的状态,所以从5.0开始,所有Elastic Stack中的项目全部统一版本号。目前最新版本是6.5.4,我们将基于这一版本进行学习。 + +![image-20200922093432839](images/image-20200922093432839.png) + +### 下载 + +到官网下载:https://www.elastic.co/cn/downloads/ + +![image-20200922094003384](images/image-20200922094003384.png) + +选择对应版本的数据,这里我使用的是Linux来进行安装,所以就先下载好ElasticSearch的Linux安装包 + +### 拉取Docker容器 + +因为我们需要部署在Linux下,为了以后迁移ElasticStack环境方便,我们就使用Docker来进行部署,首先我们拉取一个带有ssh的centos docker镜像 + +```bash +# 拉取镜像 +docker pull moxi/centos_ssh +# 制作容器 +docker run --privileged -d -it -h ElasticStack --name ElasticStack -p 11122:22 -p 9200:9200 -p 5601:5601 -p 9300:9300 -v /etc/localtime:/etc/localtime:ro moxi/centos_ssh /usr/sbin/init +``` + +然后直接远程连接11122端口即可 + +### 单机版安装 + +因为ElasticSearch不支持Root用户直接操作,因此我们需要创建一个elsearch用户 + +```bash +# 添加新用户 +useradd elsearch + +# 创建一个soft目录,存放下载的软件 +mkdir /soft + +# 进入,然后通过xftp工具,将刚刚下载的文件拖动到该目录下 +cd /soft + +# 解压缩 +tar -zxvf elasticsearch-7.9.1-linux-x86_64.tar.gz + +#重命名 +mv elasticsearch-7.9.1/ elsearch +``` + +因为刚刚我们是使用root用户操作的,所以我们还需要更改一下/soft文件夹的所属,改为elsearch用户 + +```bash +chown elsearch:elsearch /soft/ -R +``` + +然后在切换成elsearch用户进行操作 + +```bash +# 切换用户 +su - elsearch +``` + +然后我们就可以对我们的配置文件进行修改了 + +```bash +# 进入到 elsearch下的config目录 +cd /soft/elsearch/config +``` + +然后找到下面的配置 + +```yaml +#打开配置文件 +vim elasticsearch.yml + +#设置ip地址,任意网络均可访问 +network.host: 0.0.0.0 +``` + +在Elasticsearch中如果,network.host不是localhost或者127.0.0.1的话,就会认为是生产环境,会对环境的要求比较高,我们的测试环境不一定能够满足,一般情况下需要修改2处配置,如下: + +```bash +# 修改jvm启动参数 +vim conf/jvm.options + +#根据自己机器情况修改 +-Xms128m +-Xmx128m +``` + +然后在修改第二处的配置,这个配置要求我们到宿主机器上来进行配置 + +```bash +# 到宿主机上打开文件 +vim /etc/sysctl.conf +# 增加这样一条配置,一个进程在VMAs(虚拟内存区域)创建内存映射最大数量 +vm.max_map_count=655360 +# 让配置生效 +sysctl -p +``` + +### 启动ElasticSearch + +首先我们需要切换到 elsearch用户 + +```bash +su - elsearch +``` + +然后在到bin目录下,执行下面 + +```bash +# 进入bin目录 +cd /soft/elsearch/bin +# 后台启动 +./elasticsearch -d +``` + +启动成功后,访问下面的URL + +```bash +http://202.193.56.222:9200/ +``` + +如果出现了下面的信息,就表示已经成功启动了 + +![image-20200922150758205](images/image-20200922150758205.png) + +如果你在启动的时候,遇到过问题,那么请参考下面的错误分析~ + +## 错误分析 + +### 错误情况1 + +如果出现下面的错误信息 + +``` +java.lang.RuntimeException: can not run elasticsearch as root + at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:111) + at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:178) + at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:393) + at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:170) + at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:161) + at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) + at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:127) + at org.elasticsearch.cli.Command.main(Command.java:90) + at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:126) + at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92) +For complete error details, refer to the log at /soft/elsearch/logs/elasticsearch.log +[root@e588039bc613 bin]# 2020-09-22 02:59:39,537121 UTC [536] ERROR CLogger.cc@310 Cannot log to named pipe /tmp/elasticsearch-5834501324803693929/controller_log_381 as it could not be opened for writing +2020-09-22 02:59:39,537263 UTC [536] INFO Main.cc@103 Parent process died - ML controller exiting +``` + +就说明你没有切换成 elsearch用户,因为不能使用root操作es + +```bash +su - elsearch +``` + +### 错误情况2 + +```bash +[1]:max file descriptors [4096] for elasticsearch process is too low, increase to at least[65536] +``` + +解决方法:切换到root用户,编辑limits.conf添加如下内容 + +```bash +vi /etc/security/limits.conf + +# ElasticSearch添加如下内容: +* soft nofile 65536 +* hard nofile 131072 +* soft nproc 2048 +* hard nproc 4096 +``` + +### 错误情况3 + +```bash +[2]: max number of threads [1024] for user [elsearch] is too low, increase to at least +[4096] +``` + +也就是最大线程数设置的太低了,需要改成4096 + +```bash +#解决:切换到root用户,进入limits.d目录下修改配置文件。 +vi /etc/security/limits.d/90-nproc.conf +#修改如下内容: +* soft nproc 1024 +#修改为 +* soft nproc 4096 +``` + +### 错误情况4 + +```bash +[3]: system call filters failed to install; check the logs and fix your configuration +or disable system call filters at your own risk +``` + +解决:Centos6不支持SecComp,而ES5.2.0默认bootstrap.system_call_filter为true + +```bash +vim config/elasticsearch.yml +# 添加 +bootstrap.system_call_filter: false +bootstrap.memory_lock: false +``` + +### 错误情况5 + +```bash +[elsearch@e588039bc613 bin]$ Exception in thread "main" org.elasticsearch.bootstrap.BootstrapException: java.nio.file.AccessDeniedException: /soft/elsearch/config/elasticsearch.keystore +Likely root cause: java.nio.file.AccessDeniedException: /soft/elsearch/config/elasticsearch.keystore + at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:90) + at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) + at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116) + at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:219) + at java.base/java.nio.file.Files.newByteChannel(Files.java:375) + at java.base/java.nio.file.Files.newByteChannel(Files.java:426) + at org.apache.lucene.store.SimpleFSDirectory.openInput(SimpleFSDirectory.java:79) + at org.elasticsearch.common.settings.KeyStoreWrapper.load(KeyStoreWrapper.java:220) + at org.elasticsearch.bootstrap.Bootstrap.loadSecureSettings(Bootstrap.java:240) + at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:349) + at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:170) + at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:161) + at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) + at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:127) + at org.elasticsearch.cli.Command.main(Command.java:90) + at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:126) + at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92) + +``` + +我们通过排查,发现是因为 /soft/elsearch/config/elasticsearch.keystore 存在问题 + +![image-20200922111823740](images/image-20200922111823740.png) + +也就是说该文件还是所属于root用户,而我们使用elsearch用户无法操作,所以需要把它变成elsearch + +```bash +chown elsearch:elsearch elasticsearch.keystore +``` + +### 错误情况6 + +```bash +[1]: the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured +ERROR: Elasticsearch did not exit normally - check the logs at /soft/elsearch/logs/elasticsearch.log +``` + +继续修改配置 elasticsearch.yaml + +```bash +# 取消注释,并保留一个节点 +node.name: node-1 +cluster.initial_master_nodes: ["node-1"] +``` + + + +## ElasticSearchHead可视化工具 + +由于ES官方没有给ES提供可视化管理工具,仅仅是提供了后台的服务,elasticsearch-head是一个为ES开发的一个页面客户端工具,其源码托管于Github,地址为 [传送门](https://github.com/mobz/elasticsearch-head) + +head提供了以下安装方式 + +- 源码安装,通过npm run start启动(不推荐) +- 通过docker安装(推荐) +- 通过chrome插件安装(推荐) +- 通过ES的plugin方式安装(不推荐) + +### 通过Docker方式安装 + +```bash +#拉取镜像 +docker pull mobz/elasticsearch-head:5 +#创建容器 +docker create --name elasticsearch-head -p 9100:9100 mobz/elasticsearch-head:5 +#启动容器 +docker start elasticsearch-head +``` + +通过浏览器进行访问: + +![image-20200922151529269](images/image-20200922151529269.png) + +注意: +由于前后端分离开发,所以会存在跨域问题,需要在服务端做CORS的配置,如下: + +```bash +vim elasticsearch.yml + +http.cors.enabled: true http.cors.allow-origin: "*" +``` + +通过chrome插件的方式安装不存在该问题 + +### 通过Chrome插件安装 + +打开chrome的应用商店,即可安装 https://chrome.google.com/webstore/detail/elasticsearch-head/ffmkiejjmecolpfloofpjologoblkegm + +![image-20200922152428838](images/image-20200922152428838.png) + +我们也可以新建索引 + +![image-20200922152534471](images/image-20200922152534471.png) + +建议:推荐使用chrome插件的方式安装,如果网络环境不允许,就采用其它方式安装。 + +## ElasticSearch中的基本概念 + +### 索引 + +- 索引(index)是Elasticsearch对逻辑数据的逻辑存储,所以它可以分为更小的部分。 +- 可以把索引看成关系型数据库的表,索引的结构是为快速有效的全文索引准备的,特别是它不存储原始值。 +- Elasticsearch可以把索引存放在一台机器或者分散在多台服务器上,每个索引有一或多个分片(shard),每个分片可以有多个副本(replica)。 + +### 文档 + +- 存储在Elasticsearch中的主要实体叫文档(document)。用关系型数据库来类比的话,一个文档相当于数据库表中的一行记录。 +- Elasticsearch和MongoDB中的文档类似,都可以有不同的结构,但Elasticsearch的文档中,相同字段必须有相同类型。 +- 文档由多个字段组成,每个字段可能多次出现在一个文档里,这样的字段叫多值字段(multivalued)。 + 每个字段的类型,可以是文本、数值、日期等。字段类型也可以是复杂类型,一个字段包含其他子文档或者数 + 组。 + +### 映射 + +所有文档写进索引之前都会先进行分析,如何将输入的文本分割为词条、哪些词条又会被过滤,这种行为叫做 +映射(mapping)。一般由用户自己定义规则。 + +### 文档类型 + +- 在Elasticsearch中,一个索引对象可以存储很多不同用途的对象。例如,一个博客应用程序可以保存文章和评 + 论。 +- 每个文档可以有不同的结构。 +- 不同的文档类型不能为相同的属性设置不同的类型。例如,在同一索引中的所有文档类型中,一个叫title的字段必须具有相同的类型。 + +## RESTful API + +在Elasticsearch中,提供了功能丰富的RESTful API的操作,包括基本的CRUD、创建索引、删除索引等操作。 + +### 创建非结构化索引 + +在Lucene中,创建索引是需要定义字段名称以及字段的类型的,在Elasticsearch中提供了非结构化的索引,就是不需要创建索引结构,即可写入数据到索引中,实际上在Elasticsearch底层会进行结构化操作,此操作对用户是透明的。 + +### 创建空索引 + +```bash +PUT /haoke +{ + "settings": { + "index": { + "number_of_shards": "2", #分片数 + "number_of_replicas": "0" #副本数 + } + } +} +``` + +### 删除索引 + +```bash +#删除索引 +DELETE /haoke +{ + "acknowledged": true +} +``` + +### 插入数据 + +>URL规则: +>POST /{索引}/{类型}/{id} + +```bash +POST /haoke/user/1001 +#数据 +{ +"id":1001, +"name":"张三", +"age":20, +"sex":"男" +} +``` + +使用postman操作成功后 + +![image-20200922155642306](images/image-20200922155642306.png) + +我们通过ElasticSearchHead进行数据预览就能够看到我们刚刚插入的数据了 + +![image-20200922155843314](images/image-20200922155843314.png) + +说明:非结构化的索引,不需要事先创建,直接插入数据默认创建索引。不指定id插入数据: + +![image-20200922155935366](images/image-20200922155935366.png) + +### 更新数据 + +在Elasticsearch中,文档数据是不为修改的,但是可以通过覆盖的方式进行更新。 + +```bash +PUT /haoke/user/1001 +{ +"id":1001, +"name":"张三", +"age":21, +"sex":"女" +} +``` + +更新结果如下: + +![image-20200922160154599](images/image-20200922160154599.png) + +![image-20200922160201130](images/image-20200922160201130.png) + +可以看到数据已经被覆盖了。问题来了,可以局部更新吗? -- 可以的。前面不是说,文档数据不能更新吗? 其实是这样的:在内部,依然会查询到这个文档数据,然后进行覆盖操作,步骤如下: + +1. 从旧文档中检索JSON +2. 修改它 +3. 删除旧文档 +4. 索引新文档 + +```bash +#注意:这里多了_update标识 +POST /haoke/user/1001/_update +{ +"doc":{ +"age":23 +} +} +``` + +![image-20200922160709463](images/image-20200922160709463.png) + +![image-20200922160717001](images/image-20200922160717001.png) + +可以看到,数据已经是局部更新了 + +### 删除索引 + +在Elasticsearch中,删除文档数据,只需要发起DELETE请求即可,不用额外的参数 + +```bash +DELETE 1 /haoke/user/1001 +``` + +![image-20200922160752862](images/image-20200922160752862.png) + +需要注意的是,result表示已经删除,version也增加了。 + +如果删除一条不存在的数据,会响应404 + +![image-20200922161627716](images/image-20200922161627716.png) + +> 删除一个文档也不会立即从磁盘上移除,它只是被标记成已删除。Elasticsearch将会在你之后添加更多索引的时候才会在后台进行删除内容的清理。【相当于批量操作】 + +### 搜索数据 + +#### 根据id搜索数据 + +```bash +GET /haoke/user/BbPe_WcB9cFOnF3uebvr +#返回的数据如下 +{ + "_index": "haoke", + "_type": "user", + "_id": "BbPe_WcB9cFOnF3uebvr", + "_version": 8, + "found": true, + "_source": { #原始数据在这里 + "id": 1002, + "name": "李四", + "age": 40, + "sex": "男" + } +} +``` + +#### 搜索全部数据 + +```bash +GET 1 /haoke/user/_search +``` + +注意,使用查询全部数据的时候,默认只会返回10条 + +![image-20200922162228822](images/image-20200922162228822.png) + +#### 关键字搜索数据 + +```bash +#查询年龄等于20的用户 +GET /haoke/user/_search?q=age:20 +``` + +结果如下: + +![image-20200922162309797](images/image-20200922162309797.png) + +### DSL搜索 + +Elasticsearch提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。 +DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现。 + +```bash +POST /haoke/user/_search +#请求体 +{ + "query" : { + "match" : { #match只是查询的一种 + "age" : 20 + } + } +} +``` + +实现:查询年龄大于30岁的男性用户。 + +![image-20200922162943539](images/image-20200922162943539.png) + +```bash +POST /haoke/user/_search +#请求数据 +{ + "query": { + "bool": { + "filter": { + "range": { + "age": { + "gt": 30 + } + } + }, + "must": { + "match": { + "sex": "男" + } + } + } + } +} +``` + +查询出来的结果 + +![image-20200922163109515](images/image-20200922163109515.png) + +#### 全文搜索 + +```bash +POST /haoke/user/_search +#请求数据 +{ + "query": { + "match": { + "name": "张三 李四" + } + } +} +``` + +![image-20200922163315285](images/image-20200922163315285.png) + +高亮显示,只需要在添加一个 highlight即可 + +```bash +POST /haoke/user/_search +#请求数据 +{ + "query": { + "match": { + "name": "张三 李四" + } + } + "highlight": { + "fields": { + "name": {} + } + } +} +``` + +![image-20200922163432853](images/image-20200922163432853.png) + +#### 聚合 + +在Elasticsearch中,支持聚合操作,类似SQL中的group by操作。 + +```bash +POST /haoke/user/_search +{ + "aggs": { + "all_interests": { + "terms": { + "field": "age" + } + } + } +} +``` + +结果如下,我们通过年龄进行聚合 + +![image-20200922163614708](images/image-20200922163614708.png) + +从结果可以看出,年龄30的有2条数据,20的有一条,40的一条。 + +## ElasticSearch核心详解 + +### 文档 + +在Elasticsearch中,文档以JSON格式进行存储,可以是复杂的结构,如: + +```bash +{ + "_index": "haoke", + "_type": "user", + "_id": "1005", + "_version": 1, + "_score": 1, + "_source": { + "id": 1005, + "name": "孙七", + "age": 37, + "sex": "女", + "card": { + "card_number": "123456789" + } + } +} +``` + +其中,card是一个复杂对象,嵌套的Card对象 + +#### 元数据(metadata) + +一个文档不只有数据。它还包含了元数据(metadata)——关于文档的信息。三个必须的元数据节点是: + +![image-20200922165956176](images/image-20200922165956176.png) + +#### index + +索引(index)类似于关系型数据库里的“数据库”——它是我们存储和索引关联数据的地方。 + +> 提示:事实上,我们的数据被存储和索引在分片(shards)中,索引只是一个把一个或多个分片分组在一起的逻辑空间。然而,这只是一些内部细节——我们的程序完全不用关心分片。对于我们的程序而言,文档存储在索引(index)中。剩下的细节由Elasticsearch关心既可。 + +#### _type + +在应用中,我们使用对象表示一些“事物”,例如一个用户、一篇博客、一个评论,或者一封邮件。每个对象都属于一个类(class),这个类定义了属性或与对象关联的数据。user 类的对象可能包含姓名、性别、年龄和Email地址。 +在关系型数据库中,我们经常将相同类的对象存储在一个表里,因为它们有着相同的结构。同理,在Elasticsearch +中,我们使用相同类型(type)的文档表示相同的“事物”,因为他们的数据结构也是相同的。 + +每个类型(type)都有自己的映射(mapping)或者结构定义,就像传统数据库表中的列一样。所有类型下的文档被存储在同一个索引下,但是类型的映射(mapping)会告诉Elasticsearch不同的文档如何被索引。 + +_type 的名字可以是大写或小写,不能包含下划线或逗号。我们将使用blog 做为类型名。 + +#### _id + +id仅仅是一个字符串,它与_index 和_type 组合时,就可以在Elasticsearch中唯一标识一个文档。当创建一个文 +档,你可以自定义_id ,也可以让Elasticsearch帮你自动生成(32位长度) + +### 查询响应 + +#### pretty + +可以在查询url后面添加pretty参数,使得返回的json更易查看。 + +![image-20200923101056932](images/image-20200923101056932.png) + +#### 指定响应字段 + +在响应的数据中,如果我们不需要全部的字段,可以指定某些需要的字段进行返回。通过添加 _source + +```bash +GET /haoke/user/1005?_source=id,name +#响应 +{ + "_index": "haoke", + "_type": "user", + "_id": "1005", + "_version": 1, + "found": true, + "_source": { + "name": "孙七", + "id": 1005 + } +} +``` + +如不需要返回元数据,仅仅返回原始数据,可以这样: + +```bash +GET /haoke/1 user/1005/_source +``` + +![image-20200923101239226](images/image-20200923101239226.png) + +还可以这样: + +```bash +GET /haoke/user/1005/_source?_1 source=id,name +``` + +![image-20200923101319728](images/image-20200923101319728.png) + +#### 判断文档是否存在 + +如果我们只需要判断文档是否存在,而不是查询文档内容,那么可以这样: + +```bash +HEAD /haoke/user/1005 +``` + +通过发送一个head请求,来判断数据是否存在 + +![image-20200923101354992](images/image-20200923101354992.png) + +```bash +HEAD 1 /haoke/user/1006 +``` + +![image-20200923101433608](images/image-20200923101433608.png) + +> 当然,这只表示你在查询的那一刻文档不存在,但并不表示几毫秒后依旧不存在。另一个进程在这期间可能创建新文档。 + +### 批量操作 + +有些情况下可以通过批量操作以减少网络请求。如:批量查询、批量插入数据。 + +#### 批量查询 + +```bash +POST /haoke/user/_mget +{ + "ids" : [ "1001", "1003" ] +} +``` + +结果: + +![image-20200923101540616](images/image-20200923101540616.png) + +如果,某一条数据不存在,不影响整体响应,需要通过found的值进行判断是否查询到数据。 + +```bash +POST /haoke/user/_mget +{ + "ids" : [ "1001", "1006" ] +} +``` + +结果: + +![image-20200923101721344](images/image-20200923101721344.png) + +> 也就是说,一个数据的存在不会影响其它数据的返回 + +#### _bulk操作 + +在Elasticsearch中,支持批量的插入、修改、删除操作,都是通过_bulk的api完成的。 + +请求格式如下:(请求格式不同寻常) + +``` +{ action: { metadata }} +{ request body } +{ action: { metadata }} +{ request body } +... +``` + +批量插入数据: + +```bash +{"create":{"_index":"haoke","_type":"user","_id":2001}} +{"id":2001,"name":"name1","age": 20,"sex": "男"} +{"create":{"_index":"haoke","_type":"user","_id":2002}} +{"id":2002,"name":"name2","age": 20,"sex": "男"} +{"create":{"_index":"haoke","_type":"user","_id":2003}} +{"id":2003,"name":"name3","age": 20,"sex": "男"} +``` + +注意最后一行的回车。 + +![image-20200923101946147](images/image-20200923101946147.png) + +批量删除: + +```bash +{"delete":{"_index":"haoke","_type":"user","_id":2001}} +{"delete":{"_index":"haoke","_type":"user","_id":2002}} +{"delete":{"_index":"haoke","_type":"user","_id":2003}} +``` + +由于delete没有请求体,所以,action的下一行直接就是下一个action。 + +![image-20200923102044231](images/image-20200923102044231.png) + +其他操作就类似了。一次请求多少性能最高? + +- 整个批量请求需要被加载到接受我们请求节点的内存里,所以请求越大,给其它请求可用的内存就越小。有一 + 个最佳的bulk请求大小。超过这个大小,性能不再提升而且可能降低。 +- 最佳大小,当然并不是一个固定的数字。它完全取决于你的硬件、你文档的大小和复杂度以及索引和搜索的负 + 载。 +- 幸运的是,这个最佳点(sweetspot)还是容易找到的:试着批量索引标准的文档,随着大小的增长,当性能开始 + 降低,说明你每个批次的大小太大了。开始的数量可以在1000~5000个文档之间,如果你的文档非常大,可以使用较小的批次。 +- 通常着眼于你请求批次的物理大小是非常有用的。一千个1kB的文档和一千个1MB的文档大不相同。一个好的 + 批次最好保持在5-15MB大小间。 + +### 分页 + +和SQL使用LIMIT 关键字返回只有一页的结果一样,Elasticsearch接受from 和size 参数: + +- size: 结果数,默认10 +- from: 跳过开始的结果数,默认0 + +如果你想每页显示5个结果,页码从1到3,那请求如下: + +```bash +GET /_search?size=5 +GET /_search?size=5&from=5 +GET /_search?size=5&from=10 +``` + +应该当心分页太深或者一次请求太多的结果。结果在返回前会被排序。但是记住一个搜索请求常常涉及多个分 +片。每个分片生成自己排好序的结果,它们接着需要集中起来排序以确保整体排序正确。 + +```bash +GET /haoke/user/_1 search?size=1&from=2 +``` + +![image-20200923102611567](images/image-20200923102611567.png) + +#### 在集群系统中深度分页 + +为了理解为什么深度分页是有问题的,让我们假设在一个有5个主分片的索引中搜索。当我们请求结果的第一 +页(结果1到10)时,每个分片产生自己最顶端10个结果然后返回它们给请求节点(requesting node),它再 +排序这所有的50个结果以选出顶端的10个结果。 + +现在假设我们请求第1000页——结果10001到10010。工作方式都相同,不同的是每个分片都必须产生顶端的 +10010个结果。然后请求节点排序这50050个结果并丢弃50040个! + +你可以看到在分布式系统中,排序结果的花费随着分页的深入而成倍增长。这也是为什么网络搜索引擎中任何 +语句不能返回多于1000个结果的原因。 + +### 映射 + +前面我们创建的索引以及插入数据,都是由Elasticsearch进行自动判断类型,有些时候我们是需要进行明确字段类型的,否则,自动判断的类型和实际需求是不相符的。 + +自动判断的规则如下: + +![image-20200923103848097](images/image-20200923103848097.png) + +Elasticsearch中支持的类型如下: + +![image-20200923103917807](images/image-20200923103917807.png) + +- string类型在ElasticSearch 旧版本中使用较多,从ElasticSearch 5.x开始不再支持string,由text和 + keyword类型替代。 +- text 类型,当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型 + 以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段 + 不用于排序,很少用于聚合。 +- keyword类型适用于索引结构化的字段,比如email地址、主机名、状态码和标签。如果字段需要进行过 + 滤(比如查找已发布博客中status属性为published的文章)、排序、聚合。keyword类型的字段只能通过精 + 确值搜索到。 + +#### 创建明确类型的索引: + +> 如果你要像之前旧版版本一样兼容自定义 type ,需要将 \**i\**nclude_type_name=true 携带 + +```bash +put http://202.193.56.222:9200/itcast?include_type_name=true +{ + "settings":{ + "index":{ + "number_of_shards":"2", + "number_of_replicas":"0" + } + }, + "mappings":{ + "person":{ + "properties":{ + "name":{ + "type":"text" + }, + "age":{ + "type":"integer" + }, + "mail":{ + "type":"keyword" + }, + "hobby":{ + "type":"text" + } + } + } + } +} +``` + +查看映射 + +```bash +GET /itcast/_mapping +``` + +![image-20200923104201613](images/image-20200923104201613.png) + +插入数据 + +```bash +POST /itcast/_bulk +{"index":{"_index":"itcast","_type":"person"}} +{"name":"张三","age": 20,"mail": "111@qq.com","hobby":"羽毛球、乒乓球、足球"} +{"index":{"_index":"itcast","_type":"person"}} +{"name":"李四","age": 21,"mail": "222@qq.com","hobby":"羽毛球、乒乓球、足球、篮球"} +{"index":{"_index":"itcast","_type":"person"}} +{"name":"王五","age": 22,"mail": "333@qq.com","hobby":"羽毛球、篮球、游泳、听音乐"} +{"index":{"_index":"itcast","_type":"person"}} +{"name":"赵六","age": 23,"mail": "444@qq.com","hobby":"跑步、游泳"} +{"index":{"_index":"itcast","_type":"person"}} +{"name":"孙七","age": 24,"mail": "555@qq.com","hobby":"听音乐、看电影"} +``` + +![image-20200923104551405](images/image-20200923104551405.png) + +#### 测试搜索 + +```bash +POST /itcast/person/_search +{ + "query":{ + "match":{ + "hobby":"音乐" + } + } +} +``` + +![image-20200923104653427](images/image-20200923104653427.png) + +### 结构化查询 + +#### term查询 + +term 主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed 的字符串(未经分析的文本数据类型): + +```bash +{ "term": { "age": 26 }} +{ "term": { "date": "2014-09-01" }} +{ "term": { "public": true }} +{ "term": { "tag": "full_text" }} +``` + +示例 + +```bash +POST /itcast/person/_search +{ + "query":{ + "term":{ + "age":20 + } + } +} +``` + +![image-20200923104851159](images/image-20200923104851159.png) + +#### terms查询 + +terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去 +做匹配: + +```bash +{ + "terms":{ + "tag":[ + "search", + "full_text", + "nosql" + ] + } +} +``` + +示例: + +```bash +POST /itcast/person/_search +{ + "query":{ + "terms":{ + "age":[ + 20, + 21 + ] + } + } +} +``` + +![image-20200923105030182](images/image-20200923105030182.png) + +#### range查询 + +range 过滤允许我们按照指定范围查找一批数据: + +```bash +{ + "range":{ + "age":{ + "gte":20, + "lt":30 + } + } +} +``` + +范围操作符包含: + +- gt : 大于 +- gte:: 大于等于 +- lt : 小于 +- lte: 小于等于 + +示例: + +```bash +POST /itcast/person/_search +{ + "query":{ + "range":{ + "age":{ + "gte":20, + "lte":22 + } + } + } +} +``` + +#### exists 查询 + +exists 查询可以用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的IS_NULL 条件 + +```bash +{ + "exists": { + "field": "title" + } +} +``` + +这两个查询只是针对已经查出一批数据来,但是想区分出某个字段是否存在的时候使用。示例: + +```bash +POST /haoke/user/_search +{ + "query": { + "exists": { #必须包含 + "field": "card" + } + } +} +``` + +![image-20200923105416339](images/image-20200923105416339.png) + +#### match查询 + +match 查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它。 + +如果你使用 match 查询一个全文本字段,它会在真正查询之前用分析器先分析match 一下查询字符: + +```bash +{ + "match": { + "tweet": "About Search" + } +} +``` + +如果用match 下指定了一个确切值,在遇到数字,日期,布尔值或者not_analyzed 的字符串时,它将为你搜索你 +给定的值: + +```bash +{ "match": { "age": 26 }} +{ "match": { "date": "2014-09-01" }} +{ "match": { "public": true }} +{ "match": { "tag": "full_text" }} +``` + +#### bool查询 + +- bool 查询可以用来合并多个条件查询结果的布尔逻辑,它包含一下操作符: +- must :: 多个查询条件的完全匹配,相当于 and 。 +- must_not :: 多个查询条件的相反匹配,相当于 not 。 +- should :: 至少有一个查询条件匹配, 相当于 or 。 + +这些参数可以分别继承一个查询条件或者一个查询条件的数组: + +```bash +{ + "bool":{ + "must":{ + "term":{ + "folder":"inbox" + } + }, + "must_not":{ + "term":{ + "tag":"spam" + } + }, + "should":[ + { + "term":{ + "starred":true + } + }, + { + "term":{ + "unread":true + } + } + ] + } +} +``` + +### 过滤查询 + +前面讲过结构化查询,Elasticsearch也支持过滤查询,如term、range、match等。 + +示例:查询年龄为20岁的用户。 + +```bash +POST /itcast/person/_search +{ + "query":{ + "bool":{ + "filter":{ + "term":{ + "age":20 + } + } + } + } +} +``` + +#### 查询和过滤的对比 + +- 一条过滤语句会询问每个文档的字段值是否包含着特定值。 +- 查询语句会询问每个文档的字段值与特定值的匹配程度如何。 +- 一条查询语句会计算每个文档与查询语句的相关性,会给出一个相关性评分 _score,并且 按照相关性对匹 + 配到的文档进行排序。 这种评分方式非常适用于一个没有完全配置结果的全文本搜索。 +- 一个简单的文档列表,快速匹配运算并存入内存是十分方便的, 每个文档仅需要1个字节。这些缓存的过滤结果集与后续请求的结合使用是非常高效的。 +- 查询语句不仅要查找相匹配的文档,还需要计算每个文档的相关性,所以一般来说查询语句要比 过滤语句更耗时,并且查询结果也不可缓存。 + +#### 建议: + +做精确匹配搜索时,最好用过滤语句,因为过滤语句可以缓存数据。 + +## 中文分词 + +### 什么是分词 + +分词就是指将一个文本转化成一系列单词的过程,也叫文本分析,在Elasticsearch中称之为Analysis。 + +举例:我是中国人 --> 我/是/中国人 + +### 分词api + +指定分词器进行分词 + +```bash +POST /_analyze +{ + "analyzer":"standard", + "text":"hello world" +} +``` + +结果如下 + +![image-20200923110814505](images/image-20200923110814505.png) + +在结果中不仅可以看出分词的结果,还返回了该词在文本中的位置。 + +> 指定索引分词 + +```bash +POST /itcast/_analyze +{ + "analyzer": "standard", + "field": "hobby", + "text": "听音乐" +} +``` + +![image-20200923110905001](images/image-20200923110905001.png) + +### 中文分词难点 + +中文分词的难点在于,在汉语中没有明显的词汇分界点,如在英语中,空格可以作为分隔符,如果分隔不正确就会造成歧义。如: + +- 我/爱/炒肉丝 +- 我/爱/炒/肉丝 + +常用中文分词器,IK、jieba、THULAC等,推荐使用IK分词器。 + +IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出了3个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的IK Analyzer 3.0则发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。 + +采用了特有的“正向迭代最细粒度切分算法“,具有80万字/秒的高速处理能力 采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。 优化的词典存储,更小的内存占用。 + +IK分词器 Elasticsearch插件地址:https://github.com/medcl/elasticsearch-analysis-ik + +### 安装分词器 + +首先下载到最新的ik分词器:[下载地址](https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.9.1) + +下载完成后,使用xftp工具,拷贝到服务器上 + +```bash +#安装方法:将下载到的 es/plugins/ik 目录下 +mkdir es/plugins/ik + +#解压 +unzip elasticsearch-analysis-ik-7.9.1.zip + +#重启 +./bin/elasticsearch +``` + +我们通过日志,发现它已经成功加载了ik分词器插件 + +![image-20200923113200826](images/image-20200923113200826.png) + +### 测试 + +```bash +POST /_analyze +{ + "analyzer": "ik_max_word", + "text": "我是中国人" +} +``` + +我们发现ik分词器已经成功分词完成 + +![image-20200923113222937](images/image-20200923113222937.png) + +## 全文搜索 + +全文搜索两个最重要的方面是: + +- 相关性(Relevance) 它是评价查询与其结果间的相关程度,并根据这种相关程度对结果排名的一种能力,这 + 种计算方式可以是 TF/IDF 方法、地理位置邻近、模糊相似,或其他的某些算法。 +- 分词(Analysis) 它是将文本块转换为有区别的、规范化的 token 的一个过程,目的是为了创建倒排索引以及查询倒排索引。 + +### 构造数据 + +> ES 7.4 默认不在支持指定索引类型,默认索引类型是_doc + +```bash +http://202.193.56.222:9200/itcast?include_type_name=true +{ + "settings":{ + "index":{ + "number_of_shards":"1", + "number_of_replicas":"0" + } + }, + "mappings":{ + "person":{ + "properties":{ + "name":{ + "type":"text" + }, + "age":{ + "type":"integer" + }, + "mail":{ + "type":"keyword" + }, + "hobby":{ + "type":"text", + "analyzer":"ik_max_word" + } + } + } + } +} +``` + +然后插入数据 + +```bash +POST http://202.193.56.222:9200/itcast/_bulk +{"index":{"_index":"itcast","_type":"person"}} +{"name":"张三","age": 20,"mail": "111@qq.com","hobby":"羽毛球、乒乓球、足球"} +{"index":{"_index":"itcast","_type":"person"}} +{"name":"李四","age": 21,"mail": "222@qq.com","hobby":"羽毛球、乒乓球、足球、篮球"} +{"index":{"_index":"itcast","_type":"person"}} +{"name":"王五","age": 22,"mail": "333@qq.com","hobby":"羽毛球、篮球、游泳、听音乐"} +{"index":{"_index":"itcast","_type":"person"}} +{"name":"赵六","age": 23,"mail": "444@qq.com","hobby":"跑步、游泳、篮球"} +{"index":{"_index":"itcast","_type":"person"}} +{"name":"孙七","age": 24,"mail": "555@qq.com","hobby":"听音乐、看电影、羽毛球"} +``` + +![image-20200923141912153](images/image-20200923141912153.png) + +### 单词搜索 + +```bash +POST /itcast/person/_search +{ + "query":{ + "match":{ + "hobby":"音乐" + } + }, + "highlight":{ + "fields":{ + "hobby":{ + + } + } + } +} +``` + +查询出来的结果如下,并且还带有高亮 + +![image-20200923142131426](images/image-20200923142131426.png) + +过程说明: +- 检查字段类型 + - 爱好 hobby 字段是一个 text 类型( 指定了IK分词器),这意味着查询字符串本身也应该被分词。 +- 分析查询字符串 。 + - 将查询的字符串 “音乐” 传入IK分词器中,输出的结果是单个项 音乐。因为只有一个单词项,所以 match 查询执行的是单个底层 term 查询。 +- 查找匹配文档 。 + - 用 term 查询在倒排索引中查找 “音乐” 然后获取一组包含该项的文档,本例的结果是文档:3 、5 。 +- 为每个文档评分 。 + - 用 term 查询计算每个文档相关度评分 _score ,这是种将 词频(term frequency,即词 “音乐” 在相关文档的hobby 字段中出现的频率)和 反向文档频率(inverse document frequency,即词 “音乐” 在所有文档的hobby 字段中出现的频率),以及字段的长度(即字段越短相关度越高)相结合的计算方式。 + +### 多词搜索 + +```bash +POST /itcast/person/_search +{ + "query":{ + "match":{ + "hobby":"音乐 篮球" + } + }, + "highlight":{ + "fields":{ + "hobby":{ + + } + } + } +} +``` + +可以看到,包含了“音乐”、“篮球”的数据都已经被搜索到了。可是,搜索的结果并不符合我们的预期,因为我们想搜索的是既包含“音乐”又包含“篮球”的用户,显然结果返回的“或”的关系。在Elasticsearch中,可以指定词之间的逻辑关系,如下: + +```bash +POST /itcast/person/_search +{ + "query":{ + "match":{ + "hobby":"音乐 篮球" + "operator":"and" + } + }, + "highlight":{ + "fields":{ + "hobby":{ + + } + } + } +} +``` + +通过这样的话,就会让两个关键字之间存在and关系了 + +![image-20200923142538105](images/image-20200923142538105.png) + +可以看到结果符合预期。 + +前面我们测试了“OR” 和 “AND”搜索,这是两个极端,其实在实际场景中,并不会选取这2个极端,更有可能是选取这种,或者说,只需要符合一定的相似度就可以查询到数据,在Elasticsearch中也支持这样的查询,通过 +minimum_should_match来指定匹配度,如:70%; + +示例: + +```bash +{ + "query":{ + "match":{ + "hobby":{ + "query":"游泳 羽毛球", + "minimum_should_match":"80%" + } + } + }, + "highlight": { + "fields": { + "hobby": {} + } + } +} +#结果:省略显示 +"hits": { +"total": 4, #相似度为80%的情况下,查询到4条数据 +"max_score": 1.621458, +"hits": [ + +} +#设置40%进行测试: +{ + "query":{ + "match":{ + "hobby":{ + "query":"游泳 羽毛球", + "minimum_should_match":"40%" + } + } + }, + "highlight": { + "fields": { + "hobby": {} + } + } +} + +#结果: +"hits": { +"total": 5, #相似度为40%的情况下,查询到5条数据 +"max_score": 1.621458, +"hits": [ + +} +``` + +相似度应该多少合适,需要在实际的需求中进行反复测试,才可得到合理的值。 + +### 组合搜索 + +在搜索时,也可以使用过滤器中讲过的bool组合查询,示例: + +```bash +POST /itcast/person/_search +{ + "query":{ + "bool":{ + "must":{ + "match":{ + "hobby":"篮球" + } + }, + "must_not":{ + "match":{ + "hobby":"音乐" + } + }, + "should":[ + { + "match":{ + "hobby":"游泳" + } + } + ] + } + }, + "highlight":{ + "fields":{ + "hobby":{ + + } + } + } +} +``` + +>上面搜索的意思是: +>搜索结果中必须包含篮球,不能包含音乐,如果包含了游泳,那么它的相似度更高。 + +结果: + +![image-20200923145310698](images/image-20200923145310698.png) + +>评分的计算规则 +> +>bool 查询会为每个文档计算相关度评分 _score , 再将所有匹配的 must 和 should 语句的分数 _score 求和,最后除以 must 和 should 语句的总数。 +> +>must_not 语句不会影响评分; 它的作用只是将不相关的文档排除。 + +默认情况下,should中的内容不是必须匹配的,如果查询语句中没有must,那么就会至少匹配其中一个。当然了,也可以通过minimum_should_match参数进行控制,该值可以是数字也可以的百分比。 + +示例: + +```bash +POST /itcast/person/_search +{ + "query":{ + "bool":{ + "should":[ + { + "match":{ + "hobby":"游泳" + } + }, + { + "match":{ + "hobby":"篮球" + } + }, + { + "match":{ + "hobby":"音乐" + } + } + ], + "minimum_should_match":2 + } + }, + "highlight":{ + "fields":{ + "hobby":{ + + } + } + } +} +``` + +minimum_should_match为2,意思是should中的三个词,至少要满足2个。 + +### 权重 + +有些时候,我们可能需要对某些词增加权重来影响该条数据的得分。如下: + +搜索关键字为“游泳篮球”,如果结果中包含了“音乐”权重为10,包含了“跑步”权重为2。 + +```bash +POST /itcast/person/_search +{ + "query":{ + "bool":{ + "must":{ + "match":{ + "hobby":{ + "query":"游泳篮球", + "operator":"and" + } + } + }, + "should":[ + { + "match":{ + "hobby":{ + "query":"音乐", + "boost":10 + } + } + }, + { + "match":{ + "hobby":{ + "query":"跑步", + "boost":2 + } + } + } + ] + } + }, + "highlight":{ + "fields":{ + "hobby":{ + + } + } + } +} +``` + + + +## ElasticSearch集群 + +### 集群节点 + +ELasticsearch的集群是由多个节点组成的,通过cluster.name设置集群名称,并且用于区分其它的集群,每个节点通过node.name指定节点的名称。 + +在Elasticsearch中,节点的类型主要有4种: + +- master节点 + - 配置文件中node.master属性为true(默认为true),就有资格被选为master节点。master节点用于控制整个集群的操作。比如创建或删除索引,管理其它非master节点等。 +- data节点 + - 配置文件中node.data属性为true(默认为true),就有资格被设置成data节点。data节点主要用于执行数据相关的操作。比如文档的CRUD。 +- 客户端节点 + - 配置文件中node.master属性和node.data属性均为false。 + - 该节点不能作为master节点,也不能作为data节点。 + - 可以作为客户端节点,用于响应用户的请求,把请求转发到其他节点 +- 部落节点 + - 当一个节点配置tribe.*的时候,它是一个特殊的客户端,它可以连接多个集群,在所有连接的集群上执行 + 搜索和其他操作。 + +### 搭建集群 + +```bash +#启动3个虚拟机,分别在3台虚拟机上部署安装Elasticsearch +mkdir /itcast/es-cluster + +#分发到其它机器 +scp -r es-cluster elsearch@192.168.40.134:/itcast + +#node01的配置: +cluster.name: es-itcast-cluster +node.name: node01 +node.master: true +node.data: true +network.host: 0.0.0.0 +http.port: 9200 +discovery.zen.ping.unicast.hosts: ["192.168.40.133","192.168.40.134","192.168.40.135"] +# 最小节点数 +discovery.zen.minimum_master_nodes: 2 +# 跨域专用 +http.cors.enabled: true +http.cors.allow-origin: "*" + +#node02的配置: +cluster.name: es-itcast-cluster +node.name: node02 +node.master: true +node.data: true +network.host: 0.0.0.0 +http.port: 9200 +discovery.zen.ping.unicast.hosts: ["192.168.40.133","192.168.40.134","192.168.40.135"] +discovery.zen.minimum_master_nodes: 2 +http.cors.enabled: true +http.cors.allow-origin: "*" + +#node03的配置: +cluster.name: es-itcast-cluster +node.name: node02 +node.master: true +node.data: true +network.host: 0.0.0.0 +http.port: 9200 +discovery.zen.ping.unicast.hosts: ["192.168.40.133","192.168.40.134","192.168.40.135"] +discovery.zen.minimum_master_nodes: 2 +http.cors.enabled: true +http.cors.allow-origin: "*" + +#分别启动3个节点 +./elasticsearch +``` + +查看集群 + +![image-20200923151823672](images/image-20200923151823672.png) + +创建索引: + +![image-20200923151851785](images/image-20200923151851785.png) + +![image-20200923151935283](images/image-20200923151935283.png) + +查询集群状态:/_cluster/health +响应: + +![image-20200923151953227](images/image-20200923151953227.png) + +集群中有三种颜色 + +![image-20200923152005930](images/image-20200923152005930.png) + +### 分片和副本 + +为了将数据添加到Elasticsearch,我们需要索引(index)——一个存储关联数据的地方。实际上,索引只是一个用来指向一个或多个分片(shards)的“逻辑命名空间(logical namespace)”. + +- 一个分片(shard)是一个最小级别“工作单元(worker unit)”,它只是保存了索引中所有数据的一部分。 +- 我们需要知道是分片就是一个Lucene实例,并且它本身就是一个完整的搜索引擎。应用程序不会和它直接通 + 信。 +- 分片可以是主分片(primary shard)或者是复制分片(replica shard)。 +- 索引中的每个文档属于一个单独的主分片,所以主分片的数量决定了索引最多能存储多少数据。 +- 复制分片只是主分片的一个副本,它可以防止硬件故障导致的数据丢失,同时可以提供读请求,比如搜索或者从别的shard取回文档。 +- 当索引创建完成的时候,主分片的数量就固定了,但是复制分片的数量可以随时调整。 + +### 故障转移 + +#### 将data节点停止 + +这里选择将node02停止: + +![image-20200923152229908](images/image-20200923152229908.png) + +当前集群状态为黄色,表示主节点可用,副本节点不完全可用,过一段时间观察,发现节点列表中看不到node02,副本节点分配到了node01和node03,集群状态恢复到绿色。 + +![image-20200923152248547](images/image-20200923152248547.png) + +将node02恢复: ./node02/1 bin/elasticsearch + +![image-20200923152328458](images/image-20200923152328458.png) + +可以看到,node02恢复后,重新加入了集群,并且重新分配了节点信息。 + +#### 将master节点停止 + +接下来,测试将node01停止,也就是将主节点停止。 + +![image-20200923152415890](images/image-20200923152415890.png) + +从结果中可以看出,集群对master进行了重新选举,选择node03为master。并且集群状态变成黄色。 +等待一段时间后,集群状态从黄色变为了绿色: + +![image-20200923153343555](images/image-20200923153343555.png) + +恢复node01节点: + +```bash +./node01/1 bin/elasticsearch +``` + +重启之后,发现node01可以正常加入到集群中,集群状态依然为绿色: + +![image-20200923153415117](images/image-20200923153415117.png) + +特别说明: + +如果在配置文件中discovery.zen.minimum_master_nodes设置的不是N/2+1时,会出现脑裂问题,之前宕机 +的主节点恢复后不会加入到集群。 + +![image-20200923153441693](images/image-20200923153441693.png) + +### 分布式文档 + +#### 路由 + +首先,来看个问题: + +![image-20200923153556720](images/image-20200923153556720.png) + +如图所示:当我们想一个集群保存文档时,文档该存储到哪个节点呢? 是随机吗? 是轮询吗?实际上,在ELasticsearch中,会采用计算的方式来确定存储到哪个节点,计算公式如下: + +```bash +shard = hash(routing) % number_1 of_primary_shards +``` + +其中: + +- routing值是一个任意字符串,它默认是_id但也可以自定义。 +- 这个routing字符串通过哈希函数生成一个数字,然后除以主切片的数量得到一个余数(remainder),余数 + 的范围永远是0到number_of_primary_shards - 1,这个数字就是特定文档所在的分片 + +这就是为什么创建了主分片后,不能修改的原因。 + +#### 文档的写操作 + +新建、索引和删除请求都是写(write)操作,它们必须在主分片上成功完成才能复制分片上 + +![image-20200923155314424](images/image-20200923155314424.png) + +下面我们罗列在主分片和复制分片上成功新建、索引或删除一个文档必要的顺序步骤: +1. 客户端给Node 1 发送新建、索引或删除请求。 +2. 节点使用文档的_id 确定文档属于分片0 。它转发请求到Node 3 ,分片0 位于这个节点上。 +3. Node 3 在主分片上执行请求,如果成功,它转发请求到相应的位于Node 1 和Node 2 的复制节点上。当所有 +的复制节点报告成功, Node 3 报告成功到请求的节点,请求的节点再报告给客户端。 + +客户端接收到成功响应的时候,文档的修改已经被应用于主分片和所有的复制分片。你的修改生效了。 + +### 搜索文档 + +文档能够从主分片或任意一个复制分片被检索。 + +![image-20200923160046962](images/image-20200923160046962.png) + +下面我们罗列在主分片或复制分片上检索一个文档必要的顺序步骤: +1. 客户端给Node 1 发送get请求。 +2. 节点使用文档的_id 确定文档属于分片0 。分片0 对应的复制分片在三个节点上都有。此时,它转发请求到 +Node 2 。 +3. Node 2 返回文档(document)给Node 1 然后返回给客户端。对于读请求,为了平衡负载,请求节点会为每个请求选择不同的分片——它会循环所有分片副本。可能的情况是,一个被索引的文档已经存在于主分片上却还没来得及同步到复制分片上。这时复制分片会报告文档未找到,主分片会成功返回文档。一旦索引请求成功返回给用户,文档则在主分片和复制分片都是可用的。 + +### 全文搜索 + +对于全文搜索而言,文档可能分散在各个节点上,那么在分布式的情况下,如何搜索文档呢? + +搜索,分为2个阶段, + +- 搜索(query) +- 取回(fetch) + +#### 搜索(query) + +![image-20200923161323235](images/image-20200923161323235.png) + +查询阶段包含以下三步: +1. 客户端发送一个search(搜索) 请求给Node 3 , Node 3 创建了一个长度为from+size 的空优先级队 +2. Node 3 转发这个搜索请求到索引中每个分片的原本或副本。每个分片在本地执行这个查询并且结果将结果到 +一个大小为from+size 的有序本地优先队列里去。 +3. 每个分片返回document的ID和它优先队列里的所有document的排序值给协调节点Node 3 。Node 3 把这些 +值合并到自己的优先队列里产生全局排序结果。 + +#### 取回 fetch + +![image-20200923161447618](images/image-20200923161447618.png) + +分发阶段由以下步骤构成: +1. 协调节点辨别出哪个document需要取回,并且向相关分片发出GET 请求。 +2. 每个分片加载document并且根据需要丰富(enrich)它们,然后再将document返回协调节点。 +3. 一旦所有的document都被取回,协调节点会将结果返回给客户端。 + +## Java客户端 + +在Elasticsearch中,为java提供了2种客户端,一种是REST风格的客户端,另一种是Java API的客户端 + +### REST客户端 + +Elasticsearch提供了2种REST客户端,一种是低级客户端,一种是高级客户端。 + +- Java Low Level REST Client:官方提供的低级客户端。该客户端通过http来连接Elasticsearch集群。用户在使 + 用该客户端时需要将请求数据手动拼接成Elasticsearch所需JSON格式进行发送,收到响应时同样也需要将返回的JSON数据手动封装成对象。虽然麻烦,不过该客户端兼容所有的Elasticsearch版本。 +- Java High Level REST Client:官方提供的高级客户端。该客户端基于低级客户端实现,它提供了很多便捷的 + API来解决低级客户端需要手动转换数据格式的问题。 + +### 构造数据 + +```bash +POST /haoke/house/_bulk + +{"index":{"_index":"haoke","_type":"house"}} +{"id":"1001","title":"整租 · 南丹大楼 1居室 7500","price":"7500"} +{"index":{"_index":"haoke","_type":"house"}} +{"id":"1002","title":"陆家嘴板块,精装设计一室一厅,可拎包入住诚意租。","price":"8500"} +{"index":{"_index":"haoke","_type":"house"}} +{"id":"1003","title":"整租 · 健安坊 1居室 4050","price":"7500"} +{"index":{"_index":"haoke","_type":"house"}} +{"id":"1004","title":"整租 · 中凯城市之光+视野开阔+景色秀丽+拎包入住","price":"6500"} +{"index":{"_index":"haoke","_type":"house"}} +{"id":"1005","title":"整租 · 南京西路品质小区 21213三轨交汇 配套齐* 拎包入住","price":"6000"} +{"index":{"_index":"haoke","_type":"house"}} +{"id":"1006","title":"祥康里 简约风格 *南户型 拎包入住 看房随时","price":"7000"} +``` + +![image-20200923162419395](images/image-20200923162419395.png) + +### REST低级客户端 + +创建项目,加入依赖 + +```xml + + + 4.0.0 + + org.example + Study_ElasticSearch_Code + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 7 + 7 + + + + + + + + org.elasticsearch.client + elasticsearch-rest-client + 6.8.5 + + + junit + junit + 4.12 + test + + + com.fasterxml.jackson.core + jackson-databind + 2.11.1 + + + +``` + +编写测试类 + +```java +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.HttpHost; +import org.apache.http.util.EntityUtils; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestClientBuilder; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * 使用低级客户端 访问 + * + * @author: 陌溪 + * @create: 2020-09-23-16:33 + */ +public class ESApi { + private RestClient restClient; + private static final ObjectMapper MAPPER = new ObjectMapper(); + + /** + * 初始化 + */ + public void init() { + RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost("202.193.56.222", 9200, "http")); + this.restClient = restClientBuilder.build(); + } + + /** + * 查询集群状态 + */ + public void testGetInfo() throws IOException { + Request request = new Request("GET", "/_cluster/state"); + request.addParameter("pretty", "true"); + Response response = this.restClient.performRequest(request); + System.out.println(response.getStatusLine()); + System.out.println(EntityUtils.toString(response.getEntity())); + } + + /** + * 根据ID查询数据 + * @throws IOException + */ + public void testGetHouseInfo() throws IOException { + Request request = new Request("GET", "/haoke/house/Z3CduXQBYpWein3CRFug"); + request.addParameter("pretty", "true"); + Response response = this.restClient.performRequest(request); + System.out.println(response.getStatusLine()); + System.out.println(EntityUtils.toString(response.getEntity())); + } + + public void testCreateData() throws IOException { + Request request = new Request("POST", "/haoke/house"); + Map data = new HashMap<>(); + data.put("id", "2001"); + data.put("title", "张江高科"); + data.put("price", "3500"); + // 写成JSON + request.setJsonEntity(MAPPER.writeValueAsString(data)); + Response response = this.restClient.performRequest(request); + System.out.println(response.getStatusLine()); + System.out.println(EntityUtils.toString(response.getEntity())); + + } + + // 搜索数据 + public void testSearchData() throws IOException { + Request request = new Request("POST", "/haoke/house/_search"); + String searchJson = "{\"query\": {\"match\": {\"title\": \"拎包入住\"}}}"; + request.setJsonEntity(searchJson); + request.addParameter("pretty","true"); + Response response = this.restClient.performRequest(request); + System.out.println(response.getStatusLine()); + System.out.println(EntityUtils.toString(response.getEntity())); + } + + public static void main(String[] args) throws IOException { + ESApi esApi = new ESApi(); + esApi.init(); +// esApi.testGetInfo(); +// esApi.testGetHouseInfo(); + esApi.testCreateData(); + } +} +``` + +### REST高级客户端 + +创建项目,引入依赖 + +```xml + + org.elasticsearch.client + elasticsearch-rest-high-level-client + 6.8.5 + +``` + +编写测试用例 + +```java +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.HttpHost; +import org.apache.http.util.EntityUtils; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.delete.DeleteRequest; +import org.elasticsearch.action.delete.DeleteResponse; +import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.update.UpdateRequest; +import org.elasticsearch.action.update.UpdateResponse; +import org.elasticsearch.client.*; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.SearchHits; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.elasticsearch.search.fetch.subphase.FetchSourceContext; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * ES高级客户端 + * + * @author: 陌溪 + * @create: 2020-09-23-16:56 + */ +public class ESHightApi { + private RestHighLevelClient client; + + public void init() { + RestClientBuilder restClientBuilder = RestClient.builder( + new HttpHost("202.193.56.222", 9200, "http")); + this.client = new RestHighLevelClient(restClientBuilder); + } + + public void after() throws Exception { + this.client.close(); + } + + /** + * 新增文档,同步操作 + * + * @throws Exception + */ + public void testCreate() throws Exception { + Map data = new HashMap<>(); + data.put("id", "2002"); + data.put("title", "南京西路 拎包入住 一室一厅"); + data.put("price", "4500"); + IndexRequest indexRequest = new IndexRequest("haoke", "house") + .source(data); + IndexResponse indexResponse = this.client.index(indexRequest, + RequestOptions.DEFAULT); + System.out.println("id->" + indexResponse.getId()); + System.out.println("index->" + indexResponse.getIndex()); + System.out.println("type->" + indexResponse.getType()); + System.out.println("version->" + indexResponse.getVersion()); + System.out.println("result->" + indexResponse.getResult()); + System.out.println("shardInfo->" + indexResponse.getShardInfo()); + } + + /** + * 异步创建文档 + * @throws Exception + */ + public void testCreateAsync() throws Exception { + Map data = new HashMap<>(); + data.put("id", "2003"); + data.put("title", "南京东路 最新房源 二室一厅"); + data.put("price", "5500"); + IndexRequest indexRequest = new IndexRequest("haoke", "house") + .source(data); + this.client.indexAsync(indexRequest, RequestOptions.DEFAULT, new + ActionListener() { + @Override + public void onResponse(IndexResponse indexResponse) { + System.out.println("id->" + indexResponse.getId()); + System.out.println("index->" + indexResponse.getIndex()); + System.out.println("type->" + indexResponse.getType()); + System.out.println("version->" + indexResponse.getVersion()); + System.out.println("result->" + indexResponse.getResult()); + System.out.println("shardInfo->" + indexResponse.getShardInfo()); + } + @Override + public void onFailure(Exception e) { + System.out.println(e); + } + }); + System.out.println("ok"); + Thread.sleep(20000); + } + + /** + * 查询 + * @throws Exception + */ + public void testQuery() throws Exception { + GetRequest getRequest = new GetRequest("haoke", "house", + "GkpdE2gBCKv8opxuOj12"); + // 指定返回的字段 + String[] includes = new String[]{"title", "id"}; + String[] excludes = Strings.EMPTY_ARRAY; + FetchSourceContext fetchSourceContext = + new FetchSourceContext(true, includes, excludes); + getRequest.fetchSourceContext(fetchSourceContext); + GetResponse response = this.client.get(getRequest, RequestOptions.DEFAULT); + System.out.println("数据 -> " + response.getSource()); + } + + /** + * 判断是否存在 + * + * @throws Exception + */ + public void testExists() throws Exception { + GetRequest getRequest = new GetRequest("haoke", "house", + "GkpdE2gBCKv8opxuOj12"); +// 不返回的字段 + getRequest.fetchSourceContext(new FetchSourceContext(false)); + boolean exists = this.client.exists(getRequest, RequestOptions.DEFAULT); + System.out.println("exists -> " + exists); + } + /** + * 删除数据 + * + * @throws Exception + */ + public void testDelete() throws Exception { + DeleteRequest deleteRequest = new DeleteRequest("haoke", "house", + "GkpdE2gBCKv8opxuOj12"); + DeleteResponse response = this.client.delete(deleteRequest, + RequestOptions.DEFAULT); + System.out.println(response.status());// OK or NOT_FOUND + } + /** + * 更新数据 + * + * @throws Exception + */ + public void testUpdate() throws Exception { + UpdateRequest updateRequest = new UpdateRequest("haoke", "house", + "G0pfE2gBCKv8opxuRz1y"); + Map data = new HashMap<>(); + data.put("title", "张江高科2"); + data.put("price", "5000"); + updateRequest.doc(data); + UpdateResponse response = this.client.update(updateRequest, + RequestOptions.DEFAULT); + System.out.println("version -> " + response.getVersion()); + } + /** + * 测试搜索 + * + * @throws Exception + */ + public void testSearch() throws Exception { + SearchRequest searchRequest = new SearchRequest("haoke"); + searchRequest.types("house"); + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); + sourceBuilder.query(QueryBuilders.matchQuery("title", "拎包入住")); + sourceBuilder.from(0); + sourceBuilder.size(5); + sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); + searchRequest.source(sourceBuilder); + SearchResponse search = this.client.search(searchRequest, + RequestOptions.DEFAULT); + System.out.println("搜索到 " + search.getHits().totalHits + " 条数据."); + SearchHits hits = search.getHits(); + for (SearchHit hit : hits) { + System.out.println(hit.getSourceAsString()); + } + } + + public static void main(String[] args) throws Exception { + ESHightApi esHightApi = new ESHightApi(); + esHightApi.init(); + esHightApi.testCreate(); + } +} +``` + diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922092403279.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922092403279.png" new file mode 100644 index 0000000000000000000000000000000000000000..19bb45aad391580b8dd1cc0867675bea2d5b29db Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922092403279.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922092505011.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922092505011.png" new file mode 100644 index 0000000000000000000000000000000000000000..4eede9aead5f39a276d98966fbed9922c440d576 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922092505011.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922093432839.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922093432839.png" new file mode 100644 index 0000000000000000000000000000000000000000..bf1547dbdaa98fa12ef64fe4051066bd6d30a788 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922093432839.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922094003384.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922094003384.png" new file mode 100644 index 0000000000000000000000000000000000000000..1ebd724028b1afa57d3a6f198f895ccaa38f2517 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922094003384.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922111823740.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922111823740.png" new file mode 100644 index 0000000000000000000000000000000000000000..a91105f650549ce50025d1103a84683fdaf1c209 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922111823740.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922150758205.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922150758205.png" new file mode 100644 index 0000000000000000000000000000000000000000..dec9670f3ad39f81e483029d565dc41670bcfbf5 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922150758205.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922151529269.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922151529269.png" new file mode 100644 index 0000000000000000000000000000000000000000..b9c309e38785935a61fde0ec60977e510c606c3a Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922151529269.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922152428838.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922152428838.png" new file mode 100644 index 0000000000000000000000000000000000000000..5a47ca2de983b360087dbee3fdb8665237a65b70 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922152428838.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922152534471.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922152534471.png" new file mode 100644 index 0000000000000000000000000000000000000000..eb4b62a1b47022e406084444ba67cdbb6a2ec995 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922152534471.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922155642306.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922155642306.png" new file mode 100644 index 0000000000000000000000000000000000000000..acfda945c46c2e14d38c1038e73e946e1261cb49 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922155642306.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922155843314.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922155843314.png" new file mode 100644 index 0000000000000000000000000000000000000000..56238b49a87b93347c2d09177dfba8da82913489 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922155843314.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922155935366.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922155935366.png" new file mode 100644 index 0000000000000000000000000000000000000000..a53d0950bdcb91605c7c7f60c93abebe33222050 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922155935366.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160154599.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160154599.png" new file mode 100644 index 0000000000000000000000000000000000000000..0a9643386d9472c3405d49ba4fe35b9defb058a8 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160154599.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160201130.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160201130.png" new file mode 100644 index 0000000000000000000000000000000000000000..3d28de03e6817c0af50af489bf7e74efef4fd3eb Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160201130.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160709463.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160709463.png" new file mode 100644 index 0000000000000000000000000000000000000000..42b4f975c95a8bc3cffa28432ae4561fecfbe5d1 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160709463.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160717001.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160717001.png" new file mode 100644 index 0000000000000000000000000000000000000000..b65cab48fc45a401f4ab7754fec947eb24a3d933 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160717001.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160752862.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160752862.png" new file mode 100644 index 0000000000000000000000000000000000000000..1fa3cc30963ff65c9621551b87228fdcaaf35e98 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922160752862.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922161627716.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922161627716.png" new file mode 100644 index 0000000000000000000000000000000000000000..c067eef494b5edebbbd972c6047206ccd0a13e79 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922161627716.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922162228822.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922162228822.png" new file mode 100644 index 0000000000000000000000000000000000000000..ad0e9a4a9dbc134fc22255c1c3d4e605bc9d1b24 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922162228822.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922162309797.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922162309797.png" new file mode 100644 index 0000000000000000000000000000000000000000..39a7a5035fd763bbdd814872a421897bd966c8bd Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922162309797.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922162943539.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922162943539.png" new file mode 100644 index 0000000000000000000000000000000000000000..e0a726dd53741f0bb86f443c6482daf32f899fe9 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922162943539.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922163109515.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922163109515.png" new file mode 100644 index 0000000000000000000000000000000000000000..64f0643b12ac1933f0cee7817a0acd03bbedd4c7 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922163109515.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922163315285.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922163315285.png" new file mode 100644 index 0000000000000000000000000000000000000000..ed7967790bab2eec084d4e960b6d580daff0d653 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922163315285.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922163432853.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922163432853.png" new file mode 100644 index 0000000000000000000000000000000000000000..6f07a04d9346e9d753db587530979c823875aae1 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922163432853.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922163614708.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922163614708.png" new file mode 100644 index 0000000000000000000000000000000000000000..696c8438cb4f72a7bd34c12fe87463142d582f5f Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922163614708.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922165956176.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922165956176.png" new file mode 100644 index 0000000000000000000000000000000000000000..8fbbb5ea17482a7d154dadcff6dd52d184f9f265 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200922165956176.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101056932.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101056932.png" new file mode 100644 index 0000000000000000000000000000000000000000..3227acb8c744031c54b68115871b20038f74374c Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101056932.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101239226.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101239226.png" new file mode 100644 index 0000000000000000000000000000000000000000..4292c9dcb72a073f7add86a6a7b89f210f6e2aed Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101239226.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101319728.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101319728.png" new file mode 100644 index 0000000000000000000000000000000000000000..e2721bf4c43bb8f4f24915fbfe64bfce683dc0b7 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101319728.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101354992.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101354992.png" new file mode 100644 index 0000000000000000000000000000000000000000..eebc1fb5bf68d7f3ed0f7d44b63b239f003436be Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101354992.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101433608.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101433608.png" new file mode 100644 index 0000000000000000000000000000000000000000..f6234ef4d2ed25c5718284ff83c0aa1bc66fb61f Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101433608.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101540616.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101540616.png" new file mode 100644 index 0000000000000000000000000000000000000000..86d36d569f70c8d083c3113c9642b7479d55b2af Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101540616.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101721344.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101721344.png" new file mode 100644 index 0000000000000000000000000000000000000000..f80a1fc90ac21eead5fafbcd84137647c177f795 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101721344.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101946147.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101946147.png" new file mode 100644 index 0000000000000000000000000000000000000000..e18036ae70ea29faa972b7ab8998659b9e533a1a Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923101946147.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923102044231.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923102044231.png" new file mode 100644 index 0000000000000000000000000000000000000000..d83f2a5da0a00dd33ec2fe0b0121fba7df5909b5 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923102044231.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923102611567.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923102611567.png" new file mode 100644 index 0000000000000000000000000000000000000000..f2e0f96387a7ff5f64c0d7615f9b0ab921d12268 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923102611567.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923103848097.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923103848097.png" new file mode 100644 index 0000000000000000000000000000000000000000..1eaea8826ab3d3fd97d70345ee6f734f2c97f798 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923103848097.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923103917807.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923103917807.png" new file mode 100644 index 0000000000000000000000000000000000000000..e8f82ad47ec64a8686511f9f4f40382f1f775cff Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923103917807.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923104201613.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923104201613.png" new file mode 100644 index 0000000000000000000000000000000000000000..cd4b3277d0a37452cd513e9e9430856375e45526 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923104201613.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923104551405.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923104551405.png" new file mode 100644 index 0000000000000000000000000000000000000000..cd1c64fadf8f9f84627742174c9541bc24083cdc Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923104551405.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923104653427.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923104653427.png" new file mode 100644 index 0000000000000000000000000000000000000000..7bda9e5eb3a0d1f1a5794fa5e9545fdddf7e3146 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923104653427.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923104851159.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923104851159.png" new file mode 100644 index 0000000000000000000000000000000000000000..bbb302f8132c0112d4785b2e72a12771d8de8c68 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923104851159.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923105030182.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923105030182.png" new file mode 100644 index 0000000000000000000000000000000000000000..63de0ad2b2665471417c07f26fea820566dfb1dc Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923105030182.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923105416339.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923105416339.png" new file mode 100644 index 0000000000000000000000000000000000000000..ce0992abc01155b079d76a9109e48df5ae53b995 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923105416339.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923110814505.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923110814505.png" new file mode 100644 index 0000000000000000000000000000000000000000..561dd43e62feb0e3424d7acc6b49a2bbb5aca429 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923110814505.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923110905001.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923110905001.png" new file mode 100644 index 0000000000000000000000000000000000000000..fb0417b3c91f659520af18f789cdd0fd21498e9f Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923110905001.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923113200826.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923113200826.png" new file mode 100644 index 0000000000000000000000000000000000000000..9ee9095d91665036a967f65a2c7b77760001a797 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923113200826.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923113222937.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923113222937.png" new file mode 100644 index 0000000000000000000000000000000000000000..4402cdb43191bf9af694b2a0762384414b1e0450 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923113222937.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923141912153.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923141912153.png" new file mode 100644 index 0000000000000000000000000000000000000000..f15176e42231c06d0caabf4f53480a202dc83159 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923141912153.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923142131426.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923142131426.png" new file mode 100644 index 0000000000000000000000000000000000000000..da140e312f10c9a38120f5f91f72dec27c9cf9f9 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923142131426.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923142538105.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923142538105.png" new file mode 100644 index 0000000000000000000000000000000000000000..ba39fd617740b984578d859ae01abcbd02938aea Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923142538105.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923145310698.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923145310698.png" new file mode 100644 index 0000000000000000000000000000000000000000..d6c8d09f347ae0c280761187f16dd2d3b244639e Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923145310698.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923151823672.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923151823672.png" new file mode 100644 index 0000000000000000000000000000000000000000..af8190ed4b6a108a6636c6e953af48f729a64c35 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923151823672.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923151851785.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923151851785.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ec084b37d49a6d9147517c747605acd598800a5 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923151851785.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923151935283.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923151935283.png" new file mode 100644 index 0000000000000000000000000000000000000000..aa314ae0c7bbe9eb53ea297424c0c37921e05b4f Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923151935283.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923151953227.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923151953227.png" new file mode 100644 index 0000000000000000000000000000000000000000..1a84be91b462ffb6a27fc9c2752d5749dcb0df32 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923151953227.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152005930.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152005930.png" new file mode 100644 index 0000000000000000000000000000000000000000..6b2aaf6a0901826b54c7e30774f1ff87788c5dc8 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152005930.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152229908.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152229908.png" new file mode 100644 index 0000000000000000000000000000000000000000..f4078928b819bd815fd54ba360bc120e26228ac3 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152229908.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152248547.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152248547.png" new file mode 100644 index 0000000000000000000000000000000000000000..7a982dfa6b27c8d3ae1da57d598e7204e7774b05 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152248547.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152328458.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152328458.png" new file mode 100644 index 0000000000000000000000000000000000000000..2e87d0a28949cc92d9daeda74cf1f96f60e75b58 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152328458.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152415890.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152415890.png" new file mode 100644 index 0000000000000000000000000000000000000000..0d10f5e69390565103c46e58be5d8b8d09cb6a54 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923152415890.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923153343555.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923153343555.png" new file mode 100644 index 0000000000000000000000000000000000000000..fc8377d916c46e9e6d8e6c19a029d711a85177ce Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923153343555.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923153415117.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923153415117.png" new file mode 100644 index 0000000000000000000000000000000000000000..bf6d0f1d72cd8b6ae2959ebb7244885ac05a5ffb Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923153415117.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923153441693.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923153441693.png" new file mode 100644 index 0000000000000000000000000000000000000000..14482d42f4b52b75dfb5ce3e1afbfe05a53c38cb Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923153441693.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923153556720.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923153556720.png" new file mode 100644 index 0000000000000000000000000000000000000000..615aaa6c8521d2d51c242162406c7640d00ed394 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923153556720.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923155314424.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923155314424.png" new file mode 100644 index 0000000000000000000000000000000000000000..a71e5f01a0b9336aefe6b4512c26c31592bd4958 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923155314424.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923160046962.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923160046962.png" new file mode 100644 index 0000000000000000000000000000000000000000..8fdda9492504ff2c06016bc3fcf539cc4633e1f0 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923160046962.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923161323235.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923161323235.png" new file mode 100644 index 0000000000000000000000000000000000000000..cf080b21369d54fa21dda814e01d590f05510c3c Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923161323235.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923161447618.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923161447618.png" new file mode 100644 index 0000000000000000000000000000000000000000..90d0780537550d763fcac824998fe85b0dd07e44 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923161447618.png" differ diff --git "a/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923162419395.png" "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923162419395.png" new file mode 100644 index 0000000000000000000000000000000000000000..f0c4d96ba5cd215c1ddef7012b15b94eefe05080 Binary files /dev/null and "b/ElasticStack/1_ElasticSearch\344\273\213\347\273\215\344\270\216\345\256\211\350\243\205/images/image-20200923162419395.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/README.md" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..457aee1bed7781af810c6a7ce4b333e7c19378c6 --- /dev/null +++ "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/README.md" @@ -0,0 +1,792 @@ +# Beats入门简介 + +使用Beat收集nginx日志和指标数据 + +## 项目需求 + +Nginx是一款非常优秀的web服务器,往往nginx服务会作为项目的访问入口,那么,nginx的性能保障就变得非常重要了,如果nginx的运行出现了问题就会对项目有较大的影响,所以,我们需要对nginx的运行有监控措施,实时掌握nginx的运行情况,那就需要收集nginx的运行指标和分析nginx的运行日志了。 + +## 业务流程 + +![image-20200924081614472](images/image-20200924081614472.png) + +说明: + +- 通过Beats采集Nginx的指标数据和日志数据 +- Beats采集到数据后发送到Elasticsearch中 +- Kibana读取数据进行分析 +- 用户通过Kibana进行查看分析报表 + +## 部署Nginx + +部署教程可以参考这篇博客:[CentOS下如何安装Nginx?](http://www.moguit.cn/#/info?blogUid=e8d3e38ba35b4765ae128256eb44e341) + +部署完成后,我们就可以启动nginx了 + +启动完成后,我们通过下面命令,就可以获取到nginx中的内容了 + +```bash +tail -f /var/log/nginx/access.log +``` + +## Beats简介 + +通过查看ElasticStack可以发现,Beats主要用于采集数据 + +官网地址:https://www.elastic.co/cn/beats/ + +![image-20200924091657242](images/image-20200924091657242.png) + +Beats平台其实是一个轻量性数据采集器,通过集合多种单一用途的采集器,从成百上千台机器中向Logstash或ElasticSearch中发送数据。 + +![image-20200924091716757](images/image-20200924091716757.png) + +通过Beats包含以下的数据采集功能 + +- Filebeat:采集日志文件 +- Metricbeat:采集指标 +- Packetbeat:采集网络数据 + +![image-20200924092015934](images/image-20200924092015934.png) + +如果我们的数据不需要任何处理,那么就可以直接发送到ElasticSearch中 + +如果们的数据需要经过一些处理的话,那么就可以发送到Logstash中,然后处理完成后,在发送到ElasticSearch + +最后在通过Kibana对我们的数据进行一系列的可视化展示 + +![image-20200924092348121](images/image-20200924092348121.png) + +## Filebeat + +### 介绍 + +Filebeat是一个轻量级的日志采集器 + +![image-20200924092551044](images/image-20200924092551044.png) + +### 为什么要用Filebeat? + +当你面对成百上千、甚至成千上万的服务器、虚拟机和溶气气生成的日志时,请告别SSH吧!Filebeat将为你提供一种轻量型方法,用于转发和汇总日志与文件,让简单的事情不再繁华,关于Filebeat的记住以下两点: + +- 轻量级日志采集器 +- 输送至ElasticSearch或者Logstash,在Kibana中实现可视化 + +### 架构 + +用于监控、收集服务器日志文件. + +![image-20200924092749077](images/image-20200924092749077.png) + +流程如下: + +- 首先是input输入,我们可以指定多个数据输入源,然后通过通配符进行日志文件的匹配 +- 匹配到日志后,就会使用Harvester(收割机),将日志源源不断的读取到来 +- 然后收割机收割到的日志,就传递到Spooler(卷轴),然后卷轴就在将他们传到对应的地方 + +### 下载 + +官网地址:https://www.elastic.co/cn/downloads/beats/filebeat + +选中对应版本的Filebeat,我这里是Centos部署的,所以下载Linux版本 + +![image-20200924093459418](images/image-20200924093459418.png) + +下载后,我们上传到服务器上,然后创建一个文件夹 + +```bash +# 创建文件夹 +mkdir -p /soft/beats +# 解压文件 +tar -zxvf filebeat-7.9.1-linux-x86_64.tar.gz +# 重命名 +mv filebeat-7.9.1-linux-x86_64/ filebeat +``` + +然后我们进入到filebeat目录下,创建对应的配置文件 + +```bash +# 进入文件夹 +cd filebeats +# 创建配置文件 +vim mogublog.yml +``` + +添加如下内容 + +```yml +filebeat.inputs: # filebeat input输入 +- type: stdin # 标准输入 + enabled: true # 启用标准输入 +setup.template.settings: + index.number_of_shards: 3 # 指定下载数 +output.console: # 控制台输出 + pretty: true # 启用美化功能 + enable: true +``` + +### 启动 + +在我们添加完配置文件后,我们就可以对filebeat进行启动了 + +```bash +./filebeat -e -c mogublog.yml +``` + +![image-20200924094825962](images/image-20200924094825962.png) + +然后我们在控制台输入hello,就能看到我们会有一个json的输出,是通过读取到我们控制台的内容后输出的 + +![image-20200924095032365](images/image-20200924095032365.png) + +内容如下 + +```json +{ + "@timestamp":"2019-01-12T12:50:03.585Z", + "@metadata":{ #元数据信息 + "beat":"filebeat", + "type":"doc", + "version":"6.5.4" + }, + "source":"", + "offset":0, + "message":"hello", #元数据信息 + "prospector":{ + "type":"stdin" #元数据信息 + }, + "input":{ #控制台标准输入 + "type":"stdin" + }, + "beat":{ #beat版本以及主机信息 + "name":"itcast01", + "hostname":"ElasticStack", + "version":"6.5.4" + }, + "host":{ + "name":"ElasticStack" + } +} +``` + +### 读取文件 + +我们需要再次创建一个文件,叫 mogublog-log.yml,然后在文件里添加如下内容 + +```yml +filebeat.inputs: +- type: log + enabled: true + paths: + - /soft/beats/logs/*.log +setup.template.settings: + index.number_of_shards: 3 +output.console: + pretty: true + enable: true +``` + +添加完成后,我们在到下面目录创建一个日志文件 + +```bash +# 创建文件夹 +mkdir -p /soft/beats/logs + +# 进入文件夹 +cd /soft/beats/logs + +# 追加内容 +echo "hello" >> a.log +``` + +然后我们再次启动filebeat + +```bash + ./filebeat -e -c mogublog-log.yml +``` + +能够发现,它已经成功加载到了我们的日志文件 a.log + +![image-20200924095926036](images/image-20200924095926036.png) + +同时我们还可以继续往文件中追加内容 + +```bash +echo "are you ok ?" >> a.log +``` + +追加后,我们再次查看filebeat,也能看到刚刚我们追加的内容 + +![image-20200924102409656](images/image-20200924102409656.png) + +可以看出,已经检测到日志文件有更新,立刻就会读取到更新的内容,并且输出到控制台。 + +### 自定义字段 + +但我们的元数据没办法支撑我们的业务时,我们还可以自定义添加一些字段 + +```bash +filebeat.inputs: +- type: log + enabled: true + paths: + - /soft/beats/logs/*.log + tags: ["web", "test"] #添加自定义tag,便于后续的处理 + fields: #添加自定义字段 + from: test-web + fields_under_root: true #true为添加到根节点,false为添加到子节点中 +setup.template.settings: + index.number_of_shards: 3 +output.console: + pretty: true + enable: true +``` + +添加完成后,我们重启 filebeat + +```bash +./filebeat -e -c mogublog-log.yml +``` + +然后添加新的数据到 a.log中 + +```bash +echo "test-web" >> a.log +``` + +我们就可以看到字段在原来的基础上,增加了两个 + +![image-20200924103323033](images/image-20200924103323033.png) + +### 输出到ElasticSearch + +我们可以通过配置,将修改成如下所示 + +```yml +filebeat.inputs: +- type: log + enabled: true + paths: + - /soft/beats/logs/*.log + tags: ["web", "test"] + fields: + from: test-web + fields_under_root: false +setup.template.settings: + index.number_of_shards: 1 +output.elasticsearch: + hosts: ["127.0.0.1:9200"] +``` + +启动成功后,我们就能看到它已经成功连接到了es了 + +![image-20200924145624812](images/image-20200924145624812.png) + +然后我们到刚刚的 logs文件夹向 a.log文件中添加内容 + +```bash +echo "hello mogublog" >> a.log +``` + +在ES中,我们可以看到,多出了一个 filebeat的索引库 + +![image-20200924145928050](images/image-20200924145928050.png) + +然后我们浏览对应的数据,看看是否有插入的数据内容 + +![image-20200924150500441](images/image-20200924150500441.png) + +### Filebeat工作原理 + +Filebeat主要由下面几个组件组成: harvester、prospector 、input + +#### harvester + +- 负责读取单个文件的内容 +- harvester逐行读取每个文件(一行一行读取),并把这些内容发送到输出 +- 每个文件启动一个harvester,并且harvester负责打开和关闭这些文件,这就意味着harvester运行时文件描述符保持着打开的状态。 +- 在harvester正在读取文件内容的时候,文件被删除或者重命名了,那么Filebeat就会续读这个文件,这就会造成一个问题,就是只要负责这个文件的harvester没用关闭,那么磁盘空间就不会被释放,默认情况下,Filebeat保存问价你打开直到close_inactive到达 + +#### prospector + +- prospector负责管理harvester并找到所有要读取的文件来源 +- 如果输入类型为日志,则查找器将查找路径匹配的所有文件,并为每个文件启动一个harvester +- Filebeat目前支持两种prospector类型:log和stdin + +- Filebeat如何保持文件的状态 + - Filebeat保存每个文件的状态并经常将状态刷新到磁盘上的注册文件中 + - 该状态用于记住harvester正在读取的最后偏移量,并确保发送所有日志行。 + - 如果输出(例如ElasticSearch或Logstash)无法访问,Filebeat会跟踪最后发送的行,并在输出再次可以用时继续读取文件。 + - 在Filebeat运行时,每个prospector内存中也会保存的文件状态信息,当重新启动Filebat时,将使用注册文件的数量来重建文件状态,Filebeat将每个harvester在从保存的最后偏移量继续读取 + - 文件状态记录在data/registry文件中 + +### input + +- 一个input负责管理harvester,并找到所有要读取的源 +- 如果input类型是log,则input查找驱动器上与已定义的glob路径匹配的所有文件,并为每个文件启动一个harvester + +- 每个input都在自己的Go例程中运行 +- 下面的例子配置Filebeat从所有匹配指定的glob模式的文件中读取行 + +```yml +filebeat.inputs: +- type: log + paths: + - /var/log/*.log + - /var/path2/*.log +``` + +### 启动命令 + +```bash +./filebeat -e -c mogublog-es.yml +./filebeat -e -c mogublog-es.yml -d "publish" +``` + +### 参数说明 + +- **-e:**输出到标准输出,默认输出到syslog和logs下 +- **-c:**指定配置文件 +- **-d:**输出debug信息 + +### 读取Nginx中的配置文件 + +我们需要创建一个 mogublog-nginx.yml配置文件 + +```yml +filebeat.inputs: +- type: log + enabled: true + paths: + - /soft/nginx/*.log + tags: ["nginx"] + fields_under_root: false +setup.template.settings: + index.number_of_shards: 1 +output.elasticsearch: + hosts: ["127.0.0.1:9200"] +``` + +启动后,可以在Elasticsearch中看到索引以及查看数据 + +![image-20200924161739842](images/image-20200924161739842.png) + +可以看到,在message中已经获取到了nginx的日志,但是,内容并没有经过处理,只是读取到原数据,那么对于我们后期的操作是不利的,有办法解决吗? + +![image-20200924161814066](images/image-20200924161814066.png) + +### Module + +前面要想实现日志数据的读取以及处理都是自己手动配置的,其实,在Filebeat中,有大量的Module,可以简化我们的配置,直接就可以使用,如下: + +```bash +./filebeat modules list +``` + +得到的列表如下所示 + +```bash +Disabled: +activemq +apache +auditd +aws +azure +barracuda +bluecoat +cef +checkpoint +cisco +coredns +crowdstrike +cylance +elasticsearch +envoyproxy +f5 +fortinet +googlecloud +gsuite +haproxy +ibmmq +icinga +iis +imperva +infoblox +iptables +juniper +kafka +kibana +logstash +microsoft +misp +mongodb +mssql +mysql +nats +netflow +netscout +nginx +o365 +okta +osquery +panw +postgresql +rabbitmq +radware +redis +santa +sonicwall +sophos +squid +suricata +system +tomcat +traefik +zeek +zscaler +``` + +可以看到,内置了很多的module,但是都没有启用,如果需要启用需要进行enable操作: + +```bash +#启动 +./filebeat modules enable nginx +#禁用 +./filebeat modules disable nginx +``` + +可以发现,nginx的module已经被启用。 + +#### nginx module 配置 + +我们到下面的目录,就能看到module的配置了 + +```bash +# 进入到module目录 +cd modules.d/ +#查看文件 +vim nginx.yml.disabled +``` + +得到的文件内容如下所示 + +```bash +# Module: nginx +# Docs: https://www.elastic.co/guide/en/beats/filebeat/7.9/filebeat-module-nginx.html + +- module: nginx + # Access logs + access: + enabled: true + # 添加日志文件 + var.paths: ["/var/log/nginx/access.log*"] + + # Set custom paths for the log files. If left empty, + # Filebeat will choose the paths depending on your OS. + #var.paths: + + # Error logs + error: + enabled: true + var.paths: ["/var/log/nginx/error.log*"] +``` + +#### 配置filebeat + +我们需要修改刚刚的mogublog-nginx.yml文件,然后添加到我们的module + +```yml +filebeat.inputs: +setup.template.settings: + index.number_of_shards: 1 +output.elasticsearch: + hosts: ["127.0.0.1:9200"] +filebeat.config.modules: + path: ${path.config}/modules.d/*.yml + reload.enabled: false +``` + +#### 测试 + +我们启动我们的filebeat + +```bash +./filebeat -e -c itcast-nginx.yml +``` + +如果启动的时候发现出错了,错误如下所示,执行如图所示的脚本即可 【新版本的ES好像不会出现这个错误】 + +```bash +#启动会出错,如下 +ERROR fileset/factory.go:142 Error loading pipeline: Error loading pipeline for +fileset nginx/access: This module requires the following Elasticsearch plugins: +ingest-user-agent, ingest-geoip. You can install them by running the following +commands on all the Elasticsearch nodes: + sudo bin/elasticsearch-plugin install ingest-user-agent + sudo bin/elasticsearch-plugin install ingest-geoip + +``` + +启动成功后,能看到日志记录已经成功刷新进去了 + +![image-20200924164750123](images/image-20200924164750123.png) + +我们可以测试一下,刷新nginx页面,或者向错误日志中,插入数据 + +```bash +echo "err" >> error.log +``` + +能够看到,刚刚的记录已经成功插入了 + +![image-20200924164927557](images/image-20200924164927557.png) + +关于module的其它使用,可以参考文档: + +https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-modules.html + + + +## Metricbeat + +![image-20200924170741928](images/image-20200924170741928.png) + +- 定期收集操作系统或应用服务的指标数据 +- 存储到Elasticsearch中,进行实时分析 + +### Metricbeat组成 + +Metricbeat有2部分组成,一部分是Module,另一个部分为Metricset + +- Module + - 收集的对象:如 MySQL、Redis、Nginx、操作系统等 +- Metricset + - 收集指标的集合:如 cpu、memory,network等 + +以Redis Module为例: + +![image-20200924170958343](images/image-20200924170958343.png) + +### 下载 + +首先我们到[官网](https://www.elastic.co/cn/downloads/beats/metricbeat),找到Metricbeat进行下载 + +![image-20200924171232384](images/image-20200924171232384.png) + +下载完成后,我们通过xftp工具,移动到指定的目录下 + +```bash +# 移动到该目录下 +cd /soft/beats +# 解压文件 +tar -zxvf +# 修改文件名 +mv metricbeat +``` + +然后修改配置文件 + +```bash +vim metricbeat.yml +``` + +添加如下内容 + +```yml +metricbeat.config.modules: + path: ${path.config}/modules.d/*.yml + reload.enabled: false +setup.template.settings: + index.number_of_shards: 1 + index.codec: best_compression +setup.kibana: +output.elasticsearch: + hosts: [""127.0.0.1:9200"] +processors: + - add_host_metadata: ~ + - add_cloud_metadata: ~ +``` + +默认会指定的配置文件,就是在 + +```bash +${path.config}/modules.d/*.yml +``` + +也就是 system.yml文件,我们也可以自行开启其它的收集 + +### 启动 + +在配置完成后,我们通过如下命令启动即可 + +```bash +./metricbeat -e +``` + +在ELasticsearch中可以看到,系统的一些指标数据已经写入进去了: + +![image-20200924171839291](images/image-20200924171839291.png) + +### system module配置 + +```yml +- module: system + period: 10s # 采集的频率,每10秒采集一次 + metricsets: # 采集的内容 + - cpu + - load + - memory + - network + - process + - process_summary +``` + +### Metricbeat Module + +Metricbeat Module的用法和我们之前学的filebeat的用法差不多 + +```bash +#查看列表 +./metricbeat modules list +``` + +能够看到对应的列表 + +```bash +Enabled: +system #默认启用 + +Disabled: +aerospike +apache +ceph +couchbase +docker +dropwizard +elasticsearch +envoyproxy +etcd +golang +graphite +haproxy +http +jolokia +kafka +kibana +kubernetes +kvm +logstash +memcached +mongodb +munin +mysql +nginx +php_fpm +postgresql +prometheus +rabbitmq +redis +traefik +uwsgi +vsphere +windows +``` + +### Nginx Module + +#### 开启Nginx Module + +在nginx中,需要开启状态查询,才能查询到指标数据。 + +```bash +#重新编译nginx +./configure --prefix=/usr/local/nginx --with-http_stub_status_module +make +make install + +./nginx -V #查询版本信息 +nginx version: nginx/1.11.6 +built by gcc 4.4.7 20120313 (Red Hat 4.4.7-23) (GCC) +configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module + +#配置nginx +vim nginx.conf +location /nginx-status { + stub_status on; + access_log off; +} + +# 重启nginx +./nginx -s reload +``` + +测试 + +![image-20200924172317526](images/image-20200924172317526.png) + +结果说明: + +- Active connections:正在处理的活动连接数 +- server accepts handled requests + - 第一个 server 表示Nginx启动到现在共处理了9个连接 + - 第二个 accepts 表示Nginx启动到现在共成功创建 9 次握手 + - 第三个 handled requests 表示总共处理了 21 次请求 + - 请求丢失数 = 握手数 - 连接数 ,可以看出目前为止没有丢失请求 +- Reading: 0 Writing: 1 Waiting: 1 + - Reading:Nginx 读取到客户端的 Header 信息数 + - Writing:Nginx 返回给客户端 Header 信息数 + - Waiting:Nginx 已经处理完正在等候下一次请求指令的驻留链接(开启keep-alive的情况下,这个值等于 + Active - (Reading+Writing)) + +### 配置nginx module + +```bash +#启用redis module +./metricbeat modules enable nginx + +#修改redis module配置 +vim modules.d/nginx.yml +``` + +然后修改下面的信息 + +```bash +# Module: nginx +# Docs: https://www.elastic.co/guide/en/beats/metricbeat/6.5/metricbeat-modulenginx. +html + - module: nginx +#metricsets: +# - stubstatus + period: 10s +# Nginx hosts + hosts: ["http://127.0.0.1"] +# Path to server status. Default server-status + server_status_path: "nginx-status" +#username: "user" +#password: "secret" +``` + +修改完成后,启动nginx + +```bash +#启动 +./metricbeat -e +``` + +### 测试 + +我们能看到,我们的nginx数据已经成功的采集到我们的系统中了 + +![image-20200924173058267](images/image-20200924173058267.png) + +可以看到,nginx的指标数据已经写入到了Elasticsearch。 + +更多的Module使用参见官方文档: + +https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-modules.html + +## 参考 + + [Filebeat 模块与配置](https://www.cnblogs.com/cjsblog/p/9495024.html) + +[Elastic Stack(ELK)从入门到实践](https://www.bilibili.com/video/BV1iJ411c7Az) \ No newline at end of file diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924081614472.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924081614472.png" new file mode 100644 index 0000000000000000000000000000000000000000..ac0f56a1bf9a64eed938a0b5a164ea2e7e2ec5cf Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924081614472.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924091657242.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924091657242.png" new file mode 100644 index 0000000000000000000000000000000000000000..9d552592364293101ccb4ccbc9e4be0c920e1113 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924091657242.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924091716757.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924091716757.png" new file mode 100644 index 0000000000000000000000000000000000000000..67ec7a02c8c4e20b55d25e729ca0084e052851d4 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924091716757.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924092015934.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924092015934.png" new file mode 100644 index 0000000000000000000000000000000000000000..c4061a3f7770021a67c486b9c799190b0acc17fa Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924092015934.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924092348121.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924092348121.png" new file mode 100644 index 0000000000000000000000000000000000000000..d67b1a1951a1235715953f8248373d5dc1e4bf13 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924092348121.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924092551044.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924092551044.png" new file mode 100644 index 0000000000000000000000000000000000000000..1d455f7e675931c4b74c45735d20f3e62c5a704f Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924092551044.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924092749077.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924092749077.png" new file mode 100644 index 0000000000000000000000000000000000000000..bc45a4278b959dbc2f27c92f1377aa2512b7ca10 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924092749077.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924093459418.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924093459418.png" new file mode 100644 index 0000000000000000000000000000000000000000..c5ed63e4eefa9f0d478434f52d8a09eed4b7728e Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924093459418.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924094825962.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924094825962.png" new file mode 100644 index 0000000000000000000000000000000000000000..5229462a519b547330bae1ce6886a28e2fb4a65f Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924094825962.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924095032365.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924095032365.png" new file mode 100644 index 0000000000000000000000000000000000000000..b38ff11e719a807dfb037ab893a5e23507accb44 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924095032365.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924095926036.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924095926036.png" new file mode 100644 index 0000000000000000000000000000000000000000..77e86dffb4359e4a413c4d97b4d03559f6109f84 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924095926036.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924102409656.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924102409656.png" new file mode 100644 index 0000000000000000000000000000000000000000..0f6298ed0864565b0dba786e834462ee8a062ce0 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924102409656.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924103323033.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924103323033.png" new file mode 100644 index 0000000000000000000000000000000000000000..711967691d6dd23f74d09ee08b27cdf459cfe83c Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924103323033.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924145624812.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924145624812.png" new file mode 100644 index 0000000000000000000000000000000000000000..a4ac5826932898748eb824cae4eb7416663a68ba Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924145624812.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924145928050.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924145928050.png" new file mode 100644 index 0000000000000000000000000000000000000000..0ad73778a4fd338421852a18cc6001fd48fd5618 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924145928050.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924150500441.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924150500441.png" new file mode 100644 index 0000000000000000000000000000000000000000..976ee5a0a9bc06a90771dd19ac118725f4c60ab8 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924150500441.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924161739842.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924161739842.png" new file mode 100644 index 0000000000000000000000000000000000000000..18c7bba3d4eb9030fade5015a21820a3e7ecdf6d Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924161739842.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924161814066.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924161814066.png" new file mode 100644 index 0000000000000000000000000000000000000000..e5ae388887e461969690d5349ca14c80da23f7da Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924161814066.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924164750123.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924164750123.png" new file mode 100644 index 0000000000000000000000000000000000000000..82f2c738921d96a743db724bcd1bf8382226ccd6 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924164750123.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924164927557.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924164927557.png" new file mode 100644 index 0000000000000000000000000000000000000000..c9415e705f3b87f8617cef9e8dce41284deaa8d3 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924164927557.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924170741928.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924170741928.png" new file mode 100644 index 0000000000000000000000000000000000000000..412daacbef5a859b51cb126a9298a4f0955ae1ac Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924170741928.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924170958343.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924170958343.png" new file mode 100644 index 0000000000000000000000000000000000000000..2d74b8e69d25d8058a4d3a83b3a49a0f30436d5f Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924170958343.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924171232384.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924171232384.png" new file mode 100644 index 0000000000000000000000000000000000000000..c017c565922411ceef0231775a65755be4a07de9 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924171232384.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924171839291.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924171839291.png" new file mode 100644 index 0000000000000000000000000000000000000000..4c09c62d388a10afd6bbb65fc9b83312181441d3 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924171839291.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924172317526.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924172317526.png" new file mode 100644 index 0000000000000000000000000000000000000000..e0e85a48f7d5ad2533d3321bffcc0ddc8ab3e62c Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924172317526.png" differ diff --git "a/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924173058267.png" "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924173058267.png" new file mode 100644 index 0000000000000000000000000000000000000000..a89fce8e7079be81247761cc0d79518a68a44c31 Binary files /dev/null and "b/ElasticStack/2_Beats\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924173058267.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/README.md" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..5b7c0df2d524cc6cdb747c4692fc5141d3914e43 --- /dev/null +++ "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/README.md" @@ -0,0 +1,232 @@ +# Kibana入门 + +Kibana 是一款开源的数据分析和可视化平台,它是 Elastic Stack 成员之一,设计用于和 Elasticsearch 协作。您可以使用 Kibana 对 Elasticsearch 索引中的数据进行搜索、查看、交互操作。您可以很方便的利用图表、表格及地图对数据进行多元化的分析和呈现。 + +官网:https://www.elastic.co/cn/kibana + +![image-20200924193926486](images/image-20200924193926486.png) + +## 配置和安装 + +到下载地址,选择对应的版本:https://www.elastic.co/cn/downloads/kibana + +![image-20200924194324366](images/image-20200924194324366.png)下载完成后,将文件拷贝到我们的服务器上,然后解压 + +```bash +# 解压 +tar -zxvf kibana-7.9.1-linux-x86_64.tar.gz + +# 重命名 +mv kibana-7.9.1-linux-x86_64 kibana +``` + +然后在进入kibana目录,找到config文件夹下的kibana.yml进行配置的修改 + +```bash +vim /soft/kibana/config/kibana.yml +``` + +然后找到下面的内容 + +```bash +#对外暴露服务的地址 +server.host: "0.0.0.0" + +#配置Elasticsearch +elasticsearch.url: "http://127.0.0.1:9200" +``` + +## 启动 + +修改配置完成后,我们就可以启动kibana了 + +```bash +#启动 +./bin/kibana +``` + +点击启动,发现报错了 + +![image-20200924195011533](images/image-20200924195011533.png) + +原因是kibana不能使用root用户进行启动,所以我们切换到elsearch用户 + +```bash +# 将soft文件夹的所属者改成elsearch +chown elsearch:elsearch /soft/ -R + +# 切换用户 +su elsearch + +# 启动 +./bin/kibana +``` + +然后打开下面的地址,即可访问我们的kibana了 + +```bash +http://202.193.56.222:5601/ +``` + +![image-20200924200502907](images/image-20200924200502907.png) + +## 功能说明 + +![image-20200924200615995](images/image-20200924200615995.png) + +- Discover:数据探索 +- Visualize:可视化 +- Dashboard:仪表盘 +- Timelion:时序控件 +- Canvas:画布 +- Machine Learning:机器学习 +- Infrastructure:基本信息 +- Logs:数据日志展示 +- APM:性能监控 +- Dev Tools:开发者工具 +- Monitoring:监控 +- Management:管理 + +## 数据探索 + +先添加索引信息 + +![image-20200924201110208](images/image-20200924201110208.png) + +然后我们就输入匹配规则进行匹配 + +![image-20200924201234997](images/image-20200924201234997.png) + +然后选择时间字段,一般选择第一个 + +![image-20200924201312845](images/image-20200924201312845.png) + +索引创建完毕后 + +![image-20200924201354838](images/image-20200924201354838.png) + +然后我们就可以往nginx error.log日志文件中,添加几天错误记录 + +```bash +echo "hello error" >> error.log +``` + +我们追加了两条数据,然后到kibana的discover中,刷新页面,就能够看到我们刚添加的日志了,同时我们点击右侧还可以选择需要展示的字段,非常的方便 + +![image-20200924201952010](images/image-20200924201952010.png) + +点击右上角,我们还可以针对时间来进行过滤 + +![image-20200924202210114](images/image-20200924202210114.png) + +## Metricbeat仪表盘 + +现在将Metricbeat的数据展示在Kibana中,首先需要修改我们的MetricBeat配置 + +```bash +#修改metricbeat配置 +setup.kibana: + host: "192.168.40.133:5601" + +#安装仪表盘到Kibana【需要确保Kibana在正常运行,这个过程可能会有些耗时】 +./metricbeat setup --dashboards +``` + +安装完成后,如下所示 + +![image-20200924203831606](images/image-20200924203831606.png) + +然后我们启动Metricbeat + + ``` +./metricbeat -e + ``` + +然后到kibana页面下,找到我们刚刚安装的仪表盘 + +![image-20200924204708099](images/image-20200924204708099.png) + +然后我们就能够看到非常多的指标数据了 + +![image-20200924204636176](images/image-20200924204636176.png) + + + +## Nginx指标仪表盘【Metricbeat】 + +选择Metricbeat的nginx仪表盘即可 + +![image-20200924205523107](images/image-20200924205523107.png) + +然后就能够看到Nginx的指标信息了 + +![image-20200924205552446](images/image-20200924205552446.png) + +## Nginx日志仪表盘 + +我们可以和刚刚Metricbeat的仪表盘一样,也可以将filebeat收集的日志记录,推送到Kibana中 + +首先我们需要修改filebeat的 mogublog-nginx.yml配置文件 + +```yml +filebeat.inputs: +setup.template.settings: + index.number_of_shards: 1 +output.elasticsearch: + hosts: ["127.0.0.1:9200"] +filebeat.config.modules: + path: ${path.config}/modules.d/*.yml + reload.enabled: false +setup.kibana: + host: "127.0.0.1:5601" +``` + +然后按照仪表盘 + +```bash +./filebeat -c mogublog-nginx.yml setup +``` + +等待一会后,仪表盘也安装成功了 + +![image-20200924210454873](images/image-20200924210454873.png) + +然后我们启动filebeat即可 + +```bash +./filebeat -e -c mogublog-nginx.yml +``` + +启动完成后,我们回到我们的Kibana中,找到Dashboard,添加我们的filebeat - nginx即可 + +![image-20200924210913557](images/image-20200924210913557.png) + +然后就能看到我们的仪表盘了,上图就是请求的来源 + +![image-20200924210816489](images/image-20200924210816489.png) + +> 需要注意的是,这些仪表盘本身是没有的,我们需要通过filebeat来进行安装 + +## Kibana自定义仪表盘 + +在Kibana中,我们也可以自定义图标,如制作柱形图 + +![image-20200924211227780](images/image-20200924211227780.png) + +我们选择最下面的 Vertical Bar,也就是柱形图,然后在选择我们的索引 + +![image-20200924211318386](images/image-20200924211318386.png) + +这样就出来了 + +![image-20200924211427643](images/image-20200924211427643.png) + +## 开发者工具 + +在Kibana中,为开发者的测试提供了便捷的工具使用,如下: + +![image-20200924211727920](images/image-20200924211727920.png) + +我们就可以在这里面写一些请求了 + +![image-20200924212137167](images/image-20200924212137167.png) \ No newline at end of file diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924193926486.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924193926486.png" new file mode 100644 index 0000000000000000000000000000000000000000..25898f7aa3214fde612a44fd3cf8741afd31ffcf Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924193926486.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924194324366.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924194324366.png" new file mode 100644 index 0000000000000000000000000000000000000000..3d4bed84fbae75154543fc8fd14bf973f72c3132 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924194324366.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924195011533.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924195011533.png" new file mode 100644 index 0000000000000000000000000000000000000000..cedcdda6cd8d72869f2f146813c52eb695ec4e57 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924195011533.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924200502907.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924200502907.png" new file mode 100644 index 0000000000000000000000000000000000000000..2d7007baaea97182ba8e7d85d39674c16fb553ca Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924200502907.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924200615995.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924200615995.png" new file mode 100644 index 0000000000000000000000000000000000000000..958c98dd4142ff22e6c18b073d3f7893b355b718 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924200615995.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201110208.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201110208.png" new file mode 100644 index 0000000000000000000000000000000000000000..cfeb36d91efa4fb5065a4d2a34163f86e3332298 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201110208.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201234997.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201234997.png" new file mode 100644 index 0000000000000000000000000000000000000000..19102ef71b0bf8860871901aa29c2fd9a52c71b5 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201234997.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201312845.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201312845.png" new file mode 100644 index 0000000000000000000000000000000000000000..4dd2492b7b3839e82e34f586c1214ee5749516a1 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201312845.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201354838.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201354838.png" new file mode 100644 index 0000000000000000000000000000000000000000..1fdd7cb9dc9775150fc78bf8474e8c1f070d14f8 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201354838.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201952010.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201952010.png" new file mode 100644 index 0000000000000000000000000000000000000000..8aba1af5dd6d9f73003353a8e2cf5138f64d217b Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924201952010.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924202210114.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924202210114.png" new file mode 100644 index 0000000000000000000000000000000000000000..408ae19a08fdd167ed588a205b933edb4abca749 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924202210114.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924203817549.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924203817549.png" new file mode 100644 index 0000000000000000000000000000000000000000..67a6c05db5fc36cce40aea0c0f13ac08548ab73a Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924203817549.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924203831606.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924203831606.png" new file mode 100644 index 0000000000000000000000000000000000000000..8677bd89b9985c441acd521ac7b38890f9e51b2c Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924203831606.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924204636176.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924204636176.png" new file mode 100644 index 0000000000000000000000000000000000000000..42d5680d2a4e0a933cc4b6c1727a1d2acc03a913 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924204636176.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924204708099.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924204708099.png" new file mode 100644 index 0000000000000000000000000000000000000000..d66ba144184029183df5dc4e37f12ae8f9097043 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924204708099.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924205523107.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924205523107.png" new file mode 100644 index 0000000000000000000000000000000000000000..3f98ed60c6eec043eeebc2d55752525789e3c139 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924205523107.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924205552446.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924205552446.png" new file mode 100644 index 0000000000000000000000000000000000000000..dac3624595964ecd3827cf2e2854971ce38fee51 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924205552446.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924210454873.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924210454873.png" new file mode 100644 index 0000000000000000000000000000000000000000..96742490f51401766de33f2657b4d43b699237da Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924210454873.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924210816489.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924210816489.png" new file mode 100644 index 0000000000000000000000000000000000000000..c0c7fd9be9639c5ac57fcd8b3239e3880a39a2ef Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924210816489.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924210913557.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924210913557.png" new file mode 100644 index 0000000000000000000000000000000000000000..72279b3f037966d4b02f5fdd10e53056c5c385fb Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924210913557.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924211227780.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924211227780.png" new file mode 100644 index 0000000000000000000000000000000000000000..a4a53a047a0eee8a81ce57481ca9a6ef483fa0e3 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924211227780.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924211318386.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924211318386.png" new file mode 100644 index 0000000000000000000000000000000000000000..aa2bfe18d03194abf292f1d23802e3fb16847e7a Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924211318386.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924211427643.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924211427643.png" new file mode 100644 index 0000000000000000000000000000000000000000..c71e3877d1a63f20146e99190b4387a6d5e932f2 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924211427643.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924211727920.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924211727920.png" new file mode 100644 index 0000000000000000000000000000000000000000..5af687930df407c2584cdb0bbb3c52099d4ec495 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924211727920.png" differ diff --git "a/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924212137167.png" "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924212137167.png" new file mode 100644 index 0000000000000000000000000000000000000000..f7f3e338703c400d3387355bb299c8ca7e6ed6c2 Binary files /dev/null and "b/ElasticStack/3_Kibana\345\256\211\350\243\205\344\270\216\344\273\213\347\273\215/images/image-20200924212137167.png" differ diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/README.md" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..12682bff0a75b9f7b5012de92f4ff63dd917ff8b --- /dev/null +++ "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/README.md" @@ -0,0 +1,182 @@ +# Logstash入门简介 + +## 介绍 + +Logstash是一个开源的服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到最喜欢的存储库中(我们的存储库当然是ElasticSearch) + +![image-20200924213006328](images/image-20200924213006328.png) + +我们回到我们ElasticStack的架构图,可以看到Logstash是充当数据处理的需求的,当我们的数据需要处理的时候,会将它发送到Logstash进行处理,否则直接送到ElasticSearch中 + +![image-20200924213319642](images/image-20200924213319642.png) + +## 用途 + +Logstash可以处理各种各样的输入,从文档,图表中=,数据库中,然后处理完后,发送到 + +![image-20200924213350345](images/image-20200924213350345.png) + +## 部署安装 + +Logstash主要是将数据源的数据进行一行一行的处理,同时还直接过滤切割等功能。 + +![image-20200924214152859](images/image-20200924214152859.png) + +首先到官网下载logstash:https://www.elastic.co/cn/downloads/logstash + +选择我们需要下载的版本: + +![image-20200924215805219](images/image-20200924215805219.png) + +下载完成后,使用xftp工具,将其丢入到服务器中 + +```bash +#检查jdk环境,要求jdk1.8+ +java -version + +#解压安装包 +tar -xvf logstash-7.9.1.tar.gz + +#第一个logstash示例 +bin/logstash -e 'input { stdin { } } output { stdout {} }' +``` + +其实原来的logstash的作用,就是为了做数据的采集,但是因为logstash的速度比较慢,所以后面使用beats来代替了Logstash,当我们使用上面的命令进行启动的时候,就可以发现了,因为logstash使用java写的,首先需要启动虚拟机,最后下图就是启动完成的截图 + +![image-20200924221006644](images/image-20200924221006644.png) + +## 测试 + +我们在控制台输入 hello,马上就能看到它的输出信息 + +![image-20200924221052791](images/image-20200924221052791.png) + +## 配置详解 + +Logstash的配置有三部分,如下所示 + +```bash +input { #输入 +stdin { ... } #标准输入 +} +filter { #过滤,对数据进行分割、截取等处理 +... +} +output { #输出 +stdout { ... } #标准输出 +} +``` + +### 输入 + +- 采集各种样式、大小和来源的数据,数据往往以各种各样的形式,或分散或集中地存在于很多系统中。 +- Logstash 支持各种输入选择 ,可以在同一时间从众多常用来源捕捉事件。能够以连续的流式传输方式,轻松地从您的日志、指标、Web 应用、数据存储以及各种 AWS 服务采集数据。 + +![image-20200924221256569](images/image-20200924221256569.png) + +### 过滤 + +- 实时解析和转换数据 +- 数据从源传输到存储库的过程中,Logstash 过滤器能够解析各个事件,识别已命名的字段以构建结构,并将它们转换成通用格式,以便更轻松、更快速地分析和实现商业价值。 + +![image-20200924221459397](images/image-20200924221459397.png) + +### 输出 + +Logstash 提供众多输出选择,您可以将数据发送到您要指定的地方,并且能够灵活地解锁众多下游用例。 + +![image-20200924221528089](images/image-20200924221528089.png) + +## 读取自定义日志 + +前面我们通过Filebeat读取了nginx的日志,如果是自定义结构的日志,就需要读取处理后才能使用,所以,这个时候就需要使用Logstash了,因为Logstash有着强大的处理能力,可以应对各种各样的场景。 + +### 日志结构 + +```bash +2019-03-15 21:21:21|ERROR|1 读取数据出错|参数:id=1002 +``` + +可以看到,日志中的内容是使用“|”进行分割的,使用,我们在处理的时候,也需要对数据做分割处理。 + +### 编写配置文件 + +```bash +vim mogublog-pipeline.conf +``` + +然后添加如下内容 + +```bash +input { + file { + path => "/soft/beats/logs/app.log" + start_position => "beginning" + } +} +filter { + mutate { + split => {"message"=>"|"} + } +} +output { + stdout { codec => rubydebug } +} +``` + +启动 + +```bash +#启动 +./bin/logstash -f ./mogublog-pipeline.conf +``` + +然后我们就插入我们的测试数据 + +```bash +echo "2019-03-15 21:21:21|ERROR|读取数据出错|参数:id=1002" >> app.log +``` + +然后我们就可以看到logstash就会捕获到刚刚我们插入的数据,同时我们的数据也被分割了 + +![image-20200924224710757](images/image-20200924224710757.png) + +### 输出到Elasticsearch + +我们可以修改我们的配置文件,将我们的日志记录输出到ElasticSearch中 + +```bash +input { + file { + path => "/soft/beats/logs/app.log" + start_position => "beginning" + } +} +filter { + mutate { + split => {"message"=>"|"} + } +} +output { + elasticsearch { + hosts => ["127.0.0.1:9200"] + } +} +``` + +然后在重启我们的logstash + +```bash +./bin/logstash -f ./mogublog-pipeline.conf +``` + +然后向日志记录中,插入两条数据 + +```bash +echo "2019-03-15 21:21:21|ERROR|读取数据出错|参数:id=1002" >> app.log +echo "2019-03-15 21:21:21|ERROR|读取数据出错|参数:id=1002" >> app.log +``` + +最后就能够看到我们刚刚插入的数据了 + +![image-20200924230314560](images/image-20200924230314560.png) \ No newline at end of file diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924213006328.png" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924213006328.png" new file mode 100644 index 0000000000000000000000000000000000000000..6323fdb970e31ebdb4b7a5666ca517df2b4916ed Binary files /dev/null and "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924213006328.png" differ diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924213319642.png" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924213319642.png" new file mode 100644 index 0000000000000000000000000000000000000000..84ef5bd73a0db6c436d572392796424f0f3be767 Binary files /dev/null and "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924213319642.png" differ diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924213350345.png" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924213350345.png" new file mode 100644 index 0000000000000000000000000000000000000000..79f9f6f4d14c4145e75ea294ba33cfd817817718 Binary files /dev/null and "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924213350345.png" differ diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924214152859.png" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924214152859.png" new file mode 100644 index 0000000000000000000000000000000000000000..070cf2bd12a6ecb08bbfc8f2bf5831f64821d705 Binary files /dev/null and "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924214152859.png" differ diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924215805219.png" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924215805219.png" new file mode 100644 index 0000000000000000000000000000000000000000..59b9dad6ebe570ad7c4168c7ec37b2d9649e96a1 Binary files /dev/null and "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924215805219.png" differ diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221006644.png" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221006644.png" new file mode 100644 index 0000000000000000000000000000000000000000..7642fd543fa982e9518e0585054aaedccec1cdb1 Binary files /dev/null and "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221006644.png" differ diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221052791.png" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221052791.png" new file mode 100644 index 0000000000000000000000000000000000000000..bf681bf2b98af85a6553bfccfc47b4ea2abf0bfb Binary files /dev/null and "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221052791.png" differ diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221256569.png" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221256569.png" new file mode 100644 index 0000000000000000000000000000000000000000..05767c9f4f0e86b8435a3c36bd174cbed6422dfa Binary files /dev/null and "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221256569.png" differ diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221459397.png" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221459397.png" new file mode 100644 index 0000000000000000000000000000000000000000..2dc71b4e1f09d5a0c86f623ea3c19a68864268b6 Binary files /dev/null and "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221459397.png" differ diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221528089.png" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221528089.png" new file mode 100644 index 0000000000000000000000000000000000000000..28e37d78fbd2bdbe43f084718f16527c24c0f5d5 Binary files /dev/null and "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924221528089.png" differ diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924224710757.png" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924224710757.png" new file mode 100644 index 0000000000000000000000000000000000000000..7168ec16c88efebd889dae17b64304bdab1baac6 Binary files /dev/null and "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924224710757.png" differ diff --git "a/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924230314560.png" "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924230314560.png" new file mode 100644 index 0000000000000000000000000000000000000000..fe72dce886e60d88b43abc6ac2984cc4b2dbf795 Binary files /dev/null and "b/ElasticStack/4_Logstash\345\205\245\351\227\250\347\256\200\344\273\213/images/image-20200924230314560.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/README.md" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ca75423b028a6f8aac54b1a027bf8ebe58329cfa --- /dev/null +++ "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/README.md" @@ -0,0 +1,373 @@ +# ElasticStack综合案例 + +本篇将我们前面学习到的技术:ElasticSearch、Beats、Kibana、Logstash 整合起来,做一个综合性的学习,目的是为了让小伙伴们能够更加深刻的理解ElasticStack的使用 + +## 流程说明 + +![image-20200925083514711](images/image-20200925083514711.png) + +- 应用APP生产日志,用来记录用户的操作 + - [INFO] 2019-03-15 22:55:20 [Main] - DAU|5206|使用优惠券|2019-03-15 03:37:20 + - [INFO] 2019-03-15 22:55:21 [Main] - DAU|3880|浏览页面|2019-03-15 07:25:09 +- 通过Filebeat读取日志文件中的内容,并且将内容发送给Logstash,原因是需要对内容做处理 +- Logstash接收到内容后,进行处理,如分割操作,然后将内容发送到Elasticsearch中 +- Kibana会读取Elasticsearch中的数据,并且在Kibana中进行设计Dashboard,最后进行展示 + +> 说明:日志格式、图表、Dashboard都是自定义的 + +## App介绍 + +APP在生产环境应该是真实系统,然而,现在我们学习的话,为了简化操作,所以就做数据的模拟生成即可。 + +业务代码如下: + +```java +package com.log; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.RandomUtils; +import org.joda.time.DateTime; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@Slf4j +@SpringBootApplication +public class Main { + + public static final String[] VISIT = new String[]{"浏览页面", "评论商品", "加入收藏", "加入购物车", "提交订单", "使用优惠券", "领取优惠券", "搜索", "查看订单"}; + + public static void main(String[] args) throws Exception { + while(true){ + Long sleep = RandomUtils.nextLong(200, 1000 * 5); + Thread.sleep(sleep); + Long maxUserId = 9999L; + Long userId = RandomUtils.nextLong(1, maxUserId); + String visit = VISIT[RandomUtils.nextInt(0, VISIT.length)]; + DateTime now = new DateTime(); + int maxHour = now.getHourOfDay(); + int maxMillis = now.getMinuteOfHour(); + int maxSeconds = now.getSecondOfMinute(); + String date = now.plusHours(-(RandomUtils.nextInt(0, maxHour))) + .plusMinutes(-(RandomUtils.nextInt(0, maxMillis))) + .plusSeconds(-(RandomUtils.nextInt(0, maxSeconds))) + .toString("yyyy-MM-dd HH:mm:ss"); + + String result = "DAU|" + userId + "|" + visit + "|" + date; + log.error(result); + } + } +} +``` + +我们可以启动运行,就是不断的生成日志,模拟了我们的实际业务 + +```bash +09:18:32.721 [main] ERROR com.log.Main - DAU|8183|加入购物车|2020-09-25 06:10:25 +09:18:33.599 [main] ERROR com.log.Main - DAU|7097|提交订单|2020-09-25 06:18:31 +09:18:37.265 [main] ERROR com.log.Main - DAU|1468|查看订单|2020-09-25 02:04:10 +09:18:39.634 [main] ERROR com.log.Main - DAU|7821|领取优惠券|2020-09-25 02:04:07 +09:18:41.909 [main] ERROR com.log.Main - DAU|7962|提交订单|2020-09-25 03:02:39 +09:18:43.596 [main] ERROR com.log.Main - DAU|3358|评论商品|2020-09-25 08:14:19 +``` + +然后我们将该项目使用下面命令进行打包 + +```bash +mvn clean install +``` + +打包完成后,到target目录下,能够看到我们生成的jar包 + +![image-20200925092119075](images/image-20200925092119075.png) + +我们将其复制到我们的服务器上,然后创建一个启动的脚本 startup.sh + +```bash +#!/bin/bash +nohup java -Xms256m -Xmx512m -jar mogu-dashboard-generate-0.0.1-SNAPSHOT.jar > app.log 2>&1 & +``` + +然后就使用脚本进行启动 + +```bash +# 启动 +./startup.sh +# 启动成功后,会看到一个日志 app.log,我们可以查看 +tail -f app.log +``` + +## 配置Filebeat + +在有了不断产生日志的应用程序后,我们就需要创建一个Filebeat的配置文件,用于日志的收集 + +```bash +# 打开配置文件 +vim mogu-dashboard.yml + +# 写入数据 +filebeat.inputs: +- type: log + enabled: true + paths: + - /soft/app/*.log +setup.template.settings: + index.number_of_shards: 1 +output.logstash: + hosts: ["127.0.0.1:5044"] +``` + +然后我们就可以启动了【需要我们把Logstash启动起来】 + +```bash +./filebeat -e -c mogu-dashboard.yml +``` + +## 配置Logstash + +### Logstash输出到控制台 + +Logstash的主要目的就是处理Filebeat发送过来的数据,进行数据的清洗,过滤等,我们首先简单的将logstash获得的数据输出到控制台 + +```bash +# 打开配置文件 +vim mogu-dashboard.conf + +# 添加以下内容 +input { + beats { + port => "5044" + } +} +output { + stdout { codec => rubydebug } +} +``` + +然后启动我们的logstash 【注意,启动时间比较长,需要我们等待】 + +```bash +./bin/logstash -f mogu-dashboard.conf +``` + +启动logstash完成后,我们需要再次启动filebeat,回到上面的启动步骤,然后就能看到logstash输出我们的日志 + +![image-20200925095319950](images/image-20200925095319950.png) + +### 配置Logstash连接ElasticSearch + +上面的数据,其实还是我们的原始数据,并没有经过处理,所以我们这个时候就需要使用到Logstash的其它功能了。我们继续修改配置文件 + +```bash +# 打开配置文件 +vim mogu-dashboard.conf +``` + +然后修改一下的值 + +```bash +input { + beats { + port => "5044" + } +} +filter { + mutate { + split => {"message"=>"|"} + } + mutate { + add_field => { + "userId" => "%{[message][1]}" + "visit" => "%{[message][2]}" + "date" => "%{[message][3]}" + } + } + mutate { + convert => { + "userId" => "integer" + "visit" => "string" + "date" => "string" + } + } + mutate { + remove_field => [ "host" ] + } +} +#output { +# stdout { codec => rubydebug } +#} + +output { + elasticsearch { + hosts => [ "127.0.0.1:9200"] + } +} +``` + +然后再次启动 + +```bash +./bin/logstash -f mogu-dashboard.conf +``` + +其实能够看到,我们原来的数据,就经过了处理了,产生了新的字段 + +![image-20200925095824693](images/image-20200925095824693.png) + +同时我们还可以对我们的数据,进行类型转换,为了方便我们的下游进行处理 + +```bash + mutate { + convert => { + "userId" => "integer" + "visit" => "string" + "date" => "string" + } + } +``` + +### 遇到的问题1 + +```bash +[2020-09-25T02:32:44,042][WARN ][logstash.filters.mutate ][main][5fd6a2f2f396816d849f2e3e2e0a53f2500a9b58c6819e23f42d2bfd34cde207] Exception caught while applying mutate filter {:exception=>"Invalid FieldReference: `message[1]`"} +``` + +不断的刷这个错误,配置文件没问题,但添加字段那一个mutate需要给message套一层中括号: + +```bash +mutate { + add_field => { + "userId" => "%{[message][1]}" + "visit" => "%{[message][2]}" + "date" => "%{[message][3]}" + } +} +``` + +### 遇到的问题2 + +filebeat 传输到host的字段中host是一个对象 + +```bash +failed to parse field [host] of type [text] in document +``` + +解决方法就是过滤掉host字段 + +```bash +mutate { + remove_field => [ "host" ] +} + +``` + +## 启动ElasticSearch + +在我们通过Logstash发送数据到ElasticSearch,所以我们还需要启动我们的ElasticSearch + +```bash +# 切换到elsearch用户 +su elsearch + +# 到目录 +cd /soft/elsearch/bin + +# 启动 +./elasticsearch +``` + +## 启动Kibana + +我们最后就需要通过Kibana来展示我们的图形化数据 + +```bash +# 启动kibana +./bin/kibana + +# 通过浏览器访问 +http://202.193.56.222:5601/app/kibana +``` + +### 添加到索引库 + +添加Logstash索引到Kibana中: + +```bash +http://202.193.56.222:5601/app/management/kibana/indexPatterns/create +``` + +![image-20200925112345791](images/image-20200925112345791.png) + +输入我们的匹配规则,然后匹配到logstash,然后选择时间字段后创建 + +![image-20200925112534588](images/image-20200925112534588.png) + +### 创建柱形图 + +我们点击右侧Visualizations,然后开始创建图标 + +![image-20200925112621210](images/image-20200925112621210.png) + +然后选择柱形图 + +![image-20200925112705557](images/image-20200925112705557.png) + +在选择我们的索引 + +![image-20200925112758534](images/image-20200925112758534.png) + + + +最后我们定义我们的X轴,选择按照时间进行添加 + +![image-20200925113054316](images/image-20200925113054316.png) + +最后更新我们的页面,然后在选择最近的30分钟 + +![image-20200925113133267](images/image-20200925113133267.png) + +就能够看到我们的日志在源源不断的生成了,同时我们可以对我们的这个图表进行保存 + +![image-20200925113154752](images/image-20200925113154752.png) + + + +### 创建饼图 + +我们继续选择饼图 + +![image-20200925144902642](images/image-20200925144902642.png) + +然后选择我们的索引 + +![image-20200925144939062](images/image-20200925144939062.png) + +添加完成后,我们就看到这样一个页面了 + +![image-20200925145116116](images/image-20200925145116116.png) + +但是这样还不死很直观,所以我们还需要做处理,找到右侧的Buckets,然后选择Split Slices,然后把我们的每个字段都添加上去,其中visit指的是我们es中的属性 + +![image-20200925145451255](images/image-20200925145451255.png) + + + +最后选择update,得到的效果如下所示 + +![image-20200925145553509](images/image-20200925145553509.png) + +我们还可以继续给每个字段都添加label标签 + +![image-20200925145747292](images/image-20200925145747292.png) + +添加完成后,更新页面,就得到非常不错的效果了~ + +![image-20200925145807688](images/image-20200925145807688.png) + +### 数据表格 + +在图标中,选择我们需要显示的字段即可 + +![image-20200925150415045](images/image-20200925150415045.png) + +## 制作Dashboard + +![image-20200925151827734](images/image-20200925151827734.png) \ No newline at end of file diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925083514711.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925083514711.png" new file mode 100644 index 0000000000000000000000000000000000000000..408023ead2caa67d564edd9a29ca662a26000356 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925083514711.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925092119075.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925092119075.png" new file mode 100644 index 0000000000000000000000000000000000000000..3e3b95d63e960cdedb25969b12e927997022a549 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925092119075.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925095319950.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925095319950.png" new file mode 100644 index 0000000000000000000000000000000000000000..53dad675c37492b1022c5affde5351188155d94e Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925095319950.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925095824693.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925095824693.png" new file mode 100644 index 0000000000000000000000000000000000000000..627b428e82b506d549ae4c2cc10276d7a9dd4fd6 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925095824693.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112345791.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112345791.png" new file mode 100644 index 0000000000000000000000000000000000000000..6af4c8b4eee18f8f13a7c0ab4b9fb7ce7ccd4b65 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112345791.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112534588.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112534588.png" new file mode 100644 index 0000000000000000000000000000000000000000..96614e6ae9c55fa76ab9d34dd8516932fc9a9535 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112534588.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112621210.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112621210.png" new file mode 100644 index 0000000000000000000000000000000000000000..737fc4491d8a57438d4df48ed6ebf9b019cacab5 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112621210.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112705557.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112705557.png" new file mode 100644 index 0000000000000000000000000000000000000000..aa79e8018a5f675111a0864b76d3e46766f0f59e Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112705557.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112758534.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112758534.png" new file mode 100644 index 0000000000000000000000000000000000000000..0444f16ace1bd05dd1bde37c983333c548a71ba5 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925112758534.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925113054316.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925113054316.png" new file mode 100644 index 0000000000000000000000000000000000000000..7c981820d33c5efadee687e17a9c7c5e8348095e Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925113054316.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925113133267.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925113133267.png" new file mode 100644 index 0000000000000000000000000000000000000000..7ae477c0aca7ddc4618ebd3305d64b8ba56187a7 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925113133267.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925113154752.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925113154752.png" new file mode 100644 index 0000000000000000000000000000000000000000..1f524b23a38db038af43d08b5269f31dde1ddbd2 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925113154752.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925144902642.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925144902642.png" new file mode 100644 index 0000000000000000000000000000000000000000..d6c3c223d54e3c4b94fde4c0ad1b0ea7215a73bd Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925144902642.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925144939062.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925144939062.png" new file mode 100644 index 0000000000000000000000000000000000000000..915ec4920353f3fd9b0125bedc3b33a85ca440e7 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925144939062.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145116116.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145116116.png" new file mode 100644 index 0000000000000000000000000000000000000000..86d5da6cfa130daa8dec364bcd0ddec63b906f79 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145116116.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145451255.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145451255.png" new file mode 100644 index 0000000000000000000000000000000000000000..1ab3056348512dbcf5edc0a2e357e4053791c95c Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145451255.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145553509.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145553509.png" new file mode 100644 index 0000000000000000000000000000000000000000..b0ed39df03e8f1fa936a48c1348202a024f5b8f7 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145553509.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145747292.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145747292.png" new file mode 100644 index 0000000000000000000000000000000000000000..ae0005fdfb79f9d5537944245a1968b559db63e4 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145747292.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145807688.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145807688.png" new file mode 100644 index 0000000000000000000000000000000000000000..6771033ad9cbaf7dfbf4c83e2b5c2326a5239171 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925145807688.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925150415045.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925150415045.png" new file mode 100644 index 0000000000000000000000000000000000000000..f0984a5bc764d9ed07120b1229b2092c733fb363 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925150415045.png" differ diff --git "a/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925151827734.png" "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925151827734.png" new file mode 100644 index 0000000000000000000000000000000000000000..003aaea71b61f2ab00692528cf804d87efe981f3 Binary files /dev/null and "b/ElasticStack/5_ElasticStack\347\273\274\345\220\210\346\241\210\344\276\213/images/image-20200925151827734.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/README.md" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..7fad0b8bd0f6ecf2eb7011dba9be685b908ba9d0 --- /dev/null +++ "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/README.md" @@ -0,0 +1,343 @@ +# 使用ELK搭建蘑菇博客日志收集 + +## 前言 + +前阵子学习了ElasticStack的技术栈,其中包括ElasticSearch 、Beats、Kibana、Logstash。因为打算将其用于蘑菇博客的项目中,关于ElasticStack的技术栈学习,可以参考前面写的博客~ + +- [ElasticSearch介绍与安装](../1_ElasticSearch介绍与安装/README.md) +- [Beats入门简介](../2_Beats入门简介/README.md) +- [Kibana安装与介绍](../3_Kibana安装与介绍/README.md) +- [Logstash入门简介](../4_Logstash入门简介/README.md) +- [ElasticStack综合案例](../5_ElasticStack综合案例/README.md) + +## 拉取ElasticStack镜像 + +通过本教程,可以非常方便的给蘑菇博客项目,集成ELK用于分布式日志收集 + +为了更加方便的部署ELK环境,我已经提前将环境打包成了Docker镜像,发布到了DockerHub中,所以我们只需要拉取我提前制作的ElasticStack镜像即可 + +```bash +# 拉取镜像 +docker pull moxi/elastic_stack + +# 查看镜像 +docker images; +``` + +拉取完成后,查看我们的镜像信息,容量大概在4.16G左右 + +![image-20200925203411844](images/image-20200925203411844.png) + +## 制作容器 + +在我们拉取完成后,就可以开始通过镜像制作我们的ElasticStack容器了 + +```bash +docker run --privileged -d -it -h elastic_stack --name elastic_stack -v /etc/localtime:/etc/localtime:ro -p 11122:22 -p 9200:9200 -p 5601:5601 -p 5044:5044 -p 9600:9600 moxi/elastic_stack /usr/sbin/init +``` + +其中这里主要使用的端口号有 + +- 11122:用于建立ssh连接内部容器 +- 9200:ElasticSearch默认端口号 +- 5601:Kibana默认端口号 +- 5044:Logstash默认端口号 + +执行完上面的命令后,如果没有错误,那么就代表执行成功 + +![image-20200925204214191](images/image-20200925204214191.png) + +然后我们就可以通过在启动一个xshell窗口,连接我们的容器了 + +![image-20200925204336586](images/image-20200925204336586.png) + +输入你服务器的ip地址,以及端口号为 11122,然后点击确定,然后在输入服务器的账号和密码 + +- 账号:root +- 密码:mogu2018 + +即可进入到我们的容器内部,我们到/soft目录下,能看到里面安装的软件 + +![image-20200930092513748](images/image-20200930092513748.png) + + + +- ElasticSearch:分布式搜索引擎 +- jdk:java1.8 +- kibana:图形化工具 +- logstash:用于数据的过滤和处理 + +## 启动ElasticSearch + +因为ElasticSearch的启动配置要求比较高,所以我们需要修改一些配置,首先我们到宿主机【是刚刚安装Docker的机器,不是现在容器里面!!】 + +```bash +# 到宿主机上打开文件 +vim /etc/sysctl.conf + +# 增加这样一条配置,一个进程在VMAs(虚拟内存区域)创建内存映射最大数量 +vm.max_map_count=655360 + +# 让配置生效 +sysctl -p +``` + +然后再去启动ElasticSearch,因为ElasticSearch不能使用root用户直接启动,所以我们需要切换到elsearch + +```bash +# 切换用户 +su elsearch + +# 进入到ElasticSearch目录 +cd elsearch + +# 启动 +./bin/elasticsearch + +# 后台启动 +./bin/elasticsearch -d +``` + +启动完成后,我们就可以看到ElasticSearch运行在9200端口上 + +![image-20200925205336945](images/image-20200925205336945.png) + +我们输入下面的地址到浏览器中访问 + +```bash +http://your_ip:9200/ +``` + +如果出现下面的内容,表示ElasticSearch服务已经正常启动~ + +![image-20200925205443777](images/image-20200925205443777.png) + +## 启动Logstash + +Logstash的作用就是收集Beats发送过来的数据,然后进行处理,处理完成后,在将其推送到ElasticSearch中,如果需要查看更多的关于Logstash,可以跳转到上面提到的博客中 + +我们首先到Logstash目录 + +```bash +cd /soft/logstash +``` + +然后我们可以查看配置文件 + +```bash +vim mogu-dashboard.conf +``` + +可以看到我之前配置的信息 + +```bash +input { + beats { + port => "5044" + } +} +filter { + mutate { + split => {"message"=>"|"} + } + mutate { + add_field => { + "userId" => "%{[message][1]}" + "visit" => "%{[message][2]}" + "date" => "%{[message][3]}" + } + } + mutate { + convert => { + "userId" => "integer" + "visit" => "string" + "date" => "string" + } + } + mutate { + remove_field => [ "host" ] + } +} +#output { +# stdout { codec => rubydebug } +#} + +output { + if [from] == 'mogu_web' { + elasticsearch { + hosts => ["127.0.0.1:9200"] + index => "logstash_mogu_web_%{+YYYY.MM.dd}" + } + } + + if [from] == "mogu_admin" { + elasticsearch { + hosts => ["127.0.0.1:9200"] + index => "logstash_mogu_admin_%{+YYYY.MM.dd}" + } + } + + if [from] == "mogu_sms" { + elasticsearch { + hosts => ["127.0.0.1:9200"] + index => "logstash_mogu_sms_%{+YYYY.MM.dd}" + } + } + + if [from] == "mogu_picture" { + elasticsearch { + hosts => ["127.0.0.1:9200"] + index => "logstash_mogu_picture_%{+YYYY.MM.dd}" + } + } + + if [from] == "mogu_nginx" { + elasticsearch { + hosts => ["127.0.0.1:9200"] + index => "logstash_mogu_nginx_%{+YYYY.MM.dd}" + } + } +} + +``` + +> 我们可以通过获取到传递过来的from字段,就是在filebeat时候指定的 一个字段,代表是这条日志属于哪个模块的,然后在根据logstash的if判断,然后生成不同的ElasticSearch索引 + +![image-20200927144647484](images/image-20200927144647484.png) + +下面,我们指定该配置文件后,然后启动项目 + +```bash +# 前台启动 +./bin/logstash -f ./mogu-dashboard.conf + +# 后台启动 +nohup ./bin/logstash -f ./mogu-dashboard.conf > catalina.out 2>&1 & +``` + +注意:logstash的启动可能会比较慢,需要耐心的等待一会~ + +![image-20200925210154370](images/image-20200925210154370.png) + +启动完成后,会占用9600端口~,同时经过logstash的数据都会发送到ElasticSearch中 + +## 启动Beats + +### 启动filebeat + +filebeat是一个轻量级的日志文件收集器,主要用于收集我们的一些日志文件【它和应用服务器存放在一起】 + +> 需要注意,Beats不在我们ELK服务器上进行启动了,我们需要到部署蘑菇博客的服务器上,然后找到Beats目录 + +![image-20200930092617884](images/image-20200930092617884.png) + +我们首先需要到我们应用服务器中,然后启动filebeats 【如果你的目录下没有,可以参考 [Beats入门简介](../2_Beats入门简介/README.md) 安装】 + +```bash +# 进入到filebeat目录 +cd /soft/beats/filebeat +``` + +然后查看我们的配置文件 + +```bash +vim mogu-dashboard.yml +``` + +然后修改我们配置文件中logstash的地址,我们要把它改成刚刚部署的logstash服务器的ip即可 + +```bash +filebeat.inputs: +- type: log + enabled: true + paths: + - /home/mogu_blog/mogu_web/catalina.out + fields: + from: mogu_web + fields_under_root: true + +- type: log + enabled: true + paths: + - /home/mogu_blog/mogu_admin/catalina.out + fields: + from: mogu_admin + fields_under_root: true + +- type: log + enabled: true + paths: + - /home/mogu_blog/mogu_sms/catalina.out + fields: + from: mogu_sms + fields_under_root: true + +- type: log + enabled: true + paths: + - /home/mogu_blog/mogu_picture/catalina.out + fields: + from: mogu_picture + fields_under_root: true + +setup.template.settings: + index.number_of_shards: 1 +output.logstash: + hosts: ["101.132.122.175:5044"] +``` + +然后启动我们的filebeat + +```bash +# 前台启动 +./filebeat -e -c mogu-dashboard.yml + +# 后台启动 +#!/bin/bash +nohup ./filebeat -e -c mogu-dashboard.yml > catalina.out 2>&1 & +``` + +启动完成后,我们能够看到日志文件已经被加载 + +![image-20200927144808408](images/image-20200927144808408.png) + +## 启动Kibana + +Kibana的作用就是对我们的数据进行图形化的显示,首先我们到Kibana目录 【回到ELK目录下】 + +```bash +# 到kibana安装目录 +cd /soft/kibana +``` + +因为Kibana和ElasticSearch一样,不支持root用户启动,所以我们继续切换成elsearch用户 + +```bash +su elsearch +``` + +然后启动 + +```bash +./bin/kibana +``` + +查看启动信息,我们发现Kibana启动在5601端口号 + +![image-20200925210626499](images/image-20200925210626499.png) + +启动后,我们在浏览器中访问我们的地址 + +```bash +http://your_ip:5601 +``` + +![image-20200925210805478](images/image-20200925210805478.png) + + + +我们找到dashboard就可以看到蘑菇博客的日志记录了 + +![image-20200927145854642](images/image-20200927145854642.png) + +> tip:这里就只介绍了ElasticStack的日志收集,关于更多的Kibana图形化页面,小伙伴可以参考其它文件进行配置,这里就不列举出来啦~ \ No newline at end of file diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925203411844.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925203411844.png" new file mode 100644 index 0000000000000000000000000000000000000000..fa42416d42fd0780d08b3f0fbda006e0099de561 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925203411844.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925204214191.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925204214191.png" new file mode 100644 index 0000000000000000000000000000000000000000..901355dd53f4545b10463c0012721e969ef2a773 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925204214191.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925204336586.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925204336586.png" new file mode 100644 index 0000000000000000000000000000000000000000..e2f132088de638a0974978e6d1fadda596478332 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925204336586.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925204519265.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925204519265.png" new file mode 100644 index 0000000000000000000000000000000000000000..417b19d51a843055bf1ed8b924916ac3716349e1 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925204519265.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925205336945.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925205336945.png" new file mode 100644 index 0000000000000000000000000000000000000000..45cca68932552619aec2fe25af3014b4f9878dc2 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925205336945.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925205443777.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925205443777.png" new file mode 100644 index 0000000000000000000000000000000000000000..a3e75ac58e8d257692c646dec2d20286ba4c8899 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925205443777.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925210154370.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925210154370.png" new file mode 100644 index 0000000000000000000000000000000000000000..f62f92575e871a5feca8baa44fb0dde979483d62 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925210154370.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925210626499.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925210626499.png" new file mode 100644 index 0000000000000000000000000000000000000000..b6a7df1651f10593e31a185e71a5402c110fddf2 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925210626499.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925210805478.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925210805478.png" new file mode 100644 index 0000000000000000000000000000000000000000..178ced5058494d36fd827041f107b15b4d6cea7c Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925210805478.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925213245747.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925213245747.png" new file mode 100644 index 0000000000000000000000000000000000000000..4df85c9f4553f9919be2da885f2bfccb2b624117 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200925213245747.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200927144647484.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200927144647484.png" new file mode 100644 index 0000000000000000000000000000000000000000..1d7737cbe5d40d19c09d836f8a0be5bb3ff96514 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200927144647484.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200927144808408.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200927144808408.png" new file mode 100644 index 0000000000000000000000000000000000000000..eafd51457a9224d1d4f9e1b79400615a9da42e99 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200927144808408.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200927145854642.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200927145854642.png" new file mode 100644 index 0000000000000000000000000000000000000000..24525768b9d551852417729d483dd1cf757bb5a0 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200927145854642.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200930092513748.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200930092513748.png" new file mode 100644 index 0000000000000000000000000000000000000000..28af1bdbb803dc90b532c21b3933a7498d0e5151 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200930092513748.png" differ diff --git "a/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200930092617884.png" "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200930092617884.png" new file mode 100644 index 0000000000000000000000000000000000000000..7b299f45fb10074a465c9c186f3caafd03e34305 Binary files /dev/null and "b/ElasticStack/6_\344\275\277\347\224\250ELK\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242\346\227\245\345\277\227\346\224\266\351\233\206/images/image-20200930092617884.png" differ diff --git a/ElasticStack/README.md b/ElasticStack/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fc8366217faf2bc7c1e8d35cee51a8a1708c127c --- /dev/null +++ b/ElasticStack/README.md @@ -0,0 +1,21 @@ +# ElasticStack + +## 前言 + +ELK = ElasticSearch + Logstash + Kibana + +随着Beats的加入,原来的ELK体系变成了ElasticStack,即 + +ElasticStack = ElasticSearch + Logstash + Kibana + Beats + +## 笔记 + +> 来源Bilibili黑马程序员的视频:[Elastic Stack(ELK)从入门到实践](https://www.bilibili.com/video/BV1iJ411c7Az) + +- [ElasticSearch介绍与安装](./1_ElasticSearch介绍与安装) +- [Beats入门简介](./2_Beats入门简介) +- [Kibana安装与介绍](./3_Kibana安装与介绍) +- [Logstash入门简介](./4_Logstash入门简介) +- [ElasticStack综合案例](./5_ElasticStack综合案例) +- [使用ELK搭建蘑菇博客日志收集](./6_使用ELK搭建蘑菇博客日志收集) +- [源码](./Study_ElasticSearch_Code) \ No newline at end of file diff --git a/ElasticStack/Study_ElasticSearch_Code/.gitignore b/ElasticStack/Study_ElasticSearch_Code/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..df0583553f36588f85b388b0f04e0b301fed32e3 --- /dev/null +++ b/ElasticStack/Study_ElasticSearch_Code/.gitignore @@ -0,0 +1,32 @@ +/target/ +/temp/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +.settings + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +*.iml + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +/webapps/ + +/logs/ \ No newline at end of file diff --git a/ElasticStack/Study_ElasticSearch_Code/pom.xml b/ElasticStack/Study_ElasticSearch_Code/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..55bdab655e0e4276e5a44baa89c5f2c193dea7f6 --- /dev/null +++ b/ElasticStack/Study_ElasticSearch_Code/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + org.example + Study_ElasticSearch_Code + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 7 + 7 + + + + + + + + org.elasticsearch.client + elasticsearch-rest-client + 6.8.5 + + + org.elasticsearch.client + elasticsearch-rest-high-level-client + 6.8.5 + + + junit + junit + 4.12 + test + + + com.fasterxml.jackson.core + jackson-databind + 2.11.1 + + + \ No newline at end of file diff --git a/ElasticStack/Study_ElasticSearch_Code/src/main/java/ESApi.java b/ElasticStack/Study_ElasticSearch_Code/src/main/java/ESApi.java new file mode 100644 index 0000000000000000000000000000000000000000..7aec5b1316638a2f5ad5c4516ea8c8fdc7db34bf --- /dev/null +++ b/ElasticStack/Study_ElasticSearch_Code/src/main/java/ESApi.java @@ -0,0 +1,87 @@ +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.HttpHost; +import org.apache.http.util.EntityUtils; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestClientBuilder; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * 使用低级客户端 访问 + * + * @author: 陌溪 + * @create: 2020-09-23-16:33 + */ +public class ESApi { + private RestClient restClient; + private static final ObjectMapper MAPPER = new ObjectMapper(); + + /** + * 初始化 + */ + public void init() { + RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost("202.193.56.222", 9200, "http")); + this.restClient = restClientBuilder.build(); + } + + /** + * 查询集群状态 + */ + public void testGetInfo() throws IOException { + Request request = new Request("GET", "/_cluster/state"); + request.addParameter("pretty", "true"); + Response response = this.restClient.performRequest(request); + System.out.println(response.getStatusLine()); + System.out.println(EntityUtils.toString(response.getEntity())); + } + + /** + * 根据ID查询数据 + * @throws IOException + */ + public void testGetHouseInfo() throws IOException { + Request request = new Request("GET", "/haoke/house/Z3CduXQBYpWein3CRFug"); + request.addParameter("pretty", "true"); + Response response = this.restClient.performRequest(request); + System.out.println(response.getStatusLine()); + System.out.println(EntityUtils.toString(response.getEntity())); + } + + public void testCreateData() throws IOException { + Request request = new Request("POST", "/haoke/house"); + Map data = new HashMap<>(); + data.put("id", "2001"); + data.put("title", "张江高科"); + data.put("price", "3500"); + // 写成JSON + request.setJsonEntity(MAPPER.writeValueAsString(data)); + Response response = this.restClient.performRequest(request); + System.out.println(response.getStatusLine()); + System.out.println(EntityUtils.toString(response.getEntity())); + + } + + // 搜索数据 + public void testSearchData() throws IOException { + Request request = new Request("POST", "/haoke/house/_search"); + String searchJson = "{\"query\": {\"match\": {\"title\": \"拎包入住\"}}}"; + request.setJsonEntity(searchJson); + request.addParameter("pretty","true"); + Response response = this.restClient.performRequest(request); + System.out.println(response.getStatusLine()); + System.out.println(EntityUtils.toString(response.getEntity())); + } + + public static void main(String[] args) throws IOException { + ESApi esApi = new ESApi(); + esApi.init(); +// esApi.testGetInfo(); +// esApi.testGetHouseInfo(); + esApi.testCreateData(); + } +} diff --git a/ElasticStack/Study_ElasticSearch_Code/src/main/java/ESHightApi.java b/ElasticStack/Study_ElasticSearch_Code/src/main/java/ESHightApi.java new file mode 100644 index 0000000000000000000000000000000000000000..04e2dae88c06935edc3c9418181713ae59764f68 --- /dev/null +++ b/ElasticStack/Study_ElasticSearch_Code/src/main/java/ESHightApi.java @@ -0,0 +1,187 @@ +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.HttpHost; +import org.apache.http.util.EntityUtils; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.delete.DeleteRequest; +import org.elasticsearch.action.delete.DeleteResponse; +import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.update.UpdateRequest; +import org.elasticsearch.action.update.UpdateResponse; +import org.elasticsearch.client.*; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.SearchHits; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.elasticsearch.search.fetch.subphase.FetchSourceContext; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * ES高级客户端 + * + * @author: 陌溪 + * @create: 2020-09-23-16:56 + */ +public class ESHightApi { + private RestHighLevelClient client; + + public void init() { + RestClientBuilder restClientBuilder = RestClient.builder( + new HttpHost("202.193.56.222", 9200, "http")); + this.client = new RestHighLevelClient(restClientBuilder); + } + + public void after() throws Exception { + this.client.close(); + } + + /** + * 新增文档,同步操作 + * + * @throws Exception + */ + public void testCreate() throws Exception { + Map data = new HashMap<>(); + data.put("id", "2002"); + data.put("title", "南京西路 拎包入住 一室一厅"); + data.put("price", "4500"); + IndexRequest indexRequest = new IndexRequest("haoke", "house") + .source(data); + IndexResponse indexResponse = this.client.index(indexRequest, + RequestOptions.DEFAULT); + System.out.println("id->" + indexResponse.getId()); + System.out.println("index->" + indexResponse.getIndex()); + System.out.println("type->" + indexResponse.getType()); + System.out.println("version->" + indexResponse.getVersion()); + System.out.println("result->" + indexResponse.getResult()); + System.out.println("shardInfo->" + indexResponse.getShardInfo()); + } + + /** + * 异步创建文档 + * @throws Exception + */ + public void testCreateAsync() throws Exception { + Map data = new HashMap<>(); + data.put("id", "2003"); + data.put("title", "南京东路 最新房源 二室一厅"); + data.put("price", "5500"); + IndexRequest indexRequest = new IndexRequest("haoke", "house") + .source(data); + this.client.indexAsync(indexRequest, RequestOptions.DEFAULT, new + ActionListener() { + @Override + public void onResponse(IndexResponse indexResponse) { + System.out.println("id->" + indexResponse.getId()); + System.out.println("index->" + indexResponse.getIndex()); + System.out.println("type->" + indexResponse.getType()); + System.out.println("version->" + indexResponse.getVersion()); + System.out.println("result->" + indexResponse.getResult()); + System.out.println("shardInfo->" + indexResponse.getShardInfo()); + } + @Override + public void onFailure(Exception e) { + System.out.println(e); + } + }); + System.out.println("ok"); + Thread.sleep(20000); + } + + /** + * 查询 + * @throws Exception + */ + public void testQuery() throws Exception { + GetRequest getRequest = new GetRequest("haoke", "house", + "GkpdE2gBCKv8opxuOj12"); + // 指定返回的字段 + String[] includes = new String[]{"title", "id"}; + String[] excludes = Strings.EMPTY_ARRAY; + FetchSourceContext fetchSourceContext = + new FetchSourceContext(true, includes, excludes); + getRequest.fetchSourceContext(fetchSourceContext); + GetResponse response = this.client.get(getRequest, RequestOptions.DEFAULT); + System.out.println("数据 -> " + response.getSource()); + } + + /** + * 判断是否存在 + * + * @throws Exception + */ + public void testExists() throws Exception { + GetRequest getRequest = new GetRequest("haoke", "house", + "GkpdE2gBCKv8opxuOj12"); +// 不返回的字段 + getRequest.fetchSourceContext(new FetchSourceContext(false)); + boolean exists = this.client.exists(getRequest, RequestOptions.DEFAULT); + System.out.println("exists -> " + exists); + } + /** + * 删除数据 + * + * @throws Exception + */ + public void testDelete() throws Exception { + DeleteRequest deleteRequest = new DeleteRequest("haoke", "house", + "GkpdE2gBCKv8opxuOj12"); + DeleteResponse response = this.client.delete(deleteRequest, + RequestOptions.DEFAULT); + System.out.println(response.status());// OK or NOT_FOUND + } + /** + * 更新数据 + * + * @throws Exception + */ + public void testUpdate() throws Exception { + UpdateRequest updateRequest = new UpdateRequest("haoke", "house", + "G0pfE2gBCKv8opxuRz1y"); + Map data = new HashMap<>(); + data.put("title", "张江高科2"); + data.put("price", "5000"); + updateRequest.doc(data); + UpdateResponse response = this.client.update(updateRequest, + RequestOptions.DEFAULT); + System.out.println("version -> " + response.getVersion()); + } + /** + * 测试搜索 + * + * @throws Exception + */ + public void testSearch() throws Exception { + SearchRequest searchRequest = new SearchRequest("haoke"); + searchRequest.types("house"); + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); + sourceBuilder.query(QueryBuilders.matchQuery("title", "拎包入住")); + sourceBuilder.from(0); + sourceBuilder.size(5); + sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); + searchRequest.source(sourceBuilder); + SearchResponse search = this.client.search(searchRequest, + RequestOptions.DEFAULT); + System.out.println("搜索到 " + search.getHits().totalHits + " 条数据."); + SearchHits hits = search.getHits(); + for (SearchHit hit : hits) { + System.out.println(hit.getSourceAsString()); + } + } + + public static void main(String[] args) throws Exception { + ESHightApi esHightApi = new ESHightApi(); + esHightApi.init(); + esHightApi.testCreate(); + } +} diff --git a/ElasticStack/mogu-dashboard-generate/.gitignore b/ElasticStack/mogu-dashboard-generate/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..df0583553f36588f85b388b0f04e0b301fed32e3 --- /dev/null +++ b/ElasticStack/mogu-dashboard-generate/.gitignore @@ -0,0 +1,32 @@ +/target/ +/temp/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +.settings + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +*.iml + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +/webapps/ + +/logs/ \ No newline at end of file diff --git a/ElasticStack/mogu-dashboard-generate/.mvn/wrapper/MavenWrapperDownloader.java b/ElasticStack/mogu-dashboard-generate/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000000000000000000000000000000000000..a45eb6ba269cd38f8965cef786729790945d9537 --- /dev/null +++ b/ElasticStack/mogu-dashboard-generate/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,118 @@ +/* + * Copyright 2007-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if (mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if (mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if (!outputFile.getParentFile().exists()) { + if (!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/ElasticStack/mogu-dashboard-generate/.mvn/wrapper/maven-wrapper.jar b/ElasticStack/mogu-dashboard-generate/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054 Binary files /dev/null and b/ElasticStack/mogu-dashboard-generate/.mvn/wrapper/maven-wrapper.jar differ diff --git a/ElasticStack/mogu-dashboard-generate/.mvn/wrapper/maven-wrapper.properties b/ElasticStack/mogu-dashboard-generate/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..642d572ce90e5085986bdd9c9204b9404f028084 --- /dev/null +++ b/ElasticStack/mogu-dashboard-generate/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/ElasticStack/mogu-dashboard-generate/pom.xml b/ElasticStack/mogu-dashboard-generate/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..bf4f3062114a4f66fb85c7913345791967035bd9 --- /dev/null +++ b/ElasticStack/mogu-dashboard-generate/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.3.4.RELEASE + + + com.example + mogu-dashboard-generate + 0.0.1-SNAPSHOT + mogu-dashboard-generate + Demo project for Spring Boot + + + 1.8 + + + + + org.springframework.boot + spring-boot-starter + + + + + org.apache.commons + commons-lang3 + 3.11 + + + + + joda-time + joda-time + 2.10.5 + + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/ElasticStack/mogu-dashboard-generate/src/main/java/com/log/Main.java b/ElasticStack/mogu-dashboard-generate/src/main/java/com/log/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..5008323c92fb5c82b82d5af26d86bf367e77eb7b --- /dev/null +++ b/ElasticStack/mogu-dashboard-generate/src/main/java/com/log/Main.java @@ -0,0 +1,34 @@ +package com.log; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.RandomUtils; +import org.joda.time.DateTime; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@Slf4j +@SpringBootApplication +public class Main { + + public static final String[] VISIT = new String[]{"visit page", "comment product", "join collection", "join shop car", "submit order", "use coupon", "receive coupon", "search", "view order"}; + + public static void main(String[] args) throws Exception { + while(true){ + Long sleep = RandomUtils.nextLong(200, 1000 * 5); + Thread.sleep(sleep); + Long maxUserId = 9999L; + Long userId = RandomUtils.nextLong(1, maxUserId); + String visit = VISIT[RandomUtils.nextInt(0, VISIT.length)]; + DateTime now = new DateTime(); + int maxHour = now.getHourOfDay(); + int maxMillis = now.getMinuteOfHour(); + int maxSeconds = now.getSecondOfMinute(); + String date = now.plusHours(-(RandomUtils.nextInt(0, maxHour))) + .plusMinutes(-(RandomUtils.nextInt(0, maxMillis))) + .plusSeconds(-(RandomUtils.nextInt(0, maxSeconds))) + .toString("yyyy-MM-dd HH:mm:ss"); + + String result = "DAU|" + userId + "|" + visit + "|" + date; + log.error(result); + } + } +} diff --git a/ElasticStack/mogu-dashboard-generate/src/main/resources/application.yml b/ElasticStack/mogu-dashboard-generate/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..71e134b0df562f8d865ecae3b28cf9969cca3c4e --- /dev/null +++ b/ElasticStack/mogu-dashboard-generate/src/main/resources/application.yml @@ -0,0 +1,6 @@ +spring: + application: + name: mogu-log + +logging: + config: classpath:logback-boot.xml diff --git a/ElasticStack/mogu-dashboard-generate/src/main/resources/logback-boot.xml b/ElasticStack/mogu-dashboard-generate/src/main/resources/logback-boot.xml new file mode 100644 index 0000000000000000000000000000000000000000..90224e56b30cc092cc5757e71c0e7bd42a826ab6 --- /dev/null +++ b/ElasticStack/mogu-dashboard-generate/src/main/resources/logback-boot.xml @@ -0,0 +1,88 @@ + + + ${APP_NAME} + + + + + + + + + + + + + + + + + + + + + + + true + + ${CONSOLE_LOG_PATTERN} + UTF-8 + + + + + + ${LOG_FILE}/${APP_NAME}-error.log + + + ${LOG_FILE}/${APP_NAME}-error.%d{yyyy-MM-dd}.%i.log + 100MB + + 7 + + + ${CONSOLE_LOG_PATTERN_NO_COLOR} + UTF-8 + + + 100MB + + + ERROR + ACCEPT + DENY + + + + + + ${LOG_FILE}/${APP_NAME}-info.log + + + ${LOG_FILE}/${APP_NAME}-info.%d{yyyy-MM-dd}.%i.log + 100MB + + 7 + + + ${CONSOLE_LOG_PATTERN_NO_COLOR} + UTF-8 + + + INFO + ACCEPT + DENY + + + + + + + + + + \ No newline at end of file diff --git a/ElasticStack/mogu-dashboard-generate/src/test/java/com/log/MainTests.java b/ElasticStack/mogu-dashboard-generate/src/test/java/com/log/MainTests.java new file mode 100644 index 0000000000000000000000000000000000000000..2f69704aa55a214ce4fc04e5cc2e902e09040045 --- /dev/null +++ b/ElasticStack/mogu-dashboard-generate/src/test/java/com/log/MainTests.java @@ -0,0 +1,13 @@ +package com.log; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class MainTests { + + @Test + void contextLoads() { + } + +} diff --git "a/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/README.md" "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ce50916c7db39aae994ad7ba3c2d4a2f0a6edfa7 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/README.md" @@ -0,0 +1,1047 @@ +# Gin内容介绍 + +## 参考 + +参考博客和文档: + +- [Gin框架介绍及使用](https://www.liwenzhou.com/posts/Go/Gin_framework/) +- [Gin中文文档](https://gin-gonic.com/zh-cn/docs/) + +## 主要内容 + +本教程主要从下面几个方面来进行讲解 + +- Gin框架基本使用 +- GORM基本使用 +- Web开发项目实战 + +## 关于Web + +- Web是基于HTTP协议进行交互的应用网络 +- Web就是通过使用浏览器/APP访问的各种资源 + +![image-20200913201627904](images/image-20200913201627904.png)一个请求对应一个响应,以淘宝网为例,我们输入一个url,就会返回一个页面 + +![image-20200913201929752](images/image-20200913201929752.png) + +## 创建项目 + +首先我们使用Goland创建一个Go项目 + +![image-20200913202119089](images/image-20200913202119089.png) + +创建完成后,打开命令窗口,输入下面的命令,创建一个依赖管理 + +```bash +go mod init gin_demo +``` + +然后打开setting页面,勾选这个选项【不勾选会导致go.mod依赖爆红】 + +![image-20200913210316077](images/image-20200913210316077.png) + +我们创建一个main.go文件,然后使用go代码实现一个请求和响应 + +```go +package main + +import ( + "fmt" + "net/http" +) + +// http.ResponseWriter:代表响应,传递到前端的 +// *http.Request:表示请求,从前端传递过来的 +func sayHello(w http.ResponseWriter, r *http.Request) { + _, _ = fmt.Fprintln(w, "hello Golang!"); +} + +func main() { + http.HandleFunc("/hello", sayHello) + err := http.ListenAndServe(":9090", nil) + if err != nil { + fmt.Println("http server failed, err:%v \n", err) + return + } +} +``` + +在浏览器访问如下地址 + +```bash +http://localhost:9090/hello +``` + +就能打开我们的hello golang页面了 + +![image-20200913203807251](images/image-20200913203807251.png) + +我们可以给文字添加色彩 + +```bash +// http.ResponseWriter:代表响应,传递到前端的 +// *http.Request:表示请求,从前端传递过来的 +func sayHello(w http.ResponseWriter, r *http.Request) { + _, _ = fmt.Fprintln(w, "

hello Golang!

"); +} +``` + +然后重启后,在刷新 + +![image-20200913203922973](images/image-20200913203922973.png) + +我们还可以把里面的字符串放在一个文件里,我们定义一个 hello.html文件 + +```html + + hello golang + +

+ hello Golang! +

+

+ hello gin! +

+ + + + +``` + +然后修改刚刚的main.go,使用 ioutil解析文件 + +```go +package main + +import ( + "fmt" + "io/ioutil" + "net/http" +) + +// http.ResponseWriter:代表响应,传递到前端的 +// *http.Request:表示请求,从前端传递过来的 +func sayHello(w http.ResponseWriter, r *http.Request) { + html, _ := ioutil.ReadFile("./template/hello.html") + _, _ = fmt.Fprintln(w, string(html)); +} + +func main() { + http.HandleFunc("/hello", sayHello) + err := http.ListenAndServe(":9090", nil) + if err != nil { + fmt.Println("http server failed, err:%v \n", err) + return + } +} +``` + +最后刷新我们的页面,就出来这样的效果了,这就是我们通过golang开发的一个Web页面 + +![image-20200913204456513](images/image-20200913204456513.png) + +## 为什么要用框架 + +我们通过上面的http包,就能够实现一个web的开发,那为什么还要用gin呢? + +其实框架的好处,就是别人帮我们搭建了一个舞台,同时提供了很多现成的轮子,让我们专注于业务的开发,同时让开发效率更高。 + +## Gin框架介绍 + +`Gin`是一个用Go语言编写的web框架。它是一个类似于`martini`但拥有更好性能的API框架, 由于使用了`httprouter`,速度提高了近40倍。 如果你是性能和高效的追求者, 你会爱上`Gin`。 + +Go世界里最流行的Web框架,[Github](https://github.com/gin-gonic/gin)上有`32K+`star。 基于[httprouter](https://github.com/julienschmidt/httprouter)开发的Web框架。 [中文文档](https://gin-gonic.com/zh-cn/docs/)齐全,简单易用的轻量级框架。 + +## Gin框架安装与使用 + +### 安装 + +下载并安装`Gin`: + +```bash +go get -u github.com/gin-gonic/gin +``` + +### 第一个Gin示例: + +```golang +package main + +import ( + "github.com/gin-gonic/gin" +) + +func main() { + // 创建一个默认的路由引擎 + r := gin.Default() + // GET:请求方式;/hello:请求的路径 + // 当客户端以GET方法请求/hello路径时,会执行后面的匿名函数 + r.GET("/hello", func(c *gin.Context) { + // c.JSON:返回JSON格式的数据 + c.JSON(200, gin.H{ + "message": "Hello world!", + }) + }) + // 启动HTTP服务,默认在0.0.0.0:8080启动服务 + r.Run() +} +``` + +将上面的代码保存并编译执行,然后使用浏览器打开`127.0.0.1:8080/hello`就能看到一串JSON字符串。 + +## RESTful API + +REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”。 + +推荐阅读[阮一峰 理解RESTful架构](http://www.ruanyifeng.com/blog/2011/09/restful.html) + +简单来说,REST的含义就是客户端与Web服务器之间进行交互的时候,使用HTTP协议中的4个请求方法代表不同的动作。 + +- `GET`用来获取资源 +- `POST`用来新建资源 +- `PUT`用来更新资源 +- `DELETE`用来删除资源。 + +只要API程序遵循了REST风格,那就可以称其为RESTful API。目前在前后端分离的架构中,前后端基本都是通过RESTful API来进行交互。 + +例如,我们现在要编写一个管理书籍的系统,我们可以查询对一本书进行查询、创建、更新和删除等操作,我们在编写程序的时候就要设计客户端浏览器与我们Web服务端交互的方式和路径。按照经验我们通常会设计成如下模式: + +| 请求方法 | URL | 含义 | +| :------: | :----------: | :----------: | +| GET | /book | 查询书籍信息 | +| POST | /create_book | 创建书籍记录 | +| POST | /update_book | 更新书籍信息 | +| POST | /delete_book | 删除书籍信息 | + +同样的需求我们按照RESTful API设计如下: + +| 请求方法 | URL | 含义 | +| :------: | :---: | :----------: | +| GET | /book | 查询书籍信息 | +| POST | /book | 创建书籍记录 | +| PUT | /book | 更新书籍信息 | +| DELETE | /book | 删除书籍信息 | + +Gin框架支持开发RESTful API的开发。 + +```go +func main() { + r := gin.Default() + r.GET("/book", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "GET", + }) + }) + + r.POST("/book", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "POST", + }) + }) + + r.PUT("/book", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "PUT", + }) + }) + + r.DELETE("/book", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "DELETE", + }) + }) + + // 启动HTTP服务,默认在0.0.0.0:8080启动服务 + r.Run() +} +``` + +开发RESTful API的时候我们通常使用[Postman](https://www.getpostman.com/)来作为客户端的测试工具。 + +## Gin渲染 + +### HTML渲染 + +我们首先定义一个存放模板文件的`templates`文件夹,然后在其内部按照业务分别定义一个`posts`文件夹和一个`users`文件夹。 `posts/index.html`文件的内容如下: + +```template +{{define "posts/index.html"}} + + + + + + + + posts/index + + + {{.title}} + + +{{end}} +``` + +`users/index.html`文件的内容如下: + +```template +{{define "users/index.html"}} + + + + + + + users/index + + + {{.title}} + + +{{end}} +``` + +Gin框架中使用`LoadHTMLGlob()`或者`LoadHTMLFiles()`方法进行HTML模板渲染。 + +```go +func main() { + r := gin.Default() + r.LoadHTMLGlob("templates/**/*") + //r.LoadHTMLFiles("templates/posts/index.html", "templates/users/index.html") + r.GET("/posts/index", func(c *gin.Context) { + c.HTML(http.StatusOK, "posts/index.html", gin.H{ + "title": "posts/index", + }) + }) + + r.GET("users/index", func(c *gin.Context) { + c.HTML(http.StatusOK, "users/index.html", gin.H{ + "title": "users/index", + }) + }) + + r.Run(":8080") +} +``` + +### 自定义模板函数 + +定义一个不转义相应内容的`safe`模板函数如下: + +```go +func main() { + router := gin.Default() + router.SetFuncMap(template.FuncMap{ + "safe": func(str string) template.HTML{ + return template.HTML(str) + }, + }) + router.LoadHTMLFiles("./index.tmpl") + + router.GET("/index", func(c *gin.Context) { + c.HTML(http.StatusOK, "index.tmpl", "李文周的博客") + }) + + router.Run(":8080") +} +``` + +在`index.tmpl`中使用定义好的`safe`模板函数: + +```template + + + + 修改模板引擎的标识符 + + +
{{ . | safe }}
+ + +``` + +为了让index.tmpl文件有语法显示,我们还需要配置一下 + +![image-20200913213156919](images/image-20200913213156919.png) + +然后我们加入 *.tmpl,保存即可 + +### 静态文件处理 + +当我们渲染的HTML文件中引用了静态文件时,我们只需要按照以下方式在渲染页面前调用`gin.Static`方法即可。 + +```go +func main() { + r := gin.Default() + r.Static("/static", "./static") + r.LoadHTMLGlob("templates/**/*") + // ... + r.Run(":8080") +} +``` + +### 使用模板继承 + +Gin框架默认都是使用单模板,如果需要使用`block template`功能,可以通过`"github.com/gin-contrib/multitemplate"`库实现,具体示例如下: + +首先,假设我们项目目录下的templates文件夹下有以下模板文件,其中`home.tmpl`和`index.tmpl`继承了`base.tmpl`: + +```bash +templates +├── includes +│ ├── home.tmpl +│ └── index.tmpl +├── layouts +│ └── base.tmpl +└── scripts.tmpl +``` + +然后我们定义一个`loadTemplates`函数如下: + +```go +func loadTemplates(templatesDir string) multitemplate.Renderer { + r := multitemplate.NewRenderer() + layouts, err := filepath.Glob(templatesDir + "/layouts/*.tmpl") + if err != nil { + panic(err.Error()) + } + includes, err := filepath.Glob(templatesDir + "/includes/*.tmpl") + if err != nil { + panic(err.Error()) + } + // 为layouts/和includes/目录生成 templates map + for _, include := range includes { + layoutCopy := make([]string, len(layouts)) + copy(layoutCopy, layouts) + files := append(layoutCopy, include) + r.AddFromFiles(filepath.Base(include), files...) + } + return r +} +``` + +我们在`main`函数中 + +```go +func indexFunc(c *gin.Context){ + c.HTML(http.StatusOK, "index.tmpl", nil) +} + +func homeFunc(c *gin.Context){ + c.HTML(http.StatusOK, "home.tmpl", nil) +} + +func main(){ + r := gin.Default() + r.HTMLRender = loadTemplates("./templates") + r.GET("/index", indexFunc) + r.GET("/home", homeFunc) + r.Run() +} +``` + +### 补充文件路径处理 + +关于模板文件和静态文件的路径,我们需要根据公司/项目的要求进行设置。可以使用下面的函数获取当前执行程序的路径。 + +```go +func getCurrentPath() string { + if ex, err := os.Executable(); err == nil { + return filepath.Dir(ex) + } + return "./" +} +``` + +### JSON渲染 + +```go +func main() { + r := gin.Default() + + // gin.H 是map[string]interface{}的缩写 + r.GET("/someJSON", func(c *gin.Context) { + // 方式一:自己拼接JSON + c.JSON(http.StatusOK, gin.H{"message": "Hello world!"}) + }) + r.GET("/moreJSON", func(c *gin.Context) { + // 方法二:使用结构体 + var msg struct { + Name string `json:"user"` + Message string + Age int + } + msg.Name = "小王子" + msg.Message = "Hello world!" + msg.Age = 18 + c.JSON(http.StatusOK, msg) + }) + r.Run(":8080") +} +``` + +### XML渲染 + +注意需要使用具名的结构体类型。 + +```go +func main() { + r := gin.Default() + // gin.H 是map[string]interface{}的缩写 + r.GET("/someXML", func(c *gin.Context) { + // 方式一:自己拼接JSON + c.XML(http.StatusOK, gin.H{"message": "Hello world!"}) + }) + r.GET("/moreXML", func(c *gin.Context) { + // 方法二:使用结构体 + type MessageRecord struct { + Name string + Message string + Age int + } + var msg MessageRecord + msg.Name = "小王子" + msg.Message = "Hello world!" + msg.Age = 18 + c.XML(http.StatusOK, msg) + }) + r.Run(":8080") +} +``` + +### YMAL渲染 + +```go +r.GET("/someYAML", func(c *gin.Context) { + c.YAML(http.StatusOK, gin.H{"message": "ok", "status": http.StatusOK}) +}) +``` + +### protobuf渲染 + +```go +r.GET("/someProtoBuf", func(c *gin.Context) { + reps := []int64{int64(1), int64(2)} + label := "test" + // protobuf 的具体定义写在 testdata/protoexample 文件中。 + data := &protoexample.Test{ + Label: &label, + Reps: reps, + } + // 请注意,数据在响应中变为二进制数据 + // 将输出被 protoexample.Test protobuf 序列化了的数据 + c.ProtoBuf(http.StatusOK, data) +}) +``` + +## 获取参数 + +### 获取querystring参数 + +`querystring`指的是URL中`?`后面携带的参数,例如:`/user/search?username=小王子&address=沙河`。 获取请求的querystring参数的方法如下: + +```go +func main() { + //Default返回一个默认的路由引擎 + r := gin.Default() + r.GET("/user/search", func(c *gin.Context) { + // 可以添加默认值 + username := c.DefaultQuery("username", "小王子") + //username := c.Query("username") + address := c.Query("address") + //输出json结果给调用方 + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + "username": username, + "address": address, + }) + }) + r.Run() +} +``` + +我们输入对应的URL,就能获取到对应的参数了 + +```bash +http://localhost:9090/web?username=小王子&address=沙河 +``` + +### 获取form参数 + +请求的数据通过form表单来提交,例如向`/user/search`发送一个POST请求,获取请求数据的方式如下: + +```go +func main() { + //Default返回一个默认的路由引擎 + r := gin.Default() + r.POST("/user/search", func(c *gin.Context) { + // DefaultPostForm取不到值时会返回指定的默认值 + //username := c.DefaultPostForm("username", "小王子") + username := c.PostForm("username") + address := c.PostForm("address") + //输出json结果给调用方 + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + "username": username, + "address": address, + }) + }) + r.Run(":8080") +} +``` + +### 获取path参数 + +请求的参数通过URL路径传递,例如:`/user/search/小王子/沙河`。 获取请求URL路径中的参数的方式如下。 + +```go +func main() { + //Default返回一个默认的路由引擎 + r := gin.Default() + r.GET("/user/search/:username/:address", func(c *gin.Context) { + username := c.Param("username") + address := c.Param("address") + //输出json结果给调用方 + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + "username": username, + "address": address, + }) + }) + + r.Run(":8080") +} +``` + +### 参数绑定 + +为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的`Content-Type`识别请求数据类型并利用反射机制自动提取请求中`QueryString`、`form表单`、`JSON`、`XML`等参数到结构体中。 下面的示例代码演示了`.ShouldBind()`强大的功能,它能够基于请求自动提取`JSON`、`form表单`和`QueryString`类型的数据,并把值绑定到指定的结构体对象。 + +```go +// Binding from JSON +type Login struct { + User string `form:"user" json:"user" binding:"required"` + Password string `form:"password" json:"password" binding:"required"` +} + +func main() { + router := gin.Default() + + // 绑定JSON的示例 ({"user": "q1mi", "password": "123456"}) + router.POST("/loginJSON", func(c *gin.Context) { + var login Login + + if err := c.ShouldBind(&login); err == nil { + fmt.Printf("login info:%#v\n", login) + c.JSON(http.StatusOK, gin.H{ + "user": login.User, + "password": login.Password, + }) + } else { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + } + }) + + // 绑定form表单示例 (user=q1mi&password=123456) + router.POST("/loginForm", func(c *gin.Context) { + var login Login + // ShouldBind()会根据请求的Content-Type自行选择绑定器 + if err := c.ShouldBind(&login); err == nil { + c.JSON(http.StatusOK, gin.H{ + "user": login.User, + "password": login.Password, + }) + } else { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + } + }) + + // 绑定QueryString示例 (/loginQuery?user=q1mi&password=123456) + router.GET("/loginForm", func(c *gin.Context) { + var login Login + // ShouldBind()会根据请求的Content-Type自行选择绑定器 + if err := c.ShouldBind(&login); err == nil { + c.JSON(http.StatusOK, gin.H{ + "user": login.User, + "password": login.Password, + }) + } else { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + } + }) + + // Listen and serve on 0.0.0.0:8080 + router.Run(":8080") +} +``` + +`ShouldBind`会按照下面的顺序解析请求中的数据完成绑定: + +1. 如果是 `GET` 请求,只使用 `Form` 绑定引擎(`query`)。 +2. 如果是 `POST` 请求,首先检查 `content-type` 是否为 `JSON` 或 `XML`,然后再使用 `Form`(`form-data`)。 + +## 文件上传 + +### 单个文件上传 + +文件上传前端页面代码: + +```html + + + + 上传文件示例 + + +
+ + +
+ + +``` + +后端gin框架部分代码: + +```go +func main() { + router := gin.Default() + // 处理multipart forms提交文件时默认的内存限制是32 MiB + // 可以通过下面的方式修改 + // router.MaxMultipartMemory = 8 << 20 // 8 MiB + router.POST("/upload", func(c *gin.Context) { + // 单个文件 + file, err := c.FormFile("f1") + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": err.Error(), + }) + return + } + + log.Println(file.Filename) + dst := fmt.Sprintf("C:/tmp/%s", file.Filename) + // 上传文件到指定的目录 + c.SaveUploadedFile(file, dst) + c.JSON(http.StatusOK, gin.H{ + "message": fmt.Sprintf("'%s' uploaded!", file.Filename), + }) + }) + router.Run() +} +``` + +### 多个文件上传 + +```go +func main() { + router := gin.Default() + // 处理multipart forms提交文件时默认的内存限制是32 MiB + // 可以通过下面的方式修改 + // router.MaxMultipartMemory = 8 << 20 // 8 MiB + router.POST("/upload", func(c *gin.Context) { + // Multipart form + form, _ := c.MultipartForm() + files := form.File["file"] + + for index, file := range files { + log.Println(file.Filename) + dst := fmt.Sprintf("C:/tmp/%s_%d", file.Filename, index) + // 上传文件到指定的目录 + c.SaveUploadedFile(file, dst) + } + c.JSON(http.StatusOK, gin.H{ + "message": fmt.Sprintf("%d files uploaded!", len(files)), + }) + }) + router.Run() +} +``` + +## 重定向 + +### HTTP重定向 + +HTTP 重定向很容易。 内部、外部重定向均支持。 + +```go +r.GET("/test", func(c *gin.Context) { + c.Redirect(http.StatusMovedPermanently, "http://www.sogo.com/") +}) +``` + +### 路由重定向 + +路由重定向,使用`HandleContext`: + +```go +r.GET("/test", func(c *gin.Context) { + // 指定重定向的URL + c.Request.URL.Path = "/test2" + r.HandleContext(c) +}) +r.GET("/test2", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{"hello": "world"}) +}) +``` + +## Gin路由 + +### 普通路由 + +```go +r.GET("/index", func(c *gin.Context) {...}) +r.GET("/login", func(c *gin.Context) {...}) +r.POST("/login", func(c *gin.Context) {...}) +``` + +此外,还有一个可以匹配所有请求方法的`Any`方法如下: + +```go +r.Any("/test", func(c *gin.Context) {...}) +``` + +为没有配置处理函数的路由添加处理程序,默认情况下它返回404代码,下面的代码为没有匹配到路由的请求都返回`views/404.html`页面。 + +```go +r.NoRoute(func(c *gin.Context) { + c.HTML(http.StatusNotFound, "views/404.html", nil) + }) +``` + +### 路由组 + +我们可以将拥有共同URL前缀的路由划分为一个路由组。习惯性一对`{}`包裹同组的路由,这只是为了看着清晰,你用不用`{}`包裹功能上没什么区别。 + +```go +func main() { + r := gin.Default() + userGroup := r.Group("/user") + { + userGroup.GET("/index", func(c *gin.Context) {...}) + userGroup.GET("/login", func(c *gin.Context) {...}) + userGroup.POST("/login", func(c *gin.Context) {...}) + + } + shopGroup := r.Group("/shop") + { + shopGroup.GET("/index", func(c *gin.Context) {...}) + shopGroup.GET("/cart", func(c *gin.Context) {...}) + shopGroup.POST("/checkout", func(c *gin.Context) {...}) + } + r.Run() +} +``` + +路由组也是支持嵌套的,例如: + +```go +shopGroup := r.Group("/shop") + { + shopGroup.GET("/index", func(c *gin.Context) {...}) + shopGroup.GET("/cart", func(c *gin.Context) {...}) + shopGroup.POST("/checkout", func(c *gin.Context) {...}) + // 嵌套路由组 + xx := shopGroup.Group("xx") + xx.GET("/oo", func(c *gin.Context) {...}) + } +``` + +通常我们将路由分组用在划分业务逻辑或划分API版本时。 + +### 路由原理 + +Gin框架中的路由使用的是[httprouter](https://github.com/julienschmidt/httprouter)这个库。 + +其基本原理就是构造一个路由地址的前缀树。 + +## Gin中间件 + +Gin框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数。这个钩子函数就叫中间件,中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志、耗时统计等。 + +### 定义中间件 + +Gin中的中间件必须是一个`gin.HandlerFunc`类型。例如我们像下面的代码一样定义一个统计请求耗时的中间件。 + +```go +// StatCost 是一个统计耗时请求耗时的中间件 +func StatCost() gin.HandlerFunc { + return func(c *gin.Context) { + start := time.Now() + c.Set("name", "小王子") // 可以通过c.Set在请求上下文中设置值,后续的处理函数能够取到该值 + // 调用该请求的剩余处理程序 + c.Next() + // 不调用该请求的剩余处理程序 + // c.Abort() + // 计算耗时 + cost := time.Since(start) + log.Println(cost) + } +} +``` + +### 注册中间件 + +在gin框架中,我们可以为每个路由添加任意数量的中间件。 + +![image-20200917210942305](images/image-20200917210942305.png) + +![image-20200917211033323](images/image-20200917211033323.png) + +中间的这个通过 Abort() 可以阻止执行 + +![image-20200917211259531](images/image-20200917211259531.png) + +#### 为全局路由注册 + +```go +func main() { + // 新建一个没有任何默认中间件的路由 + r := gin.New() + // 注册一个全局中间件 + r.Use(StatCost()) + + r.GET("/test", func(c *gin.Context) { + name := c.MustGet("name").(string) // 从上下文取值 + log.Println(name) + c.JSON(http.StatusOK, gin.H{ + "message": "Hello world!", + }) + }) + r.Run() +} +``` + +#### 为某个路由单独注册 + +```go +// 给/test2路由单独注册中间件(可注册多个) + r.GET("/test2", StatCost(), func(c *gin.Context) { + name := c.MustGet("name").(string) // 从上下文取值 + log.Println(name) + c.JSON(http.StatusOK, gin.H{ + "message": "Hello world!", + }) + }) +``` + +#### 为路由组注册中间件 + +为路由组注册中间件有以下两种写法。 + +写法1: + +```go +shopGroup := r.Group("/shop", StatCost()) +{ + shopGroup.GET("/index", func(c *gin.Context) {...}) + ... +} +``` + +写法2: + +```go +shopGroup := r.Group("/shop") +shopGroup.Use(StatCost()) +{ + shopGroup.GET("/index", func(c *gin.Context) {...}) + ... +} +``` + +### 中间件注意事项 + +#### gin默认中间件 + +`gin.Default()`默认使用了`Logger`和`Recovery`中间件,其中: + +- `Logger`中间件将日志写入`gin.DefaultWriter`,即使配置了`GIN_MODE=release`。 +- `Recovery`中间件会recover任何`panic`。如果有panic的话,会写入500响应码。 + +如果不想使用上面两个默认的中间件,可以使用`gin.New()`新建一个没有任何默认中间件的路由。 + +#### gin中间件中使用goroutine + +当在中间件或`handler`中启动新的`goroutine`时,**不能使用**原始的上下文(c *gin.Context),必须使用其只读副本(`c.Copy()`)。 + +## 运行多个服务 + +我们可以在多个端口启动服务,例如: + +```go +package main + +import ( + "log" + "net/http" + "time" + + "github.com/gin-gonic/gin" + "golang.org/x/sync/errgroup" +) + +var ( + g errgroup.Group +) + +func router01() http.Handler { + e := gin.New() + e.Use(gin.Recovery()) + e.GET("/", func(c *gin.Context) { + c.JSON( + http.StatusOK, + gin.H{ + "code": http.StatusOK, + "error": "Welcome server 01", + }, + ) + }) + + return e +} + +func router02() http.Handler { + e := gin.New() + e.Use(gin.Recovery()) + e.GET("/", func(c *gin.Context) { + c.JSON( + http.StatusOK, + gin.H{ + "code": http.StatusOK, + "error": "Welcome server 02", + }, + ) + }) + + return e +} + +func main() { + server01 := &http.Server{ + Addr: ":8080", + Handler: router01(), + ReadTimeout: 5 * time.Second, + WriteTimeout: 10 * time.Second, + } + + server02 := &http.Server{ + Addr: ":8081", + Handler: router02(), + ReadTimeout: 5 * time.Second, + WriteTimeout: 10 * time.Second, + } + // 借助errgroup.Group或者自行开启两个goroutine分别启动两个服务 + g.Go(func() error { + return server01.ListenAndServe() + }) + + g.Go(func() error { + return server02.ListenAndServe() + }) + + if err := g.Wait(); err != nil { + log.Fatal(err) + } +} +``` diff --git "a/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913201627904.png" "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913201627904.png" new file mode 100644 index 0000000000000000000000000000000000000000..caea60e275b2cbeaadb9a1a76e8f684b95ff8bea Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913201627904.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913201929752.png" "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913201929752.png" new file mode 100644 index 0000000000000000000000000000000000000000..4ad9aa83f286ccb0fddffcbac2c2b510c0d4fe91 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913201929752.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913202119089.png" "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913202119089.png" new file mode 100644 index 0000000000000000000000000000000000000000..e98dca4053f07b1ea386562e853ab553cd8f2c5b Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913202119089.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913203807251.png" "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913203807251.png" new file mode 100644 index 0000000000000000000000000000000000000000..4055623f05fab4bf8ce872657bbb111923542cbe Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913203807251.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913203922973.png" "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913203922973.png" new file mode 100644 index 0000000000000000000000000000000000000000..c83c5adf892cd523983dc0a92508d210fe5cd694 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913203922973.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913204456513.png" "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913204456513.png" new file mode 100644 index 0000000000000000000000000000000000000000..0ed36dcca17b1c9767baf98f81e930c95852b583 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913204456513.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913210316077.png" "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913210316077.png" new file mode 100644 index 0000000000000000000000000000000000000000..20f79f285b8ca12fbb96c87db3a6ff0617f057a5 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913210316077.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913213156919.png" "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913213156919.png" new file mode 100644 index 0000000000000000000000000000000000000000..8e3fd5a6cda927bf349ee6b3867f68dc97be394c Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200913213156919.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200917210942305.png" "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200917210942305.png" new file mode 100644 index 0000000000000000000000000000000000000000..7281cc75387737866da0f00d84ce69f97c19a836 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200917210942305.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200917211033323.png" "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200917211033323.png" new file mode 100644 index 0000000000000000000000000000000000000000..8695b164304731062eb1ce4970da328c8575b62e Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200917211033323.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200917211259531.png" "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200917211259531.png" new file mode 100644 index 0000000000000000000000000000000000000000..b1f5e56045cfca7961f5caeea15c8a8d4aaee3aa Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/1_Gin\345\206\205\345\256\271\344\273\213\347\273\215/images/image-20200917211259531.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/README.md" "b/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..2701e57f3b8940263141dd91839c71cc67ac6dc8 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/README.md" @@ -0,0 +1,673 @@ +# http及Template介绍 + +## 来源 + +https://www.liwenzhou.com/posts/Go/go_template/ + +## 介绍 + +`html/template`包实现了数据驱动的模板,用于生成可防止代码注入的安全的HTML内容。它提供了和`text/template`包相同的接口,Go语言中输出HTML的场景都应使用`html/template`这个包。 + +## 模板与渲染 + +在一些前后端不分离的Web架构中,我们通常需要在后端将一些数据渲染到HTML文档中,从而实现动态的网页(网页的布局和样式大致一样,但展示的内容并不一样)效果。 + +我们这里说的模板可以理解为事先定义好的HTML文档文件,模板渲染的作用机制可以简单理解为文本替换操作–使用相应的数据去替换HTML文档中事先准备好的标记。 + +很多编程语言的Web框架中都使用各种模板引擎,比如Python语言中Flask框架中使用的jinja2模板引擎。 + +## Go语言的模板引擎 + +Go语言内置了文本模板引擎`text/template`和用于HTML文档的`html/template`。它们的作用机制可以简单归纳如下: + +1. 模板文件通常定义为`.tmpl`和`.tpl`为后缀(也可以使用其他的后缀),必须使用`UTF8`编码。 +2. 模板文件中使用`{{`和`}}`包裹和标识需要传入的数据。 +3. 传给模板这样的数据就可以通过点号(`.`)来访问,如果数据是复杂类型的数据,可以通过{ { .FieldName }}来访问它的字段。 +4. 除`{{`和`}}`包裹的内容外,其他内容均不做修改原样输出。 + +## 模板引擎的使用 + +Go语言模板引擎的使用可以分为三部分:定义模板文件、解析模板文件和模板渲染. + +### 定义模板文件 + +其中,定义模板文件时需要我们按照相关语法规则去编写,后文会详细介绍。 + +### 解析模板文件 + +上面定义好了模板文件之后,可以使用下面的常用方法去解析模板文件,得到模板对象: + +```go +func (t *Template) Parse(src string) (*Template, error) +func ParseFiles(filenames ...string) (*Template, error) +func ParseGlob(pattern string) (*Template, error) +``` + +当然,你也可以使用`func New(name string) *Template`函数创建一个名为`name`的模板,然后对其调用上面的方法去解析模板字符串或模板文件。 + +### 模板渲染 + +渲染模板简单来说就是使用数据去填充模板,当然实际上可能会复杂很多。 + +```go +func (t *Template) Execute(wr io.Writer, data interface{}) error +func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error +``` + +### 基本示例 + +#### 定义模板文件 + +我们按照Go模板语法定义一个`hello.tmpl`的模板文件,内容如下: + +```html + + + + hello + + +

hello golang

+

hello {{.}}

+ + +``` + +#### 解析和渲染模板文件 + +然后我们创建一个`main.go`文件,在其中写下HTTP server端代码如下: + +```go +package main + +import ( + "fmt" + "html/template" + "net/http" + "os" +) + +func sayHello(w http.ResponseWriter, r *http.Request) { + // 获取项目的绝对路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + fmt.Println("wd:", wd + "\\lesson04\\hello.tmpl") + // 解析指定文件生成模板对象 + tmpl, err := template.ParseFiles( wd + "\\lesson04\\hello.tmpl") + + if err != nil { + fmt.Println("create template failed, err:", err) + return + } + // 利用给定数据渲染模板,并将结果写入w + tmpl.Execute(w, "沙河小王子") +} +func main() { + http.HandleFunc("/", sayHello) + err := http.ListenAndServe(":9090", nil) + if err != nil { + fmt.Println("HTTP server failed,err:", err) + return + } +} +``` + +将上面的`main.go`文件编译执行,然后使用浏览器访问`http://127.0.0.1:9090`就能看到页面上显示了“Hello 沙河小王子”。 这就是一个最简单的模板渲染的示例,Go语言模板引擎详细用法请往下阅读。+ + +得到运行结果 + +![image-20200914201109380](images/image-20200914201109380.png) + +## 模板语法 + +### {{.}} + +模板语法都包含在`{{`和`}}`中间,其中`{{.}}`中的点表示当前对象。 + +当我们传入一个结构体对象时,我们可以根据`.`来访问结构体的对应字段。例如: + +```go +package main + +import ( + "fmt" + "html/template" + "net/http" + "os" +) + +//定义用户结构体 +type User struct { + Name string + Gender string + Age int +} + +func sayHello(w http.ResponseWriter, r *http.Request) { + // 获取项目的绝对路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + fmt.Println("wd:", wd + "\\lesson05\\hello.tmpl") + // 解析指定文件生成模板对象 + tmpl, err := template.ParseFiles( wd + "\\lesson05\\hello.tmpl") + + if err != nil { + fmt.Println("create template failed, err:", err) + return + } + + u1 := User{ + Name: "小王子", + Gender: "男", + Age: 10, + } + + // 利用给定数据渲染模板,并将结果写入w + tmpl.Execute(w, u1) +} +func main() { + http.HandleFunc("/", sayHello) + err := http.ListenAndServe(":9090", nil) + if err != nil { + fmt.Println("HTTP server failed,err:", err) + return + } +} +``` + +模板文件`hello.tmpl`内容如下: + +```html + + + + + + + Hello + + +

姓名: {{.Name}}

+

性别: {{.Gender}}

+

年龄: {{.Age}}

+ + +``` + +在浏览器输入如下网址 + +```bash +http://localhost:9090/sayHello +``` + +能够渲染出我们结构体中的值 + +![image-20200914205920172](images/image-20200914205920172.png) + +同理,当我们传入的变量是map时,也可以在模板文件中通过`.`根据key来取值。 + +```go + +// 采用一个map +m1 := map[string]interface{}{ + "Name": "小王子", + "Age": 18, + "Gender": "男", +} + +// 利用给定数据渲染模板,并将结果写入w +tmpl.Execute(w, m1) +``` + +如果我们想把map 和 结构体都传递到前端,那么就需要在定义一个大的map来进行存储 + +```bash + // 采用结构体 + u1 := User{ + Name: "小王子", + Gender: "男", + Age: 10, + } + + // 采用一个map + m1 := map[string]interface{}{ + "Name": "小王子", + "Age": 18, + "Gender": "男", + } + + m2 := map[string]interface{}{ + "map": m1, + "user": u1, + } +``` + + + +### 注释 + +```template +{{/* a comment */}} +注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止。 +``` + +### pipeline + +`pipeline`是指产生数据的操作。比如`{{.}}`、`{{.Name}}`等。Go的模板语法中支持使用管道符号`|`链接多个命令,用法和unix下的管道类似:`|`前面的命令会将运算结果(或返回值)传递给后一个命令的最后一个位置。 + +**注意:**并不是只有使用了`|`才是pipeline。Go的模板语法中,`pipeline的`概念是传递数据,只要能产生数据的,都是`pipeline`。 + +### 变量 + +我们还可以在模板中声明变量,用来保存传入模板的数据或其他语句生成的结果。具体语法如下: + +```template +$obj := {{.}} +``` + +其中`$obj`是变量的名字,在后续的代码中就可以使用该变量了。 + +### 移除空格 + +有时候我们在使用模板语法的时候会不可避免的引入一下空格或者换行符,这样模板最终渲染出来的内容可能就和我们想的不一样,这个时候可以使用`{{-`语法去除模板内容左侧的所有空白符号, 使用`-}}`去除模板内容右侧的所有空白符号。 + +例如: + +```template +{{- .Name -}} +``` + +**注意:**`-`要紧挨`{{`和`}}`,同时与模板值之间需要使用空格分隔。 + +### 条件判断 + +Go模板语法中的条件判断有以下几种: + +```template +{{if pipeline}} T1 {{end}} + +{{if pipeline}} T1 {{else}} T0 {{end}} + +{{if pipeline}} T1 {{else if pipeline}} T0 {{end}} +``` + +### range + +Go的模板语法中使用`range`关键字进行遍历,有以下两种写法,其中`pipeline`的值必须是数组、切片、字典或者通道。 + +```template +{{range pipeline}} T1 {{end}} +如果pipeline的值其长度为0,不会有任何输出 + +{{range pipeline}} T1 {{else}} T0 {{end}} +如果pipeline的值其长度为0,则会执行T0。 +``` + +### with + +```template +{{with pipeline}} T1 {{end}} +如果pipeline为empty不产生输出,否则将dot设为pipeline的值并执行T1。不修改外面的dot。 + +{{with pipeline}} T1 {{else}} T0 {{end}} +如果pipeline为empty,不改变dot并执行T0,否则dot设为pipeline的值并执行T1。 +``` + +### 预定义函数 + +执行模板时,函数从两个函数字典中查找:首先是模板函数字典,然后是全局函数字典。一般不在模板内定义函数,而是使用Funcs方法添加函数到模板里。 + +预定义的全局函数如下: + +```template +and + 函数返回它的第一个empty参数或者最后一个参数; + 就是说"and x y"等价于"if x then y else x";所有参数都会执行; +or + 返回第一个非empty参数或者最后一个参数; + 亦即"or x y"等价于"if x then x else y";所有参数都会执行; +not + 返回它的单个参数的布尔值的否定 +len + 返回它的参数的整数类型长度 +index + 执行结果为第一个参数以剩下的参数为索引/键指向的值; + 如"index x 1 2 3"返回x[1][2][3]的值;每个被索引的主体必须是数组、切片或者字典。 +print + 即fmt.Sprint +printf + 即fmt.Sprintf +println + 即fmt.Sprintln +html + 返回与其参数的文本表示形式等效的转义HTML。 + 这个函数在html/template中不可用。 +urlquery + 以适合嵌入到网址查询中的形式返回其参数的文本表示的转义值。 + 这个函数在html/template中不可用。 +js + 返回与其参数的文本表示形式等效的转义JavaScript。 +call + 执行结果是调用第一个参数的返回值,该参数必须是函数类型,其余参数作为调用该函数的参数; + 如"call .X.Y 1 2"等价于go语言里的dot.X.Y(1, 2); + 其中Y是函数类型的字段或者字典的值,或者其他类似情况; + call的第一个参数的执行结果必须是函数类型的值(和预定义函数如print明显不同); + 该函数类型值必须有1到2个返回值,如果有2个则后一个必须是error接口类型; + 如果有2个返回值的方法返回的error非nil,模板执行会中断并返回给调用模板执行者该错误; +``` + +### 比较函数 + +布尔函数会将任何类型的零值视为假,其余视为真。 + +下面是定义为函数的二元比较运算的集合: + +```template +eq 如果arg1 == arg2则返回真 +ne 如果arg1 != arg2则返回真 +lt 如果arg1 < arg2则返回真 +le 如果arg1 <= arg2则返回真 +gt 如果arg1 > arg2则返回真 +ge 如果arg1 >= arg2则返回真 +``` + +为了简化多参数相等检测,eq(只有eq)可以接受2个或更多个参数,它会将第一个参数和其余参数依次比较,返回下式的结果: + +```template +{{eq arg1 arg2 arg3}} +``` + +比较函数只适用于基本类型(或重定义的基本类型,如”type Celsius float32”)。但是,整数和浮点数不能互相比较。 + +### 自定义函数 + +Go的模板支持自定义函数。 + +```go +package main + +import ( + "fmt" + "html/template" + "net/http" + "os" +) + +/** + * @Description f1函数 + * @Param + * @return + **/ +func f1(w http.ResponseWriter, r *http.Request) { + // 定义模板 + // 解析模板 + // 获取项目的绝对路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + + // 定义一个自定义函数 + // 要么只有一个返回值,要么有两个返回值,第二个返回值必须是error类型 + kua := func(name string)(string, error) { + return name + "年轻又帅气!", nil + } + + // 创建一个名字为f的模板对象。注意,这个名字一定要和模板的名字对应上 + tmpl := template.New("hello.tmpl") + + // 告诉模板引擎,我现在多了一个自定义的函数kua + tmpl.Funcs(template.FuncMap{ + "kua": kua, + }) + + // 解析模板 + _, err = tmpl.ParseFiles( wd + "\\lesson06\\hello.tmpl") + if err != nil { + fmt.Printf("parse template failed, err:%v \n", err) + return + } + + // 采用一个map + m1 := map[string]interface{}{ + "Name": "小王子", + "Age": 18, + "Gender": "男", + } + + // 渲染模板 + tmpl.Execute(w, m1) +} +func main() { + http.HandleFunc("/hello", f1) + err := http.ListenAndServe(":9090", nil) + if err != nil { + fmt.Println("HTTP server failed,err:", err) + return + } +} +``` + +我们可以在模板文件`hello.tmpl`中按照如下方式使用我们自定义的`kua`函数了。 + +```template +{{kua .Name}} +``` + +最后运行的结果 + +![image-20200916101259659](images/image-20200916101259659.png) + +### 模板的嵌套template + +我们可以在template中嵌套其他的template。这个template可以是单独的文件,也可以是通过`define`定义的template。 + +举个例子: `t.tmpl`文件内容如下: + +```template + + + + + + + tmpl test + + + +

测试嵌套template语法

+
+ {{template "ul.tmpl"}} +
+ {{template "ol.tmpl"}} + + + +{{ define "ol.tmpl"}} +
    +
  1. 吃饭
  2. +
  3. 睡觉
  4. +
  5. 打豆豆
  6. +
+{{end}} +``` + +`ul.tmpl`文件内容如下: + +```template +
    +
  • 注释
  • +
  • 日志
  • +
  • 测试
  • +
+``` + +我们注册一个`templDemo`路由处理函数. + +```go +http.HandleFunc("/tmpl", tmplDemo) +``` + +`tmplDemo`函数的具体内容如下: + +```go +func tmplDemo(w http.ResponseWriter, r *http.Request) { + tmpl, err := template.ParseFiles("./t.tmpl", "./ul.tmpl") + if err != nil { + fmt.Println("create template failed, err:", err) + return + } + user := UserInfo{ + Name: "小王子", + Gender: "男", + Age: 18, + } + tmpl.Execute(w, user) +} +``` + +**注意**:在解析模板时,被嵌套的模板一定要在后面解析,例如上面的示例中`t.tmpl`模板中嵌套了`ul.tmpl`,所以`ul.tmpl`要在`t.tmpl`后进行解析。 + +### block + +```template +{{block "name" pipeline}} T1 {{end}} +``` + +`block`是定义模板`{{define "name"}} T1 {{end}}`和执行`{{template "name" pipeline}}`缩写,典型的用法是定义一组根模板,然后通过在其中重新定义块模板进行自定义。 + +定义一个根模板`templates/base.tmpl`,内容如下: + +```template + + + + Go Templates + + +
+ {{block "content" . }}{{end}} +
+ + +``` + +然后定义一个`templates/index.tmpl`,”继承”`base.tmpl`: + +```tempalte +{{template "base.tmpl"}} + +{{define "content"}} +
Hello world!
+{{end}} +``` + +然后使用`template.ParseGlob`按照正则匹配规则解析模板文件,然后通过`ExecuteTemplate`渲染指定的模板: + +```go +func index(w http.ResponseWriter, r *http.Request){ + tmpl, err := template.ParseGlob("templates/*.tmpl") + if err != nil { + fmt.Println("create template failed, err:", err) + return + } + err = tmpl.ExecuteTemplate(w, "index.tmpl", nil) + if err != nil { + fmt.Println("render template failed, err:", err) + return + } +} +``` + +如果我们的模板名称冲突了,例如不同业务线下都定义了一个`index.tmpl`模板,我们可以通过下面两种方法来解决。 + +1. 在模板文件开头使用`{{define 模板名}}`语句显式的为模板命名。 +2. 可以把模板文件存放在`templates`文件夹下面的不同目录中,然后使用`template.ParseGlob("templates/**/*.tmpl")`解析模板。 + +### 修改默认的标识符 + +Go标准库的模板引擎使用的花括号`{{`和`}}`作为标识,而许多前端框架(如`Vue`和 `AngularJS`)也使用`{{`和`}}`作为标识符,所以当我们同时使用Go语言模板引擎和以上前端框架时就会出现冲突,这个时候我们需要修改标识符,修改前端的或者修改Go语言的。这里演示如何修改Go语言模板引擎默认的标识符: + +```go +template.New("test").Delims("{[", "]}").ParseFiles("./t.tmpl") +``` + +最后我们在渲染的时候 + +```html + + + + + + + 自定义模板函数 + + +

姓名: {[.Name]}

+

性别: {[.Gender]}

+

年龄: {[.Age]}

+ + +``` + +最后运行结果,发现也能够正常显示 + +![image-20200916214044623](images/image-20200916214044623.png) + +## text/template与html/tempalte的区别 + +`html/template`针对的是需要返回HTML内容的场景,在模板渲染过程中会对一些有风险的内容进行转义,以此来防范跨站脚本攻击。 + +例如,我定义下面的模板文件: + +```template + + + + + + + Hello + + + {{.}} + + +``` + +这个时候传入一段JS代码并使用`html/template`去渲染该文件,会在页面上显示出转义后的JS内容。 `alert('嘿嘿嘿')` 这就是`html/template`为我们做的事。 + +但是在某些场景下,我们如果相信用户输入的内容,不想转义的话,可以自行编写一个safe函数,手动返回一个`template.HTML`类型的内容。示例如下: + +```go +func xss(w http.ResponseWriter, r *http.Request){ + tmpl,err := template.New("xss.tmpl").Funcs(template.FuncMap{ + "safe": func(s string)template.HTML { + return template.HTML(s) + }, + }).ParseFiles("./xss.tmpl") + if err != nil { + fmt.Println("create template failed, err:", err) + return + } + jsStr := `` + err = tmpl.Execute(w, jsStr) + if err != nil { + fmt.Println(err) + } +} +``` + +这样我们只需要在模板文件不需要转义的内容后面使用我们定义好的safe函数就可以了。 + +```template +{{ . | safe }} +``` \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/images/image-20200914201109380.png" "b/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/images/image-20200914201109380.png" new file mode 100644 index 0000000000000000000000000000000000000000..e214120b29afa1754d7b209fd1023e49fe8ef05d Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/images/image-20200914201109380.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/images/image-20200914205920172.png" "b/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/images/image-20200914205920172.png" new file mode 100644 index 0000000000000000000000000000000000000000..f1e4169760d6573112a7d2dade36e114de6c1394 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/images/image-20200914205920172.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/images/image-20200916101259659.png" "b/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/images/image-20200916101259659.png" new file mode 100644 index 0000000000000000000000000000000000000000..f240befbb0d62e7c2bba6ebdda362dfd8dd88a1f Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/images/image-20200916101259659.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/images/image-20200916214044623.png" "b/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/images/image-20200916214044623.png" new file mode 100644 index 0000000000000000000000000000000000000000..31adcc0289254f61235927e582949ee1b8d90f3e Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/2_http\345\217\212Template\344\273\213\347\273\215/images/image-20200916214044623.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/3_GORM\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/README.md" "b/Golang/Gin\346\241\206\346\236\266/3_GORM\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..17b071fb936297da74c61489660192167cc6f7d1 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/3_GORM\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/README.md" @@ -0,0 +1,414 @@ +# GORM介绍和使用 + +## 来源 + +- https://www.liwenzhou.com/posts/Go/gorm/ +- https://www.liwenzhou.com/posts/Go/gorm_crud/ + +## 什么是ORM + +Object Relational Mapping:对象关系映射 + +![image-20200917213143434](images/image-20200917213143434.png) + +结构体 和 SQL数据库存在映射,这个时候就有了ORM语句 + +![image-20200917213229165](images/image-20200917213229165.png) + +一句话说:就是将数据库中的表数据 和 结构体进行对应的关系 + +![image-20200917213306696](images/image-20200917213306696.png) + +## ORM的优缺点 + +**优点:** + +- 提高开发效率 + +**缺点:** + +- 牺牲执行性能【中间多了一个环节】 +- 牺牲灵活性 +- 弱化SQL能力 + +## gorm介绍 + +[Github GORM](https://github.com/jinzhu/gorm) + +[中文官方网站](https://gorm.io/zh_CN/)内含十分齐全的中文文档,有了它你甚至不需要再继续向下阅读本文。 + +gorm是一个使用Go语言编写的ORM框架。它文档齐全,对开发者友好,支持主流数据库。 + +## 安装 + +```bash +go get -u github.com/jinzhu/gorm +``` + +## 连接数据库 + +连接不同的数据库都需要导入对应数据的驱动程序,`GORM`已经贴心的为我们包装了一些驱动程序,只需要按如下方式导入需要的数据库驱动即可: + +```go +import _ "github.com/jinzhu/gorm/dialects/mysql" +// import _ "github.com/jinzhu/gorm/dialects/postgres" +// import _ "github.com/jinzhu/gorm/dialects/sqlite" +// import _ "github.com/jinzhu/gorm/dialects/mssql" +``` + +### 连接MySQL + +```go +import ( + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mysql" +) + +func main() { + db, err := gorm.Open("mysql", "user:password@(localhost)/dbname?charset=utf8mb4&parseTime=True&loc=Local") + defer db.Close() +} +``` + +### 连接PostgreSQL + +基本代码同上,注意引入对应`postgres`驱动并正确指定`gorm.Open()`参数。 + +```go +import ( + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/postgres" +) + +func main() { + db, err := gorm.Open("postgres", "host=myhost port=myport user=gorm dbname=gorm password=mypassword") + defer db.Close() +} +``` + +### 连接Sqlite3 + +基本代码同上,注意引入对应`sqlite`驱动并正确指定`gorm.Open()`参数。 + +```go +import ( + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/sqlite" +) + +func main() { + db, err := gorm.Open("sqlite3", "/tmp/gorm.db") + defer db.Close() +} +``` + +### 连接SQL Server + +基本代码同上,注意引入对应`mssql`驱动并正确指定`gorm.Open()`参数。 + +```go +import ( + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mssql" +) + +func main() { + db, err := gorm.Open("mssql", "sqlserver://username:password@localhost:1433?database=dbname") + defer db.Close() +} +``` + +## GORM基本示例 + +**注意:** + +1. 本文以MySQL数据库为例,讲解GORM各项功能的主要使用方法。 +2. 往下阅读本文前,你需要有一个能够成功连接上的MySQL数据库实例。 + +### Docker快速创建MySQL实例 + +很多同学如果不会安装MySQL或者懒得安装MySQL,可以使用一下命令快速运行一个MySQL8.0.19实例,当然前提是你要有docker环境… + +在本地的`13306`端口运行一个名为`mysql8019`,root用户名密码为`root1234`的MySQL容器环境: + +```bash +docker run --name mysql8019 -p 13306:3306 -e MYSQL_ROOT_PASSWORD=root1234 -d mysql:8.0.19 +``` + +在另外启动一个`MySQL Client`连接上面的MySQL环境,密码为上一步指定的密码`root1234`: + +```bash +docker run -it --network host --rm mysql mysql -h127.0.0.1 -P13306 --default-character-set=utf8mb4 -uroot -p +``` + +### 创建数据库 + +在使用GORM前手动创建数据库`db1`: + +```mysql +CREATE DATABASE db1; +``` + +### GORM操作MySQL + +使用GORM连接上面的`db1`进行创建、查询、更新、删除操作。 + +```go +package main + +import ( + "fmt" + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mysql" +) + +// UserInfo 用户信息 +type UserInfo struct { + ID uint + Name string + Gender string + Hobby string +} + + +func main() { + db, err := gorm.Open("mysql", "root:root1234@(127.0.0.1:13306)/db1?charset=utf8mb4&parseTime=True&loc=Local") + if err!= nil{ + panic(err) + } + defer db.Close() + + // 自动迁移 + db.AutoMigrate(&UserInfo{}) + + u1 := UserInfo{1, "七米", "男", "篮球"} + u2 := UserInfo{2, "沙河娜扎", "女", "足球"} + // 创建记录 + db.Create(&u1) + db.Create(&u2) + // 查询 + var u = new(UserInfo) + db.First(u) + fmt.Printf("%#v\n", u) + + var uu UserInfo + db.Find(&uu, "hobby=?", "足球") + fmt.Printf("%#v\n", uu) + + // 更新 + db.Model(&u).Update("hobby", "双色球") + // 删除 + db.Delete(&u) +} +``` + +## GORM Model定义 + +在使用ORM工具时,通常我们需要在代码中定义模型(Models)与数据库中的数据表进行映射,在GORM中模型(Models)通常是正常定义的结构体、基本的go类型或它们的指针。 同时也支持`sql.Scanner`及`driver.Valuer`接口(interfaces)。 + +### gorm.Model + +为了方便模型定义,GORM内置了一个`gorm.Model`结构体。`gorm.Model`是一个包含了`ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`四个字段的Golang结构体。 + +```go +// gorm.Model 定义 +type Model struct { + ID uint `gorm:"primary_key"` + CreatedAt time.Time + UpdatedAt time.Time + DeletedAt *time.Time +} +``` + +你可以将它嵌入到你自己的模型中: + +```go +// 将 `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`字段注入到`User`模型中 +type User struct { + gorm.Model + Name string +} +``` + +当然你也可以完全自己定义模型: + +```go +// 不使用gorm.Model,自行定义模型 +type User struct { + ID int + Name string +} +``` + +### 模型定义示例 + +```go +type User struct { + gorm.Model + Name string + Age sql.NullInt64 + Birthday *time.Time + Email string `gorm:"type:varchar(100);unique_index"` + Role string `gorm:"size:255"` // 设置字段大小为255 + MemberNumber *string `gorm:"unique;not null"` // 设置会员号(member number)唯一并且不为空 + Num int `gorm:"AUTO_INCREMENT"` // 设置 num 为自增类型 + Address string `gorm:"index:addr"` // 给address字段创建名为addr的索引 + IgnoreMe int `gorm:"-"` // 忽略本字段 +} +``` + +### 结构体标记(tags) + +使用结构体声明模型时,标记(tags)是可选项。gorm支持以下标记: + +#### 支持的结构体标记(Struct tags) + +| 结构体标记(Tag) | 描述 | +| :---------------: | :------------------------------------------------------: | +| Column | 指定列名 | +| Type | 指定列数据类型 | +| Size | 指定列大小, 默认值255 | +| PRIMARY_KEY | 将列指定为主键 | +| UNIQUE | 将列指定为唯一 | +| DEFAULT | 指定列默认值 | +| PRECISION | 指定列精度 | +| NOT NULL | 将列指定为非 NULL | +| AUTO_INCREMENT | 指定列是否为自增类型 | +| INDEX | 创建具有或不带名称的索引, 如果多个索引同名则创建复合索引 | +| UNIQUE_INDEX | 和 `INDEX` 类似,只不过创建的是唯一索引 | +| EMBEDDED | 将结构设置为嵌入 | +| EMBEDDED_PREFIX | 设置嵌入结构的前缀 | +| - | 忽略此字段 | + +#### 关联相关标记(tags) + +| 结构体标记(Tag) | 描述 | +| :------------------------------: | :--------------------------------: | +| MANY2MANY | 指定连接表 | +| FOREIGNKEY | 设置外键 | +| ASSOCIATION_FOREIGNKEY | 设置关联外键 | +| POLYMORPHIC | 指定多态类型 | +| POLYMORPHIC_VALUE | 指定多态值 | +| JOINTABLE_FOREIGNKEY | 指定连接表的外键 | +| ASSOCIATION_JOINTABLE_FOREIGNKEY | 指定连接表的关联外键 | +| SAVE_ASSOCIATIONS | 是否自动完成 save 的相关操作 | +| ASSOCIATION_AUTOUPDATE | 是否自动完成 update 的相关操作 | +| ASSOCIATION_AUTOCREATE | 是否自动完成 create 的相关操作 | +| ASSOCIATION_SAVE_REFERENCE | 是否自动完成引用的 save 的相关操作 | +| PRELOAD | 是否自动完成预加载的相关操作 | + +## 主键、表名、列名的约定 + +### 主键(Primary Key) + +GORM 默认会使用名为ID的字段作为表的主键。 + +```go +type User struct { + ID string // 名为`ID`的字段会默认作为表的主键 + Name string +} + +// 使用`AnimalID`作为主键 +type Animal struct { + AnimalID int64 `gorm:"primary_key"` + Name string + Age int64 +} +``` + +### 表名(Table Name) + +表名默认就是结构体名称的复数,例如: + +```go +type User struct {} // 默认表名是 `users` + +// 将 User 的表名设置为 `profiles` +func (User) TableName() string { + return "profiles" +} + +func (u User) TableName() string { + if u.Role == "admin" { + return "admin_users" + } else { + return "users" + } +} + +// 禁用默认表名的复数形式,如果置为 true,则 `User` 的默认表名是 `user` +db.SingularTable(true) +``` + +也可以通过`Table()`指定表名: + +```go +// 使用User结构体创建名为`deleted_users`的表 +db.Table("deleted_users").CreateTable(&User{}) + +var deleted_users []User +db.Table("deleted_users").Find(&deleted_users) +//// SELECT * FROM deleted_users; + +db.Table("deleted_users").Where("name = ?", "jinzhu").Delete() +//// DELETE FROM deleted_users WHERE name = 'jinzhu'; +``` + +GORM还支持更改默认表名称规则: + +```go +gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string { + return "prefix_" + defaultTableName; +} +``` + +### 列名(Column Name) + +列名由字段名称进行下划线分割来生成 + +```go +type User struct { + ID uint // column name is `id` + Name string // column name is `name` + Birthday time.Time // column name is `birthday` + CreatedAt time.Time // column name is `created_at` +} +``` + +可以使用结构体tag指定列名: + +```go +type Animal struct { + AnimalId int64 `gorm:"column:beast_id"` // set column name to `beast_id` + Birthday time.Time `gorm:"column:day_of_the_beast"` // set column name to `day_of_the_beast` + Age int64 `gorm:"column:age_of_the_beast"` // set column name to `age_of_the_beast` +} +``` + +### 时间戳跟踪 + +#### CreatedAt + +如果模型有 `CreatedAt`字段,该字段的值将会是初次创建记录的时间。 + +```go +db.Create(&user) // `CreatedAt`将会是当前时间 + +// 可以使用`Update`方法来改变`CreateAt`的值 +db.Model(&user).Update("CreatedAt", time.Now()) +``` + +#### UpdatedAt + +如果模型有`UpdatedAt`字段,该字段的值将会是每次更新记录的时间。 + +```go +db.Save(&user) // `UpdatedAt`将会是当前时间 + +db.Model(&user).Update("name", "jinzhu") // `UpdatedAt`将会是当前时间 +``` + +#### DeletedAt + +如果模型有`DeletedAt`字段,调用`Delete`删除该记录时,将会设置`DeletedAt`字段为当前时间,而不是直接将记录从数据库中删除。 \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/3_GORM\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200917213143434.png" "b/Golang/Gin\346\241\206\346\236\266/3_GORM\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200917213143434.png" new file mode 100644 index 0000000000000000000000000000000000000000..96441e2fb7a6c5076b36252da1f596bd5c72609b Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/3_GORM\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200917213143434.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/3_GORM\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200917213229165.png" "b/Golang/Gin\346\241\206\346\236\266/3_GORM\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200917213229165.png" new file mode 100644 index 0000000000000000000000000000000000000000..0bd53b7477bae0399a9f7ca4060e47af8142c7b2 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/3_GORM\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200917213229165.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/3_GORM\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200917213306696.png" "b/Golang/Gin\346\241\206\346\236\266/3_GORM\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200917213306696.png" new file mode 100644 index 0000000000000000000000000000000000000000..1d14fa1a0ed6c09889a36ea0450938ca27284e08 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/3_GORM\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200917213306696.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/4_GORM\350\277\233\350\241\214CURD/README.md" "b/Golang/Gin\346\241\206\346\236\266/4_GORM\350\277\233\350\241\214CURD/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ff781f76a9ddcdb4b5b84145d2450557e78bbcfc --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/4_GORM\350\277\233\350\241\214CURD/README.md" @@ -0,0 +1,847 @@ +# GORM CRUD指南 + +## 来源 + +https://www.liwenzhou.com/posts/Go/gorm_crud/ + +## 介绍 + +CRUD通常指数据库的增删改查操作,本文详细介绍了如何使用GORM实现创建、查询、更新和删除操作。 + +# CRUD + +CRUD通常指数据库的增删改查操作,本文详细介绍了如何使用GORM实现创建、查询、更新和删除操作。 + +本文中的`db`变量为`*gorm.DB`对象,例如: + +```go +import ( + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mysql" +) + +func main() { + db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local") + defer db.Close() + + // db.Xx +} +``` + +## 创建 + +### 创建记录 + +首先定义模型: + +```go +type User struct { + ID int64 + Name string + Age int64 +} +``` + +使用使用`NewRecord()`查询主键是否存在,主键为空使用`Create()`创建记录: + +```go +user := User{Name: "q1mi", Age: 18} + +db.NewRecord(user) // 主键为空返回`true` +db.Create(&user) // 创建user +db.NewRecord(user) // 创建`user`后返回`false` +``` + +### 默认值 + +可以通过 tag 定义字段的默认值,比如: + +```go +type User struct { + ID int64 + Name string `gorm:"default:'小王子'"` + Age int64 +} +``` + +**注意:**通过tag定义字段的默认值,在创建记录时候生成的 SQL 语句会排除没有值或值为 零值 的字段。 在将记录插入到数据库后,Gorm会从数据库加载那些字段的默认值。 + +举个例子: + +```go +var user = User{Name: "", Age: 99} +db.Create(&user) +``` + +上面代码实际执行的SQL语句是`INSERT INTO users("age") values('99');`,排除了零值字段`Name`,而在数据库中这一条数据会使用设置的默认值`小王子`作为Name字段的值。 + +**注意:**所有字段的零值, 比如`0`, `""`,`false`或者其它`零值`,都不会保存到数据库内,但会使用他们的默认值。 如果你想避免这种情况,可以考虑使用指针或实现 `Scanner/Valuer`接口,比如: + +#### 使用指针方式实现零值存入数据库 + +```go +// 使用指针 +type User struct { + ID int64 + Name *string `gorm:"default:'小王子'"` + Age int64 +} +user := User{Name: new(string), Age: 18))} +db.Create(&user) // 此时数据库中该条记录name字段的值就是'' +``` + +#### 使用Scanner/Valuer接口方式实现零值存入数据库 + +```go +// 使用 Scanner/Valuer +type User struct { + ID int64 + Name sql.NullString `gorm:"default:'小王子'"` // sql.NullString 实现了Scanner/Valuer接口 + Age int64 +} +user := User{Name: sql.NullString{"", true}, Age:18} +db.Create(&user) // 此时数据库中该条记录name字段的值就是'' +``` + +### 扩展创建选项 + +例如`PostgreSQL`数据库中可以使用下面的方式实现合并插入, 有则更新, 无则插入。 + +```go +// 为Instert语句添加扩展SQL选项 +db.Set("gorm:insert_option", "ON CONFLICT").Create(&product) +// INSERT INTO products (name, code) VALUES ("name", "code") ON CONFLICT; +``` + +## 查询 + +### 一般查询 + +```go +// 根据主键查询第一条记录 +db.First(&user) +//// SELECT * FROM users ORDER BY id LIMIT 1; + +// 随机获取一条记录 +db.Take(&user) +//// SELECT * FROM users LIMIT 1; + +// 根据主键查询最后一条记录 +db.Last(&user) +//// SELECT * FROM users ORDER BY id DESC LIMIT 1; + +// 查询所有的记录 +db.Find(&users) +//// SELECT * FROM users; + +// 查询指定的某条记录(仅当主键为整型时可用) +db.First(&user, 10) +//// SELECT * FROM users WHERE id = 10; +``` + +### Where 条件 + +#### 普通SQL查询 + +```go +// Get first matched record +db.Where("name = ?", "jinzhu").First(&user) +//// SELECT * FROM users WHERE name = 'jinzhu' limit 1; + +// Get all matched records +db.Where("name = ?", "jinzhu").Find(&users) +//// SELECT * FROM users WHERE name = 'jinzhu'; + +// <> +db.Where("name <> ?", "jinzhu").Find(&users) +//// SELECT * FROM users WHERE name <> 'jinzhu'; + +// IN +db.Where("name IN (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users) +//// SELECT * FROM users WHERE name in ('jinzhu','jinzhu 2'); + +// LIKE +db.Where("name LIKE ?", "%jin%").Find(&users) +//// SELECT * FROM users WHERE name LIKE '%jin%'; + +// AND +db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users) +//// SELECT * FROM users WHERE name = 'jinzhu' AND age >= 22; + +// Time +db.Where("updated_at > ?", lastWeek).Find(&users) +//// SELECT * FROM users WHERE updated_at > '2000-01-01 00:00:00'; + +// BETWEEN +db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users) +//// SELECT * FROM users WHERE created_at BETWEEN '2000-01-01 00:00:00' AND '2000-01-08 00:00:00'; +``` + +#### Struct & Map查询 + +```go +// Struct +db.Where(&User{Name: "jinzhu", Age: 20}).First(&user) +//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 LIMIT 1; + +// Map +db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users) +//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20; + +// 主键的切片 +db.Where([]int64{20, 21, 22}).Find(&users) +//// SELECT * FROM users WHERE id IN (20, 21, 22); +``` + +**提示:**当通过结构体进行查询时,GORM将会只通过非零值字段查询,这意味着如果你的字段值为`0`,`''`,`false`或者其他`零值`时,将不会被用于构建查询条件,例如: + +```go +db.Where(&User{Name: "jinzhu", Age: 0}).Find(&users) +//// SELECT * FROM users WHERE name = "jinzhu"; +``` + +你可以使用指针或实现 Scanner/Valuer 接口来避免这个问题. + +```go +// 使用指针 +type User struct { + gorm.Model + Name string + Age *int +} + +// 使用 Scanner/Valuer +type User struct { + gorm.Model + Name string + Age sql.NullInt64 // sql.NullInt64 实现了 Scanner/Valuer 接口 +} +``` + +### Not 条件 + +作用与 Where 类似的情形如下: + +```go +db.Not("name", "jinzhu").First(&user) +//// SELECT * FROM users WHERE name <> "jinzhu" LIMIT 1; + +// Not In +db.Not("name", []string{"jinzhu", "jinzhu 2"}).Find(&users) +//// SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2"); + +// Not In slice of primary keys +db.Not([]int64{1,2,3}).First(&user) +//// SELECT * FROM users WHERE id NOT IN (1,2,3); + +db.Not([]int64{}).First(&user) +//// SELECT * FROM users; + +// Plain SQL +db.Not("name = ?", "jinzhu").First(&user) +//// SELECT * FROM users WHERE NOT(name = "jinzhu"); + +// Struct +db.Not(User{Name: "jinzhu"}).First(&user) +//// SELECT * FROM users WHERE name <> "jinzhu"; +``` + +### Or条件 + +```go +db.Where("role = ?", "admin").Or("role = ?", "super_admin").Find(&users) +//// SELECT * FROM users WHERE role = 'admin' OR role = 'super_admin'; + +// Struct +db.Where("name = 'jinzhu'").Or(User{Name: "jinzhu 2"}).Find(&users) +//// SELECT * FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2'; + +// Map +db.Where("name = 'jinzhu'").Or(map[string]interface{}{"name": "jinzhu 2"}).Find(&users) +//// SELECT * FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2'; +``` + +### 内联条件 + +作用与`Where`查询类似,当内联条件与多个[立即执行方法](https://www.liwenzhou.com/posts/Go/gorm_crud/#autoid-1-3-1)一起使用时, 内联条件不会传递给后面的立即执行方法。 + +```go +// 根据主键获取记录 (只适用于整形主键) +db.First(&user, 23) +//// SELECT * FROM users WHERE id = 23 LIMIT 1; +// 根据主键获取记录, 如果它是一个非整形主键 +db.First(&user, "id = ?", "string_primary_key") +//// SELECT * FROM users WHERE id = 'string_primary_key' LIMIT 1; + +// Plain SQL +db.Find(&user, "name = ?", "jinzhu") +//// SELECT * FROM users WHERE name = "jinzhu"; + +db.Find(&users, "name <> ? AND age > ?", "jinzhu", 20) +//// SELECT * FROM users WHERE name <> "jinzhu" AND age > 20; + +// Struct +db.Find(&users, User{Age: 20}) +//// SELECT * FROM users WHERE age = 20; + +// Map +db.Find(&users, map[string]interface{}{"age": 20}) +//// SELECT * FROM users WHERE age = 20; +``` + +### 额外查询选项 + +```go +// 为查询 SQL 添加额外的 SQL 操作 +db.Set("gorm:query_option", "FOR UPDATE").First(&user, 10) +//// SELECT * FROM users WHERE id = 10 FOR UPDATE; +``` + +### FirstOrInit + +获取匹配的第一条记录,否则根据给定的条件初始化一个新的对象 (仅支持 struct 和 map 条件) + +```go +// 未找到 +db.FirstOrInit(&user, User{Name: "non_existing"}) +//// user -> User{Name: "non_existing"} + +// 找到 +db.Where(User{Name: "Jinzhu"}).FirstOrInit(&user) +//// user -> User{Id: 111, Name: "Jinzhu", Age: 20} +db.FirstOrInit(&user, map[string]interface{}{"name": "jinzhu"}) +//// user -> User{Id: 111, Name: "Jinzhu", Age: 20} +``` + +#### Attrs + +如果记录未找到,将使用参数初始化 struct. + +```go +// 未找到 +db.Where(User{Name: "non_existing"}).Attrs(User{Age: 20}).FirstOrInit(&user) +//// SELECT * FROM USERS WHERE name = 'non_existing'; +//// user -> User{Name: "non_existing", Age: 20} + +db.Where(User{Name: "non_existing"}).Attrs("age", 20).FirstOrInit(&user) +//// SELECT * FROM USERS WHERE name = 'non_existing'; +//// user -> User{Name: "non_existing", Age: 20} + +// 找到 +db.Where(User{Name: "Jinzhu"}).Attrs(User{Age: 30}).FirstOrInit(&user) +//// SELECT * FROM USERS WHERE name = jinzhu'; +//// user -> User{Id: 111, Name: "Jinzhu", Age: 20} +``` + +#### Assign + +不管记录是否找到,都将参数赋值给 struct. + +```go +// 未找到 +db.Where(User{Name: "non_existing"}).Assign(User{Age: 20}).FirstOrInit(&user) +//// user -> User{Name: "non_existing", Age: 20} + +// 找到 +db.Where(User{Name: "Jinzhu"}).Assign(User{Age: 30}).FirstOrInit(&user) +//// SELECT * FROM USERS WHERE name = jinzhu'; +//// user -> User{Id: 111, Name: "Jinzhu", Age: 30} +``` + +### FirstOrCreate + +获取匹配的第一条记录, 否则根据给定的条件创建一个新的记录 (仅支持 struct 和 map 条件) + +```go +// 未找到 +db.FirstOrCreate(&user, User{Name: "non_existing"}) +//// INSERT INTO "users" (name) VALUES ("non_existing"); +//// user -> User{Id: 112, Name: "non_existing"} + +// 找到 +db.Where(User{Name: "Jinzhu"}).FirstOrCreate(&user) +//// user -> User{Id: 111, Name: "Jinzhu"} +``` + +#### Attrs + +如果记录未找到,将使用参数创建 struct 和记录. + +```go + // 未找到 +db.Where(User{Name: "non_existing"}).Attrs(User{Age: 20}).FirstOrCreate(&user) +//// SELECT * FROM users WHERE name = 'non_existing'; +//// INSERT INTO "users" (name, age) VALUES ("non_existing", 20); +//// user -> User{Id: 112, Name: "non_existing", Age: 20} + +// 找到 +db.Where(User{Name: "jinzhu"}).Attrs(User{Age: 30}).FirstOrCreate(&user) +//// SELECT * FROM users WHERE name = 'jinzhu'; +//// user -> User{Id: 111, Name: "jinzhu", Age: 20} +``` + +#### Assign + +不管记录是否找到,都将参数赋值给 struct 并保存至数据库. + +```go +// 未找到 +db.Where(User{Name: "non_existing"}).Assign(User{Age: 20}).FirstOrCreate(&user) +//// SELECT * FROM users WHERE name = 'non_existing'; +//// INSERT INTO "users" (name, age) VALUES ("non_existing", 20); +//// user -> User{Id: 112, Name: "non_existing", Age: 20} + +// 找到 +db.Where(User{Name: "jinzhu"}).Assign(User{Age: 30}).FirstOrCreate(&user) +//// SELECT * FROM users WHERE name = 'jinzhu'; +//// UPDATE users SET age=30 WHERE id = 111; +//// user -> User{Id: 111, Name: "jinzhu", Age: 30} +``` + +### 高级查询 + +#### 子查询 + +基于 `*gorm.expr` 的子查询 + +```go +db.Where("amount > ?", db.Table("orders").Select("AVG(amount)").Where("state = ?", "paid").SubQuery()).Find(&orders) +// SELECT * FROM "orders" WHERE "orders"."deleted_at" IS NULL AND (amount > (SELECT AVG(amount) FROM "orders" WHERE (state = 'paid'))); +``` + +#### 选择字段 + +Select,指定你想从数据库中检索出的字段,默认会选择全部字段。 + +```go +db.Select("name, age").Find(&users) +//// SELECT name, age FROM users; + +db.Select([]string{"name", "age"}).Find(&users) +//// SELECT name, age FROM users; + +db.Table("users").Select("COALESCE(age,?)", 42).Rows() +//// SELECT COALESCE(age,'42') FROM users; +``` + +#### 排序 + +Order,指定从数据库中检索出记录的顺序。设置第二个参数 reorder 为 `true` ,可以覆盖前面定义的排序条件。 + +```go +db.Order("age desc, name").Find(&users) +//// SELECT * FROM users ORDER BY age desc, name; + +// 多字段排序 +db.Order("age desc").Order("name").Find(&users) +//// SELECT * FROM users ORDER BY age desc, name; + +// 覆盖排序 +db.Order("age desc").Find(&users1).Order("age", true).Find(&users2) +//// SELECT * FROM users ORDER BY age desc; (users1) +//// SELECT * FROM users ORDER BY age; (users2) +``` + +#### 数量 + +Limit,指定从数据库检索出的最大记录数。 + +```go +db.Limit(3).Find(&users) +//// SELECT * FROM users LIMIT 3; + +// -1 取消 Limit 条件 +db.Limit(10).Find(&users1).Limit(-1).Find(&users2) +//// SELECT * FROM users LIMIT 10; (users1) +//// SELECT * FROM users; (users2) +``` + +#### 偏移 + +Offset,指定开始返回记录前要跳过的记录数。 + +```go +db.Offset(3).Find(&users) +//// SELECT * FROM users OFFSET 3; + +// -1 取消 Offset 条件 +db.Offset(10).Find(&users1).Offset(-1).Find(&users2) +//// SELECT * FROM users OFFSET 10; (users1) +//// SELECT * FROM users; (users2) +``` + +#### 总数 + +Count,该 model 能获取的记录总数。 + +```go +db.Where("name = ?", "jinzhu").Or("name = ?", "jinzhu 2").Find(&users).Count(&count) +//// SELECT * from USERS WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (users) +//// SELECT count(*) FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (count) + +db.Model(&User{}).Where("name = ?", "jinzhu").Count(&count) +//// SELECT count(*) FROM users WHERE name = 'jinzhu'; (count) + +db.Table("deleted_users").Count(&count) +//// SELECT count(*) FROM deleted_users; + +db.Table("deleted_users").Select("count(distinct(name))").Count(&count) +//// SELECT count( distinct(name) ) FROM deleted_users; (count) +``` + +**注意** `Count` 必须是链式查询的最后一个操作 ,因为它会覆盖前面的 `SELECT`,但如果里面使用了 `count` 时不会覆盖 + +#### Group & Having + +```go +rows, err := db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Rows() +for rows.Next() { + ... +} + +// 使用Scan将多条结果扫描进事先准备好的结构体切片中 +type Result struct { + Date time.Time + Total int +} +var rets []Result +db.Table("users").Select("date(created_at) as date, sum(age) as total").Group("date(created_at)").Scan(&rets) + +rows, err := db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Having("sum(amount) > ?", 100).Rows() +for rows.Next() { + ... +} + +type Result struct { + Date time.Time + Total int64 +} +db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Having("sum(amount) > ?", 100).Scan(&results) +``` + +#### 连接 + +Joins,指定连接条件 + +```go +rows, err := db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Rows() +for rows.Next() { + ... +} + +db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&results) + +// 多连接及参数 +db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Joins("JOIN credit_cards ON credit_cards.user_id = users.id").Where("credit_cards.number = ?", "411111111111").Find(&user) +``` + +### Pluck + +Pluck,查询 model 中的一个列作为切片,如果您想要查询多个列,您应该使用 [`Scan`](https://www.liwenzhou.com/posts/Go/gorm_crud/#Scan) + +```go +var ages []int64 +db.Find(&users).Pluck("age", &ages) + +var names []string +db.Model(&User{}).Pluck("name", &names) + +db.Table("deleted_users").Pluck("name", &names) + +// 想查询多个字段? 这样做: +db.Select("name, age").Find(&users) +``` + +### 扫描 + +Scan,扫描结果至一个 struct. + +```go +type Result struct { + Name string + Age int +} + +var result Result +db.Table("users").Select("name, age").Where("name = ?", "Antonio").Scan(&result) + +var results []Result +db.Table("users").Select("name, age").Where("id > ?", 0).Scan(&results) + +// 原生 SQL +db.Raw("SELECT name, age FROM users WHERE name = ?", "Antonio").Scan(&result) +``` + +## 链式操作相关 + +### 链式操作 + +Method Chaining,Gorm 实现了链式操作接口,所以你可以把代码写成这样: + +```go +// 创建一个查询 +tx := db.Where("name = ?", "jinzhu") + +// 添加更多条件 +if someCondition { + tx = tx.Where("age = ?", 20) +} else { + tx = tx.Where("age = ?", 30) +} + +if yetAnotherCondition { + tx = tx.Where("active = ?", 1) +} +``` + +在调用立即执行方法前不会生成`Query`语句,借助这个特性你可以创建一个函数来处理一些通用逻辑。 + +### 立即执行方法 + +Immediate methods ,立即执行方法是指那些会立即生成`SQL`语句并发送到数据库的方法, 他们一般是`CRUD`方法,比如: + +`Create`, `First`, `Find`, `Take`, `Save`, `UpdateXXX`, `Delete`, `Scan`, `Row`, `Rows`… + +这有一个基于上面链式方法代码的立即执行方法的例子: + +```go +tx.Find(&user) +``` + +生成的SQL语句如下: + +```sql +SELECT * FROM users where name = 'jinzhu' AND age = 30 AND active = 1; +``` + +### 范围 + +`Scopes`,Scope是建立在链式操作的基础之上的。 + +基于它,你可以抽取一些通用逻辑,写出更多可重用的函数库。 + +```go +func AmountGreaterThan1000(db *gorm.DB) *gorm.DB { + return db.Where("amount > ?", 1000) +} + +func PaidWithCreditCard(db *gorm.DB) *gorm.DB { + return db.Where("pay_mode_sign = ?", "C") +} + +func PaidWithCod(db *gorm.DB) *gorm.DB { + return db.Where("pay_mode_sign = ?", "C") +} + +func OrderStatus(status []string) func (db *gorm.DB) *gorm.DB { + return func (db *gorm.DB) *gorm.DB { + return db.Scopes(AmountGreaterThan1000).Where("status IN (?)", status) + } +} + +db.Scopes(AmountGreaterThan1000, PaidWithCreditCard).Find(&orders) +// 查找所有金额大于 1000 的信用卡订单 + +db.Scopes(AmountGreaterThan1000, PaidWithCod).Find(&orders) +// 查找所有金额大于 1000 的 COD 订单 + +db.Scopes(AmountGreaterThan1000, OrderStatus([]string{"paid", "shipped"})).Find(&orders) +// 查找所有金额大于 1000 且已付款或者已发货的订单 +``` + +### 多个立即执行方法 + +Multiple Immediate Methods,在 GORM 中使用多个立即执行方法时,后一个立即执行方法会复用前一个**立即执行方法**的条件 (不包括内联条件) 。 + +```go +db.Where("name LIKE ?", "jinzhu%").Find(&users, "id IN (?)", []int{1, 2, 3}).Count(&count) +``` + +生成的 Sql + +```sql +SELECT * FROM users WHERE name LIKE 'jinzhu%' AND id IN (1, 2, 3) + +SELECT count(*) FROM users WHERE name LIKE 'jinzhu%' +``` + +## 更新 + +### 更新所有字段 + +`Save()`默认会更新该对象的所有字段,即使你没有赋值。 + +```go +db.First(&user) + +user.Name = "七米" +user.Age = 99 +db.Save(&user) + +//// UPDATE `users` SET `created_at` = '2020-02-16 12:52:20', `updated_at` = '2020-02-16 12:54:55', `deleted_at` = NULL, `name` = '七米', `age` = 99, `active` = true WHERE `users`.`deleted_at` IS NULL AND `users`.`id` = 1 +``` + +### 更新修改字段 + +如果你只希望更新指定字段,可以使用`Update`或者`Updates` + +```go +// 更新单个属性,如果它有变化 +db.Model(&user).Update("name", "hello") +//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111; + +// 根据给定的条件更新单个属性 +db.Model(&user).Where("active = ?", true).Update("name", "hello") +//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true; + +// 使用 map 更新多个属性,只会更新其中有变化的属性 +db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false}) +//// UPDATE users SET name='hello', age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111; + +// 使用 struct 更新多个属性,只会更新其中有变化且为非零值的字段 +db.Model(&user).Updates(User{Name: "hello", Age: 18}) +//// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111; + +// 警告:当使用 struct 更新时,GORM只会更新那些非零值的字段 +// 对于下面的操作,不会发生任何更新,"", 0, false 都是其类型的零值 +db.Model(&user).Updates(User{Name: "", Age: 0, Active: false}) +``` + +### 更新选定字段 + +如果你想更新或忽略某些字段,你可以使用 `Select`,`Omit` + +```go +db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false}) +//// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111; + +db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false}) +//// UPDATE users SET age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111; +``` + +### 无Hooks更新 + +上面的更新操作会自动运行 model 的 `BeforeUpdate`, `AfterUpdate` 方法,更新 `UpdatedAt` 时间戳, 在更新时保存其 `Associations`, 如果你不想调用这些方法,你可以使用 `UpdateColumn`, `UpdateColumns` + +```go +// 更新单个属性,类似于 `Update` +db.Model(&user).UpdateColumn("name", "hello") +//// UPDATE users SET name='hello' WHERE id = 111; + +// 更新多个属性,类似于 `Updates` +db.Model(&user).UpdateColumns(User{Name: "hello", Age: 18}) +//// UPDATE users SET name='hello', age=18 WHERE id = 111; +``` + +### 批量更新 + +批量更新时`Hooks(钩子函数)`不会运行。 + +```go +db.Table("users").Where("id IN (?)", []int{10, 11}).Updates(map[string]interface{}{"name": "hello", "age": 18}) +//// UPDATE users SET name='hello', age=18 WHERE id IN (10, 11); + +// 使用 struct 更新时,只会更新非零值字段,若想更新所有字段,请使用map[string]interface{} +db.Model(User{}).Updates(User{Name: "hello", Age: 18}) +//// UPDATE users SET name='hello', age=18; + +// 使用 `RowsAffected` 获取更新记录总数 +db.Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected +``` + +### 使用SQL表达式更新 + +先查询表中的第一条数据保存至user变量。 + +```go +var user User +db.First(&user) +db.Model(&user).Update("age", gorm.Expr("age * ? + ?", 2, 100)) +//// UPDATE `users` SET `age` = age * 2 + 100, `updated_at` = '2020-02-16 13:10:20' WHERE `users`.`id` = 1; + +db.Model(&user).Updates(map[string]interface{}{"age": gorm.Expr("age * ? + ?", 2, 100)}) +//// UPDATE "users" SET "age" = age * '2' + '100', "updated_at" = '2020-02-16 13:05:51' WHERE `users`.`id` = 1; + +db.Model(&user).UpdateColumn("age", gorm.Expr("age - ?", 1)) +//// UPDATE "users" SET "age" = age - 1 WHERE "id" = '1'; + +db.Model(&user).Where("age > 10").UpdateColumn("age", gorm.Expr("age - ?", 1)) +//// UPDATE "users" SET "age" = age - 1 WHERE "id" = '1' AND quantity > 10; +``` + +### 修改Hooks中的值 + +如果你想修改 `BeforeUpdate`, `BeforeSave` 等 Hooks 中更新的值,你可以使用 `scope.SetColumn`, 例如: + +```go +func (user *User) BeforeSave(scope *gorm.Scope) (err error) { + if pw, err := bcrypt.GenerateFromPassword(user.Password, 0); err == nil { + scope.SetColumn("EncryptedPassword", pw) + } +} +``` + +### 其它更新选项 + +```go +// 为 update SQL 添加其它的 SQL +db.Model(&user).Set("gorm:update_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Update("name", "hello") +//// UPDATE users SET name='hello', updated_at = '2013-11-17 21:34:10' WHERE id=111 OPTION (OPTIMIZE FOR UNKNOWN); +``` + +## 删除 + +### 删除记录 + +**警告** 删除记录时,请确保主键字段有值,GORM 会通过主键去删除记录,如果主键为空,GORM 会删除该 model 的所有记录。 + +```go +// 删除现有记录 +db.Delete(&email) +//// DELETE from emails where id=10; + +// 为删除 SQL 添加额外的 SQL 操作 +db.Set("gorm:delete_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Delete(&email) +//// DELETE from emails where id=10 OPTION (OPTIMIZE FOR UNKNOWN); +``` + +### 批量删除 + +删除全部匹配的记录 + +```go +db.Where("email LIKE ?", "%jinzhu%").Delete(Email{}) +//// DELETE from emails where email LIKE "%jinzhu%"; + +db.Delete(Email{}, "email LIKE ?", "%jinzhu%") +//// DELETE from emails where email LIKE "%jinzhu%"; +``` + +### 软删除 + +如果一个 model 有 `DeletedAt` 字段,他将自动获得软删除的功能! 当调用 `Delete` 方法时, 记录不会真正的从数据库中被删除, 只会将`DeletedAt` 字段的值会被设置为当前时间 + +```go +db.Delete(&user) +//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111; + +// 批量删除 +db.Where("age = ?", 20).Delete(&User{}) +//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20; + +// 查询记录时会忽略被软删除的记录 +db.Where("age = 20").Find(&user) +//// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL; + +// Unscoped 方法可以查询被软删除的记录 +db.Unscoped().Where("age = 20").Find(&users) +//// SELECT * FROM users WHERE age = 20; +``` + +### 物理删除 + +```go +// Unscoped 方法可以物理删除记录 +db.Unscoped().Delete(&order) +//// DELETE FROM orders WHERE id=10; +``` \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/.idea/.gitignore" "b/Golang/Gin\346\241\206\346\236\266/Code/.idea/.gitignore" new file mode 100644 index 0000000000000000000000000000000000000000..73f69e0958611ac6e00bde95641f6699030ad235 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/.idea/.gitignore" @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/.idea/Code.iml" "b/Golang/Gin\346\241\206\346\236\266/Code/.idea/Code.iml" new file mode 100644 index 0000000000000000000000000000000000000000..5e764c4f0b9a64bb78a5babfdd583713b2df47bf --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/.idea/Code.iml" @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/.idea/codeStyles/codeStyleConfig.xml" "b/Golang/Gin\346\241\206\346\236\266/Code/.idea/codeStyles/codeStyleConfig.xml" new file mode 100644 index 0000000000000000000000000000000000000000..a55e7a179bde3e4e772c29c0c85e53354aa54618 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/.idea/codeStyles/codeStyleConfig.xml" @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/.idea/misc.xml" "b/Golang/Gin\346\241\206\346\236\266/Code/.idea/misc.xml" new file mode 100644 index 0000000000000000000000000000000000000000..28a804d8932aba40f168fd757a74cb718a955a1a --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/.idea/misc.xml" @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/.idea/modules.xml" "b/Golang/Gin\346\241\206\346\236\266/Code/.idea/modules.xml" new file mode 100644 index 0000000000000000000000000000000000000000..74258af4a9423b83b55ce078eaca6a73a780b454 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/.idea/modules.xml" @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/.idea/vcs.xml" "b/Golang/Gin\346\241\206\346\236\266/Code/.idea/vcs.xml" new file mode 100644 index 0000000000000000000000000000000000000000..089bfa0cda100b1b3c6630b0ba6a24736128db70 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/.idea/vcs.xml" @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/go.mod" "b/Golang/Gin\346\241\206\346\236\266/Code/go.mod" new file mode 100644 index 0000000000000000000000000000000000000000..000fa30c06b39d6007c9abe3fdd2b96a4520a70c --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/go.mod" @@ -0,0 +1,16 @@ +module gin_demo + +go 1.14 + +require ( + github.com/gin-gonic/gin v1.6.3 // indirect + github.com/go-playground/validator/v10 v10.3.0 // indirect + github.com/golang/protobuf v1.4.2 // indirect + github.com/jinzhu/gorm v1.9.16 + github.com/json-iterator/go v1.1.10 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 // indirect + google.golang.org/protobuf v1.25.0 // indirect + gopkg.in/yaml.v2 v2.3.0 // indirect +) diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/go.sum" "b/Golang/Gin\346\241\206\346\236\266/Code/go.sum" new file mode 100644 index 0000000000000000000000000000000000000000..a94f735c381bd73c668318a414965e0908bf7ab0 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/go.sum" @@ -0,0 +1,142 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.3.0 h1:nZU+7q+yJoFmwvNgv/LnPUkwPal62+b2xXj0AU1Es7o= +github.com/go-playground/validator/v10 v10.3.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= +github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson02/hello.html" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson02/hello.html" new file mode 100644 index 0000000000000000000000000000000000000000..477f20ac8d260c999d7894a062681bce262ad52a --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson02/hello.html" @@ -0,0 +1,12 @@ + + hello golang + +

+ hello Golang! +

+

+ hello gin! +

+ + + diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson02/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson02/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..e4d0490f63456fabe4e187044e2541f8342f8935 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson02/main.go" @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "io/ioutil" + "net/http" +) + +// http.ResponseWriter:代表响应,传递到前端的 +// *http.Request:表示请求,从前端传递过来的 +func sayHello(w http.ResponseWriter, r *http.Request) { + html, _ := ioutil.ReadFile("./index2.tmpl") + _, _ = fmt.Fprintln(w, string(html)); +} + +func main() { + http.HandleFunc("/hello", sayHello) + err := http.ListenAndServe(":9090", nil) + if err != nil { + fmt.Println("http server failed, err:%v \n", err) + return + } +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson03/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson03/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..1c7704585aebce6643081e9cf257ee565a629c93 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson03/main.go" @@ -0,0 +1,20 @@ +package main + +import ( + "github.com/gin-gonic/gin" +) + +func main() { + // 创建一个默认的路由引擎 + r := gin.Default() + // GET:请求方式;/hello:请求的路径 + // 当客户端以GET方法请求/hello路径时,会执行后面的匿名函数 + r.GET("/hello", func(c *gin.Context) { + // c.JSON:返回JSON格式的数据 + c.JSON(200, gin.H{ + "message": "Hello world!", + }) + }) + // 启动HTTP服务,默认在0.0.0.0:8080启动服务 + r.Run() +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson04/hello.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson04/hello.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..ba56676a1ce4fc22e24a62ff01a54a5012ce7287 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson04/hello.tmpl" @@ -0,0 +1,11 @@ + + + + hello + + +

hello golang

+

hello {{.}}

+ + + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson04/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson04/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..10286b4205811c273e138a6c969a39504141a63e --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson04/main.go" @@ -0,0 +1,35 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" + "os" +) + +func sayHello(w http.ResponseWriter, r *http.Request) { + // 获取项目的绝对路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + fmt.Println("wd:", wd + "\\lesson04\\index2.tmpl") + // 解析指定文件生成模板对象 + tmpl, err := template.ParseFiles( wd + "\\lesson04\\index2.tmpl") + + if err != nil { + fmt.Println("create templates failed, err:", err) + return + } + // 利用给定数据渲染模板,并将结果写入w + tmpl.Execute(w, "沙河小王子") +} +func main() { + http.HandleFunc("/", sayHello) + err := http.ListenAndServe(":9090", nil) + if err != nil { + fmt.Println("HTTP server failed,err:", err) + return + } +} diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson05/hello.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson05/hello.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..c7b34730433ae58162790b50830d6012c7e0c8dc --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson05/hello.tmpl" @@ -0,0 +1,14 @@ + + + + + + + Hello + + +

姓名: {{.Name}}

+

性别: {{.Gender}}

+

年龄: {{.Age}}

+ + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson05/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson05/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..7ed1909de18249555ac1b1e35c1a9206d68439d3 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson05/main.go" @@ -0,0 +1,64 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" + "os" +) + +//定义用户结构体 +type User struct { + Name string + Gender string + Age int +} + +func sayHello(w http.ResponseWriter, r *http.Request) { + // 获取项目的绝对路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + fmt.Println("wd:", wd + "\\lesson05\\index2.tmpl") + // 解析指定文件生成模板对象 + tmpl, err := template.ParseFiles( wd + "\\lesson05\\index2.tmpl") + + if err != nil { + fmt.Println("create templates failed, err:", err) + return + } + + // 采用结构体 + u1 := User{ + Name: "小王子", + Gender: "男", + Age: 10, + } + fmt.Println(u1) + + // 采用一个map + m1 := map[string]interface{}{ + "Name": "小王子", + "Age": 18, + "Gender": "男", + } + + m2 := map[string]interface{}{ + "map": m1, + "users": u1, + } + fmt.Println(m2) + + // 利用给定数据渲染模板,并将结果写入w + tmpl.Execute(w, m1) +} +func main() { + http.HandleFunc("/", sayHello) + err := http.ListenAndServe(":9090", nil) + if err != nil { + fmt.Println("HTTP server failed,err:", err) + return + } +} diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson06/hello.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson06/hello.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..4ee24a0456e7defcc293a58afa6a3b2c0e34304e --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson06/hello.tmpl" @@ -0,0 +1,15 @@ + + + + + + + 自定义模板函数 + + +

{{kua .Name}}

+

姓名: {{.Name}}

+

性别: {{.Gender}}

+

年龄: {{.Age}}

+ + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson06/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson06/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..7e6891a4c07f85106469c693cc9ed5e992491d6b --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson06/main.go" @@ -0,0 +1,64 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" + "os" +) + +/** + * @Description f1函数 + * @Param + * @return + **/ +func f1(w http.ResponseWriter, r *http.Request) { + // 定义模板 + // 解析模板 + // 获取项目的绝对路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + + // 定义一个自定义函数 + // 要么只有一个返回值,要么有两个返回值,第二个返回值必须是error类型 + kua := func(name string)(string, error) { + return name + "年轻又帅气!", nil + } + + // 创建一个名字为f的模板对象。注意,这个名字一定要和模板的名字对应上 + tmpl := template.New("index2.tmpl") + + // 告诉模板引擎,我现在多了一个自定义的函数kua + tmpl.Funcs(template.FuncMap{ + "kua": kua, + }) + + // 解析模板 + _, err = tmpl.ParseFiles( wd + "\\lesson06\\index2.tmpl") + + if err != nil { + fmt.Printf("parse templates failed, err:%v \n", err) + return + } + + // 采用一个map + m1 := map[string]interface{}{ + "Name": "小王子", + "Age": 18, + "Gender": "男", + } + + // 渲染模板 + tmpl.Execute(w, m1) +} +func main() { + http.HandleFunc("/hello", f1) + err := http.ListenAndServe(":9090", nil) + if err != nil { + fmt.Println("HTTP server failed,err:", err) + return + } +} diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson07/home.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson07/home.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..bd532773284839c4ea4a74efb7992922bc9323e4 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson07/home.tmpl" @@ -0,0 +1,46 @@ + + + + + + + 模板继承 + + + +
+ +
+

这是home页面

+

hello:{{.}}

+
+ +
+ + + + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson07/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson07/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..e63bd3bba669f50b71d8ace2a8dff6b5d7d80e13 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson07/index.tmpl" @@ -0,0 +1,46 @@ + + + + + + + 模板继承 + + + +
+ +
+

这是index页面

+

hello:{{.}}

+
+ +
+ + + + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson07/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson07/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..5d37c9738ab022635ef6e272e5a68b7cfebe9cfb --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson07/main.go" @@ -0,0 +1,143 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" + "os" +) + +/** + * @Description 首页 + * @Param + * @return + **/ +func index(w http.ResponseWriter, r *http.Request) { + // 定义模板 + // 解析模板 + // 获取项目的绝对路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + + // 创建一个名字为f的模板对象。注意,这个名字一定要和模板的名字对应上 + tmpl := template.New("index.tmpl") + + // 解析模板 + _, err = tmpl.ParseFiles( wd + "\\lesson07\\index.tmpl") + + if err != nil { + fmt.Printf("parse templates failed, err:%v \n", err) + return + } + + msg := "小公主" + + // 渲染模板 + tmpl.Execute(w, msg) +} + +/** + * @Description 主页 + * @Param + * @return + **/ +func home(w http.ResponseWriter, r *http.Request) { + // 定义模板 + // 解析模板 + // 获取项目的绝对路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + + // 创建一个名字为f的模板对象。注意,这个名字一定要和模板的名字对应上 + tmpl := template.New("home.tmpl") + + // 解析模板 + _, err = tmpl.ParseFiles( wd + "\\lesson07\\home.tmpl") + + if err != nil { + fmt.Printf("parse templates failed, err:%v \n", err) + return + } + + msg := "小王子" + + // 渲染模板 + tmpl.Execute(w, msg) +} + + +/** + * @Description 首页 + * @Param + * @return + **/ +func index2(w http.ResponseWriter, r *http.Request) { + // 定义模板(使用的模板继承的方式) + // 解析模板 + // 获取项目的绝对路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + + // 解析模板 + t, err := template.ParseFiles( wd + "\\lesson07\\templates\\base.tmpl", wd + "\\lesson07\\templates\\index2.tmpl") + + if err != nil { + fmt.Printf("parse templates failed, err:%v \n", err) + return + } + + msg := "小公主" + + // 渲染模板 + t.ExecuteTemplate(w, "index2.tmpl", msg) +} + +/** + * @Description 主页 + * @Param + * @return + **/ +func home2(w http.ResponseWriter, r *http.Request) { + // 定义模板(使用的模板继承的方式) + // 解析模板 + // 获取项目的绝对路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + + // 解析模板 + t, err := template.ParseFiles( wd + "\\lesson07\\templates\\base.tmpl", wd + "\\lesson07\\templates\\home2.tmpl") + + if err != nil { + fmt.Printf("parse templates failed, err:%v \n", err) + return + } + + msg := "小公主" + + // 渲染模板 + t.ExecuteTemplate(w, "home2.tmpl", msg) +} + +func main() { + http.HandleFunc("/index", index) + http.HandleFunc("/home", home) + http.HandleFunc("/index2", index2) + http.HandleFunc("/home2", home2) + err := http.ListenAndServe(":9090", nil) + if err != nil { + fmt.Println("HTTP server failed,err:", err) + return + } +} diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson07/templates/base.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson07/templates/base.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..c53dd9f016a3285600008ecdad9511396d7030ce --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson07/templates/base.tmpl" @@ -0,0 +1,46 @@ + + + + + + + 模板继承 + + + +
+ +
+ + {{block "content" .}}{{end}} +
+ +
+ + + + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson07/templates/home2.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson07/templates/home2.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..2b2014d336ef2a95ee75eef65a3c92df702f724c --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson07/templates/home2.tmpl" @@ -0,0 +1,8 @@ +{{/*继承根模板*/}} +{{template "base.tmpl" .}} + +{{/*重新定义块模板*/}} +{{define "content"}} +

这是home2页面

+

hello:{{.}}

+{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson07/templates/index2.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson07/templates/index2.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..939932926b4e1565c0c846e180427d217c132e74 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson07/templates/index2.tmpl" @@ -0,0 +1,8 @@ +{{/*继承根模板*/}} +{{template "base.tmpl" .}} + +{{/*重新定义块模板*/}} +{{define "content"}} +

这是index2页面

+

hello:{{.}}

+{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson08/hello.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson08/hello.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..d38b2fe84fe55441d25ab5ffd5c43648eeed2733 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson08/hello.tmpl" @@ -0,0 +1,14 @@ + + + + + + + 自定义模板函数 + + +

姓名: {[.Name]}

+

性别: {[.Gender]}

+

年龄: {[.Age]}

+ + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson08/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson08/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..2a4175a7670107a9ab4351922ce521bd2a395ca6 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson08/main.go" @@ -0,0 +1,93 @@ +/** + * @Description 修改模板引擎的默认标识符 + * @author 陌溪 + * @date 2020年9月16日21:41:43 + **/ +package main + +import ( + "fmt" + "html/template" + "net/http" + "os" +) + +/** + * @Description f1函数 + * @Param + * @return + **/ +func f1(w http.ResponseWriter, r *http.Request) { + // 定义模板 + // 解析模板 + + // 获取项目的绝对路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + + // 创建一个名字为f的模板对象。注意,这个名字一定要和模板的名字对应上 + tmpl := template.New("hello.tmpl") + + // 修改默认的标识符 + tmpl = tmpl.Delims("{[", "]}") + + // 解析模板 + _, err = tmpl.ParseFiles( wd + "\\lesson08\\hello.tmpl") + + if err != nil { + fmt.Printf("parse templates failed, err:%v \n", err) + return + } + + // 采用一个map + m1 := map[string]interface{}{ + "Name": "小王子", + "Age": 18, + "Gender": "男", + } + + // 渲染模板 + tmpl.Execute(w, m1) +} + +func xss(w http.ResponseWriter, r *http.Request) { + // 定义模板 + + // 解析模板 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + // 创建一个名字为f的模板对象。注意,这个名字一定要和模板的名字对应上 + tmpl := template.New("xss.tmpl") + + // 定义一个安全的函数,让模板对 传递过去的数据不进行转义,直接通过html格式显示 + tmpl = tmpl.Funcs(template.FuncMap{ + "safe": func(str string)template.HTML { + return template.HTML(str) + }, + }) + + // 解析模板 + _, err = tmpl.ParseFiles( wd + "\\lesson08\\xss.tmpl") + if err != nil { + fmt.Printf("parse templates failed, err:%v \n", err) + return + } + // 渲染模板 + str := "" + tmpl.Execute(w, str) +} +func main() { + http.HandleFunc("/hello", f1) + http.HandleFunc("/xss", xss) + err := http.ListenAndServe(":9090", nil) + if err != nil { + fmt.Println("HTTP server failed,err:", err) + return + } +} diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson08/xss.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson08/xss.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..f6dd7324f0c2f9da091e099e20c0355c8373b1ce --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson08/xss.tmpl" @@ -0,0 +1,12 @@ + + + + + + + xss + + +

{{safe .}}

+ + \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..61894b709b67bb6e567bc4654d2d08a5eb93e3f4 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/main.go" @@ -0,0 +1,79 @@ +/** Gin框架渲染博客 + * @Description + * @Author 陌溪 + * @Date 2020/9/16 22:10 + **/ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" + "net/http" + "os" +) + +/** + * @Description 主函数 + * @Param + * @return + **/ +func main() { + // 找到模板路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + r := gin.Default() + // 模板解析 + + // 使用全局匹配规则 + r.LoadHTMLGlob(wd + "/lesson09-2/templates/*") + + r.Static("/static", wd + "/lesson09-2/static") + + // 博客日记 模板渲染 + r.GET("/bkrj", func(context *gin.Context) { + // HTTP请求 + context.HTML(http.StatusOK, "bkrj.tmpl", nil) + }) + + // 关于博主 模板渲染 + r.GET("/gybz", func(context *gin.Context) { + // HTTP请求 + context.HTML(http.StatusOK, "gybz.tmpl", nil) + }) + + // 首页 模板渲染 + r.GET("/index", func(context *gin.Context) { + // HTTP请求 + context.HTML(http.StatusOK, "index.tmpl", nil) + }) + + // 详情页 模板渲染 + r.GET("/info", func(context *gin.Context) { + // HTTP请求 + context.HTML(http.StatusOK, "info.tmpl", nil) + }) + + // 时间轴 模板渲染 + r.GET("/sjz", func(context *gin.Context) { + // HTTP请求 + context.HTML(http.StatusOK, "sjz.tmpl", nil) + }) + + // 碎言碎语 模板渲染 + r.GET("/sysy", func(context *gin.Context) { + // HTTP请求 + context.HTML(http.StatusOK, "sysy.tmpl", nil) + }) + + // 我的相册 模板渲染 + r.GET("/wdxc", func(context *gin.Context) { + // HTTP请求 + context.HTML(http.StatusOK, "wdxc.tmpl", nil) + }) + + // 启动Server + r.Run(":8080") +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/css/base.css" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/css/base.css" new file mode 100644 index 0000000000000000000000000000000000000000..59f00c848ae986b7dbdee05891f9a90e5587137c --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/css/base.css" @@ -0,0 +1,245 @@ +@charset "utf-8"; +/* CSS Document */ +* { margin: 0; padding: 0 } +img { border: 0; display: block } /*去除图片默认的1px边框;将图片标签变成块级元素,可清除默认的3px距离*/ +ul li { list-style: none; }/*去除ul li标签前面小点*/ +a { color: #222; text-decoration: none; } /* 所有a 标签的 颜色为#222; 去除默认的下划线*/ +a:hover { color: #f00; }/*所有带访问的链接,鼠标放上去的颜色为红色 */ +h1 { font-size: 28px } +h2 { font-size: 18px } +h3, h4, h5, h6 { font-size: 16px } +body { font: 15px "Microsoft YaHei", Arial, Helvetica, sans-serif; color: #222; background: #f5f5f5 } /*设置 文字大小、字体、颜色、背景*/ +header, main { width: 1200px; margin: auto } +article { width: 860px; float: left; } +aside { width: 320px; float: right; } +footer { width: 100%; padding-bottom: 20px; text-align: center; clear: both } +.touxiang { float: left; width: 50%; margin: 20px 0; } +.touxiang i { width: 100px; height: 100px; background: #fff; display: block; float: left; margin-right: 20px; border-radius: 100%; } +.touxiang i img { width: 101px; } +.touxiang h2 { margin: 20px 0 10px 0; } +.touxiang p { color: #949494; } +.guanzhu { float: right; background: #e01109; color: #fff; width: 120px; line-height: 30px; text-align: center; border-radius: 3px; position: relative; top: 40px; right: 0; cursor: pointer; } +.weixin { display: none; position: absolute; width: 120px; } +.guanzhu:hover .weixin { display: block } +nav { width: 100%; clear: both; height: 50px; line-height: 50px; background: #fff; overflow: hidden; margin-bottom: 20px; box-shadow: rgba(0,0,0,.1) 3px 5px 5px; }/*阴影 颜色透明度,左右,上下,大小*/ +nav ul { text-align: center; font-size: 0; } +nav ul li { display: inline-block; font-size: 15px; position: relative; margin: 0 3px 0 0; } +nav ul li a { display: block; padding: 0 20px; } +nav ul li a:before { content: ""; width: 0; height: 5px; top: 0; left: 0; position: absolute; transition: .5s; } +nav ul li a:hover:before, li.current a:before { width: 100%; background: #af0f09; } +nav ul li a:hover, li.current a { background: #e01109; color: #fff; } +/*blogs*/ +.blogs { } +.blogs li { overflow: hidden; margin-bottom: 20px; background: #fff; padding: 20px; position: relative; } +.top_blog .blogs li::after { position: absolute; content: ""; right: 10px; top: 40px; border-style: solid; border-width: 0 13px 13px 13px; } +.top_blog .blogs li::after { border-color: #e01109 #e01109 transparent #e01109; } +.top_blog .blogs li::before { background: #e01109; position: absolute; content: ""; right: 10px; top: 0; width: 26px; height: 30px; text-align: center; font-size: 16px; font-weight: bold; color: #fff; padding: 10px 0 0 0; } +.top_blog .blogs li:nth-child(1)::before { content: "1" } +.top_blog .blogs li:nth-child(2)::before { content: "2" } +.top_blog .blogs li:nth-child(3)::before { content: "3" } +.blogs li i { display: block; width: 160px; height: 110px; overflow: hidden; float: left; margin-right: 20px; } +.blogs li i img { width: 100%; min-height: 100%; transition: .5s; } +.blogs h2 { margin: 0 0 14px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.blog_smalltext { overflow: hidden; -webkit-box-orient: vertical; display: -webkit-box; -webkit-line-clamp: 2; font-size: 14px; color: #666; margin-bottom: 14px; } +.blog_info { color: #888; font-size: 13px; } +.blog_info span { margin-right: 15px; position: relative; padding-left: 20px; line-height: 20px; } +.blog_info span a { color: #518f97 } +.blog_info span a:hover { color: #e01109; } +.blog_info span:nth-child(n):before { position: absolute; content: ""; width: 20px; height: 20px; left: 0; top: 0; } +.blog_info span:nth-child(1) { background: url(../images/icon.png) no-repeat 0 0; background-size: 18px } +.blog_info span:nth-child(2) { background: url(../images/icon.png) no-repeat 0 -18px; background-size: 18px } +.blog_info span:nth-child(3) { background: url(../images/icon.png) no-repeat 0 -36px; background-size: 18px } +.blog_info span:nth-child(4) { background: url(../images/icon.png) no-repeat 0 -54px; background-size: 18px } +.blog_info span:nth-child(5) { background: url(../images/icon.png) no-repeat 0 -72px; background-size: 18px } +.blogs li:hover { box-shadow: rgba(0,0,0,.1) 3px 5px 5px; } +.blogs li:hover h2 { color: #F00 } +.blogs li:hover img { transform: scale(1.1) } +/*aside*/ +aside div { background: #fff; margin-bottom: 20px } +.search { background: #ed4040; position: relative; border: #ed4040 2px solid; border-radius: 5px; overflow: hidden; } +.search input.input_submit { border: 0; color: #fff; outline: none; position: absolute; top: 0; right: 0; width: 25%; display: block; font-size: 15px; height: 36px; line-height: 36px; text-indent: 1em; cursor: pointer; background: url(../images/search.png) no-repeat left 10px center; background-size: 21px; } +.search input.input_text { border: 0; line-height: 36px; height: 36px; font-size: 14px; width: 75%; outline: none; text-indent: 1em; } +h2.aside_title { padding: 20px; } +.xinqing { } +.xinqing ul { padding: 0 20px 20px; } +.xinqing ul li { margin-bottom: 20px; border: #e4e4e4 1px solid; padding: 10px; font-size: 14px; border-radius: 5px; color: #333; position: relative; } +.xinqing ul li:after { right: 100%; border: solid transparent; content: " "; height: 0; width: 0; position: absolute; border-right-color: #e4e4e4; border-width: 10px; top: 10px; } +.xinqing ul li:nth-child(odd) { background: #f5f5f5 } +.pics { overflow: hidden; } +.pics ul { overflow: hidden; margin: 0 20px 20px; } +.pics ul li { width: 33.333%; float: left; } +.pics ul li a { display: block; height: 60px; margin: 2px; overflow: hidden; background: #000 } +.pics ul li img { width: 100%; min-height: 100%; opacity: .8; transition: all .5s; } +.pics ul li a:hover img { opacity: 1; transform: scale(1.1) } +.paihang { } +.paihang ol { padding: 0 20px 20px 40px; } +.paihang ol li { margin-bottom: 20px; padding-left: 10px; } +.links span { float: right; font-size: 16px; font-weight: normal } +.links span a { color: #666; } +.links span a:hover { color: #f00 } +.links ul { padding: 0 20px 20px 20px; overflow: hidden } +.links li { width: 50%; float: left; display: inline-block; line-height: 30px; text-align: center } +.links li a { margin: 5px; border: #666 1px solid; display: block; border-radius: 3px; color: #666 } +.links li a:hover { border: #222 1px solid; color: #000 } +/*footer*/ +footer img { display: inline-block; vertical-align: middle; margin-right: 5px; } +footer p { line-height: 30px; font-size: 14px; color: #666 } +footer p span { margin: 0 10px } +footer a { color: #666 } +/*weizhi*/ +.weizhi { margin: 0 0 20px 0; font-size: 14px; color: #949494; background: url(../images/weizhi.png) no-repeat left center; background-size: 20px; padding-left: 30px } +.weizhi a { color: #949494; } +.weizhi a:hover { color: #000 } +/*suiyan*/ +.suiyan_list { } +.suiyan_list ul { overflow: hidden; } +.suiyan_list ul li { width: 25%; float: left; } +.suiyan_list ul li a { display: block; padding: 20px; margin: 30px auto; background: #fff; box-shadow: rgba(0,0,0,.1) 3px 5px 5px; width: 200px; height: 200px; transform: rotate(-10deg); position: relative; color: #333 } +.suiyan_list ul li:nth-child(even) a { -webkit-transform: rotate(10deg); top: 10px; background: rgb(255, 255, 205); ; } +.suiyan_list ul li:nth-child(3n) a { -webkit-transform: rotate(-5deg); top: -10px; background: rgb(254, 201, 227); } +.suiyan_list ul li:nth-child(5n) a { -webkit-transform: rotate(8deg); top: -10px; background: rgb(210, 251, 253); } +.suiyan_list ul li a:hover { transform: scale(1.1); transition: .2s; box-shadow: rgba(0,0,0,.5) 3px 5px 5px; } +.suiyan_time { font-size: 14px; color: #999; margin-bottom: 10px; } +.suiyan_text { line-height: 30px; } +.suiyan_list span { position: absolute; width: 50px; height: 50px; bottom: 5px; right: 5px; } +.suiyan_5 { background: url(../images/bq5.png) no-repeat; background-size: 48px; } +.suiyan_4 { background: url(../images/bq4.png) no-repeat; background-size: 48px; } +.suiyan_3 { background: url(../images/bq3.png) no-repeat; background-size: 48px; } +.suiyan_2 { background: url(../images/bq2.png) no-repeat; background-size: 48px; } +.suiyan_1 { background: url(../images/bq1.png) no-repeat; background-size: 48px; } +/*tuijian*/ +.tuijian { } +.tuijian ul { padding: 0 20px 20px 20px; } +.tuijian ul li { overflow: hidden; margin-bottom: 20px; } +.tuijian ul li a { } +.tuijian i { display: block; width: 90px; height: 60px; overflow: hidden; margin-right: 20px; float: left; } +.tuijian p { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; margin-top: 8px } +.tuijian img { width: 100%; min-height: 100%; } +/*love*/ +.love { } +.love ul { padding: 0 20px 20px 20px; overflow: hidden } +.love ul li { overflow: hidden; width: 50%; float: left; } +.love ul li a { margin: 0 3px 10px; display: block; overflow: hidden; } +.love i { display: block; width: 100%; height: 90px; overflow: hidden; } +.love p { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; } +.love img { width: 100%; min-height: 100%; } +/*tagsclous*/ +.tagsclous h2 { padding-bottom: 0 !important } +.tagsclous ul { padding: 20px; overflow: hidden; position: relative; } +.tagsclous ul:before { animation: linescroll 5s; animation-iteration-count: infinite; content: ""; width: 20px; height: 20px; background: red; position: absolute; z-index: 9 } +.tagsclous a { display: inline-block; background: #ffffff; width: 33.3333%; font-size: 14px; float: left; line-height: 40px; text-align: center; position: relative; } +.tagsclous a:nth-child(3n-1):before { width: 1px; height: 100%; content: ""; position: absolute; background: #eae5e5; left: 0; top: 0; } +.tagsclous a:nth-child(3n-1):after { width: 1px; height: 100%; content: ""; position: absolute; background: #eae5e5; right: 0; top: 0; } +.tagsclous a:nth-child(6n+1) { background: #f5f5f5; } +.tagsclous a:nth-child(6n+2) { background: #f5f5f5; } +.tagsclous a:nth-child(6n+3) { background: #f5f5f5; } +.tagsclous a:hover { background: #e01109; color: #fff } +@keyframes linescroll { 0% { +left:0px; +top:0px; +} +25% { +left:300px; +top:0px; +} +50% { +left:300px; +top:220px; +} +75% { +left:0px; +top:220px; +} +100% { +left:0px; +top:0px; +} +} +/*xiangce*/ +.xiangce_list ul { width: 25%; float: left; overflow: hidden; } +.xiangce_list li { margin: 10px } +.xiangce_list li a { margin: 0 0 30px 0; padding: 12px; background: white; border-radius: 3px; box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.05); display: block; } +.xiangce_list li img { width: 100%; margin: 0 auto 10px } +.xiangce_list li p { color: #666; text-align: center } +.xiangce_list li a:hover { box-shadow: 0px 2px 3px 1px rgba(0, 0, 0, 0.1); transform: translateY(-5px); transition: all .2s; } +.time_list { background: #fff; padding: 20px; } +.time_list li { line-height: 36px; } +.time_list li a { display: block; position: relative; } +.time_list li span { margin: 0 40px 0 0; float: left; color: #999; } +.time_list ul { position: relative; } +.time_list ul:before { position: absolute; content: ""; width: 2px; height: 100%; background: #ccc; left: 102px; top: 0; } +.time_list li a:before { position: absolute; content: ""; width: 12px; height: 12px; background: #fff; border: #ccc 2px solid; border-radius: 100%; left: 95px; top: 10px; } +.time_list li a:hover:before { background: #f00; } +.about { background: #fff; padding: 20px; font-size: 16px; line-height: 24px; } +.about p { margin: 10px 0; } +.about h2 { line-height: 40px; background: #f2f2f2; border-left: #000 4px solid; padding-left: 10px; margin: 10px 0; } +.about img { width: 80% !important; height: auto !important; margin: auto; } +.aside_right { padding: 20px; } +.aside_right h2 { margin: 0 0 10px 0; } +.aside_right ul { overflow: hidden; padding: 0 0 20px 0; } +.aside_right ul li { line-height: 30px; background: #f2f2f2; margin-bottom: 10px; text-indent: 1em; border-radius: 10px; } +.aside_right ol { line-height: 30px; margin-left: 30px; } +.container { background: #fff; padding: 20px; } +.container h1 { font-size: 24px; margin-bottom: 20px; } +.tags { overflow: hidden; margin: 10px 0; } +.tags a { display: block; float: left; background: #e01109; color: #fff; margin-right: 10px; padding: 4px 5px; } +.content { font-size: 16px; line-height: 24px; } +.content p { margin: 20px 0; } +.content img { margin: auto; max-width: 100% !important; height: auto !important; } +.info-pre-next { margin: 20px 0; } +.info-pre-next p { line-height: 30px; } +.info-pre-next p span { margin-right: 10px; font-weight: bold; } +.otherlink { margin: 20px 0; line-height: 26px; } +.otherlink h2, .pinglun_box h2 { margin-bottom: 10px; position: relative; } +.otherlink h2:before, .pinglun_box h2:before { position: absolute; content: ""; width: 4px; height: 100%; background: #f00; left: -20px; } + @media only screen and (max-width: 1200px) { +header, main { width: 90%; } +article { width: 68%; } +aside { width: 30%; } +} + @media only screen and (max-width: 768px) { +article { width: 100%; } +.touxiang { width: 60%; } +aside { display: none; } +nav ul li a { padding: 0 15px; } +img.weixin { z-index: 999; } +.suiyan_list ul { padding: 30px; } +.suiyan_list ul li { width: 33.33333%; } +.suiyan_list ul li a { padding: 10px; width: 180px; } +.suiyan_text { font-size: 14px; } +.suiyan_list ul li a:hover { z-index: 9; } +.xiangce_list li p { font-size: 14px; } +.xiangce_list li a { padding: 5px; } +.xiangce_list li { margin: 5px; } +} + @media only screen and (max-width: 480px) { +header, main { width: 96%; } +.touxiang { width: 100%; margin: 5px 0; } +.touxiang i { width: 60px; height: 60px; margin-right: 10px; } +.touxiang i img { width: 100%; } +.touxiang h2 { margin: 5px 0; } +.guanzhu { position: fixed; z-index: 9; bottom: 0; top: inherit; width: 100%; } +.guanzhu:hover .weixin { bottom: 30px; left: 33%; box-shadow: #b8b1b1 2px 2px 10px; } +footer { padding-bottom: 50px; margin-top: 20px } +nav { overflow-x: scroll; height: 40px; line-height: 40px; } +nav ul { width: max-content; overflow-x: scroll; } +.blogs li { padding: 10px; } +.blogs h2 { font-size: 16px; margin: 0 0 5px 0; } +.blogs li i { width: 90px; height: 60px; margin-right: 10px; } +.top_blog .blogs li::after { display: none; } +.top_blog .blogs li::before { display: none; } +.blog_info span:last-child { display: none; } +.suiyan_list ul li { width: 50%; } +.xiangce_list ul { width: 100% } +.xiangce_list li a { padding: 12px; } +.time_list li span { width: 100%; } +.time_list ul:before { left: 0; } +.time_list li a:before { left: -8px; } +.time_list li a { padding-left: 20px; } +.time_list li span { padding-left: 20px; } +.about img { width: 100% !important; } +.container h1 { font-size: 20px; } +.info-pre-next p, .otherlink li { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } +footer p span:last-child { display: block; } +main { overflow: hidden; } +} diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/001.jpg" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/001.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..d1ac5a248984080bda45ad76c4a6644c54ed35d4 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/001.jpg" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/002.png" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/002.png" new file mode 100644 index 0000000000000000000000000000000000000000..2b7e8bbcff16bdd64c56a61d747f4f649de0a97c Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/002.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/003.jpg" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/003.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..03d26e0d5bc827630d7f2308ce66f01ef883e372 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/003.jpg" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/004.jpg" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/004.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..c96f9ba0fbd30d914e48e27795953e3bfd496628 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/004.jpg" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/005.jpg" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/005.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..6f317b96efdcaf37d5ed1f830b22e4b1364b5b53 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/005.jpg" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/006.jpg" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/006.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..9c7d513bb8c83fd5fbc505130cd8002fd41a484d Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/006.jpg" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq1.png" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq1.png" new file mode 100644 index 0000000000000000000000000000000000000000..66ee2c171abd0180ae4a55b7a1c13bb1e4e2c8be Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq1.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq2.png" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq2.png" new file mode 100644 index 0000000000000000000000000000000000000000..de4c2bb8a8e9ddab91b0323af662d58e3c11b620 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq2.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq3.png" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq3.png" new file mode 100644 index 0000000000000000000000000000000000000000..20e7527ba5652c076cb1aeb77a5b9f1a2849f57c Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq3.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq4.png" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq4.png" new file mode 100644 index 0000000000000000000000000000000000000000..db35e2d7a35d67da596b36ce8143ba92be56da78 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq4.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq5.png" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq5.png" new file mode 100644 index 0000000000000000000000000000000000000000..2994698460c40ace8aa75d8bea521becb8252b61 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/bq5.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/ga.png" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/ga.png" new file mode 100644 index 0000000000000000000000000000000000000000..41870d162c7f19f9a04291d605253d9c2f00fd60 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/ga.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/icon.png" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/icon.png" new file mode 100644 index 0000000000000000000000000000000000000000..49bb3274c8531650ff9553824436130da43744ee Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/icon.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/search.png" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/search.png" new file mode 100644 index 0000000000000000000000000000000000000000..6b16a8616276c6ef5a8e5f16a72e3f773881b5e6 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/search.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/weizhi.png" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/weizhi.png" new file mode 100644 index 0000000000000000000000000000000000000000..5dd63065d641d9f3d438d87b72731e1f656fe5f1 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/weizhi.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/wx.png" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/wx.png" new file mode 100644 index 0000000000000000000000000000000000000000..6b0a522b1f3fce9d9c668607e2a55e42d5e515f6 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/wx.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/yangqq.png" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/yangqq.png" new file mode 100644 index 0000000000000000000000000000000000000000..1a03daa6e45f47f72630a7d5c57b086bd0e9b35c Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/images/yangqq.png" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/js/jquery.js" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/js/jquery.js" new file mode 100644 index 0000000000000000000000000000000000000000..dc20a8aba93124780b5e6b224b6db58735c15bce --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/static/js/jquery.js" @@ -0,0 +1,3 @@ +// JavaScript Document +/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 + + + +杨青青个人博客 + + + + + + +
+
杨青青 +

杨青青

+

一个爱好前端设计的80后女站长。

+
+

关注我杨青青个人微信号:476847113

+ +
+ +
+

您现在的位置是:网站首页>博客日记

+
+ + +
+
    +
  • 标题图片 +

    疫情之下,你在家办公了吗?

    +
    +

    这是一张朋友圈的集赞链接,活动是要求200个赞,我自己点了一个,还差199个,我朋友圈的好友大概2500+,虽然花了1个小时才完成,但是在“企业名录三群”我是第一个先集赞完成的,群里好友纷纷给我点赞,那天还不少朋友加我。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    想折腾也得看运气不是,我是不是太倒霉了?!

    +
    +

    给网站安装服务器系统对我来说已经不是什么问题了,但是安装电脑windows系统,我就是真的小白一枚,而且记不住,别人说,我操作一遍,隔天就能忘记!从我在京东下单购买电脑的记录来看,距离上一次安装windows环境已经一年了。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    从互联网消失的那3年,都去哪儿了?

    +
    +

    不少看过“关于我”页面介绍的朋友,怀着疑问来问我,这三年我都去哪儿了?在干什么?这里有提到过这三年,三年,作为一个女程序员,我从恋爱到结婚生子,到过上了相夫教子的家庭主妇生活。也正是因为怀孕后不能长时间上网,所以我有大把的时间用在了手机上,我离互联网越来越远,离我的个人博客小站也越来越远。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    兴趣支撑梦想,兴趣是支撑我自己前行的动力

    +
    +

    在没有学习前端设计,在没有自己博客之前,我的兴趣爱好很多,比如阅读,看电影,爬山等。这些是生活当中自己排遣娱乐的一种方式。明明觉得自己很喜欢,但有时候还是会半途而废,其实,有兴趣只是起点,保有持久兴趣才是关键。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    忙碌是自由活着的一种底气

    +
    +

    从我选择从事前端工作开始,有的人总是把这个职业想象的太美好,但当真正从事了这份职业后才发现,高薪的背后其实有太多的心酸和付出,有些是你想都想不到的。

    +

    2020-03-29杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    虽然闭关在家,但一刻也不想闲下来

    +
    +

    从疫情爆发到现在各个省市都开始陆续复工,我天天在家待着,除了带娃,我大部分时间还是在电脑前,甚至现在小朋友大部分时间也在电子产品上。从一月底到现在我一共设计了3套新模板.

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    想折腾也得看运气不是,我是不是太倒霉了?!

    +
    +

    给网站安装服务器系统对我来说已经不是什么问题了,但是安装电脑windows系统,我就是真的小白一枚,而且记不住,别人说,我操作一遍,隔天就能忘记!从我在京东下单购买电脑的记录来看,距离上一次安装windows环境已经一年了。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    从互联网消失的那3年,都去哪儿了?

    +
    +

    不少看过“关于我”页面介绍的朋友,怀着疑问来问我,这三年我都去哪儿了?在干什么?这里有提到过这三年,三年,作为一个女程序员,我从恋爱到结婚生子,到过上了相夫教子的家庭主妇生活。也正是因为怀孕后不能长时间上网,所以我有大把的时间用在了手机上,我离互联网越来越远,离我的个人博客小站也越来越远。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    兴趣支撑梦想,兴趣是支撑我自己前行的动力

    +
    +

    在没有学习前端设计,在没有自己博客之前,我的兴趣爱好很多,比如阅读,看电影,爬山等。这些是生活当中自己排遣娱乐的一种方式。明明觉得自己很喜欢,但有时候还是会半途而废,其实,有兴趣只是起点,保有持久兴趣才是关键。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
+
+ + +
+ + + + +
+ + + + + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/gybz.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/gybz.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..16e5c983941628a9707362e114a3c43e897ab9e3 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/gybz.tmpl" @@ -0,0 +1,78 @@ +{{define "gybz.tmpl"}} + + + + +杨青青个人博客 + + + + + + +
+
杨青青 +

杨青青

+

一个爱好前端设计的80后女站长。

+
+

关注我杨青青个人微信号:476847113

+ +
+ +
+

您现在的位置是:网站首页>我的相册

+ + +
+
+

这是一个前所未有、波澜壮阔的时代。七十载奋斗成就斐然,国人居住环境发生了天翻地覆的变化,从平房到筒子楼、单元楼,再到高层住宅、花园洋房、高端别墅,“居者有其屋”的朴素愿望已成昨天。何其有幸,我们生活成长在这样的七十年:搭乘时代的快车,见证了幸福的开花。

+

越努力越幸运

+ + 人生就是越努力越幸运! + +

幸福生活的创造,离不开每一位奋斗者的努力。七十年来,一代又一代奋斗者将对“国”的情意融入对品质的执着,对客户的珍视和对社会的担当。过去如此,未来亦然。

+

这些奋斗者不论职位高低,不论年龄大小,有来自一线的建筑工人,有发挥创意的建筑设计师,有兢兢业业的项目经理,有忘我工作的销售顾问,有踏实进取的经纪人。他们在自己平凡的岗位上默默付出,用点滴日夜里的细细耕作,融入美好时代的伟大进程。

+
+
+ + + +
+ + + + + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..7a945c214d6fca1d92e0c31d6da99b41e0859cc3 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/index.tmpl" @@ -0,0 +1,194 @@ +{{define "index.tmpl"}} + + + + +杨青青个人博客 + + + + + + +
+
杨青青 +

杨青青

+

一个爱好前端设计的80后女站长。

+
+

关注我杨青青个人微信号:476847113

+ +
+ +
+
+ +
+
    +
  • 标题图片 +

    兴趣支撑梦想,兴趣是支撑我自己前行的动力

    +
    +

    在没有学习前端设计,在没有自己博客之前,我的兴趣爱好很多,比如阅读,看电影,爬山等。这些是生活当中自己排遣娱乐的一种方式。明明觉得自己很喜欢,但有时候还是会半途而废,其实,有兴趣只是起点,保有持久兴趣才是关键。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    忙碌是自由活着的一种底气

    +
    +

    从我选择从事前端工作开始,有的人总是把这个职业想象的太美好,但当真正从事了这份职业后才发现,高薪的背后其实有太多的心酸和付出,有些是你想都想不到的。

    +

    2020-03-29杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    虽然闭关在家,但一刻也不想闲下来

    +
    +

    从疫情爆发到现在各个省市都开始陆续复工,我天天在家待着,除了带娃,我大部分时间还是在电脑前,甚至现在小朋友大部分时间也在电子产品上。从一月底到现在我一共设计了3套新模板.

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
+
+ + + +
+
    +
  • 标题图片 +

    疫情之下,你在家办公了吗?

    +
    +

    这是一张朋友圈的集赞链接,活动是要求200个赞,我自己点了一个,还差199个,我朋友圈的好友大概2500+,虽然花了1个小时才完成,但是在“企业名录三群”我是第一个先集赞完成的,群里好友纷纷给我点赞,那天还不少朋友加我。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    想折腾也得看运气不是,我是不是太倒霉了?!

    +
    +

    给网站安装服务器系统对我来说已经不是什么问题了,但是安装电脑windows系统,我就是真的小白一枚,而且记不住,别人说,我操作一遍,隔天就能忘记!从我在京东下单购买电脑的记录来看,距离上一次安装windows环境已经一年了。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    从互联网消失的那3年,都去哪儿了?

    +
    +

    不少看过“关于我”页面介绍的朋友,怀着疑问来问我,这三年我都去哪儿了?在干什么?这里有提到过这三年,三年,作为一个女程序员,我从恋爱到结婚生子,到过上了相夫教子的家庭主妇生活。也正是因为怀孕后不能长时间上网,所以我有大把的时间用在了手机上,我离互联网越来越远,离我的个人博客小站也越来越远。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    兴趣支撑梦想,兴趣是支撑我自己前行的动力

    +
    +

    在没有学习前端设计,在没有自己博客之前,我的兴趣爱好很多,比如阅读,看电影,爬山等。这些是生活当中自己排遣娱乐的一种方式。明明觉得自己很喜欢,但有时候还是会半途而废,其实,有兴趣只是起点,保有持久兴趣才是关键。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    忙碌是自由活着的一种底气

    +
    +

    从我选择从事前端工作开始,有的人总是把这个职业想象的太美好,但当真正从事了这份职业后才发现,高薪的背后其实有太多的心酸和付出,有些是你想都想不到的。

    +

    2020-03-29杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    虽然闭关在家,但一刻也不想闲下来

    +
    +

    从疫情爆发到现在各个省市都开始陆续复工,我天天在家待着,除了带娃,我大部分时间还是在电脑前,甚至现在小朋友大部分时间也在电子产品上。从一月底到现在我一共设计了3套新模板.

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    想折腾也得看运气不是,我是不是太倒霉了?!

    +
    +

    给网站安装服务器系统对我来说已经不是什么问题了,但是安装电脑windows系统,我就是真的小白一枚,而且记不住,别人说,我操作一遍,隔天就能忘记!从我在京东下单购买电脑的记录来看,距离上一次安装windows环境已经一年了。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    从互联网消失的那3年,都去哪儿了?

    +
    +

    不少看过“关于我”页面介绍的朋友,怀着疑问来问我,这三年我都去哪儿了?在干什么?这里有提到过这三年,三年,作为一个女程序员,我从恋爱到结婚生子,到过上了相夫教子的家庭主妇生活。也正是因为怀孕后不能长时间上网,所以我有大把的时间用在了手机上,我离互联网越来越远,离我的个人博客小站也越来越远。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
  • 标题图片 +

    兴趣支撑梦想,兴趣是支撑我自己前行的动力

    +
    +

    在没有学习前端设计,在没有自己博客之前,我的兴趣爱好很多,比如阅读,看电影,爬山等。这些是生活当中自己排遣娱乐的一种方式。明明觉得自己很喜欢,但有时候还是会半途而废,其实,有兴趣只是起点,保有持久兴趣才是关键。

    +

    2020-04-02杨青青博客人生13991200

    +
  • +
+
+ + +
+ + + + +
+ + + + + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/info.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/info.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..520fa4f9593c35def606878cd933b2c406765801 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/info.tmpl" @@ -0,0 +1,144 @@ +{{define "info.tmpl"}} + + + + +杨青青个人博客 + + + + + + +
+
杨青青 +

杨青青

+

一个爱好前端设计的80后女站长。

+
+

关注我杨青青个人微信号:476847113

+ +
+ +
+

您现在的位置是:网站首页>博客日记

+
+
+

兴趣支撑梦想,兴趣是支撑我自己前行的动力

+

2020-04-02杨青青博客人生13991200

+ +
在没有学习前端设计,在没有自己博客之前,我的兴趣爱好很多,比如阅读,看电影,爬山等。这些是生活当中自己排遣娱乐的一种方式。明明觉得自己很喜欢,但有时候还是会半途而废,其实,有兴趣只是起点,保有持久兴趣才是关键。 +

在学校的时候,我的专业是计算机软件,前端是第一学期的第一本书讲的课程。那会儿我不喜欢前端,出于是学校必修课程,所以不得不学,所有做的页面都是Table布局,我一点儿也学不进去。我可以在学校网吧里面熬夜装扮我的QQ空间,我也不愿意用表格去搭建一个网站。装扮QQ空间,我还能去结交点儿朋友,但是做网页,我不知道我要学这个干嘛。

+

+

直到交毕业设计,寝室的同学Copy来一份她高中同学做的网页,我们四个人,看得目瞪口呆。flash视频,音乐播放,图片点击再切换下一图,这些好多效果都在一个页面展示出来了,这样的毕业作品,我们四个人就是复制了他代码,改成自己的都改了好几天。

+

就从改他的源码开始,我觉得网站开发很好玩,做这么漂亮的网页,可以放视频,放照片,放音乐等等,为我埋下一颗兴趣的种子。也许我的兴趣是比较灵动的内在动力,做一个自己的个人博客网站,目的不为赚钱,只为了丰富自己,表现自己。

+

+

人在奋斗与进步的过程中最难办的是如何面对困难以及如何坚持下去。失去了兴趣,坚持不了多久。失去了意志力和自我控制力就难免会被带离初心与原生目标。

+

其实我就想顺着自己的一条道儿走就可以了

+
+
+ + +
+

文章评论

+
+
+
+ + + + +
+ + + + + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/sjz.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/sjz.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..6190f660d6c277970b283af9445f588160bbfa65 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/sjz.tmpl" @@ -0,0 +1,60 @@ +{{define "sjz.tmpl"}} + + + + +杨青青个人博客 + + + + + + +
+
杨青青 +

杨青青

+

一个爱好前端设计的80后女站长。

+
+

关注我杨青青个人微信号:476847113

+ +
+ +
+

您现在的位置是:网站首页>我的相册

+ +
+ + + + + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/sysy.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/sysy.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..066983a7d968b86f9b87759b5fc76d7fc472a8cf --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/sysy.tmpl" @@ -0,0 +1,80 @@ +{{define "sysy.tmpl"}} + + + + +杨青青个人博客 + + + + + + +
+
杨青青 +

杨青青

+

一个爱好前端设计的80后女站长。

+
+

关注我杨青青个人微信号:476847113

+ +
+ +
+

您现在的位置是:网站首页>碎言碎语

+ +
+ + + + + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/wdxc.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/wdxc.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..159aaa34968fbbff9f1ec03a5ffb1516f680ecfb --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09-2/templates/wdxc.tmpl" @@ -0,0 +1,78 @@ +{{define "wdxc.tmpl"}} + + + + +杨青青个人博客 + + + + + + +
+
杨青青 +

杨青青

+

一个爱好前端设计的80后女站长。

+
+

关注我杨青青个人微信号:476847113

+ +
+ +
+

您现在的位置是:网站首页>我的相册

+ +
+ + + + + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..0dddb8ffbcbba8a80c949675f06da6a11f3c9154 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09/main.go" @@ -0,0 +1,62 @@ +/** Gin框架的使用 + * @Description + * @Author 陌溪 + * @Date 2020/9/16 22:10 + **/ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" + "html/template" + "net/http" + "os" +) + +/** + * @Description 主函数 + * @Param + * @return + **/ +func main() { + // 找到模板路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + r := gin.Default() + // 模板解析 + //r.LoadHTMLFiles(wd + "/lesson09/templates/users/index.tmpl", wd + "/lesson09/templates/posts/index.tmpl") + + // Gin框架中添加自定义的函数 + r.SetFuncMap(template.FuncMap{ + "safe": func(str string) template.HTML{ + return template.HTML(str) + }, + }) + + // 使用全局匹配规则 + r.LoadHTMLGlob(wd + "/lesson09/templates/**/*") + + r.Static("/xxx", wd + "/lesson09/static") + + // 模板渲染 + r.GET("/posts/index", func(context *gin.Context) { + // HTTP请求 + context.HTML(http.StatusOK, "posts/index.tmpl", gin.H{ + "title": "www.moguit.cn", + }) + }) + + // 模板渲染 + r.GET("/users/index", func(context *gin.Context) { + // HTTP请求 + context.HTML(http.StatusOK, "users/index.tmpl", gin.H{ + "title": "admin.moguit.cn", + }) + }) + + // 启动Server + r.Run(":9090") +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09/static/index.css" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09/static/index.css" new file mode 100644 index 0000000000000000000000000000000000000000..f932716802ce3b5920ddd26e9b533b170f84ee3e --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09/static/index.css" @@ -0,0 +1,3 @@ +* { + background-color: antiquewhite; +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09/static/index.js" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09/static/index.js" new file mode 100644 index 0000000000000000000000000000000000000000..5556fb3132c96844ecc686fc82b498877a595d16 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09/static/index.js" @@ -0,0 +1 @@ +alert(1) \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09/templates/posts/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09/templates/posts/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..24388fc9f8f1effa352f7839c853ff5e96669b8a --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09/templates/posts/index.tmpl" @@ -0,0 +1,16 @@ +{{define "posts/index.tmpl"}} + + + + + + + posts/index + + + +{{safe .title}} + + + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson09/templates/users/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09/templates/users/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..24cb364da216470d9c7212503c611858e7ce8552 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson09/templates/users/index.tmpl" @@ -0,0 +1,14 @@ +{{define "users/index.tmpl"}} + + + + + + + posts/index + + +{{.title}} + + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson10/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson10/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..03427cd0fc47ecb5409293608cb6c195ed1bc3e4 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson10/main.go" @@ -0,0 +1,60 @@ +/** Gin框架使用Json格式返回数据 + * @Description + * @Author 陌溪 + * @Date 2020/9/16 22:10 + **/ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" + "net/http" +) + +/** + * @Description 定义一个消息结构体 + **/ +type msg struct{ + Name string + Message string + Age int +} + +/** + * @Description 主函数 + * @Param + * @return + **/ +func main() { + + + // 生成默认的路由 + r := gin.Default() + + r.GET("/json", func(context *gin.Context) { + //data := map[string]interface{}{ + // "name": "小王子", + // "age": 18, + // "message": "hello gin json", + //} + + // gin中的 map[string]interface{} 类型 + data := gin.H{ + "name": "小王子", + "age": 18, + "message": "hello gin json", + } + + data2 := msg{ + Name: "小王子", + Age: 10, + Message: "hello 小王子", + } + fmt.Println(data2) + // Json的序列化,默认是使用Go内部的序列化 + context.JSON(http.StatusOK, data) + }) + + // 启动Server + r.Run(":9090") +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson10/static/index.css" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson10/static/index.css" new file mode 100644 index 0000000000000000000000000000000000000000..f932716802ce3b5920ddd26e9b533b170f84ee3e --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson10/static/index.css" @@ -0,0 +1,3 @@ +* { + background-color: antiquewhite; +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson10/static/index.js" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson10/static/index.js" new file mode 100644 index 0000000000000000000000000000000000000000..5556fb3132c96844ecc686fc82b498877a595d16 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson10/static/index.js" @@ -0,0 +1 @@ +alert(1) \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson10/templates/posts/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson10/templates/posts/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..24388fc9f8f1effa352f7839c853ff5e96669b8a --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson10/templates/posts/index.tmpl" @@ -0,0 +1,16 @@ +{{define "posts/index.tmpl"}} + + + + + + + posts/index + + + +{{safe .title}} + + + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson10/templates/users/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson10/templates/users/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..24cb364da216470d9c7212503c611858e7ce8552 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson10/templates/users/index.tmpl" @@ -0,0 +1,14 @@ +{{define "users/index.tmpl"}} + + + + + + + posts/index + + +{{.title}} + + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson11/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson11/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..9ae72c513f94c944bd258b9b9aaf037407f0c442 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson11/main.go" @@ -0,0 +1,58 @@ +/** + * @Description Gin框架使用 QueryString,从前台接收参数 + * @Author 陌溪 + * @Date 2020年9月17日14:52:33 + **/ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" + "net/http" +) + +/** + * @Description 主函数 + * @Param + * @return + **/ +func main() { + + // 生成默认的路由 + r := gin.Default() + + // GET请求 URL ?后面是querystring参数 + r.GET("/web", func(context *gin.Context) { + + // 获取浏览器那边发请求携带的query string参数 + // http://localhost:9090/web?keyword=123 -> 这样就能获取到keyword + keyword := context.Query("keyword") + + // 获取UserName,如果不存在就取默认值 + userName := context.DefaultQuery("userName", "default user") + fmt.Println(userName) + + // 取不到就返回false + name, ok := context.GetQuery("name") + if ok { + fmt.Println("没有获取到name") + return + } + fmt.Print(name) + + + // gin中的 map[string]interface{} 类型 + data := gin.H{ + "name": "小王子", + "age": 18, + "message": "hello gin json", + "keyword": keyword, + } + + // Json的序列化,默认是使用Go内部的序列化 + context.JSON(http.StatusOK, data) + }) + + // 启动Server + r.Run(":9090") +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson12/error.html" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson12/error.html" new file mode 100644 index 0000000000000000000000000000000000000000..c3b288c0430977f3bf9c84ad3391206909f9c4e8 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson12/error.html" @@ -0,0 +1,12 @@ +{{define "index.tmpl"}} + + + + + error + + +

错误页面

+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson12/home.html" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson12/home.html" new file mode 100644 index 0000000000000000000000000000000000000000..bc4188612c5f6d6a5eb2128716a84b8ceea65d15 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson12/home.html" @@ -0,0 +1,12 @@ +{{define "home.html"}} + + + + + Home + + +

hello {{.}}

+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson12/login.html" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson12/login.html" new file mode 100644 index 0000000000000000000000000000000000000000..85afc481e3167af58e39a52b1f3bbab2beb3eab2 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson12/login.html" @@ -0,0 +1,22 @@ +{{define "login.html"}} + + + + + Login + + +
+
+ + +
+
+ + +
+ +
+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson12/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson12/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..cd209499708af38fec3839adb4516e260a0c190c --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson12/main.go" @@ -0,0 +1,54 @@ +/** + * @Description Gin框架 接收 Form表单提交的参数 + * @Author 陌溪 + * @Date 2020年9月17日15:12:32 + **/ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" + "net/http" + "os" +) + +/** + * @Description 主函数 + * @Param + * @return + **/ +func main() { + // 找到模板路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + + // 生成默认的路由 + r := gin.Default() + + r.LoadHTMLFiles(wd + "/lesson12/login.html", wd + "/lesson12/home.html", wd + "/lesson12/index.tmpl") + + r.GET("/login", func(context *gin.Context) { + context.HTML(http.StatusOK, "login.html", nil) + }) + + r.POST("/login", func(context *gin.Context) { + + username := context.PostForm("username") + password := context.PostForm("password") + + if username == "admin" && password == "admin" { + context.HTML(http.StatusOK, "home.html", username) + } else { + context.HTML(http.StatusOK, "index.tmpl", nil) + } + + }) + + + + // 启动Server + r.Run(":9090") +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson13/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson13/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..9b59664a658db64a37d9cabf671a8e5ad69d548a --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson13/index.tmpl" @@ -0,0 +1,14 @@ +{{define "index.tmpl"}} + + + + + error + + +

参数信息

+

{{.name}}

+

{{.age}}

+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson13/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson13/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..4664823feb356aef41449164881d4575f88d1234 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson13/main.go" @@ -0,0 +1,56 @@ +/** + * @Description Gin框架 接收 URL Path上的参数 【注意,返回的都是string类型】 + * @Author 陌溪 + * @Date 2020年9月17日16:26:43 + **/ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" + "net/http" + "os" +) + +/** + * @Description 主函数 + * @Param + * @return + **/ +func main() { + // 找到模板路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + + // 生成默认的路由 + r := gin.Default() + + r.LoadHTMLFiles(wd + "/lesson13/index.tmpl") + + r.GET("/user/:name/:age", func(context *gin.Context) { + name := context.Param("name") + age := context.Param("age") + data := gin.H{ + "name": name, + "age": age, + } + context.HTML(http.StatusOK, "index.tmpl", data) + }) + + r.GET("/posts/:name/:age", func(context *gin.Context) { + name := context.Param("name") + age := context.Param("age") + data := gin.H{ + "name": name, + "age": age, + } + context.HTML(http.StatusOK, "index.tmpl", data) + }) + + + // 启动Server + r.Run(":9090") +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson14/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson14/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..0bce069159edc49e87bdcd4667fd03a187d4c722 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson14/index.tmpl" @@ -0,0 +1,14 @@ +{{define "index.tmpl"}} + + + + + error + + +

参数信息

+

{{.Username}}

+

{{.Password}}

+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson14/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson14/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..19fcf0a46a013f3e4927f9c8d72bf9101915b838 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson14/main.go" @@ -0,0 +1,96 @@ +/** + * @Description Gin框架中的 参数绑定,也就是将结构体和我们的参数进行绑定 + * @Author 陌溪 + * @Date 2020年9月17日17:12:04 + **/ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" + "net/http" +) + +type UserInfo struct { + Username string `form:"username" json:"username" binding:"required"` + Password string `form:"password" json:"password" binding:"required"` +} +/** + * @Description 主函数 + * @Param + * @return + **/ +func main() { + // 找到模板路径 + // 生成默认的路由 + r := gin.Default() + + // 请求方式 http://localhost:9090/user?username=zhangsan&password=123 + r.GET("/user", func(context *gin.Context) { + //username := context.Param("username") + //password := context.Param("password") + //u := UserInfo{ + // UserName: username, + // Password: password, + //} + + var userInfo UserInfo + // 传递的是指针,将参数绑定到UserInfo中 + err := context.ShouldBind(&userInfo) + fmt.Println(userInfo) + if err != nil { + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + } else { + context.JSON(http.StatusOK, gin.H{ + "status": "ok", + "userInfo": userInfo, + }) + } + }) + + r.GET("/form", func(context *gin.Context) { + var userInfo UserInfo + // 传递的是指针,将参数绑定到UserInfo中 + err := context.ShouldBind(&userInfo) + fmt.Println(userInfo) + if err != nil { + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + } else { + context.JSON(http.StatusOK, gin.H{ + "status": "ok", + "userInfo": userInfo, + }) + } + }) + + /** + * @Description 前端发送Json格式的请求 + * @Param + * @return + **/ + r.POST("/json", func(context *gin.Context) { + + var userInfo UserInfo + // 传递的是指针,将参数绑定到UserInfo中 + err := context.ShouldBind(&userInfo) + fmt.Println(userInfo) + if err != nil { + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + } else { + context.JSON(http.StatusOK, gin.H{ + "status": "ok", + "userInfo": userInfo, + }) + } + }) + + + // 启动Server + r.Run(":9090") +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson15/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson15/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..cb168e4d2853a9f85dedfb11550218a580ff4390 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson15/index.tmpl" @@ -0,0 +1,15 @@ +{{define "index.tmpl"}} + + + + + 文件上传 + + +
+ + +
+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson15/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson15/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..e1c46617a30ede74a86e70b8412442c279452a45 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson15/main.go" @@ -0,0 +1,71 @@ +/** + * @Description Gin框架中的 文件上传 + * @Author 陌溪 + * @Date 2020年9月17日17:12:04 + **/ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" + "net/http" + "os" +) + +type UserInfo struct { + Username string `form:"username" json:"username" binding:"required"` + Password string `form:"password" json:"password" binding:"required"` +} +/** + * @Description 主函数 + * @Param + * @return + **/ +func main() { + // 找到模板路径 + // 生成默认的路由 + r := gin.Default() + + // 找到模板路径 + wd, err := os.Getwd() + if err != nil { + fmt.Printf("get wd failed, err:%v \n", wd) + return + } + // 加载模板 + r.LoadHTMLFiles(wd + "/lesson15/index.tmpl") + + /** + * @Description 跳转到文件上传页面 + * @Param + * @return + **/ + r.GET("/index", func(context *gin.Context) { + context.HTML(http.StatusOK, "index.tmpl", nil) + }) + + /** + * @Description 图片上传接口 + * @Param + * @return + **/ + r.POST("/upload", func(context *gin.Context) { + // 从请求中读取文件【和请求中获取携带的参数是一样的】 + fileObj, err := context.FormFile("f1") + if err != nil { + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + } else { + // 将读取的文件保存到本地【服务端本地】 + dst := fmt.Sprintf("./%s", fileObj.Filename) + context.SaveUploadedFile(fileObj, dst) + context.JSON(http.StatusOK, gin.H{ + "success": "上传成功", + }) + } + }) + + // 启动Server + r.Run(":9090") +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson16/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson16/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..cb168e4d2853a9f85dedfb11550218a580ff4390 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson16/index.tmpl" @@ -0,0 +1,15 @@ +{{define "index.tmpl"}} + + + + + 文件上传 + + +
+ + +
+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson16/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson16/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..16a24b0aa54c7c9a26a976f12826a77e7018250f --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson16/main.go" @@ -0,0 +1,53 @@ +/** + * @Description Gin框架中的 请求重定向 + * @Author 陌溪 + * @Date 2020年9月17日17:12:04 + **/ +package main + +import ( + "github.com/gin-gonic/gin" + "net/http" +) + +/** + * @Description 主函数 + * @Param + * @return + **/ +func main() { + // 找到模板路径 + // 生成默认的路由 + r := gin.Default() + + + /** + * @Description 请求重定向 + * @Param + * @return + **/ + r.GET("/baidu", func(context *gin.Context) { + context.Redirect(http.StatusMovedPermanently, "http://www.baidu.com") + }) + + /** + * @Description 请求重定向【返回的是/b的数据】 + * @Param + * @return + **/ + r.GET("/a", func(context *gin.Context) { + // 把请求的URI修改 + context.Request.URL.Path = "/b" + // 继续后续的处理,重新请求 /b + r.HandleContext(context) + }) + + r.GET("/b", func(context *gin.Context) { + context.JSON(http.StatusOK, gin.H{ + "success": "我是/b", + }) + }) + + // 启动Server + r.Run(":9090") +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson17/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson17/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..cb168e4d2853a9f85dedfb11550218a580ff4390 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson17/index.tmpl" @@ -0,0 +1,15 @@ +{{define "index.tmpl"}} + + + + + 文件上传 + + +
+ + +
+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson17/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson17/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..0f33167ea0ebceef830c5301fca1ad09a237e3b1 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson17/main.go" @@ -0,0 +1,102 @@ +/** + * @Description Gin框架中的 Gin路由 和 路由组 + * @Author 陌溪 + * @Date 2020年9月17日18:36:05 + **/ +package main + +import ( + "github.com/gin-gonic/gin" + "net/http" +) + +/** + * @Description 主函数 + * @Param + * @return + **/ +func main() { + // 找到模板路径 + // 生成默认的路由 + r := gin.Default() + + + /** + * @Description 访问/index的GET请求会走这一条处理逻辑【】 + * @Param + * @return + **/ + r.GET("/index", func(context *gin.Context) { + context.JSON(http.StatusOK, gin.H{ + "code": "success", + "message": "GET", + }) + }) + + r.POST("/index", func(context *gin.Context) { + context.JSON(http.StatusOK, gin.H{ + "code": "success", + "message": "POST", + }) + }) + + /** + * @Description PUT是更新操作 + * @Param + * @return + **/ + r.PUT("/index", func(context *gin.Context) { + context.JSON(http.StatusOK, gin.H{ + "code": "success", + "message": "PUT", + }) + }) + + /** + * @Description DELETE是删除操作 + * @Param + * @return + **/ + r.DELETE("/index", func(context *gin.Context) { + context.JSON(http.StatusOK, gin.H{ + "code": "success", + "message": "DELETE", + }) + }) + + /** + * @Description 当所有的路由都没匹配,返回404页面 + * @Param + * @return + **/ + r.NoRoute(func(context *gin.Context) { + context.JSON(http.StatusNotFound, gin.H{ + "code": "404", + "message": "NoRoute", + }) + }) + + // 路由组,把共用的前缀提取出来,创建一个路由组 + videoGroup := r.Group("/video") + { + videoGroup.GET("/index", func(context *gin.Context) { + context.JSON(http.StatusOK, gin.H{ + "msg": "/video/index", + }) + }) + videoGroup.GET("/about", func(context *gin.Context) { + context.JSON(http.StatusOK, gin.H{ + "msg": "/video/about", + }) + }) + videoGroup.GET("/home", func(context *gin.Context) { + context.JSON(http.StatusOK, gin.H{ + "msg": "/video/home", + }) + }) + } + + + // 启动Server + r.Run(":8080") +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson18/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson18/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..cb168e4d2853a9f85dedfb11550218a580ff4390 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson18/index.tmpl" @@ -0,0 +1,15 @@ +{{define "index.tmpl"}} + + + + + 文件上传 + + +
+ + +
+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson18/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson18/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..74abbcfdd6152c7c79079eee2a29ae8f1b9a94d5 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson18/main.go" @@ -0,0 +1,98 @@ +/** + * @Description Gin框架中的 中间件 + * @Author 陌溪 + * @Date 2020年9月17日20:54:58 + **/ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" + "net/http" + "time" +) + +/** + * @Description 定义一个中间件 + * @Param context + * @return + **/ +func indexHandle(context *gin.Context) { + fmt.Println("index") + context.JSON(http.StatusOK, gin.H{ + "code": "success", + "message": "GET", + }) +} + +/** + * @Description 定义第一个中间件 + * @Param context + * @return + **/ +func timeHandle(context *gin.Context) { + fmt.Println("index2") + // 获取开始时间 + start := time.Now() + time.Sleep(time.Second) + context.JSON(http.StatusOK, gin.H{ + "code": "success", + "message": "GET", + }) + + // 调用该请求的剩余处理程序 + context.Next() + + // 计算耗时 + cost := time.Since(start) + fmt.Println("消耗的时间:", cost) +} + +/** + * @Description 鉴权中间件 + * @Param doCheck 是否开启校验 + * @return + **/ +func authMiddleware(doCheck bool)gin.HandlerFunc { + // 连接数据库 + // 或者一些其它工作 + return func(context *gin.Context) { + // 存放具体的逻辑 + // 是否登录的判断 + // if是登录用户 + // c.Next() + // else + // c.Abort() + } +} + +/** + * @Description 主函数 + * @Param + * @return + **/ +func main() { + // 找到模板路径 + // 生成默认的路由【默认包含了Logger() 和 Recovery() 中间件】 + r := gin.Default() + + // 全局注册中间件【全局注册后,就不需要在其它地方在写一次了】 + r.Use(timeHandle) + + /** + * @Description index方法 + * @Param + * @return + **/ + // r.GET("/index", indexHandle, timeHandle) + + r.GET("/index", indexHandle) + + r.GET("/home", indexHandle) + + r.GET("/about", indexHandle) + + + // 启动Server + r.Run(":8080") +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson19/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson19/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..cb168e4d2853a9f85dedfb11550218a580ff4390 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson19/index.tmpl" @@ -0,0 +1,15 @@ +{{define "index.tmpl"}} + + + + + 文件上传 + + +
+ + +
+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson19/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson19/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..df7e6a08a57322c3cfe2f2ad64b6a5762a78f399 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson19/main.go" @@ -0,0 +1,57 @@ +/** + * @Description Gin框架中 使用GORM + * @Author 陌溪 + * @Date 2020年9月17日21:38:50 + **/ +package main + +// 导入mysql驱动 +import ( + "fmt" + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mysql" +) + +/** + * @Description UserInfo 用户信息 + **/ +type UserInfo struct { + ID uint + Name string + Gender string + Hobby string +} + +func main() { + db, err := gorm.Open("mysql", "root:root@(localhost)/mogu_demo?charset=utf8mb4&parseTime=True&loc=Local") + defer db.Close() + if err != nil { + fmt.Printf("connect msyql failed, err: %v \n", err) + return + } + fmt.Println("connect mysql success") + + // 自动迁移【把结构体和数据表进行对应】 + db.AutoMigrate(&UserInfo{}) + + // 创建记录 + u1 := UserInfo{ + ID: 1, + Name: "陌溪", + Gender: "男", + Hobby: "看书", + } + db.Create(&u1) + + // 查询数据 + var u UserInfo + db.First(&u) + fmt.Printf("u: %#v \n", u) + + // 更新 + db.Model(&u).Update("hobby", "双色球") + + // 删除 + db.Delete(&u) + +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson20/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson20/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..cb168e4d2853a9f85dedfb11550218a580ff4390 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson20/index.tmpl" @@ -0,0 +1,15 @@ +{{define "index.tmpl"}} + + + + + 文件上传 + + +
+ + +
+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson20/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson20/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..fe0c19cf6cbe236fd8e021222370a7f70d5aa896 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson20/main.go" @@ -0,0 +1,74 @@ +/** + * @Description Gin框架中 使用GORM中的Model + * @Author 陌溪 + * @Date 2020年9月17日21:38:50 + **/ +package main + +// 导入mysql驱动 +import ( + "database/sql" + "fmt" + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mysql" + "time" +) + +/** + * @Description 定义模型 + **/ +type User struct { + // 内嵌gorm.Model + gorm.Model + Name string + Age sql.NullInt64 // 零值类型 + Birthday *time.Time + // 建立唯一索引 + Email string `gorm:"type:varchar(100);unique_index"` + Role string `gorm:"size:255"` // 设置字段大小为255 + MemberNumber *string `gorm:"unique;not null"` // 设置会员号(member number)唯一并且不为空 + Num int `gorm:"AUTO_INCREMENT"` // 设置 num 为自增类型 + Address string `gorm:"index:addr"` // 给address字段创建名为addr的索引 + IgnoreMe int `gorm:"-"` // 忽略本字段,不会存在数据库中 +} + +func main() { + + // 关于默认表名的修改函数 + gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string { + return "prefix_" + defaultTableName; + } + + db, err := gorm.Open("mysql", "root:root@(localhost)/mogu_demo?charset=utf8mb4&parseTime=True&loc=Local") + defer db.Close() + if err != nil { + fmt.Printf("connect msyql failed, err: %v \n", err) + return + } + fmt.Println("connect mysql success") + + // 禁用表名的负数形式【默认会在表名后面加s】 + db.SingularTable(false) + + // 自动迁移【把结构体和数据表进行对应】 + db.AutoMigrate(&User{}) + + // 创建记录 + u1 := User{ + Name: "陌溪", + } + + db.Create(&u1) + + // 查询数据 + var u User + db.First(&u) + fmt.Printf("u: %#v \n", u) + + // 更新 + db.Model(&u).Update("hobby", "双色球") + + // 删除 + db.Delete(&u) + +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson21/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson21/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..cb168e4d2853a9f85dedfb11550218a580ff4390 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson21/index.tmpl" @@ -0,0 +1,15 @@ +{{define "index.tmpl"}} + + + + + 文件上传 + + +
+ + +
+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson21/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson21/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..b3d2b5614db0d440433264533282c9387282147d --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson21/main.go" @@ -0,0 +1,84 @@ +/** + * @Description Gin框架中 使用GORM增删改查 + * @Author 陌溪 + * @Date 2020年9月17日21:38:50 + **/ +package main + +// 导入mysql驱动 +import ( + "fmt" + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mysql" +) + +/** + * @Description 定义模型 + **/ +type User struct { + ID int64 + Name string + Age int64 + // 设置默认值【注意:通过tag定义字段的默认值,在创建记录时候生成的SQL语句会排除没有值或零值的字段。在将记录插入到数据库后,Gorm会】 + Gender string `gorm:"default:'男'"` +} + +func main() { + + // 关于默认表名的修改函数 + gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string { + return "prefix_" + defaultTableName; + } + + db, err := gorm.Open("mysql", "root:root@(localhost)/mogu_demo?charset=utf8mb4&parseTime=True&loc=Local") + defer db.Close() + if err != nil { + fmt.Printf("connect msyql failed, err: %v \n", err) + return + } + fmt.Println("connect mysql success") + + // 禁用表名的负数形式【默认会在表名后面加s】 + db.SingularTable(false) + + // 自动迁移【把结构体和数据表进行对应】 + db.AutoMigrate(&User{}) + + // 在代码层面创建一个结构体对象 + u1 := User{ + Name: "陌溪", + Age: 16, + } + + // 创建结构体 【这里推荐传递一个指针进去,直接传结构体存在一个拷贝的问题,如果结构体比较大,可能会有时间消耗】 + fmt.Println("判断主键是否为空:", db.NewRecord(&u1)) // true 因为数据库中没有记录 + db.Create(&u1) + fmt.Println("判断主键是否为空:", db.NewRecord(&u1)) // false 因为数据库中有记录 + + // 查询数据【&u是接收查询结果的】 + var u User + // 传入u的地址,用于修改u的内容 + db.First(&u) + fmt.Printf("u: %#v \n", u) + + // 查询多条记录 + var users []User + // 通过DEBUG查看执行的SQL语句 + db.Debug().Find(&users) + fmt.Printf("users: %#v \n", users) + + // where条件查询 + var whereUsers []User + db.Where(map[string]interface{}{ + "ID": 1, + }).Debug().Find(&whereUsers) + fmt.Printf("where users: %#v \n", whereUsers) + + + //// 更新 + //db.Model(&u).Update("hobby", "双色球") + // + //// 删除 + //db.Delete(&u) + +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson22/index.tmpl" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson22/index.tmpl" new file mode 100644 index 0000000000000000000000000000000000000000..cb168e4d2853a9f85dedfb11550218a580ff4390 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson22/index.tmpl" @@ -0,0 +1,15 @@ +{{define "index.tmpl"}} + + + + + 文件上传 + + +
+ + +
+ + +{{end}} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson22/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson22/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..64c173d009fbe5c31772f2cb92e2b705c032999f --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson22/main.go" @@ -0,0 +1,75 @@ +/** + * @Description Gin框架中 GORM更新操作 + * @Author 陌溪 + * @Date 2020年9月18日10:57:57 + **/ +package main + +// 导入mysql驱动 +import ( + "fmt" + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mysql" +) + +/** + * @Description 定义模型 + **/ +type User struct { + gorm.Model + Name string + Age int64 + // 用户是否激活 + Active bool +} + +func main() { + + db, err := gorm.Open("mysql", "root:root@(localhost)/mogu_demo?charset=utf8mb4&parseTime=True&loc=Local") + defer db.Close() + if err != nil { + fmt.Printf("connect msyql failed, err: %v \n", err) + return + } + + fmt.Println("connect mysql success") + + // 禁用表名的负数形式【默认会在表名后面加s】 + db.SingularTable(false) + + // 自动迁移【把结构体和数据表进行对应】 + db.AutoMigrate(&User{}) + + // 创建记录 + u1 := User{Name: "moxi", Age: 18, Active: true} + db.Create(&u1) + + u2 := User{Name: "jinzhou", Age: 20, Active: true} + db.Create(&u2) + + // 查询 + var user User + db.First(&user) + fmt.Printf("user: %v \n", user) + + // 修改 + user.Name = "qimi" + user.Age = 99 + // 默认会修改全部的字段 + db.Debug().Save(&user) + + // 更新指定的字段 + db.Debug().Model(&user).Update("name", "小王子") + + // 忽略某个字段 【通过omit忽略active字段】 + m1 := map[string]interface{}{ + "name": "小溪", + "age": 28, + "active": true, + } + db.Model(&user).Omit("active").Updates(m1) + + + + +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/go.mod" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/go.mod" new file mode 100644 index 0000000000000000000000000000000000000000..bab42324bbd44c051be6ea503a3dc1f35f9ed4c0 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/go.mod" @@ -0,0 +1,17 @@ +module bubble + +go 1.14 + +require ( + github.com/gin-gonic/gin v1.6.3 // indirect + github.com/go-playground/validator/v10 v10.3.0 // indirect + github.com/golang/protobuf v1.4.2 // indirect + github.com/jinzhu/gorm v1.9.16 // indirect + github.com/json-iterator/go v1.1.10 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/ugorji/go v1.1.8 // indirect + golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20 // indirect + google.golang.org/protobuf v1.25.0 // indirect + gopkg.in/yaml.v2 v2.3.0 // indirect +) diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/go.sum" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/go.sum" new file mode 100644 index 0000000000000000000000000000000000000000..abc31678f8628d2c0284322e2b2661cbc5c9f925 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/go.sum" @@ -0,0 +1,146 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.3.0 h1:nZU+7q+yJoFmwvNgv/LnPUkwPal62+b2xXj0AU1Es7o= +github.com/go-playground/validator/v10 v10.3.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= +github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.1.8 h1:/D9x7IRpfMHDlizVOgxrag5Fh+/NY+LtI8bsr+AswRA= +github.com/ugorji/go v1.1.8/go.mod h1:0lNM99SwWUIRhCXnigEMClngXBk/EmpTXa7mgiewYWA= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.1.8 h1:4dryPvxMP9OtkjIbuNeK2nb27M38XMHLGlfNSNph/5s= +github.com/ugorji/go/codec v1.1.8/go.mod h1:X00B19HDtwvKbQY2DcYjvZxKQp8mzrJoQ6EgoIY/D2E= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20 h1:4X356008q5SA3YXu8PiRap39KFmy4Lf6sGlceJKZQsU= +golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..99fb3ddd97669994985898e3bfe22a99fa89f4ab --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/main.go" @@ -0,0 +1,163 @@ +/** + * @Description 待办事项后台接口 + * @Author 陌溪 + * @Date 2020/9/18 16:02 + **/ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mysql" + "net/http" +) + +/** + * @Description 定义全局的数据库对象 + **/ +var ( + DB *gorm.DB +) + +/** + * @Description 实体类 + * @Param + * @return + **/ +type Todo struct { + ID int `json:"id"` + Title string `json:"title"` + Status bool `json:"status"` +} + +/** + * @Description 初始化mysql + * @Param + * @return err + **/ +func initMySQL() (err error) { + DB, err = gorm.Open("mysql", "root:root@(localhost)/mogu_demo?charset=utf8mb4&parseTime=True&loc=Local") + if err != nil { + fmt.Printf("connect msyql failed, err: %v \n", err) + return + } + // 测试是否能够连通 + return DB.DB().Ping() +} + +func main() { + + err := initMySQL() + if err != nil { + panic(err) + } else { + fmt.Println("connect mysql success") + } + // 延迟关闭数据库 + defer DB.Close() + + // 模型关闭 自动迁移【把结构体和数据表进行对应】 + DB.AutoMigrate(&Todo{}) + + // 定义Gin默认路由 + r := gin.Default() + // 告诉Gin框架模板文件引用的静态文件去哪里找 + r.Static("/static", "static") + // 告诉Gin框架去哪里找模板文件 + r.LoadHTMLGlob("templates/*") + + // 访问待办事项首页 + r.GET("/", func(c *gin.Context) { + c.HTML(http.StatusOK, "index.html", nil) + }) + + // v1 待办事项 + // 前端页面填写代办事项,点击提交就会发送请求到这里 + v1Group := r.Group("v1") + { + // 添加 + v1Group.POST("/todo", func(context *gin.Context) { + // 从请求中把数据取出来 + var todo Todo + context.BindJSON(&todo) + // 存入数据库 + err := DB.Create(&todo).Error + // 响应 + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "error": err.Error(), + }) + } else { + context.JSON(http.StatusOK, todo) + } + }) + // 查看【查看所有】 + v1Group.GET("/todo", func(context *gin.Context) { + // 查询所有数据 + var todoList [] Todo + err := DB.Find(&todoList).Error + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "error": err.Error(), + }) + } else { + context.JSON(http.StatusOK, todoList) + } + }) + // 查看【查看某个】 + v1Group.GET("/todo/:id", func(context *gin.Context) { + + }) + // 修改 + v1Group.PUT("/todo/:id", func(context *gin.Context) { + id, ok := context.Params.Get("id") + if !ok { + context.JSON(http.StatusOK, gin.H{ + "error": err.Error(), + }) + } else { + var todo Todo + err := DB.Where("id=?", id).First(&todo).Error + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "error": err.Error(), + }) + } else { + // 将内容进行修改 + context.BindJSON(&todo) + err = DB.Save(&todo).Error + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "error": err.Error(), + }) + } else { + context.JSON(http.StatusOK, todo) + } + } + } + }) + + // 删除 + v1Group.DELETE("/todo/:id", func(context *gin.Context) { + id, ok := context.Params.Get("id") + if !ok { + context.JSON(http.StatusOK, gin.H{ + "error": err.Error(), + }) + } else { + var todo Todo + err := DB.Where("id=?", id).Delete(todo) + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "error": err, + }) + } else { + context.JSON(http.StatusOK, todo) + } + } + }) + } + + r.Run(":8080") +} diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/css/app.224ec165.css" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/css/app.224ec165.css" new file mode 100644 index 0000000000000000000000000000000000000000..779676cc13e4d30ec2cd70a043b4f8146687f83b --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/css/app.224ec165.css" @@ -0,0 +1 @@ +.el-table .warning-row{background:#fdf5e6}.el-table .success-row{text-decoration:line-through}.el-footer,.el-header{background-color:#409eff;color:#fff;text-align:center;line-height:60px}.el-footer{background-color:#909399;display:block;width:100%;position:fixed;bottom:0}body{margin:0} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/css/chunk-vendors.57db8905.css" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/css/chunk-vendors.57db8905.css" new file mode 100644 index 0000000000000000000000000000000000000000..384bb0163ba60c7b3e475fc8bb61d730267b442c --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/css/chunk-vendors.57db8905.css" @@ -0,0 +1 @@ +.el-pagination--small .arrow.disabled,.el-table--hidden,.el-table .hidden-columns,.el-table td.is-hidden>*,.el-table th.is-hidden>*{visibility:hidden}.el-dropdown .el-dropdown-selfdefine:focus:active,.el-dropdown .el-dropdown-selfdefine:focus:not(.focusing),.el-message__closeBtn:focus,.el-message__content:focus,.el-popover:focus,.el-popover:focus:active,.el-popover__reference:focus:hover,.el-popover__reference:focus:not(.focusing),.el-rate:active,.el-rate:focus,.el-tooltip:focus:hover,.el-tooltip:focus:not(.focusing),.el-upload-list__item.is-success:active,.el-upload-list__item.is-success:not(.focusing):focus{outline-width:0}.el-input__suffix,.el-tree.is-dragging .el-tree-node__content *{pointer-events:none}@font-face{font-family:element-icons;src:url(../../static/fonts/element-icons.535877f5.woff) format("woff"),url(../../static/fonts/element-icons.732389de.ttf) format("truetype");font-weight:400;font-display:"auto";font-style:normal}[class*=" el-icon-"],[class^=el-icon-]{font-family:element-icons!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;vertical-align:baseline;display:inline-block;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.el-icon-ice-cream-round:before{content:"\e6a0"}.el-icon-ice-cream-square:before{content:"\e6a3"}.el-icon-lollipop:before{content:"\e6a4"}.el-icon-potato-strips:before{content:"\e6a5"}.el-icon-milk-tea:before{content:"\e6a6"}.el-icon-ice-drink:before{content:"\e6a7"}.el-icon-ice-tea:before{content:"\e6a9"}.el-icon-coffee:before{content:"\e6aa"}.el-icon-orange:before{content:"\e6ab"}.el-icon-pear:before{content:"\e6ac"}.el-icon-apple:before{content:"\e6ad"}.el-icon-cherry:before{content:"\e6ae"}.el-icon-watermelon:before{content:"\e6af"}.el-icon-grape:before{content:"\e6b0"}.el-icon-refrigerator:before{content:"\e6b1"}.el-icon-goblet-square-full:before{content:"\e6b2"}.el-icon-goblet-square:before{content:"\e6b3"}.el-icon-goblet-full:before{content:"\e6b4"}.el-icon-goblet:before{content:"\e6b5"}.el-icon-cold-drink:before{content:"\e6b6"}.el-icon-coffee-cup:before{content:"\e6b8"}.el-icon-water-cup:before{content:"\e6b9"}.el-icon-hot-water:before{content:"\e6ba"}.el-icon-ice-cream:before{content:"\e6bb"}.el-icon-dessert:before{content:"\e6bc"}.el-icon-sugar:before{content:"\e6bd"}.el-icon-tableware:before{content:"\e6be"}.el-icon-burger:before{content:"\e6bf"}.el-icon-knife-fork:before{content:"\e6c1"}.el-icon-fork-spoon:before{content:"\e6c2"}.el-icon-chicken:before{content:"\e6c3"}.el-icon-food:before{content:"\e6c4"}.el-icon-dish-1:before{content:"\e6c5"}.el-icon-dish:before{content:"\e6c6"}.el-icon-moon-night:before{content:"\e6ee"}.el-icon-moon:before{content:"\e6f0"}.el-icon-cloudy-and-sunny:before{content:"\e6f1"}.el-icon-partly-cloudy:before{content:"\e6f2"}.el-icon-cloudy:before{content:"\e6f3"}.el-icon-sunny:before{content:"\e6f6"}.el-icon-sunset:before{content:"\e6f7"}.el-icon-sunrise-1:before{content:"\e6f8"}.el-icon-sunrise:before{content:"\e6f9"}.el-icon-heavy-rain:before{content:"\e6fa"}.el-icon-lightning:before{content:"\e6fb"}.el-icon-light-rain:before{content:"\e6fc"}.el-icon-wind-power:before{content:"\e6fd"}.el-icon-baseball:before{content:"\e712"}.el-icon-soccer:before{content:"\e713"}.el-icon-football:before{content:"\e715"}.el-icon-basketball:before{content:"\e716"}.el-icon-ship:before{content:"\e73f"}.el-icon-truck:before{content:"\e740"}.el-icon-bicycle:before{content:"\e741"}.el-icon-mobile-phone:before{content:"\e6d3"}.el-icon-service:before{content:"\e6d4"}.el-icon-key:before{content:"\e6e2"}.el-icon-unlock:before{content:"\e6e4"}.el-icon-lock:before{content:"\e6e5"}.el-icon-watch:before{content:"\e6fe"}.el-icon-watch-1:before{content:"\e6ff"}.el-icon-timer:before{content:"\e702"}.el-icon-alarm-clock:before{content:"\e703"}.el-icon-map-location:before{content:"\e704"}.el-icon-delete-location:before{content:"\e705"}.el-icon-add-location:before{content:"\e706"}.el-icon-location-information:before{content:"\e707"}.el-icon-location-outline:before{content:"\e708"}.el-icon-location:before{content:"\e79e"}.el-icon-place:before{content:"\e709"}.el-icon-discover:before{content:"\e70a"}.el-icon-first-aid-kit:before{content:"\e70b"}.el-icon-trophy-1:before{content:"\e70c"}.el-icon-trophy:before{content:"\e70d"}.el-icon-medal:before{content:"\e70e"}.el-icon-medal-1:before{content:"\e70f"}.el-icon-stopwatch:before{content:"\e710"}.el-icon-mic:before{content:"\e711"}.el-icon-copy-document:before{content:"\e718"}.el-icon-full-screen:before{content:"\e719"}.el-icon-switch-button:before{content:"\e71b"}.el-icon-aim:before{content:"\e71c"}.el-icon-crop:before{content:"\e71d"}.el-icon-odometer:before{content:"\e71e"}.el-icon-time:before{content:"\e71f"}.el-icon-bangzhu:before{content:"\e724"}.el-icon-close-notification:before{content:"\e726"}.el-icon-microphone:before{content:"\e727"}.el-icon-turn-off-microphone:before{content:"\e728"}.el-icon-position:before{content:"\e729"}.el-icon-postcard:before{content:"\e72a"}.el-icon-message:before{content:"\e72b"}.el-icon-chat-line-square:before{content:"\e72d"}.el-icon-chat-dot-square:before{content:"\e72e"}.el-icon-chat-dot-round:before{content:"\e72f"}.el-icon-chat-square:before{content:"\e730"}.el-icon-chat-line-round:before{content:"\e731"}.el-icon-chat-round:before{content:"\e732"}.el-icon-set-up:before{content:"\e733"}.el-icon-turn-off:before{content:"\e734"}.el-icon-open:before{content:"\e735"}.el-icon-connection:before{content:"\e736"}.el-icon-link:before{content:"\e737"}.el-icon-cpu:before{content:"\e738"}.el-icon-thumb:before{content:"\e739"}.el-icon-female:before{content:"\e73a"}.el-icon-male:before{content:"\e73b"}.el-icon-guide:before{content:"\e73c"}.el-icon-news:before{content:"\e73e"}.el-icon-price-tag:before{content:"\e744"}.el-icon-discount:before{content:"\e745"}.el-icon-wallet:before{content:"\e747"}.el-icon-coin:before{content:"\e748"}.el-icon-money:before{content:"\e749"}.el-icon-bank-card:before{content:"\e74a"}.el-icon-box:before{content:"\e74b"}.el-icon-present:before{content:"\e74c"}.el-icon-sell:before{content:"\e6d5"}.el-icon-sold-out:before{content:"\e6d6"}.el-icon-shopping-bag-2:before{content:"\e74d"}.el-icon-shopping-bag-1:before{content:"\e74e"}.el-icon-shopping-cart-2:before{content:"\e74f"}.el-icon-shopping-cart-1:before{content:"\e750"}.el-icon-shopping-cart-full:before{content:"\e751"}.el-icon-smoking:before{content:"\e752"}.el-icon-no-smoking:before{content:"\e753"}.el-icon-house:before{content:"\e754"}.el-icon-table-lamp:before{content:"\e755"}.el-icon-school:before{content:"\e756"}.el-icon-office-building:before{content:"\e757"}.el-icon-toilet-paper:before{content:"\e758"}.el-icon-notebook-2:before{content:"\e759"}.el-icon-notebook-1:before{content:"\e75a"}.el-icon-files:before{content:"\e75b"}.el-icon-collection:before{content:"\e75c"}.el-icon-receiving:before{content:"\e75d"}.el-icon-suitcase-1:before{content:"\e760"}.el-icon-suitcase:before{content:"\e761"}.el-icon-film:before{content:"\e763"}.el-icon-collection-tag:before{content:"\e765"}.el-icon-data-analysis:before{content:"\e766"}.el-icon-pie-chart:before{content:"\e767"}.el-icon-data-board:before{content:"\e768"}.el-icon-data-line:before{content:"\e76d"}.el-icon-reading:before{content:"\e769"}.el-icon-magic-stick:before{content:"\e76a"}.el-icon-coordinate:before{content:"\e76b"}.el-icon-mouse:before{content:"\e76c"}.el-icon-brush:before{content:"\e76e"}.el-icon-headset:before{content:"\e76f"}.el-icon-umbrella:before{content:"\e770"}.el-icon-scissors:before{content:"\e771"}.el-icon-mobile:before{content:"\e773"}.el-icon-attract:before{content:"\e774"}.el-icon-monitor:before{content:"\e775"}.el-icon-search:before{content:"\e778"}.el-icon-takeaway-box:before{content:"\e77a"}.el-icon-paperclip:before{content:"\e77d"}.el-icon-printer:before{content:"\e77e"}.el-icon-document-add:before{content:"\e782"}.el-icon-document:before{content:"\e785"}.el-icon-document-checked:before{content:"\e786"}.el-icon-document-copy:before{content:"\e787"}.el-icon-document-delete:before{content:"\e788"}.el-icon-document-remove:before{content:"\e789"}.el-icon-tickets:before{content:"\e78b"}.el-icon-folder-checked:before{content:"\e77f"}.el-icon-folder-delete:before{content:"\e780"}.el-icon-folder-remove:before{content:"\e781"}.el-icon-folder-add:before{content:"\e783"}.el-icon-folder-opened:before{content:"\e784"}.el-icon-folder:before{content:"\e78a"}.el-icon-edit-outline:before{content:"\e764"}.el-icon-edit:before{content:"\e78c"}.el-icon-date:before{content:"\e78e"}.el-icon-c-scale-to-original:before{content:"\e7c6"}.el-icon-view:before{content:"\e6ce"}.el-icon-loading:before{content:"\e6cf"}.el-icon-rank:before{content:"\e6d1"}.el-icon-sort-down:before{content:"\e7c4"}.el-icon-sort-up:before{content:"\e7c5"}.el-icon-sort:before{content:"\e6d2"}.el-icon-finished:before{content:"\e6cd"}.el-icon-refresh-left:before{content:"\e6c7"}.el-icon-refresh-right:before{content:"\e6c8"}.el-icon-refresh:before{content:"\e6d0"}.el-icon-video-play:before{content:"\e7c0"}.el-icon-video-pause:before{content:"\e7c1"}.el-icon-d-arrow-right:before{content:"\e6dc"}.el-icon-d-arrow-left:before{content:"\e6dd"}.el-icon-arrow-up:before{content:"\e6e1"}.el-icon-arrow-down:before{content:"\e6df"}.el-icon-arrow-right:before{content:"\e6e0"}.el-icon-arrow-left:before{content:"\e6de"}.el-icon-top-right:before{content:"\e6e7"}.el-icon-top-left:before{content:"\e6e8"}.el-icon-top:before{content:"\e6e6"}.el-icon-bottom:before{content:"\e6eb"}.el-icon-right:before{content:"\e6e9"}.el-icon-back:before{content:"\e6ea"}.el-icon-bottom-right:before{content:"\e6ec"}.el-icon-bottom-left:before{content:"\e6ed"}.el-icon-caret-top:before{content:"\e78f"}.el-icon-caret-bottom:before{content:"\e790"}.el-icon-caret-right:before{content:"\e791"}.el-icon-caret-left:before{content:"\e792"}.el-icon-d-caret:before{content:"\e79a"}.el-icon-share:before{content:"\e793"}.el-icon-menu:before{content:"\e798"}.el-icon-s-grid:before{content:"\e7a6"}.el-icon-s-check:before{content:"\e7a7"}.el-icon-s-data:before{content:"\e7a8"}.el-icon-s-opportunity:before{content:"\e7aa"}.el-icon-s-custom:before{content:"\e7ab"}.el-icon-s-claim:before{content:"\e7ad"}.el-icon-s-finance:before{content:"\e7ae"}.el-icon-s-comment:before{content:"\e7af"}.el-icon-s-flag:before{content:"\e7b0"}.el-icon-s-marketing:before{content:"\e7b1"}.el-icon-s-shop:before{content:"\e7b4"}.el-icon-s-open:before{content:"\e7b5"}.el-icon-s-management:before{content:"\e7b6"}.el-icon-s-ticket:before{content:"\e7b7"}.el-icon-s-release:before{content:"\e7b8"}.el-icon-s-home:before{content:"\e7b9"}.el-icon-s-promotion:before{content:"\e7ba"}.el-icon-s-operation:before{content:"\e7bb"}.el-icon-s-unfold:before{content:"\e7bc"}.el-icon-s-fold:before{content:"\e7a9"}.el-icon-s-platform:before{content:"\e7bd"}.el-icon-s-order:before{content:"\e7be"}.el-icon-s-cooperation:before{content:"\e7bf"}.el-icon-bell:before{content:"\e725"}.el-icon-message-solid:before{content:"\e799"}.el-icon-video-camera:before{content:"\e772"}.el-icon-video-camera-solid:before{content:"\e796"}.el-icon-camera:before{content:"\e779"}.el-icon-camera-solid:before{content:"\e79b"}.el-icon-download:before{content:"\e77c"}.el-icon-upload2:before{content:"\e77b"}.el-icon-upload:before{content:"\e7c3"}.el-icon-picture-outline-round:before{content:"\e75f"}.el-icon-picture-outline:before{content:"\e75e"}.el-icon-picture:before{content:"\e79f"}.el-icon-close:before{content:"\e6db"}.el-icon-check:before{content:"\e6da"}.el-icon-plus:before{content:"\e6d9"}.el-icon-minus:before{content:"\e6d8"}.el-icon-help:before{content:"\e73d"}.el-icon-s-help:before{content:"\e7b3"}.el-icon-circle-close:before{content:"\e78d"}.el-icon-circle-check:before{content:"\e720"}.el-icon-circle-plus-outline:before{content:"\e723"}.el-icon-remove-outline:before{content:"\e722"}.el-icon-zoom-out:before{content:"\e776"}.el-icon-zoom-in:before{content:"\e777"}.el-icon-error:before{content:"\e79d"}.el-icon-success:before{content:"\e79c"}.el-icon-circle-plus:before{content:"\e7a0"}.el-icon-remove:before{content:"\e7a2"}.el-icon-info:before{content:"\e7a1"}.el-icon-question:before{content:"\e7a4"}.el-icon-warning-outline:before{content:"\e6c9"}.el-icon-warning:before{content:"\e7a3"}.el-icon-goods:before{content:"\e7c2"}.el-icon-s-goods:before{content:"\e7b2"}.el-icon-star-off:before{content:"\e717"}.el-icon-star-on:before{content:"\e797"}.el-icon-more-outline:before{content:"\e6cc"}.el-icon-more:before{content:"\e794"}.el-icon-phone-outline:before{content:"\e6cb"}.el-icon-phone:before{content:"\e795"}.el-icon-user:before{content:"\e6e3"}.el-icon-user-solid:before{content:"\e7a5"}.el-icon-setting:before{content:"\e6ca"}.el-icon-s-tools:before{content:"\e7ac"}.el-icon-delete:before{content:"\e6d7"}.el-icon-delete-solid:before{content:"\e7c9"}.el-icon-eleme:before{content:"\e7c7"}.el-icon-platform-eleme:before{content:"\e7ca"}.el-icon-loading{-webkit-animation:rotating 2s linear infinite;animation:rotating 2s linear infinite}.el-icon--right{margin-left:5px}.el-icon--left{margin-right:5px}@-webkit-keyframes rotating{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotating{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.el-pagination{white-space:nowrap;padding:2px 5px;color:#303133;font-weight:700}.el-pagination:after,.el-pagination:before{display:table;content:""}.el-pagination:after{clear:both}.el-pagination button,.el-pagination span:not([class*=suffix]){display:inline-block;font-size:13px;min-width:35.5px;height:28px;line-height:28px;vertical-align:top;-webkit-box-sizing:border-box;box-sizing:border-box}.el-pagination .el-input__inner{text-align:center;-moz-appearance:textfield;line-height:normal}.el-pagination .el-input__suffix{right:0;-webkit-transform:scale(.8);transform:scale(.8)}.el-pagination .el-select .el-input{width:100px;margin:0 5px}.el-pagination .el-select .el-input .el-input__inner{padding-right:25px;border-radius:3px}.el-pagination button{border:none;padding:0 6px;background:0 0}.el-pagination button:focus{outline:0}.el-pagination button:hover{color:#409eff}.el-pagination button:disabled{color:#c0c4cc;background-color:#fff;cursor:not-allowed}.el-pagination .btn-next,.el-pagination .btn-prev{background:50% no-repeat #fff;background-size:16px;cursor:pointer;margin:0;color:#303133}.el-pagination .btn-next .el-icon,.el-pagination .btn-prev .el-icon{display:block;font-size:12px;font-weight:700}.el-pagination .btn-prev{padding-right:12px}.el-pagination .btn-next{padding-left:12px}.el-pagination .el-pager li.disabled{color:#c0c4cc;cursor:not-allowed}.el-pager li,.el-pager li.btn-quicknext:hover,.el-pager li.btn-quickprev:hover{cursor:pointer}.el-pagination--small .btn-next,.el-pagination--small .btn-prev,.el-pagination--small .el-pager li,.el-pagination--small .el-pager li.btn-quicknext,.el-pagination--small .el-pager li.btn-quickprev,.el-pagination--small .el-pager li:last-child{border-color:transparent;font-size:12px;line-height:22px;height:22px;min-width:22px}.el-pagination--small .more:before,.el-pagination--small li.more:before{line-height:24px}.el-pagination--small button,.el-pagination--small span:not([class*=suffix]){height:22px;line-height:22px}.el-pagination--small .el-pagination__editor,.el-pagination--small .el-pagination__editor.el-input .el-input__inner{height:22px}.el-pagination__sizes{margin:0 10px 0 0;font-weight:400;color:#606266}.el-pagination__sizes .el-input .el-input__inner{font-size:13px;padding-left:8px}.el-pagination__sizes .el-input .el-input__inner:hover{border-color:#409eff}.el-pagination__total{margin-right:10px;font-weight:400;color:#606266}.el-pagination__jump{margin-left:24px;font-weight:400;color:#606266}.el-pagination__jump .el-input__inner{padding:0 3px}.el-pagination__rightwrapper{float:right}.el-pagination__editor{line-height:18px;padding:0 2px;height:28px;text-align:center;margin:0 2px;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:3px}.el-pager,.el-pagination.is-background .btn-next,.el-pagination.is-background .btn-prev{padding:0}.el-pagination__editor.el-input{width:50px}.el-pagination__editor.el-input .el-input__inner{height:28px}.el-pagination__editor .el-input__inner::-webkit-inner-spin-button,.el-pagination__editor .el-input__inner::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.el-pagination.is-background .btn-next,.el-pagination.is-background .btn-prev,.el-pagination.is-background .el-pager li{margin:0 5px;background-color:#f4f4f5;color:#606266;min-width:30px;border-radius:2px}.el-pagination.is-background .btn-next.disabled,.el-pagination.is-background .btn-next:disabled,.el-pagination.is-background .btn-prev.disabled,.el-pagination.is-background .btn-prev:disabled,.el-pagination.is-background .el-pager li.disabled{color:#c0c4cc}.el-pagination.is-background .el-pager li:not(.disabled):hover{color:#409eff}.el-pagination.is-background .el-pager li:not(.disabled).active{background-color:#409eff;color:#fff}.el-dialog,.el-pager li{background:#fff;-webkit-box-sizing:border-box}.el-pagination.is-background.el-pagination--small .btn-next,.el-pagination.is-background.el-pagination--small .btn-prev,.el-pagination.is-background.el-pagination--small .el-pager li{margin:0 3px;min-width:22px}.el-pager,.el-pager li{vertical-align:top;margin:0;display:inline-block}.el-pager{-moz-user-select:none;user-select:none;list-style:none;font-size:0}.el-date-table,.el-pager,.el-table th{-webkit-user-select:none;-ms-user-select:none}.el-pager .more:before{line-height:30px}.el-pager li{padding:0 4px;font-size:13px;min-width:35.5px;height:28px;line-height:28px;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center}.el-menu--collapse .el-menu .el-submenu,.el-menu--popup{min-width:200px}.el-pager li.btn-quicknext,.el-pager li.btn-quickprev{line-height:28px;color:#303133}.el-pager li.btn-quicknext.disabled,.el-pager li.btn-quickprev.disabled{color:#c0c4cc}.el-pager li.active+li{border-left:0}.el-pager li:hover{color:#409eff}.el-pager li.active{color:#409eff;cursor:default}@-webkit-keyframes v-modal-in{0%{opacity:0}}@-webkit-keyframes v-modal-out{to{opacity:0}}.el-dialog{position:relative;margin:0 auto 50px;border-radius:2px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.3);box-shadow:0 1px 3px rgba(0,0,0,.3);-webkit-box-sizing:border-box;box-sizing:border-box;width:50%}.el-dialog.is-fullscreen{width:100%;margin-top:0;margin-bottom:0;height:100%;overflow:auto}.el-dialog__wrapper{position:fixed;top:0;right:0;bottom:0;left:0;overflow:auto;margin:0}.el-dialog__header{padding:20px 20px 10px}.el-dialog__headerbtn{position:absolute;top:20px;right:20px;padding:0;background:0 0;border:none;outline:0;cursor:pointer;font-size:16px}.el-dialog__headerbtn .el-dialog__close{color:#909399}.el-dialog__headerbtn:focus .el-dialog__close,.el-dialog__headerbtn:hover .el-dialog__close{color:#409eff}.el-dialog__title{line-height:24px;font-size:18px;color:#303133}.el-dialog__body{padding:30px 20px;color:#606266;font-size:14px;word-break:break-all}.el-dialog__footer{padding:10px 20px 20px;text-align:right;-webkit-box-sizing:border-box;box-sizing:border-box}.el-dialog--center{text-align:center}.el-dialog--center .el-dialog__body{text-align:initial;padding:25px 25px 30px}.el-dialog--center .el-dialog__footer{text-align:inherit}.dialog-fade-enter-active{-webkit-animation:dialog-fade-in .3s;animation:dialog-fade-in .3s}.dialog-fade-leave-active{-webkit-animation:dialog-fade-out .3s;animation:dialog-fade-out .3s}@-webkit-keyframes dialog-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes dialog-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@-webkit-keyframes dialog-fade-out{0%{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}to{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes dialog-fade-out{0%{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}to{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.el-autocomplete{position:relative;display:inline-block}.el-autocomplete-suggestion{margin:5px 0;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:4px;border:1px solid #e4e7ed;-webkit-box-sizing:border-box;box-sizing:border-box;background-color:#fff}.el-dropdown-menu,.el-menu--collapse .el-submenu .el-menu{z-index:10;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-autocomplete-suggestion__wrap{max-height:280px;padding:10px 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-autocomplete-suggestion__list{margin:0;padding:0}.el-autocomplete-suggestion li{padding:0 20px;margin:0;line-height:34px;cursor:pointer;color:#606266;font-size:14px;list-style:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.el-autocomplete-suggestion li.highlighted,.el-autocomplete-suggestion li:hover{background-color:#f5f7fa}.el-autocomplete-suggestion li.divider{margin-top:6px;border-top:1px solid #000}.el-autocomplete-suggestion li.divider:last-child{margin-bottom:-6px}.el-autocomplete-suggestion.is-loading li{text-align:center;height:100px;line-height:100px;font-size:20px;color:#999}.el-autocomplete-suggestion.is-loading li:after{display:inline-block;content:"";height:100%;vertical-align:middle}.el-autocomplete-suggestion.is-loading li:hover{background-color:#fff}.el-autocomplete-suggestion.is-loading .el-icon-loading{vertical-align:middle}.el-dropdown{display:inline-block;position:relative;color:#606266;font-size:14px}.el-dropdown .el-button-group{display:block}.el-dropdown .el-button-group .el-button{float:none}.el-dropdown .el-dropdown__caret-button{padding-left:5px;padding-right:5px;position:relative;border-left:none}.el-dropdown .el-dropdown__caret-button:before{content:"";position:absolute;display:block;width:1px;top:5px;bottom:5px;left:0;background:hsla(0,0%,100%,.5)}.el-dropdown .el-dropdown__caret-button.el-button--default:before{background:rgba(220,223,230,.5)}.el-dropdown .el-dropdown__caret-button:hover:before{top:0;bottom:0}.el-dropdown .el-dropdown__caret-button .el-dropdown__icon{padding-left:0}.el-dropdown__icon{font-size:12px;margin:0 3px}.el-dropdown-menu{position:absolute;top:0;left:0;padding:10px 0;margin:5px 0;background-color:#fff;border:1px solid #ebeef5;border-radius:4px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-dropdown-menu__item{list-style:none;line-height:36px;padding:0 20px;margin:0;font-size:14px;color:#606266;cursor:pointer;outline:0}.el-dropdown-menu__item:focus,.el-dropdown-menu__item:not(.is-disabled):hover{background-color:#ecf5ff;color:#66b1ff}.el-dropdown-menu__item i{margin-right:5px}.el-dropdown-menu__item--divided{position:relative;margin-top:6px;border-top:1px solid #ebeef5}.el-dropdown-menu__item--divided:before{content:"";height:6px;display:block;margin:0 -20px;background-color:#fff}.el-dropdown-menu__item.is-disabled{cursor:default;color:#bbb;pointer-events:none}.el-dropdown-menu--medium{padding:6px 0}.el-dropdown-menu--medium .el-dropdown-menu__item{line-height:30px;padding:0 17px;font-size:14px}.el-dropdown-menu--medium .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:6px}.el-dropdown-menu--medium .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:6px;margin:0 -17px}.el-dropdown-menu--small{padding:6px 0}.el-dropdown-menu--small .el-dropdown-menu__item{line-height:27px;padding:0 15px;font-size:13px}.el-dropdown-menu--small .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:4px}.el-dropdown-menu--small .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:4px;margin:0 -15px}.el-dropdown-menu--mini{padding:3px 0}.el-dropdown-menu--mini .el-dropdown-menu__item{line-height:24px;padding:0 10px;font-size:12px}.el-dropdown-menu--mini .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:3px}.el-dropdown-menu--mini .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:3px;margin:0 -10px}.el-menu{border-right:1px solid #e6e6e6;list-style:none;position:relative;margin:0;padding-left:0}.el-menu,.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus,.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,.el-menu--horizontal>.el-submenu .el-submenu__title:hover{background-color:#fff}.el-menu:after,.el-menu:before{display:table;content:""}.el-menu:after{clear:both}.el-menu.el-menu--horizontal{border-bottom:1px solid #e6e6e6}.el-menu--horizontal{border-right:none}.el-menu--horizontal>.el-menu-item{float:left;height:60px;line-height:60px;margin:0;border-bottom:2px solid transparent;color:#909399}.el-menu--horizontal>.el-menu-item a,.el-menu--horizontal>.el-menu-item a:hover{color:inherit}.el-menu--horizontal>.el-submenu{float:left}.el-menu--horizontal>.el-submenu:focus,.el-menu--horizontal>.el-submenu:hover{outline:0}.el-menu--horizontal>.el-submenu:focus .el-submenu__title,.el-menu--horizontal>.el-submenu:hover .el-submenu__title{color:#303133}.el-menu--horizontal>.el-submenu.is-active .el-submenu__title{border-bottom:2px solid #409eff;color:#303133}.el-menu--horizontal>.el-submenu .el-submenu__title{height:60px;line-height:60px;border-bottom:2px solid transparent;color:#909399}.el-menu--horizontal>.el-submenu .el-submenu__icon-arrow{position:static;vertical-align:middle;margin-left:8px;margin-top:-3px}.el-menu--horizontal .el-menu .el-menu-item,.el-menu--horizontal .el-menu .el-submenu__title{background-color:#fff;float:none;height:36px;line-height:36px;padding:0 10px;color:#909399}.el-menu--horizontal .el-menu .el-menu-item.is-active,.el-menu--horizontal .el-menu .el-submenu.is-active>.el-submenu__title{color:#303133}.el-menu--horizontal .el-menu-item:not(.is-disabled):focus,.el-menu--horizontal .el-menu-item:not(.is-disabled):hover{outline:0;color:#303133}.el-menu--horizontal>.el-menu-item.is-active{border-bottom:2px solid #409eff;color:#303133}.el-menu--collapse{width:64px}.el-menu--collapse>.el-menu-item [class^=el-icon-],.el-menu--collapse>.el-submenu>.el-submenu__title [class^=el-icon-]{margin:0;vertical-align:middle;width:24px;text-align:center}.el-menu--collapse>.el-menu-item .el-submenu__icon-arrow,.el-menu--collapse>.el-submenu>.el-submenu__title .el-submenu__icon-arrow{display:none}.el-menu--collapse>.el-menu-item span,.el-menu--collapse>.el-submenu>.el-submenu__title span{height:0;width:0;overflow:hidden;visibility:hidden;display:inline-block}.el-menu--collapse>.el-menu-item.is-active i{color:inherit}.el-menu--collapse .el-submenu{position:relative}.el-menu--collapse .el-submenu .el-menu{position:absolute;margin-left:5px;top:0;left:100%;border:1px solid #e4e7ed;border-radius:2px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-menu-item,.el-submenu__title{height:56px;line-height:56px;position:relative;-webkit-box-sizing:border-box;white-space:nowrap;list-style:none}.el-menu--collapse .el-submenu.is-opened>.el-submenu__title .el-submenu__icon-arrow{-webkit-transform:none;transform:none}.el-menu--popup{z-index:100;border:none;padding:5px 0;border-radius:2px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-menu--popup-bottom-start{margin-top:5px}.el-menu--popup-right-start{margin-left:5px;margin-right:5px}.el-menu-item{font-size:14px;color:#303133;padding:0 20px;cursor:pointer;-webkit-transition:border-color .3s,background-color .3s,color .3s;transition:border-color .3s,background-color .3s,color .3s;-webkit-box-sizing:border-box;box-sizing:border-box}.el-menu-item *{vertical-align:middle}.el-menu-item i{color:#909399}.el-menu-item:focus,.el-menu-item:hover{outline:0;background-color:#ecf5ff}.el-menu-item.is-disabled{opacity:.25;cursor:not-allowed;background:0 0!important}.el-menu-item [class^=el-icon-]{margin-right:5px;width:24px;text-align:center;font-size:18px;vertical-align:middle}.el-menu-item.is-active{color:#409eff}.el-menu-item.is-active i{color:inherit}.el-submenu{list-style:none;margin:0;padding-left:0}.el-submenu__title{font-size:14px;color:#303133;padding:0 20px;cursor:pointer;-webkit-transition:border-color .3s,background-color .3s,color .3s;transition:border-color .3s,background-color .3s,color .3s;-webkit-box-sizing:border-box;box-sizing:border-box}.el-submenu__title *{vertical-align:middle}.el-submenu__title i{color:#909399}.el-submenu__title:focus,.el-submenu__title:hover{outline:0;background-color:#ecf5ff}.el-submenu__title.is-disabled{opacity:.25;cursor:not-allowed;background:0 0!important}.el-submenu__title:hover{background-color:#ecf5ff}.el-submenu .el-menu{border:none}.el-submenu .el-menu-item{height:50px;line-height:50px;padding:0 45px;min-width:200px}.el-submenu__icon-arrow{position:absolute;top:50%;right:20px;margin-top:-7px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-size:12px}.el-submenu.is-active .el-submenu__title{border-bottom-color:#409eff}.el-submenu.is-opened>.el-submenu__title .el-submenu__icon-arrow{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.el-submenu.is-disabled .el-menu-item,.el-submenu.is-disabled .el-submenu__title{opacity:.25;cursor:not-allowed;background:0 0!important}.el-submenu [class^=el-icon-]{vertical-align:middle;margin-right:5px;width:24px;text-align:center;font-size:18px}.el-menu-item-group>ul{padding:0}.el-menu-item-group__title{padding:7px 0 7px 20px;line-height:normal;font-size:12px;color:#909399}.el-radio-button__inner,.el-radio-group{display:inline-block;line-height:1;vertical-align:middle}.horizontal-collapse-transition .el-submenu__title .el-submenu__icon-arrow{-webkit-transition:.2s;transition:.2s;opacity:0}.el-radio-group{font-size:0}.el-radio-button{position:relative;display:inline-block;outline:0}.el-radio-button__inner{white-space:nowrap;background:#fff;border:1px solid #dcdfe6;font-weight:500;border-left:0;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;position:relative;cursor:pointer;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);padding:12px 20px;font-size:14px;border-radius:0}.el-radio-button__inner.is-round{padding:12px 20px}.el-radio-button__inner:hover{color:#409eff}.el-radio-button__inner [class*=el-icon-]{line-height:.9}.el-radio-button__inner [class*=el-icon-]+span{margin-left:5px}.el-radio-button:first-child .el-radio-button__inner{border-left:1px solid #dcdfe6;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.el-radio-button__orig-radio{opacity:0;outline:0;position:absolute;z-index:-1}.el-radio-button__orig-radio:checked+.el-radio-button__inner{color:#fff;background-color:#409eff;border-color:#409eff;-webkit-box-shadow:-1px 0 0 0 #409eff;box-shadow:-1px 0 0 0 #409eff}.el-radio-button__orig-radio:disabled+.el-radio-button__inner{color:#c0c4cc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#ebeef5;-webkit-box-shadow:none;box-shadow:none}.el-radio-button__orig-radio:disabled:checked+.el-radio-button__inner{background-color:#f2f6fc}.el-radio-button:last-child .el-radio-button__inner{border-radius:0 4px 4px 0}.el-popover,.el-radio-button:first-child:last-child .el-radio-button__inner{border-radius:4px}.el-radio-button--medium .el-radio-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.el-radio-button--medium .el-radio-button__inner.is-round{padding:10px 20px}.el-radio-button--small .el-radio-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.el-radio-button--small .el-radio-button__inner.is-round{padding:9px 15px}.el-radio-button--mini .el-radio-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.el-radio-button--mini .el-radio-button__inner.is-round{padding:7px 15px}.el-radio-button:focus:not(.is-focus):not(:active):not(.is-disabled){-webkit-box-shadow:0 0 2px 2px #409eff;box-shadow:0 0 2px 2px #409eff}.el-switch{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;position:relative;font-size:14px;line-height:20px;height:20px;vertical-align:middle}.el-switch__core,.el-switch__label{display:inline-block;cursor:pointer}.el-switch.is-disabled .el-switch__core,.el-switch.is-disabled .el-switch__label{cursor:not-allowed}.el-switch__label{-webkit-transition:.2s;transition:.2s;height:20px;font-size:14px;font-weight:500;vertical-align:middle;color:#303133}.el-switch__label.is-active{color:#409eff}.el-switch__label--left{margin-right:10px}.el-switch__label--right{margin-left:10px}.el-switch__label *{line-height:1;font-size:14px;display:inline-block}.el-switch__input{position:absolute;width:0;height:0;opacity:0;margin:0}.el-switch__core{margin:0;position:relative;width:40px;height:20px;border:1px solid #dcdfe6;outline:0;border-radius:10px;-webkit-box-sizing:border-box;box-sizing:border-box;background:#dcdfe6;-webkit-transition:border-color .3s,background-color .3s;transition:border-color .3s,background-color .3s;vertical-align:middle}.el-switch__core:after{content:"";position:absolute;top:1px;left:1px;border-radius:100%;-webkit-transition:all .3s;transition:all .3s;width:16px;height:16px;background-color:#fff}.el-switch.is-checked .el-switch__core{border-color:#409eff;background-color:#409eff}.el-switch.is-checked .el-switch__core:after{left:100%;margin-left:-17px}.el-switch.is-disabled{opacity:.6}.el-switch--wide .el-switch__label.el-switch__label--left span{left:10px}.el-switch--wide .el-switch__label.el-switch__label--right span{right:10px}.el-switch .label-fade-enter,.el-switch .label-fade-leave-active{opacity:0}.el-select-dropdown{position:absolute;z-index:1001;border:1px solid #e4e7ed;border-radius:4px;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-box-sizing:border-box;box-sizing:border-box;margin:5px 0}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected{color:#409eff;background-color:#fff}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected.hover{background-color:#f5f7fa}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected:after{position:absolute;right:20px;font-family:element-icons;content:"\e6da";font-size:12px;font-weight:700;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.el-select-dropdown .el-scrollbar.is-empty .el-select-dropdown__list{padding:0}.el-select-dropdown__empty{padding:10px 0;margin:0;text-align:center;color:#999;font-size:14px}.el-select-dropdown__wrap{max-height:274px}.el-select-dropdown__list{list-style:none;padding:6px 0;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-select-dropdown__item{font-size:14px;padding:0 20px;position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#606266;height:34px;line-height:34px;box-sizing:border-box;cursor:pointer}.el-select-dropdown__item,.el-select .el-tag,.el-table{-webkit-box-sizing:border-box}.el-select-dropdown__item.is-disabled{color:#c0c4cc;cursor:not-allowed}.el-select-dropdown__item.is-disabled:hover{background-color:#fff}.el-select-dropdown__item.hover,.el-select-dropdown__item:hover{background-color:#f5f7fa}.el-select-dropdown__item.selected{color:#409eff;font-weight:700}.el-select-group{margin:0;padding:0}.el-select-group__wrap{position:relative;list-style:none;margin:0;padding:0}.el-select-group__wrap:not(:last-of-type){padding-bottom:24px}.el-select-group__wrap:not(:last-of-type):after{content:"";position:absolute;display:block;left:20px;right:20px;bottom:12px;height:1px;background:#e4e7ed}.el-select-group__title{padding-left:20px;font-size:12px;color:#909399;line-height:30px}.el-select-group .el-select-dropdown__item{padding-left:20px}.el-select{display:inline-block;position:relative}.el-select .el-select__tags>span{display:contents}.el-select:hover .el-input__inner{border-color:#c0c4cc}.el-select .el-input__inner{cursor:pointer;padding-right:35px}.el-select .el-input__inner:focus{border-color:#409eff}.el-select .el-input .el-select__caret{color:#c0c4cc;font-size:14px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;-webkit-transform:rotate(180deg);transform:rotate(180deg);cursor:pointer}.el-select .el-input .el-select__caret.is-reverse{-webkit-transform:rotate(0);transform:rotate(0)}.el-select .el-input .el-select__caret.is-show-close{font-size:14px;text-align:center;-webkit-transform:rotate(180deg);transform:rotate(180deg);border-radius:100%;color:#c0c4cc;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.el-select .el-input .el-select__caret.is-show-close:hover{color:#909399}.el-select .el-input.is-disabled .el-input__inner{cursor:not-allowed}.el-select .el-input.is-disabled .el-input__inner:hover{border-color:#e4e7ed}.el-select .el-input.is-focus .el-input__inner{border-color:#409eff}.el-select>.el-input{display:block}.el-select__input{border:none;outline:0;padding:0;margin-left:15px;color:#666;font-size:14px;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:28px;background-color:transparent}.el-select__input.is-mini{height:14px}.el-select__close{cursor:pointer;position:absolute;top:8px;z-index:1000;right:25px;color:#c0c4cc;line-height:18px;font-size:14px}.el-select__close:hover{color:#909399}.el-select__tags{position:absolute;line-height:normal;white-space:normal;z-index:1;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-wrap:wrap;flex-wrap:wrap}.el-select .el-tag__close{margin-top:-2px}.el-select .el-tag{-webkit-box-sizing:border-box;box-sizing:border-box;border-color:transparent;margin:2px 0 2px 6px;background-color:#f0f2f5}.el-select .el-tag__close.el-icon-close{background-color:#c0c4cc;right:-7px;top:0;color:#fff}.el-select .el-tag__close.el-icon-close:hover{background-color:#909399}.el-table,.el-table__expanded-cell{background-color:#fff}.el-select .el-tag__close.el-icon-close:before{display:block;-webkit-transform:translateY(.5px);transform:translateY(.5px)}.el-table{position:relative;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-flex:1;-ms-flex:1;flex:1;width:100%;max-width:100%;font-size:14px;color:#606266}.el-table--mini,.el-table--small,.el-table__expand-icon{font-size:12px}.el-table__empty-block{min-height:60px;text-align:center;width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-table__empty-text{line-height:60px;width:50%;color:#909399}.el-table__expand-column .cell{padding:0;text-align:center}.el-table__expand-icon{position:relative;cursor:pointer;color:#666;-webkit-transition:-webkit-transform .2s ease-in-out;transition:-webkit-transform .2s ease-in-out;transition:transform .2s ease-in-out;transition:transform .2s ease-in-out,-webkit-transform .2s ease-in-out;height:20px}.el-table__expand-icon--expanded{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-table__expand-icon>.el-icon{position:absolute;left:50%;top:50%;margin-left:-5px;margin-top:-5px}.el-table__expanded-cell[class*=cell]{padding:20px 50px}.el-table__expanded-cell:hover{background-color:transparent!important}.el-table__placeholder{display:inline-block;width:20px}.el-table__append-wrapper{overflow:hidden}.el-table--fit{border-right:0;border-bottom:0}.el-table--fit td.gutter,.el-table--fit th.gutter{border-right-width:1px}.el-table--scrollable-x .el-table__body-wrapper{overflow-x:auto}.el-table--scrollable-y .el-table__body-wrapper{overflow-y:auto}.el-table thead{color:#909399;font-weight:500}.el-table thead.is-group th{background:#f5f7fa}.el-table th,.el-table tr{background-color:#fff}.el-table td,.el-table th{padding:12px 0;min-width:0;-webkit-box-sizing:border-box;box-sizing:border-box;text-overflow:ellipsis;vertical-align:middle;position:relative;text-align:left}.el-table td.is-center,.el-table th.is-center{text-align:center}.el-table td.is-right,.el-table th.is-right{text-align:right}.el-table td.gutter,.el-table th.gutter{width:15px;border-right-width:0;border-bottom-width:0;padding:0}.el-table--medium td,.el-table--medium th{padding:10px 0}.el-table--small td,.el-table--small th{padding:8px 0}.el-table--mini td,.el-table--mini th{padding:6px 0}.el-table .cell,.el-table th div{padding-right:10px;overflow:hidden;text-overflow:ellipsis}.el-table--border td:first-child .cell,.el-table--border th:first-child .cell,.el-table .cell,.el-table th div{padding-left:10px}.el-table tr input[type=checkbox]{margin:0}.el-table td,.el-table th.is-leaf{border-bottom:1px solid #ebeef5}.el-table th.is-sortable{cursor:pointer}.el-table th{white-space:nowrap;overflow:hidden;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.el-table th div{line-height:40px;white-space:nowrap}.el-table th>.cell,.el-table th div{display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box}.el-table th>.cell{position:relative;word-wrap:normal;text-overflow:ellipsis;vertical-align:middle;width:100%}.el-table th>.cell.highlight{color:#409eff}.el-table th.required>div:before{display:inline-block;content:"";width:8px;height:8px;border-radius:50%;background:#ff4d51;margin-right:5px;vertical-align:middle}.el-table td div{-webkit-box-sizing:border-box;box-sizing:border-box}.el-table td.gutter{width:0}.el-table .cell{-webkit-box-sizing:border-box;box-sizing:border-box;white-space:normal;word-break:break-all;line-height:23px}.el-table .cell.el-tooltip{white-space:nowrap;min-width:50px}.el-table--border,.el-table--group{border:1px solid #ebeef5}.el-table--border:after,.el-table--group:after,.el-table:before{content:"";position:absolute;background-color:#ebeef5;z-index:1}.el-table--border:after,.el-table--group:after{top:0;right:0;width:1px;height:100%}.el-table:before{left:0;bottom:0;width:100%;height:1px}.el-table--border{border-right:none;border-bottom:none}.el-table--border.el-loading-parent--relative{border-color:transparent}.el-table--border td,.el-table--border th,.el-table__body-wrapper .el-table--border.is-scrolling-left~.el-table__fixed{border-right:1px solid #ebeef5}.el-table--border th.gutter:last-of-type{border-bottom:1px solid #ebeef5;border-bottom-width:1px}.el-table--border th,.el-table__fixed-right-patch{border-bottom:1px solid #ebeef5}.el-table__fixed,.el-table__fixed-right{position:absolute;top:0;left:0;overflow-x:hidden;overflow-y:hidden;-webkit-box-shadow:0 0 10px rgba(0,0,0,.12);box-shadow:0 0 10px rgba(0,0,0,.12)}.el-table__fixed-right:before,.el-table__fixed:before{content:"";position:absolute;left:0;bottom:0;width:100%;height:1px;background-color:#ebeef5;z-index:4}.el-table__fixed-right-patch{position:absolute;top:-1px;right:0;background-color:#fff}.el-table__fixed-right{top:0;left:auto;right:0}.el-table__fixed-right .el-table__fixed-body-wrapper,.el-table__fixed-right .el-table__fixed-footer-wrapper,.el-table__fixed-right .el-table__fixed-header-wrapper{left:auto;right:0}.el-table__fixed-header-wrapper{position:absolute;left:0;top:0;z-index:3}.el-table__fixed-footer-wrapper{position:absolute;left:0;bottom:0;z-index:3}.el-table__fixed-footer-wrapper tbody td{border-top:1px solid #ebeef5;background-color:#f5f7fa;color:#606266}.el-table__fixed-body-wrapper{position:absolute;left:0;top:37px;overflow:hidden;z-index:3}.el-table__body-wrapper,.el-table__footer-wrapper,.el-table__header-wrapper{width:100%}.el-table__footer-wrapper{margin-top:-1px}.el-table__footer-wrapper td{border-top:1px solid #ebeef5}.el-table__body,.el-table__footer,.el-table__header{table-layout:fixed;border-collapse:separate}.el-table__footer-wrapper,.el-table__header-wrapper{overflow:hidden}.el-table__footer-wrapper tbody td,.el-table__header-wrapper tbody td{background-color:#f5f7fa;color:#606266}.el-table__body-wrapper{overflow:hidden;position:relative}.el-table__body-wrapper.is-scrolling-left~.el-table__fixed,.el-table__body-wrapper.is-scrolling-none~.el-table__fixed,.el-table__body-wrapper.is-scrolling-none~.el-table__fixed-right,.el-table__body-wrapper.is-scrolling-right~.el-table__fixed-right{-webkit-box-shadow:none;box-shadow:none}.el-picker-panel,.el-table-filter{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-table__body-wrapper .el-table--border.is-scrolling-right~.el-table__fixed-right{border-left:1px solid #ebeef5}.el-table .caret-wrapper{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:34px;width:24px;vertical-align:middle;cursor:pointer;overflow:initial;position:relative}.el-table .sort-caret{width:0;height:0;border:5px solid transparent;position:absolute;left:7px}.el-table .sort-caret.ascending{border-bottom-color:#c0c4cc;top:5px}.el-table .sort-caret.descending{border-top-color:#c0c4cc;bottom:7px}.el-table .ascending .sort-caret.ascending{border-bottom-color:#409eff}.el-table .descending .sort-caret.descending{border-top-color:#409eff}.el-table .hidden-columns{position:absolute;z-index:-1}.el-table--striped .el-table__body tr.el-table__row--striped td{background:#fafafa}.el-table--striped .el-table__body tr.el-table__row--striped.current-row td{background-color:#ecf5ff}.el-table__body tr.hover-row.current-row>td,.el-table__body tr.hover-row.el-table__row--striped.current-row>td,.el-table__body tr.hover-row.el-table__row--striped>td,.el-table__body tr.hover-row>td{background-color:#f5f7fa}.el-table__body tr.current-row>td{background-color:#ecf5ff}.el-table__column-resize-proxy{position:absolute;left:200px;top:0;bottom:0;width:0;border-left:1px solid #ebeef5;z-index:10}.el-table__column-filter-trigger{display:inline-block;line-height:34px;cursor:pointer}.el-table__column-filter-trigger i{color:#909399;font-size:12px;-webkit-transform:scale(.75);transform:scale(.75)}.el-table--enable-row-transition .el-table__body td{-webkit-transition:background-color .25s ease;transition:background-color .25s ease}.el-table--enable-row-hover .el-table__body tr:hover>td{background-color:#f5f7fa}.el-table--fluid-height .el-table__fixed,.el-table--fluid-height .el-table__fixed-right{bottom:0;overflow:hidden}.el-table [class*=el-table__row--level] .el-table__expand-icon{display:inline-block;width:20px;line-height:20px;height:20px;text-align:center;margin-right:3px}.el-table-column--selection .cell{padding-left:14px;padding-right:14px}.el-table-filter{border:1px solid #ebeef5;border-radius:2px;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-box-sizing:border-box;box-sizing:border-box;margin:2px 0}.el-date-table td,.el-date-table td div{height:30px;-webkit-box-sizing:border-box}.el-table-filter__list{padding:5px 0;margin:0;list-style:none;min-width:100px}.el-table-filter__list-item{line-height:36px;padding:0 10px;cursor:pointer;font-size:14px}.el-table-filter__list-item:hover{background-color:#ecf5ff;color:#66b1ff}.el-table-filter__list-item.is-active{background-color:#409eff;color:#fff}.el-table-filter__content{min-width:100px}.el-table-filter__bottom{border-top:1px solid #ebeef5;padding:8px}.el-table-filter__bottom button{background:0 0;border:none;color:#606266;cursor:pointer;font-size:13px;padding:0 3px}.el-date-table.is-week-mode .el-date-table__row.current div,.el-date-table.is-week-mode .el-date-table__row:hover div,.el-date-table td.in-range div,.el-date-table td.in-range div:hover{background-color:#f2f6fc}.el-table-filter__bottom button:hover{color:#409eff}.el-table-filter__bottom button:focus{outline:0}.el-table-filter__bottom button.is-disabled{color:#c0c4cc;cursor:not-allowed}.el-table-filter__wrap{max-height:280px}.el-table-filter__checkbox-group{padding:10px}.el-table-filter__checkbox-group label.el-checkbox{display:block;margin-right:5px;margin-bottom:8px;margin-left:5px}.el-table-filter__checkbox-group .el-checkbox:last-child{margin-bottom:0}.el-date-table{font-size:12px;-moz-user-select:none;user-select:none}.el-date-table,.el-slider__button-wrapper,.el-time-panel{-webkit-user-select:none;-ms-user-select:none}.el-date-table.is-week-mode .el-date-table__row:hover td.available:hover{color:#606266}.el-date-table.is-week-mode .el-date-table__row:hover td:first-child div{margin-left:5px;border-top-left-radius:15px;border-bottom-left-radius:15px}.el-date-table.is-week-mode .el-date-table__row:hover td:last-child div{margin-right:5px;border-top-right-radius:15px;border-bottom-right-radius:15px}.el-date-table td{width:32px;padding:4px 0;text-align:center;cursor:pointer;position:relative}.el-date-table td,.el-date-table td div{-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-table td div{padding:3px 0}.el-date-table td span{width:24px;height:24px;display:block;margin:0 auto;line-height:24px;position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);border-radius:50%}.el-date-table td.next-month,.el-date-table td.prev-month{color:#c0c4cc}.el-date-table td.today{position:relative}.el-date-table td.today span{color:#409eff;font-weight:700}.el-date-table td.today.end-date span,.el-date-table td.today.start-date span{color:#fff}.el-date-table td.available:hover{color:#409eff}.el-date-table td.current:not(.disabled) span{color:#fff;background-color:#409eff}.el-date-table td.end-date div,.el-date-table td.start-date div{color:#fff}.el-date-table td.end-date span,.el-date-table td.start-date span{background-color:#409eff}.el-date-table td.start-date div{margin-left:5px;border-top-left-radius:15px;border-bottom-left-radius:15px}.el-date-table td.end-date div{margin-right:5px;border-top-right-radius:15px;border-bottom-right-radius:15px}.el-date-table td.disabled div{background-color:#f5f7fa;opacity:1;cursor:not-allowed;color:#c0c4cc}.el-date-table td.selected div{margin-left:5px;margin-right:5px;background-color:#f2f6fc;border-radius:15px}.el-date-table td.selected div:hover{background-color:#f2f6fc}.el-date-table td.selected span{background-color:#409eff;color:#fff;border-radius:15px}.el-date-table td.week{font-size:80%;color:#606266}.el-month-table,.el-year-table{font-size:12px;border-collapse:collapse}.el-date-table th{padding:5px;color:#606266;font-weight:400;border-bottom:1px solid #ebeef5}.el-month-table{margin:-1px}.el-month-table td{text-align:center;padding:8px 0;cursor:pointer}.el-month-table td div{height:48px;padding:6px 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-month-table td.today .cell{color:#409eff;font-weight:700}.el-month-table td.today.end-date .cell,.el-month-table td.today.start-date .cell{color:#fff}.el-month-table td.disabled .cell{background-color:#f5f7fa;cursor:not-allowed;color:#c0c4cc}.el-month-table td.disabled .cell:hover{color:#c0c4cc}.el-month-table td .cell{width:60px;height:36px;display:block;line-height:36px;color:#606266;margin:0 auto;border-radius:18px}.el-month-table td .cell:hover{color:#409eff}.el-month-table td.in-range div,.el-month-table td.in-range div:hover{background-color:#f2f6fc}.el-month-table td.end-date div,.el-month-table td.start-date div{color:#fff}.el-month-table td.end-date .cell,.el-month-table td.start-date .cell{color:#fff;background-color:#409eff}.el-month-table td.start-date div{border-top-left-radius:24px;border-bottom-left-radius:24px}.el-month-table td.end-date div{border-top-right-radius:24px;border-bottom-right-radius:24px}.el-month-table td.current:not(.disabled) .cell{color:#409eff}.el-year-table{margin:-1px}.el-year-table .el-icon{color:#303133}.el-year-table td{text-align:center;padding:20px 3px;cursor:pointer}.el-year-table td.today .cell{color:#409eff;font-weight:700}.el-year-table td.disabled .cell{background-color:#f5f7fa;cursor:not-allowed;color:#c0c4cc}.el-year-table td.disabled .cell:hover{color:#c0c4cc}.el-year-table td .cell{width:48px;height:32px;display:block;line-height:32px;color:#606266;margin:0 auto}.el-year-table td .cell:hover,.el-year-table td.current:not(.disabled) .cell{color:#409eff}.el-date-range-picker{width:646px}.el-date-range-picker.has-sidebar{width:756px}.el-date-range-picker table{table-layout:fixed;width:100%}.el-date-range-picker .el-picker-panel__body{min-width:513px}.el-date-range-picker .el-picker-panel__content{margin:0}.el-date-range-picker__header{position:relative;text-align:center;height:28px}.el-date-range-picker__header [class*=arrow-left]{float:left}.el-date-range-picker__header [class*=arrow-right]{float:right}.el-date-range-picker__header div{font-size:16px;font-weight:500;margin-right:50px}.el-date-range-picker__content{float:left;width:50%;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:16px}.el-date-range-picker__content.is-left{border-right:1px solid #e4e4e4}.el-date-range-picker__content .el-date-range-picker__header div{margin-left:50px;margin-right:50px}.el-date-range-picker__editors-wrap{-webkit-box-sizing:border-box;box-sizing:border-box;display:table-cell}.el-date-range-picker__editors-wrap.is-right{text-align:right}.el-date-range-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-range-picker__time-header>.el-icon-arrow-right{font-size:20px;vertical-align:middle;display:table-cell;color:#303133}.el-date-range-picker__time-picker-wrap{position:relative;display:table-cell;padding:0 5px}.el-date-range-picker__time-picker-wrap .el-picker-panel{position:absolute;top:13px;right:0;z-index:1;background:#fff}.el-date-picker{width:322px}.el-date-picker.has-sidebar.has-time{width:434px}.el-date-picker.has-sidebar{width:438px}.el-date-picker.has-time .el-picker-panel__body-wrapper{position:relative}.el-date-picker .el-picker-panel__content{width:292px}.el-date-picker table{table-layout:fixed;width:100%}.el-date-picker__editor-wrap{position:relative;display:table-cell;padding:0 5px}.el-date-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-picker__header{margin:12px;text-align:center}.el-date-picker__header--bordered{margin-bottom:0;padding-bottom:12px;border-bottom:1px solid #ebeef5}.el-date-picker__header--bordered+.el-picker-panel__content{margin-top:0}.el-date-picker__header-label{font-size:16px;font-weight:500;padding:0 5px;line-height:22px;text-align:center;cursor:pointer;color:#606266}.el-date-picker__header-label.active,.el-date-picker__header-label:hover{color:#409eff}.el-date-picker__prev-btn{float:left}.el-date-picker__next-btn{float:right}.el-date-picker__time-wrap{padding:10px;text-align:center}.el-date-picker__time-label{float:left;cursor:pointer;line-height:30px;margin-left:10px}.time-select{margin:5px 0;min-width:0}.time-select .el-picker-panel__content{max-height:200px;margin:0}.time-select-item{padding:8px 10px;font-size:14px;line-height:20px}.time-select-item.selected:not(.disabled){color:#409eff;font-weight:700}.time-select-item.disabled{color:#e4e7ed;cursor:not-allowed}.time-select-item:hover{background-color:#f5f7fa;font-weight:700;cursor:pointer}.el-date-editor{position:relative;display:inline-block;text-align:left}.el-date-editor.el-input,.el-date-editor.el-input__inner{width:220px}.el-date-editor--monthrange.el-input,.el-date-editor--monthrange.el-input__inner{width:300px}.el-date-editor--daterange.el-input,.el-date-editor--daterange.el-input__inner,.el-date-editor--timerange.el-input,.el-date-editor--timerange.el-input__inner{width:350px}.el-date-editor--datetimerange.el-input,.el-date-editor--datetimerange.el-input__inner{width:400px}.el-date-editor--dates .el-input__inner{text-overflow:ellipsis;white-space:nowrap}.el-date-editor .el-icon-circle-close{cursor:pointer}.el-date-editor .el-range__icon{font-size:14px;margin-left:-5px;color:#c0c4cc;float:left;line-height:32px}.el-date-editor .el-range-input,.el-date-editor .el-range-separator{height:100%;margin:0;text-align:center;display:inline-block;font-size:14px}.el-date-editor .el-range-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;outline:0;padding:0;width:39%;color:#606266}.el-date-editor .el-range-input::-webkit-input-placeholder{color:#c0c4cc}.el-date-editor .el-range-input:-ms-input-placeholder{color:#c0c4cc}.el-date-editor .el-range-input::-ms-input-placeholder{color:#c0c4cc}.el-date-editor .el-range-input::-moz-placeholder{color:#c0c4cc}.el-date-editor .el-range-input::placeholder{color:#c0c4cc}.el-date-editor .el-range-separator{padding:0 5px;line-height:32px;width:5%;color:#303133}.el-date-editor .el-range__close-icon{font-size:14px;color:#c0c4cc;width:25px;display:inline-block;float:right;line-height:32px}.el-range-editor.el-input__inner{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:3px 10px}.el-range-editor .el-range-input{line-height:1}.el-range-editor.is-active,.el-range-editor.is-active:hover{border-color:#409eff}.el-range-editor--medium.el-input__inner{height:36px}.el-range-editor--medium .el-range-separator{line-height:28px;font-size:14px}.el-range-editor--medium .el-range-input{font-size:14px}.el-range-editor--medium .el-range__close-icon,.el-range-editor--medium .el-range__icon{line-height:28px}.el-range-editor--small.el-input__inner{height:32px}.el-range-editor--small .el-range-separator{line-height:24px;font-size:13px}.el-range-editor--small .el-range-input{font-size:13px}.el-range-editor--small .el-range__close-icon,.el-range-editor--small .el-range__icon{line-height:24px}.el-range-editor--mini.el-input__inner{height:28px}.el-range-editor--mini .el-range-separator{line-height:20px;font-size:12px}.el-range-editor--mini .el-range-input{font-size:12px}.el-range-editor--mini .el-range__close-icon,.el-range-editor--mini .el-range__icon{line-height:20px}.el-range-editor.is-disabled{background-color:#f5f7fa;border-color:#e4e7ed;color:#c0c4cc;cursor:not-allowed}.el-range-editor.is-disabled:focus,.el-range-editor.is-disabled:hover{border-color:#e4e7ed}.el-range-editor.is-disabled input{background-color:#f5f7fa;color:#c0c4cc;cursor:not-allowed}.el-range-editor.is-disabled input::-webkit-input-placeholder{color:#c0c4cc}.el-range-editor.is-disabled input:-ms-input-placeholder{color:#c0c4cc}.el-range-editor.is-disabled input::-ms-input-placeholder{color:#c0c4cc}.el-range-editor.is-disabled input::-moz-placeholder{color:#c0c4cc}.el-range-editor.is-disabled input::placeholder{color:#c0c4cc}.el-range-editor.is-disabled .el-range-separator{color:#c0c4cc}.el-picker-panel{color:#606266;border:1px solid #e4e7ed;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);background:#fff;border-radius:4px;line-height:30px;margin:5px 0}.el-picker-panel,.el-popover,.el-time-panel{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-picker-panel__body-wrapper:after,.el-picker-panel__body:after{content:"";display:table;clear:both}.el-picker-panel__content{position:relative;margin:15px}.el-picker-panel__footer{border-top:1px solid #e4e4e4;padding:4px;text-align:right;background-color:#fff;position:relative;font-size:0}.el-picker-panel__shortcut{display:block;width:100%;border:0;background-color:transparent;line-height:28px;font-size:14px;color:#606266;padding-left:12px;text-align:left;outline:0;cursor:pointer}.el-picker-panel__shortcut:hover{color:#409eff}.el-picker-panel__shortcut.active{background-color:#e6f1fe;color:#409eff}.el-picker-panel__btn{border:1px solid #dcdcdc;color:#333;line-height:24px;border-radius:2px;padding:0 20px;cursor:pointer;background-color:transparent;outline:0;font-size:12px}.el-picker-panel__btn[disabled]{color:#ccc;cursor:not-allowed}.el-picker-panel__icon-btn{font-size:12px;color:#303133;border:0;background:0 0;cursor:pointer;outline:0;margin-top:8px}.el-picker-panel__icon-btn:hover{color:#409eff}.el-picker-panel__icon-btn.is-disabled{color:#bbb}.el-picker-panel__icon-btn.is-disabled:hover{cursor:not-allowed}.el-picker-panel__link-btn{vertical-align:middle}.el-picker-panel [slot=sidebar],.el-picker-panel__sidebar{position:absolute;top:0;bottom:0;width:110px;border-right:1px solid #e4e4e4;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;background-color:#fff;overflow:auto}.el-picker-panel [slot=sidebar]+.el-picker-panel__body,.el-picker-panel__sidebar+.el-picker-panel__body{margin-left:110px}.el-time-spinner.has-seconds .el-time-spinner__wrapper{width:33.3%}.el-time-spinner__wrapper{max-height:190px;overflow:auto;display:inline-block;width:50%;vertical-align:top;position:relative}.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default){padding-bottom:15px}.el-time-spinner__input.el-input .el-input__inner,.el-time-spinner__list{padding:0;text-align:center}.el-time-spinner__wrapper.is-arrow{-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;overflow:hidden}.el-time-spinner__wrapper.is-arrow .el-time-spinner__list{-webkit-transform:translateY(-32px);transform:translateY(-32px)}.el-time-spinner__wrapper.is-arrow .el-time-spinner__item:hover:not(.disabled):not(.active){background:#fff;cursor:default}.el-time-spinner__arrow{font-size:12px;color:#909399;position:absolute;left:0;width:100%;z-index:1;text-align:center;height:30px;line-height:30px;cursor:pointer}.el-time-spinner__arrow:hover{color:#409eff}.el-time-spinner__arrow.el-icon-arrow-up{top:10px}.el-time-spinner__arrow.el-icon-arrow-down{bottom:10px}.el-time-spinner__input.el-input{width:70%}.el-time-spinner__list{margin:0;list-style:none}.el-time-spinner__list:after,.el-time-spinner__list:before{content:"";display:block;width:100%;height:80px}.el-time-spinner__item{height:32px;line-height:32px;font-size:12px;color:#606266}.el-time-spinner__item:hover:not(.disabled):not(.active){background:#f5f7fa;cursor:pointer}.el-time-spinner__item.active:not(.disabled){color:#303133;font-weight:700}.el-time-spinner__item.disabled{color:#c0c4cc;cursor:not-allowed}.el-time-panel{margin:5px 0;border:1px solid #e4e7ed;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:2px;position:absolute;width:180px;left:0;z-index:1000;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;-webkit-box-sizing:content-box;box-sizing:content-box}.el-time-panel__content{font-size:0;position:relative;overflow:hidden}.el-time-panel__content:after,.el-time-panel__content:before{content:"";top:50%;position:absolute;margin-top:-15px;height:32px;z-index:-1;left:0;right:0;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;text-align:left;border-top:1px solid #e4e7ed;border-bottom:1px solid #e4e7ed}.el-time-panel__content:after{left:50%;margin-left:12%;margin-right:12%}.el-time-panel__content:before{padding-left:50%;margin-right:12%;margin-left:12%}.el-time-panel__content.has-seconds:after{left:66.66667%}.el-time-panel__content.has-seconds:before{padding-left:33.33333%}.el-time-panel__footer{border-top:1px solid #e4e4e4;padding:4px;height:36px;line-height:25px;text-align:right;-webkit-box-sizing:border-box;box-sizing:border-box}.el-time-panel__btn{border:none;line-height:28px;padding:0 5px;margin:0 5px;cursor:pointer;background-color:transparent;outline:0;font-size:12px;color:#303133}.el-time-panel__btn.confirm{font-weight:800;color:#409eff}.el-time-range-picker{width:354px;overflow:visible}.el-time-range-picker__content{position:relative;text-align:center;padding:10px}.el-time-range-picker__cell{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:4px 7px 7px;width:50%;display:inline-block}.el-time-range-picker__header{margin-bottom:5px;text-align:center;font-size:14px}.el-time-range-picker__body{border-radius:2px;border:1px solid #e4e7ed}.el-popover{position:absolute;background:#fff;min-width:150px;border:1px solid #ebeef5;padding:12px;z-index:2000;color:#606266;line-height:1.4;text-align:justify;font-size:14px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);word-break:break-all}.el-popover--plain{padding:18px 20px}.el-popover__title{color:#303133;font-size:16px;line-height:1;margin-bottom:12px}.v-modal-enter{-webkit-animation:v-modal-in .2s ease;animation:v-modal-in .2s ease}.v-modal-leave{-webkit-animation:v-modal-out .2s ease forwards;animation:v-modal-out .2s ease forwards}@keyframes v-modal-in{0%{opacity:0}}@keyframes v-modal-out{to{opacity:0}}.v-modal{position:fixed;left:0;top:0;width:100%;height:100%;opacity:.5;background:#000}.el-popup-parent--hidden{overflow:hidden}.el-message-box{display:inline-block;width:420px;padding-bottom:10px;vertical-align:middle;background-color:#fff;border-radius:4px;border:1px solid #ebeef5;font-size:18px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);text-align:left;overflow:hidden;-webkit-backface-visibility:hidden;backface-visibility:hidden}.el-message-box__wrapper{position:fixed;top:0;bottom:0;left:0;right:0;text-align:center}.el-message-box__wrapper:after{content:"";display:inline-block;height:100%;width:0;vertical-align:middle}.el-message-box__header{position:relative;padding:15px 15px 10px}.el-message-box__title{padding-left:0;margin-bottom:0;font-size:18px;line-height:1;color:#303133}.el-message-box__headerbtn{position:absolute;top:15px;right:15px;padding:0;border:none;outline:0;background:0 0;font-size:16px;cursor:pointer}.el-form-item.is-error .el-input__inner,.el-form-item.is-error .el-input__inner:focus,.el-form-item.is-error .el-textarea__inner,.el-form-item.is-error .el-textarea__inner:focus,.el-message-box__input input.invalid,.el-message-box__input input.invalid:focus{border-color:#f56c6c}.el-message-box__headerbtn .el-message-box__close{color:#909399}.el-message-box__headerbtn:focus .el-message-box__close,.el-message-box__headerbtn:hover .el-message-box__close{color:#409eff}.el-message-box__content{position:relative;padding:10px 15px;color:#606266;font-size:14px}.el-message-box__input{padding-top:15px}.el-message-box__status{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);font-size:24px!important}.el-message-box__status:before{padding-left:1px}.el-message-box__status+.el-message-box__message{padding-left:36px;padding-right:12px}.el-message-box__status.el-icon-success{color:#67c23a}.el-message-box__status.el-icon-info{color:#909399}.el-message-box__status.el-icon-warning{color:#e6a23c}.el-message-box__status.el-icon-error{color:#f56c6c}.el-message-box__message{margin:0}.el-message-box__message p{margin:0;line-height:24px}.el-message-box__errormsg{color:#f56c6c;font-size:12px;min-height:18px;margin-top:2px}.el-message-box__btns{padding:5px 15px 0;text-align:right}.el-message-box__btns button:nth-child(2){margin-left:10px}.el-message-box__btns-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.el-container,.el-container.is-vertical,.el-drawer,.el-link,.el-steps--vertical{-webkit-box-direction:normal}.el-message-box--center{padding-bottom:30px}.el-message-box--center .el-message-box__header{padding-top:30px}.el-message-box--center .el-message-box__title{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-message-box--center .el-message-box__status{position:relative;top:auto;padding-right:5px;text-align:center;-webkit-transform:translateY(-1px);transform:translateY(-1px)}.el-message-box--center .el-message-box__message{margin-left:0}.el-message-box--center .el-message-box__btns,.el-message-box--center .el-message-box__content{text-align:center}.el-message-box--center .el-message-box__content{padding-left:27px;padding-right:27px}.msgbox-fade-enter-active{-webkit-animation:msgbox-fade-in .3s;animation:msgbox-fade-in .3s}.msgbox-fade-leave-active{-webkit-animation:msgbox-fade-out .3s;animation:msgbox-fade-out .3s}@-webkit-keyframes msgbox-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes msgbox-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@-webkit-keyframes msgbox-fade-out{0%{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}to{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes msgbox-fade-out{0%{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}to{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.el-breadcrumb{font-size:14px;line-height:1}.el-breadcrumb:after,.el-breadcrumb:before{display:table;content:""}.el-breadcrumb:after{clear:both}.el-breadcrumb__separator{margin:0 9px;font-weight:700;color:#c0c4cc}.el-breadcrumb__separator[class*=icon]{margin:0 6px;font-weight:400}.el-breadcrumb__item{float:left}.el-breadcrumb__inner{color:#606266}.el-breadcrumb__inner.is-link,.el-breadcrumb__inner a{font-weight:700;text-decoration:none;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1);color:#303133}.el-breadcrumb__inner.is-link:hover,.el-breadcrumb__inner a:hover{color:#409eff;cursor:pointer}.el-breadcrumb__item:last-child .el-breadcrumb__inner,.el-breadcrumb__item:last-child .el-breadcrumb__inner:hover,.el-breadcrumb__item:last-child .el-breadcrumb__inner a,.el-breadcrumb__item:last-child .el-breadcrumb__inner a:hover{font-weight:400;color:#606266;cursor:text}.el-breadcrumb__item:last-child .el-breadcrumb__separator{display:none}.el-form--label-left .el-form-item__label{text-align:left}.el-form--label-top .el-form-item__label{float:none;display:inline-block;text-align:left;padding:0 0 10px}.el-form--inline .el-form-item{display:inline-block;margin-right:10px;vertical-align:top}.el-form--inline .el-form-item__label{float:none;display:inline-block}.el-form--inline .el-form-item__content{display:inline-block;vertical-align:top}.el-form--inline.el-form--label-top .el-form-item__content{display:block}.el-form-item{margin-bottom:22px}.el-form-item:after,.el-form-item:before{display:table;content:""}.el-form-item:after{clear:both}.el-form-item .el-form-item{margin-bottom:0}.el-form-item--mini.el-form-item,.el-form-item--small.el-form-item{margin-bottom:18px}.el-form-item .el-input__validateIcon{display:none}.el-form-item--medium .el-form-item__content,.el-form-item--medium .el-form-item__label{line-height:36px}.el-form-item--small .el-form-item__content,.el-form-item--small .el-form-item__label{line-height:32px}.el-form-item--small .el-form-item__error{padding-top:2px}.el-form-item--mini .el-form-item__content,.el-form-item--mini .el-form-item__label{line-height:28px}.el-form-item--mini .el-form-item__error{padding-top:1px}.el-form-item__label-wrap{float:left}.el-form-item__label-wrap .el-form-item__label{display:inline-block;float:none}.el-form-item__label{text-align:right;vertical-align:middle;float:left;font-size:14px;color:#606266;line-height:40px;padding:0 12px 0 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-form-item__content{line-height:40px;position:relative;font-size:14px}.el-form-item__content:after,.el-form-item__content:before{display:table;content:""}.el-form-item__content:after{clear:both}.el-form-item__content .el-input-group{vertical-align:top}.el-form-item__error{color:#f56c6c;font-size:12px;line-height:1;padding-top:4px;position:absolute;top:100%;left:0}.el-form-item__error--inline{position:relative;top:auto;left:auto;display:inline-block;margin-left:10px}.el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap>.el-form-item__label:before,.el-form-item.is-required:not(.is-no-asterisk)>.el-form-item__label:before{content:"*";color:#f56c6c;margin-right:4px}.el-form-item.is-error .el-input-group__append .el-input__inner,.el-form-item.is-error .el-input-group__prepend .el-input__inner{border-color:transparent}.el-form-item.is-error .el-input__validateIcon{color:#f56c6c}.el-form-item--feedback .el-input__validateIcon{display:inline-block}.el-tabs__header{padding:0;position:relative;margin:0 0 15px}.el-tabs__active-bar{position:absolute;bottom:0;left:0;height:2px;background-color:#409eff;z-index:1;-webkit-transition:-webkit-transform .3s cubic-bezier(.645,.045,.355,1);transition:-webkit-transform .3s cubic-bezier(.645,.045,.355,1);transition:transform .3s cubic-bezier(.645,.045,.355,1);transition:transform .3s cubic-bezier(.645,.045,.355,1),-webkit-transform .3s cubic-bezier(.645,.045,.355,1);list-style:none}.el-tabs__new-tab{float:right;border:1px solid #d3dce6;height:18px;width:18px;line-height:18px;margin:12px 0 9px 10px;border-radius:3px;text-align:center;font-size:12px;color:#d3dce6;cursor:pointer;-webkit-transition:all .15s;transition:all .15s}.el-collapse-item__arrow,.el-tabs__nav{-webkit-transition:-webkit-transform .3s}.el-tabs__new-tab .el-icon-plus{-webkit-transform:scale(.8);transform:scale(.8)}.el-tabs__new-tab:hover{color:#409eff}.el-tabs__nav-wrap{overflow:hidden;margin-bottom:-1px;position:relative}.el-tabs__nav-wrap:after{content:"";position:absolute;left:0;bottom:0;width:100%;height:2px;background-color:#e4e7ed;z-index:1}.el-tabs--border-card>.el-tabs__header .el-tabs__nav-wrap:after,.el-tabs--card>.el-tabs__header .el-tabs__nav-wrap:after{content:none}.el-tabs__nav-wrap.is-scrollable{padding:0 20px;-webkit-box-sizing:border-box;box-sizing:border-box}.el-tabs__nav-scroll{overflow:hidden}.el-tabs__nav-next,.el-tabs__nav-prev{position:absolute;cursor:pointer;line-height:44px;font-size:12px;color:#909399}.el-tabs__nav-next{right:0}.el-tabs__nav-prev{left:0}.el-tabs__nav{white-space:nowrap;position:relative;transition:-webkit-transform .3s;-webkit-transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;float:left;z-index:2}.el-tabs__nav.is-stretch{min-width:100%;display:-webkit-box;display:-ms-flexbox;display:flex}.el-tabs__nav.is-stretch>*{-webkit-box-flex:1;-ms-flex:1;flex:1;text-align:center}.el-tabs__item{padding:0 20px;height:40px;-webkit-box-sizing:border-box;box-sizing:border-box;line-height:40px;display:inline-block;list-style:none;font-size:14px;font-weight:500;color:#303133;position:relative}.el-tabs__item:focus,.el-tabs__item:focus:active{outline:0}.el-tabs__item:focus.is-active.is-focus:not(:active){-webkit-box-shadow:0 0 2px 2px #409eff inset;box-shadow:inset 0 0 2px 2px #409eff;border-radius:3px}.el-tabs__item .el-icon-close{border-radius:50%;text-align:center;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);margin-left:5px}.el-tabs__item .el-icon-close:before{-webkit-transform:scale(.9);transform:scale(.9);display:inline-block}.el-tabs__item .el-icon-close:hover{background-color:#c0c4cc;color:#fff}.el-tabs__item.is-active{color:#409eff}.el-tabs__item:hover{color:#409eff;cursor:pointer}.el-tabs__item.is-disabled{color:#c0c4cc;cursor:default}.el-tabs__content{overflow:hidden;position:relative}.el-tabs--card>.el-tabs__header{border-bottom:1px solid #e4e7ed}.el-tabs--card>.el-tabs__header .el-tabs__nav{border:1px solid #e4e7ed;border-bottom:none;border-radius:4px 4px 0 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-tabs--card>.el-tabs__header .el-tabs__active-bar{display:none}.el-tabs--card>.el-tabs__header .el-tabs__item .el-icon-close{position:relative;font-size:12px;width:0;height:14px;vertical-align:middle;line-height:15px;overflow:hidden;top:-1px;right:-2px;-webkit-transform-origin:100% 50%;transform-origin:100% 50%}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active.is-closable .el-icon-close,.el-tabs--card>.el-tabs__header .el-tabs__item.is-closable:hover .el-icon-close{width:14px}.el-tabs--card>.el-tabs__header .el-tabs__item{border-bottom:1px solid transparent;border-left:1px solid #e4e7ed;-webkit-transition:color .3s cubic-bezier(.645,.045,.355,1),padding .3s cubic-bezier(.645,.045,.355,1);transition:color .3s cubic-bezier(.645,.045,.355,1),padding .3s cubic-bezier(.645,.045,.355,1)}.el-tabs--card>.el-tabs__header .el-tabs__item:first-child{border-left:none}.el-tabs--card>.el-tabs__header .el-tabs__item.is-closable:hover{padding-left:13px;padding-right:13px}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active{border-bottom-color:#fff}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active.is-closable{padding-left:20px;padding-right:20px}.el-tabs--border-card{background:#fff;border:1px solid #dcdfe6;-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04);box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04)}.el-tabs--border-card>.el-tabs__content{padding:15px}.el-tabs--border-card>.el-tabs__header{background-color:#f5f7fa;border-bottom:1px solid #e4e7ed;margin:0}.el-tabs--border-card>.el-tabs__header .el-tabs__item{-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);border:1px solid transparent;margin-top:-1px;color:#909399}.el-tabs--border-card>.el-tabs__header .el-tabs__item+.el-tabs__item,.el-tabs--border-card>.el-tabs__header .el-tabs__item:first-child{margin-left:-1px}.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active{color:#409eff;background-color:#fff;border-right-color:#dcdfe6;border-left-color:#dcdfe6}.el-tabs--border-card>.el-tabs__header .el-tabs__item:not(.is-disabled):hover{color:#409eff}.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-disabled{color:#c0c4cc}.el-tabs--border-card>.el-tabs__header .is-scrollable .el-tabs__item:first-child{margin-left:0}.el-tabs--bottom .el-tabs__item.is-bottom:nth-child(2),.el-tabs--bottom .el-tabs__item.is-top:nth-child(2),.el-tabs--top .el-tabs__item.is-bottom:nth-child(2),.el-tabs--top .el-tabs__item.is-top:nth-child(2){padding-left:0}.el-tabs--bottom .el-tabs__item.is-bottom:last-child,.el-tabs--bottom .el-tabs__item.is-top:last-child,.el-tabs--top .el-tabs__item.is-bottom:last-child,.el-tabs--top .el-tabs__item.is-top:last-child{padding-right:0}.el-tabs--bottom.el-tabs--border-card>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--bottom.el-tabs--card>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--bottom .el-tabs--left>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--bottom .el-tabs--right>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--top.el-tabs--border-card>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--top.el-tabs--card>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--top .el-tabs--left>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--top .el-tabs--right>.el-tabs__header .el-tabs__item:nth-child(2){padding-left:20px}.el-tabs--bottom.el-tabs--border-card>.el-tabs__header .el-tabs__item:last-child,.el-tabs--bottom.el-tabs--card>.el-tabs__header .el-tabs__item:last-child,.el-tabs--bottom .el-tabs--left>.el-tabs__header .el-tabs__item:last-child,.el-tabs--bottom .el-tabs--right>.el-tabs__header .el-tabs__item:last-child,.el-tabs--top.el-tabs--border-card>.el-tabs__header .el-tabs__item:last-child,.el-tabs--top.el-tabs--card>.el-tabs__header .el-tabs__item:last-child,.el-tabs--top .el-tabs--left>.el-tabs__header .el-tabs__item:last-child,.el-tabs--top .el-tabs--right>.el-tabs__header .el-tabs__item:last-child{padding-right:20px}.el-tabs--bottom .el-tabs__header.is-bottom{margin-bottom:0;margin-top:10px}.el-tabs--bottom.el-tabs--border-card .el-tabs__header.is-bottom{border-bottom:0;border-top:1px solid #dcdfe6}.el-tabs--bottom.el-tabs--border-card .el-tabs__nav-wrap.is-bottom{margin-top:-1px;margin-bottom:0}.el-tabs--bottom.el-tabs--border-card .el-tabs__item.is-bottom:not(.is-active){border:1px solid transparent}.el-tabs--bottom.el-tabs--border-card .el-tabs__item.is-bottom{margin:0 -1px -1px}.el-tabs--left,.el-tabs--right{overflow:hidden}.el-tabs--left .el-tabs__header.is-left,.el-tabs--left .el-tabs__header.is-right,.el-tabs--left .el-tabs__nav-scroll,.el-tabs--left .el-tabs__nav-wrap.is-left,.el-tabs--left .el-tabs__nav-wrap.is-right,.el-tabs--right .el-tabs__header.is-left,.el-tabs--right .el-tabs__header.is-right,.el-tabs--right .el-tabs__nav-scroll,.el-tabs--right .el-tabs__nav-wrap.is-left,.el-tabs--right .el-tabs__nav-wrap.is-right{height:100%}.el-tabs--left .el-tabs__active-bar.is-left,.el-tabs--left .el-tabs__active-bar.is-right,.el-tabs--right .el-tabs__active-bar.is-left,.el-tabs--right .el-tabs__active-bar.is-right{top:0;bottom:auto;width:2px;height:auto}.el-tabs--left .el-tabs__nav-wrap.is-left,.el-tabs--left .el-tabs__nav-wrap.is-right,.el-tabs--right .el-tabs__nav-wrap.is-left,.el-tabs--right .el-tabs__nav-wrap.is-right{margin-bottom:0}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-next,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev{height:30px;line-height:30px;width:100%;text-align:center;cursor:pointer}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-next i,.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev i,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-next i,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev i,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-next i,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev i,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-next i,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev i{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev{left:auto;top:0}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-next{right:auto;bottom:0}.el-tabs--left .el-tabs__active-bar.is-left,.el-tabs--left .el-tabs__nav-wrap.is-left:after{right:0;left:auto}.el-tabs--left .el-tabs__nav-wrap.is-left.is-scrollable,.el-tabs--left .el-tabs__nav-wrap.is-right.is-scrollable,.el-tabs--right .el-tabs__nav-wrap.is-left.is-scrollable,.el-tabs--right .el-tabs__nav-wrap.is-right.is-scrollable{padding:30px 0}.el-tabs--left .el-tabs__nav-wrap.is-left:after,.el-tabs--left .el-tabs__nav-wrap.is-right:after,.el-tabs--right .el-tabs__nav-wrap.is-left:after,.el-tabs--right .el-tabs__nav-wrap.is-right:after{height:100%;width:2px;bottom:auto;top:0}.el-tabs--left .el-tabs__nav.is-left,.el-tabs--left .el-tabs__nav.is-right,.el-tabs--right .el-tabs__nav.is-left,.el-tabs--right .el-tabs__nav.is-right{float:none}.el-tabs--left .el-tabs__item.is-left,.el-tabs--left .el-tabs__item.is-right,.el-tabs--right .el-tabs__item.is-left,.el-tabs--right .el-tabs__item.is-right{display:block}.el-tabs--left.el-tabs--card .el-tabs__active-bar.is-left,.el-tabs--right.el-tabs--card .el-tabs__active-bar.is-right{display:none}.el-tabs--left .el-tabs__header.is-left{float:left;margin-bottom:0;margin-right:10px}.el-tabs--left .el-tabs__nav-wrap.is-left{margin-right:-1px}.el-tabs--left .el-tabs__item.is-left{text-align:right}.el-tabs--left.el-tabs--card .el-tabs__item.is-left{border-left:none;border-right:1px solid #e4e7ed;border-bottom:none;border-top:1px solid #e4e7ed;text-align:left}.el-tabs--left.el-tabs--card .el-tabs__item.is-left:first-child{border-right:1px solid #e4e7ed;border-top:none}.el-tabs--left.el-tabs--card .el-tabs__item.is-left.is-active{border:1px solid #e4e7ed;border-right-color:#fff;border-left:none;border-bottom:none}.el-tabs--left.el-tabs--card .el-tabs__item.is-left.is-active:first-child{border-top:none}.el-tabs--left.el-tabs--card .el-tabs__item.is-left.is-active:last-child{border-bottom:none}.el-tabs--left.el-tabs--card .el-tabs__nav{border-radius:4px 0 0 4px;border-bottom:1px solid #e4e7ed;border-right:none}.el-tabs--left.el-tabs--card .el-tabs__new-tab{float:none}.el-tabs--left.el-tabs--border-card .el-tabs__header.is-left{border-right:1px solid #dfe4ed}.el-tabs--left.el-tabs--border-card .el-tabs__item.is-left{border:1px solid transparent;margin:-1px 0 -1px -1px}.el-tabs--left.el-tabs--border-card .el-tabs__item.is-left.is-active{border-color:#d1dbe5 transparent}.el-tabs--right .el-tabs__header.is-right{float:right;margin-bottom:0;margin-left:10px}.el-tabs--right .el-tabs__nav-wrap.is-right{margin-left:-1px}.el-tabs--right .el-tabs__nav-wrap.is-right:after{left:0;right:auto}.el-tabs--right .el-tabs__active-bar.is-right{left:0}.el-tabs--right.el-tabs--card .el-tabs__item.is-right{border-bottom:none;border-top:1px solid #e4e7ed}.el-tabs--right.el-tabs--card .el-tabs__item.is-right:first-child{border-left:1px solid #e4e7ed;border-top:none}.el-tabs--right.el-tabs--card .el-tabs__item.is-right.is-active{border:1px solid #e4e7ed;border-left-color:#fff;border-right:none;border-bottom:none}.el-tabs--right.el-tabs--card .el-tabs__item.is-right.is-active:first-child{border-top:none}.el-tabs--right.el-tabs--card .el-tabs__item.is-right.is-active:last-child{border-bottom:none}.el-tabs--right.el-tabs--card .el-tabs__nav{border-radius:0 4px 4px 0;border-bottom:1px solid #e4e7ed;border-left:none}.el-tabs--right.el-tabs--border-card .el-tabs__header.is-right{border-left:1px solid #dfe4ed}.el-tabs--right.el-tabs--border-card .el-tabs__item.is-right{border:1px solid transparent;margin:-1px -1px -1px 0}.el-tabs--right.el-tabs--border-card .el-tabs__item.is-right.is-active{border-color:#d1dbe5 transparent}.slideInLeft-transition,.slideInRight-transition{display:inline-block}.slideInRight-enter{-webkit-animation:slideInRight-enter .3s;animation:slideInRight-enter .3s}.slideInRight-leave{position:absolute;left:0;right:0;-webkit-animation:slideInRight-leave .3s;animation:slideInRight-leave .3s}.slideInLeft-enter{-webkit-animation:slideInLeft-enter .3s;animation:slideInLeft-enter .3s}.slideInLeft-leave{position:absolute;left:0;right:0;-webkit-animation:slideInLeft-leave .3s;animation:slideInLeft-leave .3s}@-webkit-keyframes slideInRight-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInRight-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes slideInRight-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%);opacity:0}}@keyframes slideInRight-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%);opacity:0}}@-webkit-keyframes slideInLeft-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInLeft-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes slideInLeft-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%);opacity:0}}@keyframes slideInLeft-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%);opacity:0}}.el-tree{position:relative;cursor:default;background:#fff;color:#606266}.el-tree__empty-block{position:relative;min-height:60px;text-align:center;width:100%;height:100%}.el-tree__empty-text{position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);color:#909399}.el-tree__drop-indicator{position:absolute;left:0;right:0;height:1px;background-color:#409eff}.el-tree-node{white-space:nowrap;outline:0}.el-tree-node:focus>.el-tree-node__content{background-color:#f5f7fa}.el-tree-node.is-drop-inner>.el-tree-node__content .el-tree-node__label{background-color:#409eff;color:#fff}.el-tree-node__content{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:26px;cursor:pointer}.el-tree-node__content>.el-tree-node__expand-icon{padding:6px}.el-tree-node__content>label.el-checkbox{margin-right:8px}.el-tree-node__content:hover{background-color:#f5f7fa}.el-tree.is-dragging .el-tree-node__content{cursor:move}.el-tree.is-dragging.is-drop-not-allow .el-tree-node__content{cursor:not-allowed}.el-tree-node__expand-icon{cursor:pointer;color:#c0c4cc;font-size:12px;-webkit-transform:rotate(0);transform:rotate(0);-webkit-transition:-webkit-transform .3s ease-in-out;transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;transition:transform .3s ease-in-out,-webkit-transform .3s ease-in-out}.el-tree-node__expand-icon.expanded{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-tree-node__expand-icon.is-leaf{color:transparent;cursor:default}.el-tree-node__label{font-size:14px}.el-tree-node__loading-icon{margin-right:8px;font-size:14px;color:#c0c4cc}.el-tree-node>.el-tree-node__children{overflow:hidden;background-color:transparent}.el-tree-node.is-expanded>.el-tree-node__children{display:block}.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content{background-color:#f0f7ff}.el-alert{width:100%;padding:8px 16px;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;position:relative;background-color:#fff;overflow:hidden;opacity:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-transition:opacity .2s;transition:opacity .2s}.el-alert.is-light .el-alert__closebtn{color:#c0c4cc}.el-alert.is-dark .el-alert__closebtn,.el-alert.is-dark .el-alert__description{color:#fff}.el-alert.is-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-alert--success.is-light{background-color:#f0f9eb;color:#67c23a}.el-alert--success.is-light .el-alert__description{color:#67c23a}.el-alert--success.is-dark{background-color:#67c23a;color:#fff}.el-alert--info.is-light{background-color:#f4f4f5;color:#909399}.el-alert--info.is-dark{background-color:#909399;color:#fff}.el-alert--info .el-alert__description{color:#909399}.el-alert--warning.is-light{background-color:#fdf6ec;color:#e6a23c}.el-alert--warning.is-light .el-alert__description{color:#e6a23c}.el-alert--warning.is-dark{background-color:#e6a23c;color:#fff}.el-alert--error.is-light{background-color:#fef0f0;color:#f56c6c}.el-alert--error.is-light .el-alert__description{color:#f56c6c}.el-alert--error.is-dark{background-color:#f56c6c;color:#fff}.el-alert__content{display:table-cell;padding:0 8px}.el-alert__icon{font-size:16px;width:16px}.el-alert__icon.is-big{font-size:28px;width:28px}.el-alert__title{font-size:13px;line-height:18px}.el-alert__title.is-bold{font-weight:700}.el-alert .el-alert__description{font-size:12px;margin:5px 0 0}.el-alert__closebtn{font-size:12px;opacity:1;position:absolute;top:12px;right:15px;cursor:pointer}.el-alert-fade-enter,.el-alert-fade-leave-active,.el-loading-fade-enter,.el-loading-fade-leave-active,.el-notification-fade-leave-active{opacity:0}.el-alert__closebtn.is-customed{font-style:normal;font-size:13px;top:9px}.el-notification{display:-webkit-box;display:-ms-flexbox;display:flex;width:330px;padding:14px 26px 14px 13px;border-radius:8px;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #ebeef5;position:fixed;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-transition:opacity .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;transition:opacity .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;transition:opacity .3s,transform .3s,left .3s,right .3s,top .4s,bottom .3s;transition:opacity .3s,transform .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;overflow:hidden}.el-notification.right{right:16px}.el-notification.left{left:16px}.el-notification__group{margin-left:13px;margin-right:8px}.el-notification__title{font-weight:700;font-size:16px;color:#303133;margin:0}.el-notification__content{font-size:14px;line-height:21px;margin:6px 0 0;color:#606266;text-align:justify}.el-notification__content p{margin:0}.el-notification__icon{height:24px;width:24px;font-size:24px}.el-notification__closeBtn{position:absolute;top:18px;right:15px;cursor:pointer;color:#909399;font-size:16px}.el-notification__closeBtn:hover{color:#606266}.el-notification .el-icon-success{color:#67c23a}.el-notification .el-icon-error{color:#f56c6c}.el-notification .el-icon-info{color:#909399}.el-notification .el-icon-warning{color:#e6a23c}.el-notification-fade-enter.right{right:0;-webkit-transform:translateX(100%);transform:translateX(100%)}.el-notification-fade-enter.left{left:0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}.el-input-number{position:relative;display:inline-block;width:180px;line-height:38px}.el-input-number .el-input{display:block}.el-input-number .el-input__inner{-webkit-appearance:none;padding-left:50px;padding-right:50px;text-align:center}.el-input-number__decrease,.el-input-number__increase{position:absolute;z-index:1;top:1px;width:40px;height:auto;text-align:center;background:#f5f7fa;color:#606266;cursor:pointer;font-size:13px}.el-input-number__decrease:hover,.el-input-number__increase:hover{color:#409eff}.el-input-number__decrease:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled),.el-input-number__increase:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled){border-color:#409eff}.el-input-number__decrease.is-disabled,.el-input-number__increase.is-disabled{color:#c0c4cc;cursor:not-allowed}.el-input-number__increase{right:1px;border-radius:0 4px 4px 0;border-left:1px solid #dcdfe6}.el-input-number__decrease{left:1px;border-radius:4px 0 0 4px;border-right:1px solid #dcdfe6}.el-input-number.is-disabled .el-input-number__decrease,.el-input-number.is-disabled .el-input-number__increase{border-color:#e4e7ed;color:#e4e7ed}.el-input-number.is-disabled .el-input-number__decrease:hover,.el-input-number.is-disabled .el-input-number__increase:hover{color:#e4e7ed;cursor:not-allowed}.el-input-number--medium{width:200px;line-height:34px}.el-input-number--medium .el-input-number__decrease,.el-input-number--medium .el-input-number__increase{width:36px;font-size:14px}.el-input-number--medium .el-input__inner{padding-left:43px;padding-right:43px}.el-input-number--small{width:130px;line-height:30px}.el-input-number--small .el-input-number__decrease,.el-input-number--small .el-input-number__increase{width:32px;font-size:13px}.el-input-number--small .el-input-number__decrease [class*=el-icon],.el-input-number--small .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.9);transform:scale(.9)}.el-input-number--small .el-input__inner{padding-left:39px;padding-right:39px}.el-input-number--mini{width:130px;line-height:26px}.el-input-number--mini .el-input-number__decrease,.el-input-number--mini .el-input-number__increase{width:28px;font-size:12px}.el-input-number--mini .el-input-number__decrease [class*=el-icon],.el-input-number--mini .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.8);transform:scale(.8)}.el-input-number--mini .el-input__inner{padding-left:35px;padding-right:35px}.el-input-number.is-without-controls .el-input__inner{padding-left:15px;padding-right:15px}.el-input-number.is-controls-right .el-input__inner{padding-left:15px;padding-right:50px}.el-input-number.is-controls-right .el-input-number__decrease,.el-input-number.is-controls-right .el-input-number__increase{height:auto;line-height:19px}.el-input-number.is-controls-right .el-input-number__decrease [class*=el-icon],.el-input-number.is-controls-right .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.8);transform:scale(.8)}.el-input-number.is-controls-right .el-input-number__increase{border-radius:0 4px 0 0;border-bottom:1px solid #dcdfe6}.el-input-number.is-controls-right .el-input-number__decrease{right:1px;bottom:1px;top:auto;left:auto;border-right:none;border-left:1px solid #dcdfe6;border-radius:0 0 4px}.el-input-number.is-controls-right[class*=medium] [class*=decrease],.el-input-number.is-controls-right[class*=medium] [class*=increase]{line-height:17px}.el-input-number.is-controls-right[class*=small] [class*=decrease],.el-input-number.is-controls-right[class*=small] [class*=increase]{line-height:15px}.el-input-number.is-controls-right[class*=mini] [class*=decrease],.el-input-number.is-controls-right[class*=mini] [class*=increase]{line-height:13px}.el-tooltip__popper{position:absolute;border-radius:4px;padding:10px;z-index:2000;font-size:12px;line-height:1.2;min-width:10px;word-wrap:break-word}.el-tooltip__popper .popper__arrow,.el-tooltip__popper .popper__arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-tooltip__popper .popper__arrow{border-width:6px}.el-tooltip__popper .popper__arrow:after{content:" ";border-width:5px}.el-progress-bar__inner:after,.el-row:after,.el-row:before,.el-slider:after,.el-slider:before,.el-slider__button-wrapper:after,.el-upload-cover:after{content:""}.el-tooltip__popper[x-placement^=top]{margin-bottom:12px}.el-tooltip__popper[x-placement^=top] .popper__arrow{bottom:-6px;border-top-color:#303133;border-bottom-width:0}.el-tooltip__popper[x-placement^=top] .popper__arrow:after{bottom:1px;margin-left:-5px;border-top-color:#303133;border-bottom-width:0}.el-tooltip__popper[x-placement^=bottom]{margin-top:12px}.el-tooltip__popper[x-placement^=bottom] .popper__arrow{top:-6px;border-top-width:0;border-bottom-color:#303133}.el-tooltip__popper[x-placement^=bottom] .popper__arrow:after{top:1px;margin-left:-5px;border-top-width:0;border-bottom-color:#303133}.el-tooltip__popper[x-placement^=right]{margin-left:12px}.el-tooltip__popper[x-placement^=right] .popper__arrow{left:-6px;border-right-color:#303133;border-left-width:0}.el-tooltip__popper[x-placement^=right] .popper__arrow:after{bottom:-5px;left:1px;border-right-color:#303133;border-left-width:0}.el-tooltip__popper[x-placement^=left]{margin-right:12px}.el-tooltip__popper[x-placement^=left] .popper__arrow{right:-6px;border-right-width:0;border-left-color:#303133}.el-tooltip__popper[x-placement^=left] .popper__arrow:after{right:1px;bottom:-5px;margin-left:-5px;border-right-width:0;border-left-color:#303133}.el-tooltip__popper.is-dark{background:#303133;color:#fff}.el-tooltip__popper.is-light{background:#fff;border:1px solid #303133}.el-tooltip__popper.is-light[x-placement^=top] .popper__arrow{border-top-color:#303133}.el-tooltip__popper.is-light[x-placement^=top] .popper__arrow:after{border-top-color:#fff}.el-tooltip__popper.is-light[x-placement^=bottom] .popper__arrow{border-bottom-color:#303133}.el-tooltip__popper.is-light[x-placement^=bottom] .popper__arrow:after{border-bottom-color:#fff}.el-tooltip__popper.is-light[x-placement^=left] .popper__arrow{border-left-color:#303133}.el-tooltip__popper.is-light[x-placement^=left] .popper__arrow:after{border-left-color:#fff}.el-tooltip__popper.is-light[x-placement^=right] .popper__arrow{border-right-color:#303133}.el-tooltip__popper.is-light[x-placement^=right] .popper__arrow:after{border-right-color:#fff}.el-slider:after,.el-slider:before{display:table}.el-slider__button-wrapper .el-tooltip,.el-slider__button-wrapper:after{vertical-align:middle;display:inline-block}.el-slider:after{clear:both}.el-slider__runway{width:100%;height:6px;margin:16px 0;background-color:#e4e7ed;border-radius:3px;position:relative;cursor:pointer;vertical-align:middle}.el-slider__runway.show-input{margin-right:160px;width:auto}.el-slider__runway.disabled{cursor:default}.el-slider__runway.disabled .el-slider__bar{background-color:#c0c4cc}.el-slider__runway.disabled .el-slider__button{border-color:#c0c4cc}.el-slider__runway.disabled .el-slider__button-wrapper.dragging,.el-slider__runway.disabled .el-slider__button-wrapper.hover,.el-slider__runway.disabled .el-slider__button-wrapper:hover{cursor:not-allowed}.el-slider__runway.disabled .el-slider__button.dragging,.el-slider__runway.disabled .el-slider__button.hover,.el-slider__runway.disabled .el-slider__button:hover{-webkit-transform:scale(1);transform:scale(1);cursor:not-allowed}.el-slider__button-wrapper,.el-slider__stop{-webkit-transform:translateX(-50%);position:absolute}.el-slider__input{float:right;margin-top:3px;width:130px}.el-slider__input.el-input-number--mini{margin-top:5px}.el-slider__input.el-input-number--medium{margin-top:0}.el-slider__input.el-input-number--large{margin-top:-2px}.el-slider__bar{height:6px;background-color:#409eff;border-top-left-radius:3px;border-bottom-left-radius:3px;position:absolute}.el-slider__button-wrapper{height:36px;width:36px;z-index:1001;top:-15px;-webkit-transform:translateX(-50%);transform:translateX(-50%);background-color:transparent;text-align:center;user-select:none;line-height:normal}.el-slider__button,.el-slider__button-wrapper,.el-step__icon-inner{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.el-slider__button-wrapper:after{height:100%}.el-slider__button-wrapper.hover,.el-slider__button-wrapper:hover{cursor:-webkit-grab;cursor:grab}.el-slider__button-wrapper.dragging{cursor:-webkit-grabbing;cursor:grabbing}.el-slider__button{width:16px;height:16px;border:2px solid #409eff;background-color:#fff;border-radius:50%;-webkit-transition:.2s;transition:.2s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.el-slider__button.dragging,.el-slider__button.hover,.el-slider__button:hover{-webkit-transform:scale(1.2);transform:scale(1.2)}.el-slider__button.hover,.el-slider__button:hover{cursor:-webkit-grab;cursor:grab}.el-slider__button.dragging{cursor:-webkit-grabbing;cursor:grabbing}.el-slider__stop{height:6px;width:6px;border-radius:100%;background-color:#fff;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.el-slider__marks{top:0;left:12px;width:18px;height:100%}.el-slider__marks-text{position:absolute;-webkit-transform:translateX(-50%);transform:translateX(-50%);font-size:14px;color:#909399;margin-top:15px}.el-slider.is-vertical{position:relative}.el-slider.is-vertical .el-slider__runway{width:6px;height:100%;margin:0 16px}.el-slider.is-vertical .el-slider__bar{width:6px;height:auto;border-radius:0 0 3px 3px}.el-slider.is-vertical .el-slider__button-wrapper{top:auto;left:-15px}.el-slider.is-vertical .el-slider__button-wrapper,.el-slider.is-vertical .el-slider__stop{-webkit-transform:translateY(50%);transform:translateY(50%)}.el-slider.is-vertical.el-slider--with-input{padding-bottom:58px}.el-slider.is-vertical.el-slider--with-input .el-slider__input{overflow:visible;float:none;position:absolute;bottom:22px;width:36px;margin-top:15px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input__inner{text-align:center;padding-left:5px;padding-right:5px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__decrease,.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase{top:32px;margin-top:-1px;border:1px solid #dcdfe6;line-height:20px;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__decrease{width:18px;right:18px;border-bottom-left-radius:4px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase{width:19px;border-bottom-right-radius:4px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase~.el-input .el-input__inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.el-slider.is-vertical.el-slider--with-input .el-slider__input:hover .el-input-number__decrease,.el-slider.is-vertical.el-slider--with-input .el-slider__input:hover .el-input-number__increase{border-color:#c0c4cc}.el-slider.is-vertical.el-slider--with-input .el-slider__input:active .el-input-number__decrease,.el-slider.is-vertical.el-slider--with-input .el-slider__input:active .el-input-number__increase{border-color:#409eff}.el-slider.is-vertical .el-slider__marks-text{margin-top:0;left:15px;-webkit-transform:translateY(50%);transform:translateY(50%)}.el-loading-parent--relative{position:relative!important}.el-loading-parent--hidden{overflow:hidden!important}.el-loading-mask{position:absolute;z-index:2000;background-color:hsla(0,0%,100%,.9);margin:0;top:0;right:0;bottom:0;left:0;-webkit-transition:opacity .3s;transition:opacity .3s}.el-loading-mask.is-fullscreen{position:fixed}.el-loading-mask.is-fullscreen .el-loading-spinner{margin-top:-25px}.el-loading-mask.is-fullscreen .el-loading-spinner .circular{height:50px;width:50px}.el-loading-spinner{top:50%;margin-top:-21px;width:100%;text-align:center;position:absolute}.el-col-pull-0,.el-col-pull-1,.el-col-pull-2,.el-col-pull-3,.el-col-pull-4,.el-col-pull-5,.el-col-pull-6,.el-col-pull-7,.el-col-pull-8,.el-col-pull-9,.el-col-pull-10,.el-col-pull-11,.el-col-pull-13,.el-col-pull-14,.el-col-pull-15,.el-col-pull-16,.el-col-pull-17,.el-col-pull-18,.el-col-pull-19,.el-col-pull-20,.el-col-pull-21,.el-col-pull-22,.el-col-pull-23,.el-col-pull-24,.el-col-push-0,.el-col-push-1,.el-col-push-2,.el-col-push-3,.el-col-push-4,.el-col-push-5,.el-col-push-6,.el-col-push-7,.el-col-push-8,.el-col-push-9,.el-col-push-10,.el-col-push-11,.el-col-push-12,.el-col-push-13,.el-col-push-14,.el-col-push-15,.el-col-push-16,.el-col-push-17,.el-col-push-18,.el-col-push-19,.el-col-push-20,.el-col-push-21,.el-col-push-22,.el-col-push-23,.el-col-push-24,.el-row{position:relative}.el-loading-spinner .el-loading-text{color:#409eff;margin:3px 0;font-size:14px}.el-loading-spinner .circular{height:42px;width:42px;-webkit-animation:loading-rotate 2s linear infinite;animation:loading-rotate 2s linear infinite}.el-loading-spinner .path{-webkit-animation:loading-dash 1.5s ease-in-out infinite;animation:loading-dash 1.5s ease-in-out infinite;stroke-dasharray:90,150;stroke-dashoffset:0;stroke-width:2;stroke:#409eff;stroke-linecap:round}.el-loading-spinner i{color:#409eff}@-webkit-keyframes loading-rotate{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes loading-rotate{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@-webkit-keyframes loading-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40px}to{stroke-dasharray:90,150;stroke-dashoffset:-120px}}@keyframes loading-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40px}to{stroke-dasharray:90,150;stroke-dashoffset:-120px}}.el-row{-webkit-box-sizing:border-box;box-sizing:border-box}.el-row:after,.el-row:before{display:table}.el-row:after{clear:both}.el-row--flex{display:-webkit-box;display:-ms-flexbox;display:flex}.el-col-0,.el-row--flex:after,.el-row--flex:before{display:none}.el-row--flex.is-justify-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-row--flex.is-justify-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.el-row--flex.is-justify-space-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.el-row--flex.is-justify-space-around{-ms-flex-pack:distribute;justify-content:space-around}.el-row--flex.is-align-middle{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-row--flex.is-align-bottom{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}[class*=el-col-]{float:left;-webkit-box-sizing:border-box;box-sizing:border-box}.el-upload--picture-card,.el-upload-dragger{-webkit-box-sizing:border-box;cursor:pointer}.el-col-0{width:0}.el-col-offset-0{margin-left:0}.el-col-pull-0{right:0}.el-col-push-0{left:0}.el-col-1{width:4.16667%}.el-col-offset-1{margin-left:4.16667%}.el-col-pull-1{right:4.16667%}.el-col-push-1{left:4.16667%}.el-col-2{width:8.33333%}.el-col-offset-2{margin-left:8.33333%}.el-col-pull-2{right:8.33333%}.el-col-push-2{left:8.33333%}.el-col-3{width:12.5%}.el-col-offset-3{margin-left:12.5%}.el-col-pull-3{right:12.5%}.el-col-push-3{left:12.5%}.el-col-4{width:16.66667%}.el-col-offset-4{margin-left:16.66667%}.el-col-pull-4{right:16.66667%}.el-col-push-4{left:16.66667%}.el-col-5{width:20.83333%}.el-col-offset-5{margin-left:20.83333%}.el-col-pull-5{right:20.83333%}.el-col-push-5{left:20.83333%}.el-col-6{width:25%}.el-col-offset-6{margin-left:25%}.el-col-pull-6{right:25%}.el-col-push-6{left:25%}.el-col-7{width:29.16667%}.el-col-offset-7{margin-left:29.16667%}.el-col-pull-7{right:29.16667%}.el-col-push-7{left:29.16667%}.el-col-8{width:33.33333%}.el-col-offset-8{margin-left:33.33333%}.el-col-pull-8{right:33.33333%}.el-col-push-8{left:33.33333%}.el-col-9{width:37.5%}.el-col-offset-9{margin-left:37.5%}.el-col-pull-9{right:37.5%}.el-col-push-9{left:37.5%}.el-col-10{width:41.66667%}.el-col-offset-10{margin-left:41.66667%}.el-col-pull-10{right:41.66667%}.el-col-push-10{left:41.66667%}.el-col-11{width:45.83333%}.el-col-offset-11{margin-left:45.83333%}.el-col-pull-11{right:45.83333%}.el-col-push-11{left:45.83333%}.el-col-12{width:50%}.el-col-offset-12{margin-left:50%}.el-col-pull-12{position:relative;right:50%}.el-col-push-12{left:50%}.el-col-13{width:54.16667%}.el-col-offset-13{margin-left:54.16667%}.el-col-pull-13{right:54.16667%}.el-col-push-13{left:54.16667%}.el-col-14{width:58.33333%}.el-col-offset-14{margin-left:58.33333%}.el-col-pull-14{right:58.33333%}.el-col-push-14{left:58.33333%}.el-col-15{width:62.5%}.el-col-offset-15{margin-left:62.5%}.el-col-pull-15{right:62.5%}.el-col-push-15{left:62.5%}.el-col-16{width:66.66667%}.el-col-offset-16{margin-left:66.66667%}.el-col-pull-16{right:66.66667%}.el-col-push-16{left:66.66667%}.el-col-17{width:70.83333%}.el-col-offset-17{margin-left:70.83333%}.el-col-pull-17{right:70.83333%}.el-col-push-17{left:70.83333%}.el-col-18{width:75%}.el-col-offset-18{margin-left:75%}.el-col-pull-18{right:75%}.el-col-push-18{left:75%}.el-col-19{width:79.16667%}.el-col-offset-19{margin-left:79.16667%}.el-col-pull-19{right:79.16667%}.el-col-push-19{left:79.16667%}.el-col-20{width:83.33333%}.el-col-offset-20{margin-left:83.33333%}.el-col-pull-20{right:83.33333%}.el-col-push-20{left:83.33333%}.el-col-21{width:87.5%}.el-col-offset-21{margin-left:87.5%}.el-col-pull-21{right:87.5%}.el-col-push-21{left:87.5%}.el-col-22{width:91.66667%}.el-col-offset-22{margin-left:91.66667%}.el-col-pull-22{right:91.66667%}.el-col-push-22{left:91.66667%}.el-col-23{width:95.83333%}.el-col-offset-23{margin-left:95.83333%}.el-col-pull-23{right:95.83333%}.el-col-push-23{left:95.83333%}.el-col-24{width:100%}.el-col-offset-24{margin-left:100%}.el-col-pull-24{right:100%}.el-col-push-24{left:100%}@media only screen and (max-width:767px){.el-col-xs-0{display:none;width:0}.el-col-xs-offset-0{margin-left:0}.el-col-xs-pull-0{position:relative;right:0}.el-col-xs-push-0{position:relative;left:0}.el-col-xs-1{width:4.16667%}.el-col-xs-offset-1{margin-left:4.16667%}.el-col-xs-pull-1{position:relative;right:4.16667%}.el-col-xs-push-1{position:relative;left:4.16667%}.el-col-xs-2{width:8.33333%}.el-col-xs-offset-2{margin-left:8.33333%}.el-col-xs-pull-2{position:relative;right:8.33333%}.el-col-xs-push-2{position:relative;left:8.33333%}.el-col-xs-3{width:12.5%}.el-col-xs-offset-3{margin-left:12.5%}.el-col-xs-pull-3{position:relative;right:12.5%}.el-col-xs-push-3{position:relative;left:12.5%}.el-col-xs-4{width:16.66667%}.el-col-xs-offset-4{margin-left:16.66667%}.el-col-xs-pull-4{position:relative;right:16.66667%}.el-col-xs-push-4{position:relative;left:16.66667%}.el-col-xs-5{width:20.83333%}.el-col-xs-offset-5{margin-left:20.83333%}.el-col-xs-pull-5{position:relative;right:20.83333%}.el-col-xs-push-5{position:relative;left:20.83333%}.el-col-xs-6{width:25%}.el-col-xs-offset-6{margin-left:25%}.el-col-xs-pull-6{position:relative;right:25%}.el-col-xs-push-6{position:relative;left:25%}.el-col-xs-7{width:29.16667%}.el-col-xs-offset-7{margin-left:29.16667%}.el-col-xs-pull-7{position:relative;right:29.16667%}.el-col-xs-push-7{position:relative;left:29.16667%}.el-col-xs-8{width:33.33333%}.el-col-xs-offset-8{margin-left:33.33333%}.el-col-xs-pull-8{position:relative;right:33.33333%}.el-col-xs-push-8{position:relative;left:33.33333%}.el-col-xs-9{width:37.5%}.el-col-xs-offset-9{margin-left:37.5%}.el-col-xs-pull-9{position:relative;right:37.5%}.el-col-xs-push-9{position:relative;left:37.5%}.el-col-xs-10{width:41.66667%}.el-col-xs-offset-10{margin-left:41.66667%}.el-col-xs-pull-10{position:relative;right:41.66667%}.el-col-xs-push-10{position:relative;left:41.66667%}.el-col-xs-11{width:45.83333%}.el-col-xs-offset-11{margin-left:45.83333%}.el-col-xs-pull-11{position:relative;right:45.83333%}.el-col-xs-push-11{position:relative;left:45.83333%}.el-col-xs-12{width:50%}.el-col-xs-offset-12{margin-left:50%}.el-col-xs-pull-12{position:relative;right:50%}.el-col-xs-push-12{position:relative;left:50%}.el-col-xs-13{width:54.16667%}.el-col-xs-offset-13{margin-left:54.16667%}.el-col-xs-pull-13{position:relative;right:54.16667%}.el-col-xs-push-13{position:relative;left:54.16667%}.el-col-xs-14{width:58.33333%}.el-col-xs-offset-14{margin-left:58.33333%}.el-col-xs-pull-14{position:relative;right:58.33333%}.el-col-xs-push-14{position:relative;left:58.33333%}.el-col-xs-15{width:62.5%}.el-col-xs-offset-15{margin-left:62.5%}.el-col-xs-pull-15{position:relative;right:62.5%}.el-col-xs-push-15{position:relative;left:62.5%}.el-col-xs-16{width:66.66667%}.el-col-xs-offset-16{margin-left:66.66667%}.el-col-xs-pull-16{position:relative;right:66.66667%}.el-col-xs-push-16{position:relative;left:66.66667%}.el-col-xs-17{width:70.83333%}.el-col-xs-offset-17{margin-left:70.83333%}.el-col-xs-pull-17{position:relative;right:70.83333%}.el-col-xs-push-17{position:relative;left:70.83333%}.el-col-xs-18{width:75%}.el-col-xs-offset-18{margin-left:75%}.el-col-xs-pull-18{position:relative;right:75%}.el-col-xs-push-18{position:relative;left:75%}.el-col-xs-19{width:79.16667%}.el-col-xs-offset-19{margin-left:79.16667%}.el-col-xs-pull-19{position:relative;right:79.16667%}.el-col-xs-push-19{position:relative;left:79.16667%}.el-col-xs-20{width:83.33333%}.el-col-xs-offset-20{margin-left:83.33333%}.el-col-xs-pull-20{position:relative;right:83.33333%}.el-col-xs-push-20{position:relative;left:83.33333%}.el-col-xs-21{width:87.5%}.el-col-xs-offset-21{margin-left:87.5%}.el-col-xs-pull-21{position:relative;right:87.5%}.el-col-xs-push-21{position:relative;left:87.5%}.el-col-xs-22{width:91.66667%}.el-col-xs-offset-22{margin-left:91.66667%}.el-col-xs-pull-22{position:relative;right:91.66667%}.el-col-xs-push-22{position:relative;left:91.66667%}.el-col-xs-23{width:95.83333%}.el-col-xs-offset-23{margin-left:95.83333%}.el-col-xs-pull-23{position:relative;right:95.83333%}.el-col-xs-push-23{position:relative;left:95.83333%}.el-col-xs-24{width:100%}.el-col-xs-offset-24{margin-left:100%}.el-col-xs-pull-24{position:relative;right:100%}.el-col-xs-push-24{position:relative;left:100%}}@media only screen and (min-width:768px){.el-col-sm-0{display:none;width:0}.el-col-sm-offset-0{margin-left:0}.el-col-sm-pull-0{position:relative;right:0}.el-col-sm-push-0{position:relative;left:0}.el-col-sm-1{width:4.16667%}.el-col-sm-offset-1{margin-left:4.16667%}.el-col-sm-pull-1{position:relative;right:4.16667%}.el-col-sm-push-1{position:relative;left:4.16667%}.el-col-sm-2{width:8.33333%}.el-col-sm-offset-2{margin-left:8.33333%}.el-col-sm-pull-2{position:relative;right:8.33333%}.el-col-sm-push-2{position:relative;left:8.33333%}.el-col-sm-3{width:12.5%}.el-col-sm-offset-3{margin-left:12.5%}.el-col-sm-pull-3{position:relative;right:12.5%}.el-col-sm-push-3{position:relative;left:12.5%}.el-col-sm-4{width:16.66667%}.el-col-sm-offset-4{margin-left:16.66667%}.el-col-sm-pull-4{position:relative;right:16.66667%}.el-col-sm-push-4{position:relative;left:16.66667%}.el-col-sm-5{width:20.83333%}.el-col-sm-offset-5{margin-left:20.83333%}.el-col-sm-pull-5{position:relative;right:20.83333%}.el-col-sm-push-5{position:relative;left:20.83333%}.el-col-sm-6{width:25%}.el-col-sm-offset-6{margin-left:25%}.el-col-sm-pull-6{position:relative;right:25%}.el-col-sm-push-6{position:relative;left:25%}.el-col-sm-7{width:29.16667%}.el-col-sm-offset-7{margin-left:29.16667%}.el-col-sm-pull-7{position:relative;right:29.16667%}.el-col-sm-push-7{position:relative;left:29.16667%}.el-col-sm-8{width:33.33333%}.el-col-sm-offset-8{margin-left:33.33333%}.el-col-sm-pull-8{position:relative;right:33.33333%}.el-col-sm-push-8{position:relative;left:33.33333%}.el-col-sm-9{width:37.5%}.el-col-sm-offset-9{margin-left:37.5%}.el-col-sm-pull-9{position:relative;right:37.5%}.el-col-sm-push-9{position:relative;left:37.5%}.el-col-sm-10{width:41.66667%}.el-col-sm-offset-10{margin-left:41.66667%}.el-col-sm-pull-10{position:relative;right:41.66667%}.el-col-sm-push-10{position:relative;left:41.66667%}.el-col-sm-11{width:45.83333%}.el-col-sm-offset-11{margin-left:45.83333%}.el-col-sm-pull-11{position:relative;right:45.83333%}.el-col-sm-push-11{position:relative;left:45.83333%}.el-col-sm-12{width:50%}.el-col-sm-offset-12{margin-left:50%}.el-col-sm-pull-12{position:relative;right:50%}.el-col-sm-push-12{position:relative;left:50%}.el-col-sm-13{width:54.16667%}.el-col-sm-offset-13{margin-left:54.16667%}.el-col-sm-pull-13{position:relative;right:54.16667%}.el-col-sm-push-13{position:relative;left:54.16667%}.el-col-sm-14{width:58.33333%}.el-col-sm-offset-14{margin-left:58.33333%}.el-col-sm-pull-14{position:relative;right:58.33333%}.el-col-sm-push-14{position:relative;left:58.33333%}.el-col-sm-15{width:62.5%}.el-col-sm-offset-15{margin-left:62.5%}.el-col-sm-pull-15{position:relative;right:62.5%}.el-col-sm-push-15{position:relative;left:62.5%}.el-col-sm-16{width:66.66667%}.el-col-sm-offset-16{margin-left:66.66667%}.el-col-sm-pull-16{position:relative;right:66.66667%}.el-col-sm-push-16{position:relative;left:66.66667%}.el-col-sm-17{width:70.83333%}.el-col-sm-offset-17{margin-left:70.83333%}.el-col-sm-pull-17{position:relative;right:70.83333%}.el-col-sm-push-17{position:relative;left:70.83333%}.el-col-sm-18{width:75%}.el-col-sm-offset-18{margin-left:75%}.el-col-sm-pull-18{position:relative;right:75%}.el-col-sm-push-18{position:relative;left:75%}.el-col-sm-19{width:79.16667%}.el-col-sm-offset-19{margin-left:79.16667%}.el-col-sm-pull-19{position:relative;right:79.16667%}.el-col-sm-push-19{position:relative;left:79.16667%}.el-col-sm-20{width:83.33333%}.el-col-sm-offset-20{margin-left:83.33333%}.el-col-sm-pull-20{position:relative;right:83.33333%}.el-col-sm-push-20{position:relative;left:83.33333%}.el-col-sm-21{width:87.5%}.el-col-sm-offset-21{margin-left:87.5%}.el-col-sm-pull-21{position:relative;right:87.5%}.el-col-sm-push-21{position:relative;left:87.5%}.el-col-sm-22{width:91.66667%}.el-col-sm-offset-22{margin-left:91.66667%}.el-col-sm-pull-22{position:relative;right:91.66667%}.el-col-sm-push-22{position:relative;left:91.66667%}.el-col-sm-23{width:95.83333%}.el-col-sm-offset-23{margin-left:95.83333%}.el-col-sm-pull-23{position:relative;right:95.83333%}.el-col-sm-push-23{position:relative;left:95.83333%}.el-col-sm-24{width:100%}.el-col-sm-offset-24{margin-left:100%}.el-col-sm-pull-24{position:relative;right:100%}.el-col-sm-push-24{position:relative;left:100%}}@media only screen and (min-width:992px){.el-col-md-0{display:none;width:0}.el-col-md-offset-0{margin-left:0}.el-col-md-pull-0{position:relative;right:0}.el-col-md-push-0{position:relative;left:0}.el-col-md-1{width:4.16667%}.el-col-md-offset-1{margin-left:4.16667%}.el-col-md-pull-1{position:relative;right:4.16667%}.el-col-md-push-1{position:relative;left:4.16667%}.el-col-md-2{width:8.33333%}.el-col-md-offset-2{margin-left:8.33333%}.el-col-md-pull-2{position:relative;right:8.33333%}.el-col-md-push-2{position:relative;left:8.33333%}.el-col-md-3{width:12.5%}.el-col-md-offset-3{margin-left:12.5%}.el-col-md-pull-3{position:relative;right:12.5%}.el-col-md-push-3{position:relative;left:12.5%}.el-col-md-4{width:16.66667%}.el-col-md-offset-4{margin-left:16.66667%}.el-col-md-pull-4{position:relative;right:16.66667%}.el-col-md-push-4{position:relative;left:16.66667%}.el-col-md-5{width:20.83333%}.el-col-md-offset-5{margin-left:20.83333%}.el-col-md-pull-5{position:relative;right:20.83333%}.el-col-md-push-5{position:relative;left:20.83333%}.el-col-md-6{width:25%}.el-col-md-offset-6{margin-left:25%}.el-col-md-pull-6{position:relative;right:25%}.el-col-md-push-6{position:relative;left:25%}.el-col-md-7{width:29.16667%}.el-col-md-offset-7{margin-left:29.16667%}.el-col-md-pull-7{position:relative;right:29.16667%}.el-col-md-push-7{position:relative;left:29.16667%}.el-col-md-8{width:33.33333%}.el-col-md-offset-8{margin-left:33.33333%}.el-col-md-pull-8{position:relative;right:33.33333%}.el-col-md-push-8{position:relative;left:33.33333%}.el-col-md-9{width:37.5%}.el-col-md-offset-9{margin-left:37.5%}.el-col-md-pull-9{position:relative;right:37.5%}.el-col-md-push-9{position:relative;left:37.5%}.el-col-md-10{width:41.66667%}.el-col-md-offset-10{margin-left:41.66667%}.el-col-md-pull-10{position:relative;right:41.66667%}.el-col-md-push-10{position:relative;left:41.66667%}.el-col-md-11{width:45.83333%}.el-col-md-offset-11{margin-left:45.83333%}.el-col-md-pull-11{position:relative;right:45.83333%}.el-col-md-push-11{position:relative;left:45.83333%}.el-col-md-12{width:50%}.el-col-md-offset-12{margin-left:50%}.el-col-md-pull-12{position:relative;right:50%}.el-col-md-push-12{position:relative;left:50%}.el-col-md-13{width:54.16667%}.el-col-md-offset-13{margin-left:54.16667%}.el-col-md-pull-13{position:relative;right:54.16667%}.el-col-md-push-13{position:relative;left:54.16667%}.el-col-md-14{width:58.33333%}.el-col-md-offset-14{margin-left:58.33333%}.el-col-md-pull-14{position:relative;right:58.33333%}.el-col-md-push-14{position:relative;left:58.33333%}.el-col-md-15{width:62.5%}.el-col-md-offset-15{margin-left:62.5%}.el-col-md-pull-15{position:relative;right:62.5%}.el-col-md-push-15{position:relative;left:62.5%}.el-col-md-16{width:66.66667%}.el-col-md-offset-16{margin-left:66.66667%}.el-col-md-pull-16{position:relative;right:66.66667%}.el-col-md-push-16{position:relative;left:66.66667%}.el-col-md-17{width:70.83333%}.el-col-md-offset-17{margin-left:70.83333%}.el-col-md-pull-17{position:relative;right:70.83333%}.el-col-md-push-17{position:relative;left:70.83333%}.el-col-md-18{width:75%}.el-col-md-offset-18{margin-left:75%}.el-col-md-pull-18{position:relative;right:75%}.el-col-md-push-18{position:relative;left:75%}.el-col-md-19{width:79.16667%}.el-col-md-offset-19{margin-left:79.16667%}.el-col-md-pull-19{position:relative;right:79.16667%}.el-col-md-push-19{position:relative;left:79.16667%}.el-col-md-20{width:83.33333%}.el-col-md-offset-20{margin-left:83.33333%}.el-col-md-pull-20{position:relative;right:83.33333%}.el-col-md-push-20{position:relative;left:83.33333%}.el-col-md-21{width:87.5%}.el-col-md-offset-21{margin-left:87.5%}.el-col-md-pull-21{position:relative;right:87.5%}.el-col-md-push-21{position:relative;left:87.5%}.el-col-md-22{width:91.66667%}.el-col-md-offset-22{margin-left:91.66667%}.el-col-md-pull-22{position:relative;right:91.66667%}.el-col-md-push-22{position:relative;left:91.66667%}.el-col-md-23{width:95.83333%}.el-col-md-offset-23{margin-left:95.83333%}.el-col-md-pull-23{position:relative;right:95.83333%}.el-col-md-push-23{position:relative;left:95.83333%}.el-col-md-24{width:100%}.el-col-md-offset-24{margin-left:100%}.el-col-md-pull-24{position:relative;right:100%}.el-col-md-push-24{position:relative;left:100%}}@media only screen and (min-width:1200px){.el-col-lg-0{display:none;width:0}.el-col-lg-offset-0{margin-left:0}.el-col-lg-pull-0{position:relative;right:0}.el-col-lg-push-0{position:relative;left:0}.el-col-lg-1{width:4.16667%}.el-col-lg-offset-1{margin-left:4.16667%}.el-col-lg-pull-1{position:relative;right:4.16667%}.el-col-lg-push-1{position:relative;left:4.16667%}.el-col-lg-2{width:8.33333%}.el-col-lg-offset-2{margin-left:8.33333%}.el-col-lg-pull-2{position:relative;right:8.33333%}.el-col-lg-push-2{position:relative;left:8.33333%}.el-col-lg-3{width:12.5%}.el-col-lg-offset-3{margin-left:12.5%}.el-col-lg-pull-3{position:relative;right:12.5%}.el-col-lg-push-3{position:relative;left:12.5%}.el-col-lg-4{width:16.66667%}.el-col-lg-offset-4{margin-left:16.66667%}.el-col-lg-pull-4{position:relative;right:16.66667%}.el-col-lg-push-4{position:relative;left:16.66667%}.el-col-lg-5{width:20.83333%}.el-col-lg-offset-5{margin-left:20.83333%}.el-col-lg-pull-5{position:relative;right:20.83333%}.el-col-lg-push-5{position:relative;left:20.83333%}.el-col-lg-6{width:25%}.el-col-lg-offset-6{margin-left:25%}.el-col-lg-pull-6{position:relative;right:25%}.el-col-lg-push-6{position:relative;left:25%}.el-col-lg-7{width:29.16667%}.el-col-lg-offset-7{margin-left:29.16667%}.el-col-lg-pull-7{position:relative;right:29.16667%}.el-col-lg-push-7{position:relative;left:29.16667%}.el-col-lg-8{width:33.33333%}.el-col-lg-offset-8{margin-left:33.33333%}.el-col-lg-pull-8{position:relative;right:33.33333%}.el-col-lg-push-8{position:relative;left:33.33333%}.el-col-lg-9{width:37.5%}.el-col-lg-offset-9{margin-left:37.5%}.el-col-lg-pull-9{position:relative;right:37.5%}.el-col-lg-push-9{position:relative;left:37.5%}.el-col-lg-10{width:41.66667%}.el-col-lg-offset-10{margin-left:41.66667%}.el-col-lg-pull-10{position:relative;right:41.66667%}.el-col-lg-push-10{position:relative;left:41.66667%}.el-col-lg-11{width:45.83333%}.el-col-lg-offset-11{margin-left:45.83333%}.el-col-lg-pull-11{position:relative;right:45.83333%}.el-col-lg-push-11{position:relative;left:45.83333%}.el-col-lg-12{width:50%}.el-col-lg-offset-12{margin-left:50%}.el-col-lg-pull-12{position:relative;right:50%}.el-col-lg-push-12{position:relative;left:50%}.el-col-lg-13{width:54.16667%}.el-col-lg-offset-13{margin-left:54.16667%}.el-col-lg-pull-13{position:relative;right:54.16667%}.el-col-lg-push-13{position:relative;left:54.16667%}.el-col-lg-14{width:58.33333%}.el-col-lg-offset-14{margin-left:58.33333%}.el-col-lg-pull-14{position:relative;right:58.33333%}.el-col-lg-push-14{position:relative;left:58.33333%}.el-col-lg-15{width:62.5%}.el-col-lg-offset-15{margin-left:62.5%}.el-col-lg-pull-15{position:relative;right:62.5%}.el-col-lg-push-15{position:relative;left:62.5%}.el-col-lg-16{width:66.66667%}.el-col-lg-offset-16{margin-left:66.66667%}.el-col-lg-pull-16{position:relative;right:66.66667%}.el-col-lg-push-16{position:relative;left:66.66667%}.el-col-lg-17{width:70.83333%}.el-col-lg-offset-17{margin-left:70.83333%}.el-col-lg-pull-17{position:relative;right:70.83333%}.el-col-lg-push-17{position:relative;left:70.83333%}.el-col-lg-18{width:75%}.el-col-lg-offset-18{margin-left:75%}.el-col-lg-pull-18{position:relative;right:75%}.el-col-lg-push-18{position:relative;left:75%}.el-col-lg-19{width:79.16667%}.el-col-lg-offset-19{margin-left:79.16667%}.el-col-lg-pull-19{position:relative;right:79.16667%}.el-col-lg-push-19{position:relative;left:79.16667%}.el-col-lg-20{width:83.33333%}.el-col-lg-offset-20{margin-left:83.33333%}.el-col-lg-pull-20{position:relative;right:83.33333%}.el-col-lg-push-20{position:relative;left:83.33333%}.el-col-lg-21{width:87.5%}.el-col-lg-offset-21{margin-left:87.5%}.el-col-lg-pull-21{position:relative;right:87.5%}.el-col-lg-push-21{position:relative;left:87.5%}.el-col-lg-22{width:91.66667%}.el-col-lg-offset-22{margin-left:91.66667%}.el-col-lg-pull-22{position:relative;right:91.66667%}.el-col-lg-push-22{position:relative;left:91.66667%}.el-col-lg-23{width:95.83333%}.el-col-lg-offset-23{margin-left:95.83333%}.el-col-lg-pull-23{position:relative;right:95.83333%}.el-col-lg-push-23{position:relative;left:95.83333%}.el-col-lg-24{width:100%}.el-col-lg-offset-24{margin-left:100%}.el-col-lg-pull-24{position:relative;right:100%}.el-col-lg-push-24{position:relative;left:100%}}@media only screen and (min-width:1920px){.el-col-xl-0{display:none;width:0}.el-col-xl-offset-0{margin-left:0}.el-col-xl-pull-0{position:relative;right:0}.el-col-xl-push-0{position:relative;left:0}.el-col-xl-1{width:4.16667%}.el-col-xl-offset-1{margin-left:4.16667%}.el-col-xl-pull-1{position:relative;right:4.16667%}.el-col-xl-push-1{position:relative;left:4.16667%}.el-col-xl-2{width:8.33333%}.el-col-xl-offset-2{margin-left:8.33333%}.el-col-xl-pull-2{position:relative;right:8.33333%}.el-col-xl-push-2{position:relative;left:8.33333%}.el-col-xl-3{width:12.5%}.el-col-xl-offset-3{margin-left:12.5%}.el-col-xl-pull-3{position:relative;right:12.5%}.el-col-xl-push-3{position:relative;left:12.5%}.el-col-xl-4{width:16.66667%}.el-col-xl-offset-4{margin-left:16.66667%}.el-col-xl-pull-4{position:relative;right:16.66667%}.el-col-xl-push-4{position:relative;left:16.66667%}.el-col-xl-5{width:20.83333%}.el-col-xl-offset-5{margin-left:20.83333%}.el-col-xl-pull-5{position:relative;right:20.83333%}.el-col-xl-push-5{position:relative;left:20.83333%}.el-col-xl-6{width:25%}.el-col-xl-offset-6{margin-left:25%}.el-col-xl-pull-6{position:relative;right:25%}.el-col-xl-push-6{position:relative;left:25%}.el-col-xl-7{width:29.16667%}.el-col-xl-offset-7{margin-left:29.16667%}.el-col-xl-pull-7{position:relative;right:29.16667%}.el-col-xl-push-7{position:relative;left:29.16667%}.el-col-xl-8{width:33.33333%}.el-col-xl-offset-8{margin-left:33.33333%}.el-col-xl-pull-8{position:relative;right:33.33333%}.el-col-xl-push-8{position:relative;left:33.33333%}.el-col-xl-9{width:37.5%}.el-col-xl-offset-9{margin-left:37.5%}.el-col-xl-pull-9{position:relative;right:37.5%}.el-col-xl-push-9{position:relative;left:37.5%}.el-col-xl-10{width:41.66667%}.el-col-xl-offset-10{margin-left:41.66667%}.el-col-xl-pull-10{position:relative;right:41.66667%}.el-col-xl-push-10{position:relative;left:41.66667%}.el-col-xl-11{width:45.83333%}.el-col-xl-offset-11{margin-left:45.83333%}.el-col-xl-pull-11{position:relative;right:45.83333%}.el-col-xl-push-11{position:relative;left:45.83333%}.el-col-xl-12{width:50%}.el-col-xl-offset-12{margin-left:50%}.el-col-xl-pull-12{position:relative;right:50%}.el-col-xl-push-12{position:relative;left:50%}.el-col-xl-13{width:54.16667%}.el-col-xl-offset-13{margin-left:54.16667%}.el-col-xl-pull-13{position:relative;right:54.16667%}.el-col-xl-push-13{position:relative;left:54.16667%}.el-col-xl-14{width:58.33333%}.el-col-xl-offset-14{margin-left:58.33333%}.el-col-xl-pull-14{position:relative;right:58.33333%}.el-col-xl-push-14{position:relative;left:58.33333%}.el-col-xl-15{width:62.5%}.el-col-xl-offset-15{margin-left:62.5%}.el-col-xl-pull-15{position:relative;right:62.5%}.el-col-xl-push-15{position:relative;left:62.5%}.el-col-xl-16{width:66.66667%}.el-col-xl-offset-16{margin-left:66.66667%}.el-col-xl-pull-16{position:relative;right:66.66667%}.el-col-xl-push-16{position:relative;left:66.66667%}.el-col-xl-17{width:70.83333%}.el-col-xl-offset-17{margin-left:70.83333%}.el-col-xl-pull-17{position:relative;right:70.83333%}.el-col-xl-push-17{position:relative;left:70.83333%}.el-col-xl-18{width:75%}.el-col-xl-offset-18{margin-left:75%}.el-col-xl-pull-18{position:relative;right:75%}.el-col-xl-push-18{position:relative;left:75%}.el-col-xl-19{width:79.16667%}.el-col-xl-offset-19{margin-left:79.16667%}.el-col-xl-pull-19{position:relative;right:79.16667%}.el-col-xl-push-19{position:relative;left:79.16667%}.el-col-xl-20{width:83.33333%}.el-col-xl-offset-20{margin-left:83.33333%}.el-col-xl-pull-20{position:relative;right:83.33333%}.el-col-xl-push-20{position:relative;left:83.33333%}.el-col-xl-21{width:87.5%}.el-col-xl-offset-21{margin-left:87.5%}.el-col-xl-pull-21{position:relative;right:87.5%}.el-col-xl-push-21{position:relative;left:87.5%}.el-col-xl-22{width:91.66667%}.el-col-xl-offset-22{margin-left:91.66667%}.el-col-xl-pull-22{position:relative;right:91.66667%}.el-col-xl-push-22{position:relative;left:91.66667%}.el-col-xl-23{width:95.83333%}.el-col-xl-offset-23{margin-left:95.83333%}.el-col-xl-pull-23{position:relative;right:95.83333%}.el-col-xl-push-23{position:relative;left:95.83333%}.el-col-xl-24{width:100%}.el-col-xl-offset-24{margin-left:100%}.el-col-xl-pull-24{position:relative;right:100%}.el-col-xl-push-24{position:relative;left:100%}}@-webkit-keyframes progress{0%{background-position:0 0}to{background-position:32px 0}}.el-upload{display:inline-block;text-align:center;cursor:pointer;outline:0}.el-upload__input{display:none}.el-upload__tip{font-size:12px;color:#606266;margin-top:7px}.el-upload iframe{position:absolute;z-index:-1;top:0;left:0;opacity:0;filter:alpha(opacity=0)}.el-upload--picture-card{background-color:#fbfdff;border:1px dashed #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:148px;height:148px;line-height:146px;vertical-align:top}.el-upload--picture-card i{font-size:28px;color:#8c939d}.el-upload--picture-card:hover,.el-upload:focus{border-color:#409eff;color:#409eff}.el-upload:focus .el-upload-dragger{border-color:#409eff}.el-upload-dragger{background-color:#fff;border:1px dashed #d9d9d9;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:360px;height:180px;text-align:center;position:relative;overflow:hidden}.el-upload-dragger .el-icon-upload{font-size:67px;color:#c0c4cc;margin:40px 0 16px;line-height:50px}.el-upload-dragger+.el-upload__tip{text-align:center}.el-upload-dragger~.el-upload__files{border-top:1px solid #dcdfe6;margin-top:7px;padding-top:5px}.el-upload-dragger .el-upload__text{color:#606266;font-size:14px;text-align:center}.el-upload-dragger .el-upload__text em{color:#409eff;font-style:normal}.el-upload-dragger:hover{border-color:#409eff}.el-upload-dragger.is-dragover{background-color:rgba(32,159,255,.06);border:2px dashed #409eff}.el-upload-list{margin:0;padding:0;list-style:none}.el-upload-list__item{-webkit-transition:all .5s cubic-bezier(.55,0,.1,1);transition:all .5s cubic-bezier(.55,0,.1,1);font-size:14px;color:#606266;line-height:1.8;margin-top:5px;position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;width:100%}.el-upload-list__item .el-progress{position:absolute;top:20px;width:100%}.el-upload-list__item .el-progress__text{position:absolute;right:0;top:-13px}.el-upload-list__item .el-progress-bar{margin-right:0;padding-right:0}.el-upload-list__item:first-child{margin-top:10px}.el-upload-list__item .el-icon-upload-success{color:#67c23a}.el-upload-list__item .el-icon-close{display:none;position:absolute;top:5px;right:5px;cursor:pointer;opacity:.75;color:#606266}.el-upload-list__item .el-icon-close:hover{opacity:1}.el-upload-list__item .el-icon-close-tip{display:none;position:absolute;top:5px;right:5px;font-size:12px;cursor:pointer;opacity:1;color:#409eff}.el-upload-list__item:hover{background-color:#f5f7fa}.el-upload-list__item:hover .el-icon-close{display:inline-block}.el-upload-list__item:hover .el-progress__text{display:none}.el-upload-list__item.is-success .el-upload-list__item-status-label{display:block}.el-upload-list__item.is-success .el-upload-list__item-name:focus,.el-upload-list__item.is-success .el-upload-list__item-name:hover{color:#409eff;cursor:pointer}.el-upload-list__item.is-success:focus:not(:hover) .el-icon-close-tip{display:inline-block}.el-upload-list__item.is-success:active .el-icon-close-tip,.el-upload-list__item.is-success:focus .el-upload-list__item-status-label,.el-upload-list__item.is-success:hover .el-upload-list__item-status-label,.el-upload-list__item.is-success:not(.focusing):focus .el-icon-close-tip{display:none}.el-upload-list.is-disabled .el-upload-list__item:hover .el-upload-list__item-status-label{display:block}.el-upload-list__item-name{color:#606266;display:block;margin-right:40px;overflow:hidden;padding-left:4px;text-overflow:ellipsis;-webkit-transition:color .3s;transition:color .3s;white-space:nowrap}.el-upload-list__item-name [class^=el-icon]{height:100%;margin-right:7px;color:#909399;line-height:inherit}.el-upload-list__item-status-label{position:absolute;right:5px;top:0;line-height:inherit;display:none}.el-upload-list__item-delete{position:absolute;right:10px;top:0;font-size:12px;color:#606266;display:none}.el-upload-list__item-delete:hover{color:#409eff}.el-upload-list--picture-card{margin:0;display:inline;vertical-align:top}.el-upload-list--picture-card .el-upload-list__item{overflow:hidden;background-color:#fff;border:1px solid #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:148px;height:148px;margin:0 8px 8px 0;display:inline-block}.el-upload-list--picture-card .el-upload-list__item .el-icon-check,.el-upload-list--picture-card .el-upload-list__item .el-icon-circle-check{color:#fff}.el-upload-list--picture-card .el-upload-list__item .el-icon-close,.el-upload-list--picture-card .el-upload-list__item:hover .el-upload-list__item-status-label{display:none}.el-upload-list--picture-card .el-upload-list__item:hover .el-progress__text{display:block}.el-upload-list--picture-card .el-upload-list__item-name{display:none}.el-upload-list--picture-card .el-upload-list__item-thumbnail{width:100%;height:100%}.el-upload-list--picture-card .el-upload-list__item-status-label{position:absolute;right:-15px;top:-6px;width:40px;height:24px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 0 1pc 1px rgba(0,0,0,.2);box-shadow:0 0 1pc 1px rgba(0,0,0,.2)}.el-upload-list--picture-card .el-upload-list__item-status-label i{font-size:12px;margin-top:11px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.el-upload-list--picture-card .el-upload-list__item-actions{position:absolute;width:100%;height:100%;left:0;top:0;cursor:default;text-align:center;color:#fff;opacity:0;font-size:20px;background-color:rgba(0,0,0,.5);-webkit-transition:opacity .3s;transition:opacity .3s}.el-upload-list--picture-card .el-upload-list__item-actions:after{display:inline-block;content:"";height:100%;vertical-align:middle}.el-upload-list--picture-card .el-upload-list__item-actions span{display:none;cursor:pointer}.el-upload-list--picture-card .el-upload-list__item-actions span+span{margin-left:15px}.el-upload-list--picture-card .el-upload-list__item-actions .el-upload-list__item-delete{position:static;font-size:inherit;color:inherit}.el-upload-list--picture-card .el-upload-list__item-actions:hover{opacity:1}.el-upload-list--picture-card .el-upload-list__item-actions:hover span{display:inline-block}.el-upload-list--picture-card .el-progress{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);bottom:auto;width:126px}.el-upload-list--picture-card .el-progress .el-progress__text{top:50%}.el-upload-list--picture .el-upload-list__item{overflow:hidden;z-index:0;background-color:#fff;border:1px solid #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:10px;padding:10px 10px 10px 90px;height:92px}.el-upload-list--picture .el-upload-list__item .el-icon-check,.el-upload-list--picture .el-upload-list__item .el-icon-circle-check{color:#fff}.el-upload-list--picture .el-upload-list__item:hover .el-upload-list__item-status-label{background:0 0;-webkit-box-shadow:none;box-shadow:none;top:-2px;right:-12px}.el-upload-list--picture .el-upload-list__item:hover .el-progress__text{display:block}.el-upload-list--picture .el-upload-list__item.is-success .el-upload-list__item-name{line-height:70px;margin-top:0}.el-upload-list--picture .el-upload-list__item.is-success .el-upload-list__item-name i{display:none}.el-upload-list--picture .el-upload-list__item-thumbnail{vertical-align:middle;display:inline-block;width:70px;height:70px;float:left;position:relative;z-index:1;margin-left:-80px;background-color:#fff}.el-upload-list--picture .el-upload-list__item-name{display:block;margin-top:20px}.el-upload-list--picture .el-upload-list__item-name i{font-size:70px;line-height:1;position:absolute;left:9px;top:10px}.el-upload-list--picture .el-upload-list__item-status-label{position:absolute;right:-17px;top:-7px;width:46px;height:26px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 1px 1px #ccc;box-shadow:0 1px 1px #ccc}.el-upload-list--picture .el-upload-list__item-status-label i{font-size:12px;margin-top:12px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.el-upload-list--picture .el-progress{position:relative;top:-7px}.el-upload-cover{position:absolute;left:0;top:0;width:100%;height:100%;overflow:hidden;z-index:10;cursor:default}.el-upload-cover:after{display:inline-block;height:100%;vertical-align:middle}.el-upload-cover img{display:block;width:100%;height:100%}.el-upload-cover__label{position:absolute;right:-15px;top:-6px;width:40px;height:24px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 0 1pc 1px rgba(0,0,0,.2);box-shadow:0 0 1pc 1px rgba(0,0,0,.2)}.el-upload-cover__label i{font-size:12px;margin-top:11px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);color:#fff}.el-upload-cover__progress{display:inline-block;vertical-align:middle;position:static;width:243px}.el-upload-cover__progress+.el-upload__inner{opacity:0}.el-upload-cover__content{position:absolute;top:0;left:0;width:100%;height:100%}.el-upload-cover__interact{position:absolute;bottom:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.72);text-align:center}.el-upload-cover__interact .btn{display:inline-block;color:#fff;font-size:14px;cursor:pointer;vertical-align:middle;-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);margin-top:60px}.el-upload-cover__interact .btn span{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.el-upload-cover__interact .btn:not(:first-child){margin-left:35px}.el-upload-cover__interact .btn:hover{-webkit-transform:translateY(-13px);transform:translateY(-13px)}.el-upload-cover__interact .btn:hover span{opacity:1}.el-upload-cover__interact .btn i{color:#fff;display:block;font-size:24px;line-height:inherit;margin:0 auto 5px}.el-upload-cover__title{position:absolute;bottom:0;left:0;background-color:#fff;height:36px;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:400;text-align:left;padding:0 10px;margin:0;line-height:36px;font-size:14px;color:#303133}.el-upload-cover+.el-upload__inner{opacity:0;position:relative;z-index:1}.el-progress{position:relative;line-height:1}.el-progress__text{font-size:14px;color:#606266;display:inline-block;vertical-align:middle;margin-left:10px;line-height:1}.el-progress__text i{vertical-align:middle;display:block}.el-progress--circle,.el-progress--dashboard{display:inline-block}.el-progress--circle .el-progress__text,.el-progress--dashboard .el-progress__text{position:absolute;top:50%;left:0;width:100%;text-align:center;margin:0;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-progress--circle .el-progress__text i,.el-progress--dashboard .el-progress__text i{vertical-align:middle;display:inline-block}.el-progress--without-text .el-progress__text{display:none}.el-progress--without-text .el-progress-bar{padding-right:0;margin-right:0;display:block}.el-progress-bar,.el-progress-bar__inner:after,.el-progress-bar__innerText,.el-spinner{display:inline-block;vertical-align:middle}.el-progress--text-inside .el-progress-bar{padding-right:0;margin-right:0}.el-progress.is-success .el-progress-bar__inner{background-color:#67c23a}.el-progress.is-success .el-progress__text{color:#67c23a}.el-progress.is-warning .el-progress-bar__inner{background-color:#e6a23c}.el-progress.is-warning .el-progress__text{color:#e6a23c}.el-progress.is-exception .el-progress-bar__inner{background-color:#f56c6c}.el-progress.is-exception .el-progress__text{color:#f56c6c}.el-progress-bar{padding-right:50px;width:100%;margin-right:-55px;-webkit-box-sizing:border-box;box-sizing:border-box}.el-progress-bar__outer{height:6px;border-radius:100px;background-color:#ebeef5;overflow:hidden;position:relative;vertical-align:middle}.el-progress-bar__inner{position:absolute;left:0;top:0;height:100%;background-color:#409eff;text-align:right;border-radius:100px;line-height:1;white-space:nowrap;-webkit-transition:width .6s ease;transition:width .6s ease}.el-card,.el-message{border-radius:4px;overflow:hidden}.el-progress-bar__inner:after{height:100%}.el-progress-bar__innerText{color:#fff;font-size:12px;margin:0 5px}@keyframes progress{0%{background-position:0 0}to{background-position:32px 0}}.el-time-spinner{width:100%;white-space:nowrap}.el-spinner-inner{-webkit-animation:rotate 2s linear infinite;animation:rotate 2s linear infinite;width:50px;height:50px}.el-spinner-inner .path{stroke:#ececec;stroke-linecap:round;-webkit-animation:dash 1.5s ease-in-out infinite;animation:dash 1.5s ease-in-out infinite}@-webkit-keyframes rotate{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotate{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@-webkit-keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}.el-message{min-width:380px;-webkit-box-sizing:border-box;box-sizing:border-box;border-width:1px;border-style:solid;border-color:#ebeef5;position:fixed;left:50%;top:20px;-webkit-transform:translateX(-50%);transform:translateX(-50%);background-color:#edf2fc;-webkit-transition:opacity .3s,top .4s,-webkit-transform .4s;transition:opacity .3s,top .4s,-webkit-transform .4s;transition:opacity .3s,transform .4s,top .4s;transition:opacity .3s,transform .4s,top .4s,-webkit-transform .4s;padding:15px 15px 15px 20px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-message.is-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-message.is-closable .el-message__content{padding-right:16px}.el-message p{margin:0}.el-message--info .el-message__content{color:#909399}.el-message--success{background-color:#f0f9eb;border-color:#e1f3d8}.el-message--success .el-message__content{color:#67c23a}.el-message--warning{background-color:#fdf6ec;border-color:#faecd8}.el-message--warning .el-message__content{color:#e6a23c}.el-message--error{background-color:#fef0f0;border-color:#fde2e2}.el-message--error .el-message__content{color:#f56c6c}.el-message__icon{margin-right:10px}.el-message__content{padding:0;font-size:14px;line-height:1}.el-message__closeBtn{position:absolute;top:50%;right:15px;-webkit-transform:translateY(-50%);transform:translateY(-50%);cursor:pointer;color:#c0c4cc;font-size:16px}.el-message__closeBtn:hover{color:#909399}.el-message .el-icon-success{color:#67c23a}.el-message .el-icon-error{color:#f56c6c}.el-message .el-icon-info{color:#909399}.el-message .el-icon-warning{color:#e6a23c}.el-message-fade-enter,.el-message-fade-leave-active{opacity:0;-webkit-transform:translate(-50%,-100%);transform:translate(-50%,-100%)}.el-badge{position:relative;vertical-align:middle;display:inline-block}.el-badge__content{background-color:#f56c6c;border-radius:10px;color:#fff;display:inline-block;font-size:12px;height:18px;line-height:18px;padding:0 6px;text-align:center;white-space:nowrap;border:1px solid #fff}.el-badge__content.is-fixed{position:absolute;top:0;right:10px;-webkit-transform:translateY(-50%) translateX(100%);transform:translateY(-50%) translateX(100%)}.el-rate__icon,.el-rate__item{position:relative;display:inline-block}.el-badge__content.is-fixed.is-dot{right:5px}.el-badge__content.is-dot{height:8px;width:8px;padding:0;right:0;border-radius:50%}.el-badge__content--primary{background-color:#409eff}.el-badge__content--success{background-color:#67c23a}.el-badge__content--warning{background-color:#e6a23c}.el-badge__content--info{background-color:#909399}.el-badge__content--danger{background-color:#f56c6c}.el-card{border:1px solid #ebeef5;background-color:#fff;color:#303133;-webkit-transition:.3s;transition:.3s}.el-card.is-always-shadow,.el-card.is-hover-shadow:focus,.el-card.is-hover-shadow:hover{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-card__header{padding:18px 20px;border-bottom:1px solid #ebeef5;-webkit-box-sizing:border-box;box-sizing:border-box}.el-card__body{padding:20px}.el-rate{height:20px;line-height:1}.el-rate__item{font-size:0;vertical-align:middle}.el-rate__icon{font-size:18px;margin-right:6px;color:#c0c4cc;-webkit-transition:.3s;transition:.3s}.el-rate__decimal,.el-rate__icon .path2{position:absolute;top:0;left:0}.el-rate__icon.hover{-webkit-transform:scale(1.15);transform:scale(1.15)}.el-rate__decimal{display:inline-block;overflow:hidden}.el-step.is-vertical,.el-steps{display:-webkit-box;display:-ms-flexbox}.el-rate__text{font-size:14px;vertical-align:middle}.el-steps{display:-webkit-box;display:-ms-flexbox;display:flex}.el-steps--simple{padding:13px 8%;border-radius:4px;background:#f5f7fa}.el-steps--horizontal{white-space:nowrap}.el-steps--vertical{height:100%;-webkit-box-orient:vertical;-ms-flex-flow:column;flex-flow:column}.el-step{position:relative;-ms-flex-negative:1;flex-shrink:1}.el-step:last-of-type .el-step__line{display:none}.el-step:last-of-type.is-flex{-ms-flex-preferred-size:auto!important;flex-basis:auto!important;-ms-flex-negative:0;flex-shrink:0;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.el-step:last-of-type .el-step__description,.el-step:last-of-type .el-step__main{padding-right:0}.el-step__head{position:relative;width:100%}.el-step__head.is-process{color:#303133;border-color:#303133}.el-step__head.is-wait{color:#c0c4cc;border-color:#c0c4cc}.el-step__head.is-success{color:#67c23a;border-color:#67c23a}.el-step__head.is-error{color:#f56c6c;border-color:#f56c6c}.el-step__head.is-finish{color:#409eff;border-color:#409eff}.el-step__icon{position:relative;z-index:1;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:24px;height:24px;font-size:14px;-webkit-box-sizing:border-box;box-sizing:border-box;background:#fff;-webkit-transition:.15s ease-out;transition:.15s ease-out}.el-step__icon.is-text{border-radius:50%;border:2px solid;border-color:inherit}.el-step__icon.is-icon{width:40px}.el-step__icon-inner{display:inline-block;user-select:none;text-align:center;font-weight:700;line-height:1;color:inherit}.el-button,.el-checkbox,.el-image-viewer__btn,.el-step__icon-inner{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.el-step__icon-inner[class*=el-icon]:not(.is-status){font-size:25px;font-weight:400}.el-step__icon-inner.is-status{-webkit-transform:translateY(1px);transform:translateY(1px)}.el-step__line{position:absolute;border-color:inherit;background-color:#c0c4cc}.el-step__line-inner{display:block;border-width:1px;border-style:solid;border-color:inherit;-webkit-transition:.15s ease-out;transition:.15s ease-out;-webkit-box-sizing:border-box;box-sizing:border-box;width:0;height:0}.el-step__main{white-space:normal;text-align:left}.el-step__title{font-size:16px;line-height:38px}.el-step__title.is-process{font-weight:700;color:#303133}.el-step__title.is-wait{color:#c0c4cc}.el-step__title.is-success{color:#67c23a}.el-step__title.is-error{color:#f56c6c}.el-step__title.is-finish{color:#409eff}.el-step__description{padding-right:10%;margin-top:-5px;font-size:12px;line-height:20px;font-weight:400}.el-step__description.is-process{color:#303133}.el-step__description.is-wait{color:#c0c4cc}.el-step__description.is-success{color:#67c23a}.el-step__description.is-error{color:#f56c6c}.el-step__description.is-finish{color:#409eff}.el-step.is-horizontal{display:inline-block}.el-step.is-horizontal .el-step__line{height:2px;top:11px;left:0;right:0}.el-step.is-vertical{display:-webkit-box;display:-ms-flexbox;display:flex}.el-step.is-vertical .el-step__head{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;width:24px}.el-step.is-vertical .el-step__main{padding-left:10px;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.el-step.is-vertical .el-step__title{line-height:24px;padding-bottom:8px}.el-step.is-vertical .el-step__line{width:2px;top:0;bottom:0;left:11px}.el-step.is-vertical .el-step__icon.is-icon{width:24px}.el-step.is-center .el-step__head,.el-step.is-center .el-step__main{text-align:center}.el-step.is-center .el-step__description{padding-left:20%;padding-right:20%}.el-step.is-center .el-step__line{left:50%;right:-50%}.el-step.is-simple{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-step.is-simple .el-step__head{width:auto;font-size:0;padding-right:10px}.el-step.is-simple .el-step__icon{background:0 0;width:16px;height:16px;font-size:12px}.el-step.is-simple .el-step__icon-inner[class*=el-icon]:not(.is-status){font-size:18px}.el-step.is-simple .el-step__icon-inner.is-status{-webkit-transform:scale(.8) translateY(1px);transform:scale(.8) translateY(1px)}.el-step.is-simple .el-step__main{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.el-step.is-simple .el-step__title{font-size:16px;line-height:20px}.el-step.is-simple:not(:last-of-type) .el-step__title{max-width:50%;word-break:break-all}.el-step.is-simple .el-step__arrow{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-step.is-simple .el-step__arrow:after,.el-step.is-simple .el-step__arrow:before{content:"";display:inline-block;position:absolute;height:15px;width:1px;background:#c0c4cc}.el-step.is-simple .el-step__arrow:before{-webkit-transform:rotate(-45deg) translateY(-4px);transform:rotate(-45deg) translateY(-4px);-webkit-transform-origin:0 0;transform-origin:0 0}.el-step.is-simple .el-step__arrow:after{-webkit-transform:rotate(45deg) translateY(4px);transform:rotate(45deg) translateY(4px);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}.el-step.is-simple:last-of-type .el-step__arrow{display:none}.el-carousel{position:relative}.el-carousel--horizontal{overflow-x:hidden}.el-carousel--vertical{overflow-y:hidden}.el-carousel__container{position:relative;height:300px}.el-carousel__arrow{border:none;outline:0;padding:0;margin:0;height:36px;width:36px;cursor:pointer;-webkit-transition:.3s;transition:.3s;border-radius:50%;background-color:rgba(31,45,61,.11);color:#fff;position:absolute;top:50%;z-index:10;-webkit-transform:translateY(-50%);transform:translateY(-50%);text-align:center;font-size:12px}.el-carousel__arrow--left{left:16px}.el-carousel__arrow--right{right:16px}.el-carousel__arrow:hover{background-color:rgba(31,45,61,.23)}.el-carousel__arrow i{cursor:pointer}.el-carousel__indicators{position:absolute;list-style:none;margin:0;padding:0;z-index:2}.el-carousel__indicators--horizontal{bottom:0;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.el-carousel__indicators--vertical{right:0;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-carousel__indicators--outside{bottom:26px;text-align:center;position:static;-webkit-transform:none;transform:none}.el-carousel__indicators--outside .el-carousel__indicator:hover button{opacity:.64}.el-carousel__indicators--outside button{background-color:#c0c4cc;opacity:.24}.el-carousel__indicators--labels{left:0;right:0;-webkit-transform:none;transform:none;text-align:center}.el-carousel__indicators--labels .el-carousel__button{height:auto;width:auto;padding:2px 18px;font-size:12px}.el-carousel__indicators--labels .el-carousel__indicator{padding:6px 4px}.el-carousel__indicator{background-color:transparent;cursor:pointer}.el-carousel__indicator:hover button{opacity:.72}.el-carousel__indicator--horizontal{display:inline-block;padding:12px 4px}.el-carousel__indicator--vertical{padding:4px 12px}.el-carousel__indicator--vertical .el-carousel__button{width:2px;height:15px}.el-carousel__indicator.is-active button{opacity:1}.el-carousel__button{display:block;opacity:.48;width:30px;height:2px;background-color:#fff;border:none;outline:0;padding:0;margin:0;cursor:pointer;-webkit-transition:.3s;transition:.3s}.el-carousel__item,.el-carousel__mask{height:100%;top:0;left:0;position:absolute}.carousel-arrow-left-enter,.carousel-arrow-left-leave-active{-webkit-transform:translateY(-50%) translateX(-10px);transform:translateY(-50%) translateX(-10px);opacity:0}.carousel-arrow-right-enter,.carousel-arrow-right-leave-active{-webkit-transform:translateY(-50%) translateX(10px);transform:translateY(-50%) translateX(10px);opacity:0}.el-carousel__item{width:100%;display:inline-block;overflow:hidden;z-index:0}.el-carousel__item.is-active{z-index:2}.el-carousel__item--card,.el-carousel__item.is-animating{-webkit-transition:-webkit-transform .4s ease-in-out;transition:-webkit-transform .4s ease-in-out;transition:transform .4s ease-in-out;transition:transform .4s ease-in-out,-webkit-transform .4s ease-in-out}.el-carousel__item--card{width:50%}.el-carousel__item--card.is-in-stage{cursor:pointer;z-index:1}.el-carousel__item--card.is-in-stage.is-hover .el-carousel__mask,.el-carousel__item--card.is-in-stage:hover .el-carousel__mask{opacity:.12}.el-carousel__item--card.is-active{z-index:2}.el-carousel__mask{width:100%;background-color:#fff;opacity:.24;-webkit-transition:.2s;transition:.2s}.el-fade-in-enter,.el-fade-in-leave-active,.el-fade-in-linear-enter,.el-fade-in-linear-leave,.el-fade-in-linear-leave-active,.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active{opacity:0}.el-fade-in-linear-enter-active,.el-fade-in-linear-leave-active,.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.el-fade-in-enter-active,.el-fade-in-leave-active,.el-zoom-in-center-enter-active,.el-zoom-in-center-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.el-zoom-in-center-enter,.el-zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.el-zoom-in-top-enter-active,.el-zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center top;transform-origin:center top}.el-zoom-in-top-enter,.el-zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.el-zoom-in-bottom-enter-active,.el-zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center bottom;transform-origin:center bottom}.el-zoom-in-bottom-enter,.el-zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.el-zoom-in-left-enter-active,.el-zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1);transform:scale(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:top left;transform-origin:top left}.el-zoom-in-left-enter,.el-zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45);transform:scale(.45)}.collapse-transition{-webkit-transition:height .3s ease-in-out,padding-top .3s ease-in-out,padding-bottom .3s ease-in-out;transition:height .3s ease-in-out,padding-top .3s ease-in-out,padding-bottom .3s ease-in-out}.horizontal-collapse-transition{-webkit-transition:width .3s ease-in-out,padding-left .3s ease-in-out,padding-right .3s ease-in-out;transition:width .3s ease-in-out,padding-left .3s ease-in-out,padding-right .3s ease-in-out}.el-list-enter-active,.el-list-leave-active{-webkit-transition:all 1s;transition:all 1s}.el-list-enter,.el-list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.el-opacity-transition{-webkit-transition:opacity .3s cubic-bezier(.55,0,.1,1);transition:opacity .3s cubic-bezier(.55,0,.1,1)}.el-collapse{border-top:1px solid #ebeef5;border-bottom:1px solid #ebeef5}.el-collapse-item.is-disabled .el-collapse-item__header{color:#bbb;cursor:not-allowed}.el-collapse-item__header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:48px;line-height:48px;background-color:#fff;color:#303133;cursor:pointer;border-bottom:1px solid #ebeef5;font-size:13px;font-weight:500;-webkit-transition:border-bottom-color .3s;transition:border-bottom-color .3s;outline:0}.el-collapse-item__arrow{margin:0 8px 0 auto;transition:-webkit-transform .3s;-webkit-transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-weight:300}.el-collapse-item__arrow.is-active{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-collapse-item__header.focusing:focus:not(:hover){color:#409eff}.el-collapse-item__header.is-active{border-bottom-color:transparent}.el-collapse-item__wrap{will-change:height;background-color:#fff;overflow:hidden;box-sizing:border-box;border-bottom:1px solid #ebeef5}.el-cascader__tags,.el-collapse-item__wrap,.el-tag{-webkit-box-sizing:border-box}.el-collapse-item__content{padding-bottom:25px;font-size:13px;color:#303133;line-height:1.769230769230769}.el-collapse-item:last-child{margin-bottom:-1px}.el-popper .popper__arrow,.el-popper .popper__arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0,0,0,.03));filter:drop-shadow(0 2px 12px rgba(0,0,0,.03))}.el-popper .popper__arrow:after{content:" ";border-width:6px}.el-popper[x-placement^=top]{margin-bottom:12px}.el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#ebeef5;border-bottom-width:0}.el-popper[x-placement^=top] .popper__arrow:after{bottom:1px;margin-left:-6px;border-top-color:#fff;border-bottom-width:0}.el-popper[x-placement^=bottom]{margin-top:12px}.el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#ebeef5}.el-popper[x-placement^=bottom] .popper__arrow:after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#fff}.el-popper[x-placement^=right]{margin-left:12px}.el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#ebeef5;border-left-width:0}.el-popper[x-placement^=right] .popper__arrow:after{bottom:-6px;left:1px;border-right-color:#fff;border-left-width:0}.el-popper[x-placement^=left]{margin-right:12px}.el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#ebeef5}.el-popper[x-placement^=left] .popper__arrow:after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#fff}.el-tag{background-color:#ecf5ff;border-color:#d9ecff;display:inline-block;height:32px;padding:0 10px;line-height:30px;font-size:12px;color:#409eff;border-width:1px;border-style:solid;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}.el-tag.is-hit{border-color:#409eff}.el-tag .el-tag__close{color:#409eff}.el-tag .el-tag__close:hover{color:#fff;background-color:#409eff}.el-tag.el-tag--info{background-color:#f4f4f5;border-color:#e9e9eb;color:#909399}.el-tag.el-tag--info.is-hit{border-color:#909399}.el-tag.el-tag--info .el-tag__close{color:#909399}.el-tag.el-tag--info .el-tag__close:hover{color:#fff;background-color:#909399}.el-tag.el-tag--success{background-color:#f0f9eb;border-color:#e1f3d8;color:#67c23a}.el-tag.el-tag--success.is-hit{border-color:#67c23a}.el-tag.el-tag--success .el-tag__close{color:#67c23a}.el-tag.el-tag--success .el-tag__close:hover{color:#fff;background-color:#67c23a}.el-tag.el-tag--warning{background-color:#fdf6ec;border-color:#faecd8;color:#e6a23c}.el-tag.el-tag--warning.is-hit{border-color:#e6a23c}.el-tag.el-tag--warning .el-tag__close{color:#e6a23c}.el-tag.el-tag--warning .el-tag__close:hover{color:#fff;background-color:#e6a23c}.el-tag.el-tag--danger{background-color:#fef0f0;border-color:#fde2e2;color:#f56c6c}.el-tag.el-tag--danger.is-hit{border-color:#f56c6c}.el-tag.el-tag--danger .el-tag__close{color:#f56c6c}.el-tag.el-tag--danger .el-tag__close:hover{color:#fff;background-color:#f56c6c}.el-tag .el-icon-close{border-radius:50%;text-align:center;position:relative;cursor:pointer;font-size:12px;height:16px;width:16px;line-height:16px;vertical-align:middle;top:-1px;right:-5px}.el-tag .el-icon-close:before{display:block}.el-tag--dark{background-color:#409eff;color:#fff}.el-tag--dark,.el-tag--dark.is-hit{border-color:#409eff}.el-tag--dark .el-tag__close{color:#fff}.el-tag--dark .el-tag__close:hover{color:#fff;background-color:#66b1ff}.el-tag--dark.el-tag--info{background-color:#909399;border-color:#909399;color:#fff}.el-tag--dark.el-tag--info.is-hit{border-color:#909399}.el-tag--dark.el-tag--info .el-tag__close{color:#fff}.el-tag--dark.el-tag--info .el-tag__close:hover{color:#fff;background-color:#a6a9ad}.el-tag--dark.el-tag--success{background-color:#67c23a;border-color:#67c23a;color:#fff}.el-tag--dark.el-tag--success.is-hit{border-color:#67c23a}.el-tag--dark.el-tag--success .el-tag__close{color:#fff}.el-tag--dark.el-tag--success .el-tag__close:hover{color:#fff;background-color:#85ce61}.el-tag--dark.el-tag--warning{background-color:#e6a23c;border-color:#e6a23c;color:#fff}.el-tag--dark.el-tag--warning.is-hit{border-color:#e6a23c}.el-tag--dark.el-tag--warning .el-tag__close{color:#fff}.el-tag--dark.el-tag--warning .el-tag__close:hover{color:#fff;background-color:#ebb563}.el-tag--dark.el-tag--danger{background-color:#f56c6c;border-color:#f56c6c;color:#fff}.el-tag--dark.el-tag--danger.is-hit{border-color:#f56c6c}.el-tag--dark.el-tag--danger .el-tag__close{color:#fff}.el-tag--dark.el-tag--danger .el-tag__close:hover{color:#fff;background-color:#f78989}.el-tag--plain{background-color:#fff;border-color:#b3d8ff;color:#409eff}.el-tag--plain.is-hit{border-color:#409eff}.el-tag--plain .el-tag__close{color:#409eff}.el-tag--plain .el-tag__close:hover{color:#fff;background-color:#409eff}.el-tag--plain.el-tag--info{background-color:#fff;border-color:#d3d4d6;color:#909399}.el-tag--plain.el-tag--info.is-hit{border-color:#909399}.el-tag--plain.el-tag--info .el-tag__close{color:#909399}.el-tag--plain.el-tag--info .el-tag__close:hover{color:#fff;background-color:#909399}.el-tag--plain.el-tag--success{background-color:#fff;border-color:#c2e7b0;color:#67c23a}.el-tag--plain.el-tag--success.is-hit{border-color:#67c23a}.el-tag--plain.el-tag--success .el-tag__close{color:#67c23a}.el-tag--plain.el-tag--success .el-tag__close:hover{color:#fff;background-color:#67c23a}.el-tag--plain.el-tag--warning{background-color:#fff;border-color:#f5dab1;color:#e6a23c}.el-tag--plain.el-tag--warning.is-hit{border-color:#e6a23c}.el-tag--plain.el-tag--warning .el-tag__close{color:#e6a23c}.el-tag--plain.el-tag--warning .el-tag__close:hover{color:#fff;background-color:#e6a23c}.el-tag--plain.el-tag--danger{background-color:#fff;border-color:#fbc4c4;color:#f56c6c}.el-tag--plain.el-tag--danger.is-hit{border-color:#f56c6c}.el-tag--plain.el-tag--danger .el-tag__close{color:#f56c6c}.el-tag--plain.el-tag--danger .el-tag__close:hover{color:#fff;background-color:#f56c6c}.el-tag--medium{height:28px;line-height:26px}.el-tag--medium .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.el-tag--small{height:24px;padding:0 8px;line-height:22px}.el-tag--small .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.el-tag--mini{height:20px;padding:0 5px;line-height:19px}.el-tag--mini .el-icon-close{margin-left:-3px;-webkit-transform:scale(.7);transform:scale(.7)}.el-cascader{display:inline-block;position:relative;font-size:14px;line-height:40px}.el-cascader:not(.is-disabled):hover .el-input__inner{cursor:pointer;border-color:#c0c4cc}.el-cascader .el-input .el-input__inner:focus,.el-cascader .el-input.is-focus .el-input__inner{border-color:#409eff}.el-cascader .el-input{cursor:pointer}.el-cascader .el-input .el-input__inner{text-overflow:ellipsis}.el-cascader .el-input .el-icon-arrow-down{-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-size:14px}.el-cascader .el-input .el-icon-arrow-down.is-reverse{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.el-cascader .el-input .el-icon-circle-close:hover{color:#909399}.el-cascader--medium{font-size:14px;line-height:36px}.el-cascader--small{font-size:13px;line-height:32px}.el-cascader--mini{font-size:12px;line-height:28px}.el-cascader.is-disabled .el-cascader__label{z-index:2;color:#c0c4cc}.el-cascader__dropdown{margin:5px 0;font-size:14px;background:#fff;border:1px solid #e4e7ed;border-radius:4px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-cascader__tags{position:absolute;left:0;right:30px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;line-height:normal;text-align:left;-webkit-box-sizing:border-box;box-sizing:border-box}.el-cascader__tags .el-tag{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;max-width:100%;margin:2px 0 2px 6px;text-overflow:ellipsis;background:#f0f2f5}.el-cascader__tags .el-tag:not(.is-hit){border-color:transparent}.el-cascader__tags .el-tag>span{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:hidden;text-overflow:ellipsis}.el-cascader__tags .el-tag .el-icon-close{-webkit-box-flex:0;-ms-flex:none;flex:none;background-color:#c0c4cc;color:#fff}.el-cascader__tags .el-tag .el-icon-close:hover{background-color:#909399}.el-cascader__suggestion-panel{border-radius:4px}.el-cascader__suggestion-list{max-height:204px;margin:0;padding:6px 0;font-size:14px;color:#606266;text-align:center}.el-cascader__suggestion-item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:34px;padding:0 15px;text-align:left;outline:0;cursor:pointer}.el-cascader__suggestion-item:focus,.el-cascader__suggestion-item:hover{background:#f5f7fa}.el-cascader__suggestion-item.is-checked{color:#409eff;font-weight:700}.el-cascader__suggestion-item>span{margin-right:10px}.el-cascader__empty-text{margin:10px 0;color:#c0c4cc}.el-cascader__search-input{-webkit-box-flex:1;-ms-flex:1;flex:1;height:24px;min-width:60px;margin:2px 0 2px 15px;padding:0;color:#606266;border:none;outline:0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-cascader__search-input::-webkit-input-placeholder{color:#c0c4cc}.el-cascader__search-input:-ms-input-placeholder{color:#c0c4cc}.el-cascader__search-input::-ms-input-placeholder{color:#c0c4cc}.el-cascader__search-input::-moz-placeholder{color:#c0c4cc}.el-cascader__search-input::placeholder{color:#c0c4cc}.el-color-predefine{font-size:12px;margin-top:8px;width:280px}.el-color-predefine,.el-color-predefine__colors{display:-webkit-box;display:-ms-flexbox;display:flex}.el-color-predefine__colors{-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-wrap:wrap;flex-wrap:wrap}.el-color-predefine__color-selector{margin:0 0 8px 8px;width:20px;height:20px;border-radius:4px;cursor:pointer}.el-color-predefine__color-selector:nth-child(10n+1){margin-left:0}.el-color-predefine__color-selector.selected{-webkit-box-shadow:0 0 3px 2px #409eff;box-shadow:0 0 3px 2px #409eff}.el-color-predefine__color-selector>div{display:-webkit-box;display:-ms-flexbox;display:flex;height:100%;border-radius:3px}.el-color-predefine__color-selector.is-alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.el-color-hue-slider{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;width:280px;height:12px;background-color:red;padding:0 2px}.el-color-hue-slider__bar{position:relative;background:-webkit-gradient(linear,left top,right top,color-stop(0,red),color-stop(17%,#ff0),color-stop(33%,#0f0),color-stop(50%,#0ff),color-stop(67%,#00f),color-stop(83%,#f0f),to(red));background:linear-gradient(90deg,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red);height:100%}.el-color-hue-slider__thumb{position:absolute;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;left:0;top:0;width:4px;height:100%;border-radius:1px;background:#fff;border:1px solid #f0f0f0;-webkit-box-shadow:0 0 2px rgba(0,0,0,.6);box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.el-color-hue-slider.is-vertical{width:12px;height:180px;padding:2px 0}.el-color-hue-slider.is-vertical .el-color-hue-slider__bar{background:-webkit-gradient(linear,left top,left bottom,color-stop(0,red),color-stop(17%,#ff0),color-stop(33%,#0f0),color-stop(50%,#0ff),color-stop(67%,#00f),color-stop(83%,#f0f),to(red));background:linear-gradient(180deg,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red)}.el-color-hue-slider.is-vertical .el-color-hue-slider__thumb{left:0;top:0;width:100%;height:4px}.el-color-svpanel{position:relative;width:280px;height:180px}.el-color-svpanel__black,.el-color-svpanel__white{position:absolute;top:0;left:0;right:0;bottom:0}.el-color-svpanel__white{background:-webkit-gradient(linear,left top,right top,from(#fff),to(hsla(0,0%,100%,0)));background:linear-gradient(90deg,#fff,hsla(0,0%,100%,0))}.el-color-svpanel__black{background:-webkit-gradient(linear,left bottom,left top,from(#000),to(transparent));background:linear-gradient(0deg,#000,transparent)}.el-color-svpanel__cursor{position:absolute}.el-color-svpanel__cursor>div{cursor:head;width:4px;height:4px;-webkit-box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);border-radius:50%;-webkit-transform:translate(-2px,-2px);transform:translate(-2px,-2px)}.el-color-alpha-slider{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;width:280px;height:12px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.el-color-alpha-slider__bar{position:relative;background:-webkit-gradient(linear,left top,right top,color-stop(0,hsla(0,0%,100%,0)),to(#fff));background:linear-gradient(90deg,hsla(0,0%,100%,0) 0,#fff);height:100%}.el-color-alpha-slider__thumb{position:absolute;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;left:0;top:0;width:4px;height:100%;border-radius:1px;background:#fff;border:1px solid #f0f0f0;-webkit-box-shadow:0 0 2px rgba(0,0,0,.6);box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.el-color-alpha-slider.is-vertical{width:20px;height:180px}.el-color-alpha-slider.is-vertical .el-color-alpha-slider__bar{background:-webkit-gradient(linear,left top,left bottom,color-stop(0,hsla(0,0%,100%,0)),to(#fff));background:linear-gradient(180deg,hsla(0,0%,100%,0) 0,#fff)}.el-color-alpha-slider.is-vertical .el-color-alpha-slider__thumb{left:0;top:0;width:100%;height:4px}.el-color-dropdown{width:300px}.el-color-dropdown__main-wrapper{margin-bottom:6px}.el-color-dropdown__main-wrapper:after{content:"";display:table;clear:both}.el-color-dropdown__btns{margin-top:6px;text-align:right}.el-color-dropdown__value{float:left;line-height:26px;font-size:12px;color:#000;width:160px}.el-color-dropdown__btn{border:1px solid #dcdcdc;color:#333;line-height:24px;border-radius:2px;padding:0 20px;cursor:pointer;background-color:transparent;outline:0;font-size:12px}.el-color-dropdown__btn[disabled]{color:#ccc;cursor:not-allowed}.el-color-dropdown__btn:hover{color:#409eff;border-color:#409eff}.el-color-dropdown__link-btn{cursor:pointer;color:#409eff;text-decoration:none;padding:15px;font-size:12px}.el-color-dropdown__link-btn:hover{color:tint(#409eff,20%)}.el-color-picker{display:inline-block;position:relative;line-height:normal;height:40px}.el-color-picker.is-disabled .el-color-picker__trigger{cursor:not-allowed}.el-color-picker--medium{height:36px}.el-color-picker--medium .el-color-picker__trigger{height:36px;width:36px}.el-color-picker--medium .el-color-picker__mask{height:34px;width:34px}.el-color-picker--small{height:32px}.el-color-picker--small .el-color-picker__trigger{height:32px;width:32px}.el-color-picker--small .el-color-picker__mask{height:30px;width:30px}.el-color-picker--small .el-color-picker__empty,.el-color-picker--small .el-color-picker__icon{-webkit-transform:translate3d(-50%,-50%,0) scale(.8);transform:translate3d(-50%,-50%,0) scale(.8)}.el-color-picker--mini{height:28px}.el-color-picker--mini .el-color-picker__trigger{height:28px;width:28px}.el-color-picker--mini .el-color-picker__mask{height:26px;width:26px}.el-color-picker--mini .el-color-picker__empty,.el-color-picker--mini .el-color-picker__icon{-webkit-transform:translate3d(-50%,-50%,0) scale(.8);transform:translate3d(-50%,-50%,0) scale(.8)}.el-color-picker__mask{height:38px;width:38px;border-radius:4px;position:absolute;top:1px;left:1px;z-index:1;cursor:not-allowed;background-color:hsla(0,0%,100%,.7)}.el-color-picker__trigger{display:inline-block;height:40px;width:40px;padding:4px;border:1px solid #e6e6e6;border-radius:4px;font-size:0;cursor:pointer}.el-color-picker__color,.el-color-picker__trigger{-webkit-box-sizing:border-box;box-sizing:border-box;position:relative}.el-color-picker__color{display:block;border:1px solid #999;border-radius:2px;width:100%;height:100%;text-align:center}.el-color-picker__color.is-alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.el-color-picker__color-inner{position:absolute;left:0;top:0;right:0;bottom:0}.el-color-picker__empty,.el-color-picker__icon{top:50%;left:50%;font-size:12px;position:absolute}.el-color-picker__empty{color:#999}.el-color-picker__empty,.el-color-picker__icon{-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}.el-color-picker__icon{display:inline-block;width:100%;color:#fff;text-align:center}.el-color-picker__panel{position:absolute;z-index:10;padding:6px;-webkit-box-sizing:content-box;box-sizing:content-box;background-color:#fff;border:1px solid #ebeef5;border-radius:4px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:inherit;color:#606266;background-color:#fff;background-image:none;border:1px solid #dcdfe6;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.el-textarea__inner::-webkit-input-placeholder{color:#c0c4cc}.el-textarea__inner:-ms-input-placeholder{color:#c0c4cc}.el-textarea__inner::-ms-input-placeholder{color:#c0c4cc}.el-textarea__inner::-moz-placeholder{color:#c0c4cc}.el-textarea__inner::placeholder{color:#c0c4cc}.el-textarea__inner:hover{border-color:#c0c4cc}.el-textarea__inner:focus{outline:0;border-color:#409eff}.el-textarea .el-input__count{color:#909399;background:#fff;position:absolute;font-size:12px;bottom:5px;right:10px}.el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#e4e7ed;color:#c0c4cc;cursor:not-allowed}.el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#c0c4cc}.el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#c0c4cc}.el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#c0c4cc}.el-textarea.is-disabled .el-textarea__inner::-moz-placeholder{color:#c0c4cc}.el-textarea.is-disabled .el-textarea__inner::placeholder{color:#c0c4cc}.el-textarea.is-exceed .el-textarea__inner{border-color:#f56c6c}.el-textarea.is-exceed .el-input__count{color:#f56c6c}.el-input{position:relative;font-size:14px;display:inline-block;width:100%}.el-input::-webkit-scrollbar{z-index:11;width:6px}.el-input::-webkit-scrollbar:horizontal{height:6px}.el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.el-input::-webkit-scrollbar-corner,.el-input::-webkit-scrollbar-track{background:#fff}.el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.el-input .el-input__clear{color:#c0c4cc;font-size:14px;cursor:pointer;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.el-input .el-input__clear:hover{color:#909399}.el-input .el-input__count{height:100%;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#909399;font-size:12px}.el-input .el-input__count .el-input__count-inner{background:#fff;line-height:normal;display:inline-block;padding:0 5px}.el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #dcdfe6;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;height:40px;line-height:40px;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.el-button,.el-input__inner,.el-transfer-panel{-webkit-box-sizing:border-box}.el-input__prefix,.el-input__suffix{position:absolute;top:0;-webkit-transition:all .3s;height:100%;color:#c0c4cc;text-align:center}.el-input__inner::-webkit-input-placeholder{color:#c0c4cc}.el-input__inner:-ms-input-placeholder{color:#c0c4cc}.el-input__inner::-ms-input-placeholder{color:#c0c4cc}.el-input__inner::-moz-placeholder{color:#c0c4cc}.el-input__inner::placeholder{color:#c0c4cc}.el-input__inner:hover{border-color:#c0c4cc}.el-input.is-active .el-input__inner,.el-input__inner:focus{border-color:#409eff;outline:0}.el-input__suffix{right:5px;-webkit-transition:all .3s;transition:all .3s}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{left:5px}.el-input__icon,.el-input__prefix{-webkit-transition:all .3s;transition:all .3s}.el-input__icon{height:100%;width:25px;text-align:center;line-height:40px}.el-input__icon:after{content:"";height:100%;width:0;display:inline-block;vertical-align:middle}.el-input__validateIcon{pointer-events:none}.el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#e4e7ed;color:#c0c4cc;cursor:not-allowed}.el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__inner::-moz-placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__inner::placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__icon{cursor:not-allowed}.el-input.is-exceed .el-input__inner{border-color:#f56c6c}.el-input.is-exceed .el-input__suffix .el-input__count{color:#f56c6c}.el-input--suffix .el-input__inner{padding-right:30px}.el-input--prefix .el-input__inner{padding-left:30px}.el-input--medium{font-size:14px}.el-input--medium .el-input__inner{height:36px;line-height:36px}.el-input--medium .el-input__icon{line-height:36px}.el-input--small{font-size:13px}.el-input--small .el-input__inner{height:32px;line-height:32px}.el-input--small .el-input__icon{line-height:32px}.el-input--mini{font-size:12px}.el-input--mini .el-input__inner{height:28px;line-height:28px}.el-input--mini .el-input__icon{line-height:28px}.el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate;border-spacing:0}.el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.el-input-group__append,.el-input-group__prepend{background-color:#f5f7fa;color:#909399;vertical-align:middle;display:table-cell;position:relative;border:1px solid #dcdfe6;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.el-input-group--prepend .el-input__inner,.el-input-group__append{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--append .el-input__inner,.el-input-group__prepend{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append:focus,.el-input-group__prepend:focus{outline:0}.el-input-group__append .el-button,.el-input-group__append .el-select,.el-input-group__prepend .el-button,.el-input-group__prepend .el-select{display:inline-block;margin:-10px -20px}.el-input-group__append button.el-button,.el-input-group__append div.el-select .el-input__inner,.el-input-group__append div.el-select:hover .el-input__inner,.el-input-group__prepend button.el-button,.el-input-group__prepend div.el-select .el-input__inner,.el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.el-input-group__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0}.el-input-group__append{border-left:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner,.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.el-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#fff;border:1px solid #dcdfe6;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:.1s;transition:.1s;font-weight:500;padding:12px 20px;font-size:14px;border-radius:4px}.el-button+.el-button{margin-left:10px}.el-button:focus,.el-button:hover{color:#409eff;border-color:#c6e2ff;background-color:#ecf5ff}.el-button:active{color:#3a8ee6;border-color:#3a8ee6;outline:0}.el-button::-moz-focus-inner{border:0}.el-button [class*=el-icon-]+span{margin-left:5px}.el-button.is-plain:focus,.el-button.is-plain:hover{background:#fff;border-color:#409eff;color:#409eff}.el-button.is-active,.el-button.is-plain:active{color:#3a8ee6;border-color:#3a8ee6}.el-button.is-plain:active{background:#fff;outline:0}.el-button.is-disabled,.el-button.is-disabled:focus,.el-button.is-disabled:hover{color:#c0c4cc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#ebeef5}.el-link,.el-transfer-panel__filter .el-icon-circle-close{cursor:pointer}.el-button.is-disabled.el-button--text{background-color:transparent}.el-button.is-disabled.is-plain,.el-button.is-disabled.is-plain:focus,.el-button.is-disabled.is-plain:hover{background-color:#fff;border-color:#ebeef5;color:#c0c4cc}.el-button.is-loading{position:relative;pointer-events:none}.el-button.is-loading:before{pointer-events:none;content:"";position:absolute;left:-1px;top:-1px;right:-1px;bottom:-1px;border-radius:inherit;background-color:hsla(0,0%,100%,.35)}.el-button.is-round{border-radius:20px;padding:12px 23px}.el-button.is-circle{border-radius:50%;padding:12px}.el-button--primary{color:#fff;background-color:#409eff;border-color:#409eff}.el-button--primary:focus,.el-button--primary:hover{background:#66b1ff;border-color:#66b1ff;color:#fff}.el-button--primary.is-active,.el-button--primary:active{background:#3a8ee6;border-color:#3a8ee6;color:#fff}.el-button--primary:active{outline:0}.el-button--primary.is-disabled,.el-button--primary.is-disabled:active,.el-button--primary.is-disabled:focus,.el-button--primary.is-disabled:hover{color:#fff;background-color:#a0cfff;border-color:#a0cfff}.el-button--primary.is-plain{color:#409eff;background:#ecf5ff;border-color:#b3d8ff}.el-button--primary.is-plain:focus,.el-button--primary.is-plain:hover{background:#409eff;border-color:#409eff;color:#fff}.el-button--primary.is-plain:active{background:#3a8ee6;border-color:#3a8ee6;color:#fff;outline:0}.el-button--primary.is-plain.is-disabled,.el-button--primary.is-plain.is-disabled:active,.el-button--primary.is-plain.is-disabled:focus,.el-button--primary.is-plain.is-disabled:hover{color:#8cc5ff;background-color:#ecf5ff;border-color:#d9ecff}.el-button--success{color:#fff;background-color:#67c23a;border-color:#67c23a}.el-button--success:focus,.el-button--success:hover{background:#85ce61;border-color:#85ce61;color:#fff}.el-button--success.is-active,.el-button--success:active{background:#5daf34;border-color:#5daf34;color:#fff}.el-button--success:active{outline:0}.el-button--success.is-disabled,.el-button--success.is-disabled:active,.el-button--success.is-disabled:focus,.el-button--success.is-disabled:hover{color:#fff;background-color:#b3e19d;border-color:#b3e19d}.el-button--success.is-plain{color:#67c23a;background:#f0f9eb;border-color:#c2e7b0}.el-button--success.is-plain:focus,.el-button--success.is-plain:hover{background:#67c23a;border-color:#67c23a;color:#fff}.el-button--success.is-plain:active{background:#5daf34;border-color:#5daf34;color:#fff;outline:0}.el-button--success.is-plain.is-disabled,.el-button--success.is-plain.is-disabled:active,.el-button--success.is-plain.is-disabled:focus,.el-button--success.is-plain.is-disabled:hover{color:#a4da89;background-color:#f0f9eb;border-color:#e1f3d8}.el-button--warning{color:#fff;background-color:#e6a23c;border-color:#e6a23c}.el-button--warning:focus,.el-button--warning:hover{background:#ebb563;border-color:#ebb563;color:#fff}.el-button--warning.is-active,.el-button--warning:active{background:#cf9236;border-color:#cf9236;color:#fff}.el-button--warning:active{outline:0}.el-button--warning.is-disabled,.el-button--warning.is-disabled:active,.el-button--warning.is-disabled:focus,.el-button--warning.is-disabled:hover{color:#fff;background-color:#f3d19e;border-color:#f3d19e}.el-button--warning.is-plain{color:#e6a23c;background:#fdf6ec;border-color:#f5dab1}.el-button--warning.is-plain:focus,.el-button--warning.is-plain:hover{background:#e6a23c;border-color:#e6a23c;color:#fff}.el-button--warning.is-plain:active{background:#cf9236;border-color:#cf9236;color:#fff;outline:0}.el-button--warning.is-plain.is-disabled,.el-button--warning.is-plain.is-disabled:active,.el-button--warning.is-plain.is-disabled:focus,.el-button--warning.is-plain.is-disabled:hover{color:#f0c78a;background-color:#fdf6ec;border-color:#faecd8}.el-button--danger{color:#fff;background-color:#f56c6c;border-color:#f56c6c}.el-button--danger:focus,.el-button--danger:hover{background:#f78989;border-color:#f78989;color:#fff}.el-button--danger.is-active,.el-button--danger:active{background:#dd6161;border-color:#dd6161;color:#fff}.el-button--danger:active{outline:0}.el-button--danger.is-disabled,.el-button--danger.is-disabled:active,.el-button--danger.is-disabled:focus,.el-button--danger.is-disabled:hover{color:#fff;background-color:#fab6b6;border-color:#fab6b6}.el-button--danger.is-plain{color:#f56c6c;background:#fef0f0;border-color:#fbc4c4}.el-button--danger.is-plain:focus,.el-button--danger.is-plain:hover{background:#f56c6c;border-color:#f56c6c;color:#fff}.el-button--danger.is-plain:active{background:#dd6161;border-color:#dd6161;color:#fff;outline:0}.el-button--danger.is-plain.is-disabled,.el-button--danger.is-plain.is-disabled:active,.el-button--danger.is-plain.is-disabled:focus,.el-button--danger.is-plain.is-disabled:hover{color:#f9a7a7;background-color:#fef0f0;border-color:#fde2e2}.el-button--info{color:#fff;background-color:#909399;border-color:#909399}.el-button--info:focus,.el-button--info:hover{background:#a6a9ad;border-color:#a6a9ad;color:#fff}.el-button--info.is-active,.el-button--info:active{background:#82848a;border-color:#82848a;color:#fff}.el-button--info:active{outline:0}.el-button--info.is-disabled,.el-button--info.is-disabled:active,.el-button--info.is-disabled:focus,.el-button--info.is-disabled:hover{color:#fff;background-color:#c8c9cc;border-color:#c8c9cc}.el-button--info.is-plain{color:#909399;background:#f4f4f5;border-color:#d3d4d6}.el-button--info.is-plain:focus,.el-button--info.is-plain:hover{background:#909399;border-color:#909399;color:#fff}.el-button--info.is-plain:active{background:#82848a;border-color:#82848a;color:#fff;outline:0}.el-button--info.is-plain.is-disabled,.el-button--info.is-plain.is-disabled:active,.el-button--info.is-plain.is-disabled:focus,.el-button--info.is-plain.is-disabled:hover{color:#bcbec2;background-color:#f4f4f5;border-color:#e9e9eb}.el-button--text,.el-button--text.is-disabled,.el-button--text.is-disabled:focus,.el-button--text.is-disabled:hover,.el-button--text:active{border-color:transparent}.el-button--medium{padding:10px 20px;font-size:14px;border-radius:4px}.el-button--mini,.el-button--small{font-size:12px;border-radius:3px}.el-button--medium.is-round{padding:10px 20px}.el-button--medium.is-circle{padding:10px}.el-button--small,.el-button--small.is-round{padding:9px 15px}.el-button--small.is-circle{padding:9px}.el-button--mini,.el-button--mini.is-round{padding:7px 15px}.el-button--mini.is-circle{padding:7px}.el-button--text{color:#409eff;background:0 0;padding-left:0;padding-right:0}.el-button--text:focus,.el-button--text:hover{color:#66b1ff;border-color:transparent;background-color:transparent}.el-button--text:active{color:#3a8ee6;background-color:transparent}.el-button-group{display:inline-block;vertical-align:middle}.el-button-group:after,.el-button-group:before{display:table;content:""}.el-button-group:after{clear:both}.el-button-group>.el-button{float:left;position:relative}.el-button-group>.el-button+.el-button{margin-left:0}.el-button-group>.el-button.is-disabled{z-index:1}.el-button-group>.el-button:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.el-button-group>.el-button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.el-button-group>.el-button:first-child:last-child{border-radius:4px}.el-button-group>.el-button:first-child:last-child.is-round{border-radius:20px}.el-button-group>.el-button:first-child:last-child.is-circle{border-radius:50%}.el-button-group>.el-button:not(:first-child):not(:last-child){border-radius:0}.el-button-group>.el-button:not(:last-child){margin-right:-1px}.el-button-group>.el-button.is-active,.el-button-group>.el-button:active,.el-button-group>.el-button:focus,.el-button-group>.el-button:hover{z-index:1}.el-button-group>.el-dropdown>.el-button{border-top-left-radius:0;border-bottom-left-radius:0;border-left-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--primary:first-child{border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--primary:last-child{border-left-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--primary:not(:first-child):not(:last-child){border-left-color:hsla(0,0%,100%,.5);border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--success:first-child{border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--success:last-child{border-left-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--success:not(:first-child):not(:last-child){border-left-color:hsla(0,0%,100%,.5);border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--warning:first-child{border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--warning:last-child{border-left-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--warning:not(:first-child):not(:last-child){border-left-color:hsla(0,0%,100%,.5);border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--danger:first-child{border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--danger:last-child{border-left-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--danger:not(:first-child):not(:last-child){border-left-color:hsla(0,0%,100%,.5);border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--info:first-child{border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--info:last-child{border-left-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--info:not(:first-child):not(:last-child){border-left-color:hsla(0,0%,100%,.5);border-right-color:hsla(0,0%,100%,.5)}.el-transfer{font-size:14px}.el-transfer__buttons{display:inline-block;vertical-align:middle;padding:0 30px}.el-transfer__button{display:block;margin:0 auto;padding:10px;border-radius:50%;color:#fff;background-color:#409eff;font-size:0}.el-transfer__button.is-with-texts{border-radius:4px}.el-transfer__button.is-disabled,.el-transfer__button.is-disabled:hover{border:1px solid #dcdfe6;background-color:#f5f7fa;color:#c0c4cc}.el-transfer__button:first-child{margin-bottom:10px}.el-transfer__button:nth-child(2){margin:0}.el-transfer__button i,.el-transfer__button span{font-size:14px}.el-transfer__button [class*=el-icon-]+span{margin-left:0}.el-transfer-panel{border:1px solid #ebeef5;border-radius:4px;overflow:hidden;background:#fff;display:inline-block;vertical-align:middle;width:200px;max-height:100%;-webkit-box-sizing:border-box;box-sizing:border-box;position:relative}.el-transfer-panel__body{height:246px}.el-transfer-panel__body.is-with-footer{padding-bottom:40px}.el-transfer-panel__list{margin:0;padding:6px 0;list-style:none;height:246px;overflow:auto;-webkit-box-sizing:border-box;box-sizing:border-box}.el-transfer-panel__list.is-filterable{height:194px;padding-top:0}.el-transfer-panel__item{height:30px;line-height:30px;padding-left:15px;display:block}.el-transfer-panel__item+.el-transfer-panel__item{margin-left:0;display:block!important}.el-transfer-panel__item.el-checkbox{color:#606266}.el-transfer-panel__item:hover{color:#409eff}.el-transfer-panel__item.el-checkbox .el-checkbox__label{width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;-webkit-box-sizing:border-box;box-sizing:border-box;padding-left:24px;line-height:30px}.el-transfer-panel__item .el-checkbox__input{position:absolute;top:8px}.el-transfer-panel__filter{text-align:center;margin:15px;-webkit-box-sizing:border-box;box-sizing:border-box;display:block;width:auto}.el-transfer-panel__filter .el-input__inner{height:32px;width:100%;font-size:12px;display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:16px;padding-right:10px;padding-left:30px}.el-transfer-panel__filter .el-input__icon{margin-left:5px}.el-transfer-panel .el-transfer-panel__header{height:40px;line-height:40px;background:#f5f7fa;margin:0;padding-left:15px;border-bottom:1px solid #ebeef5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#000}.el-transfer-panel .el-transfer-panel__header .el-checkbox{display:block;line-height:40px}.el-transfer-panel .el-transfer-panel__header .el-checkbox .el-checkbox__label{font-size:16px;color:#303133;font-weight:400}.el-transfer-panel .el-transfer-panel__header .el-checkbox .el-checkbox__label span{position:absolute;right:15px;color:#909399;font-size:12px;font-weight:400}.el-divider__text,.el-link{font-weight:500;font-size:14px}.el-transfer-panel .el-transfer-panel__footer{height:40px;background:#fff;margin:0;padding:0;border-top:1px solid #ebeef5;position:absolute;bottom:0;left:0;width:100%;z-index:1}.el-transfer-panel .el-transfer-panel__footer:after{display:inline-block;content:"";height:100%;vertical-align:middle}.el-container,.el-timeline-item__node{display:-webkit-box;display:-ms-flexbox}.el-transfer-panel .el-transfer-panel__footer .el-checkbox{padding-left:20px;color:#606266}.el-transfer-panel .el-transfer-panel__empty{margin:0;height:30px;line-height:30px;padding:6px 15px 0;color:#909399;text-align:center}.el-transfer-panel .el-checkbox__label{padding-left:8px}.el-transfer-panel .el-checkbox__inner{height:14px;width:14px;border-radius:3px}.el-transfer-panel .el-checkbox__inner:after{height:6px;width:3px;left:4px}.el-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-ms-flex-direction:row;flex-direction:row;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-preferred-size:auto;flex-basis:auto;box-sizing:border-box;min-width:0}.el-aside,.el-container,.el-header{-webkit-box-sizing:border-box}.el-container.is-vertical{-webkit-box-orient:vertical;-ms-flex-direction:column;flex-direction:column}.el-header{padding:0 20px}.el-aside,.el-header{-webkit-box-sizing:border-box;box-sizing:border-box;-ms-flex-negative:0;flex-shrink:0}.el-aside{overflow:auto}.el-footer,.el-main{-webkit-box-sizing:border-box}.el-main{display:block;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-preferred-size:auto;flex-basis:auto;overflow:auto;padding:20px}.el-footer,.el-main{-webkit-box-sizing:border-box;box-sizing:border-box}.el-footer{padding:0 20px;-ms-flex-negative:0;flex-shrink:0}.el-timeline{margin:0;font-size:14px;list-style:none}.el-timeline .el-timeline-item:last-child .el-timeline-item__tail{display:none}.el-timeline-item{position:relative;padding-bottom:20px}.el-timeline-item__wrapper{position:relative;padding-left:28px;top:-3px}.el-timeline-item__tail{position:absolute;left:4px;height:100%;border-left:2px solid #e4e7ed}.el-timeline-item__icon{color:#fff;font-size:13px}.el-timeline-item__node{position:absolute;background-color:#e4e7ed;border-radius:50%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-image__error,.el-timeline-item__dot{display:-webkit-box;display:-ms-flexbox}.el-timeline-item__node--normal{left:-1px;width:12px;height:12px}.el-timeline-item__node--large{left:-2px;width:14px;height:14px}.el-timeline-item__node--primary{background-color:#409eff}.el-timeline-item__node--success{background-color:#67c23a}.el-timeline-item__node--warning{background-color:#e6a23c}.el-timeline-item__node--danger{background-color:#f56c6c}.el-timeline-item__node--info{background-color:#909399}.el-timeline-item__dot{position:absolute;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-timeline-item__content{color:#303133}.el-timeline-item__timestamp{color:#909399;line-height:1;font-size:13px}.el-timeline-item__timestamp.is-top{margin-bottom:8px;padding-top:4px}.el-timeline-item__timestamp.is-bottom{margin-top:8px}.el-link{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:horizontal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;vertical-align:middle;position:relative;text-decoration:none;outline:0;padding:0}.el-link.is-underline:hover:after{content:"";position:absolute;left:0;right:0;height:0;bottom:0;border-bottom:1px solid #409eff}.el-link.el-link--default:after,.el-link.el-link--primary.is-underline:hover:after,.el-link.el-link--primary:after{border-color:#409eff}.el-link.is-disabled{cursor:not-allowed}.el-link [class*=el-icon-]+span{margin-left:5px}.el-link.el-link--default{color:#606266}.el-link.el-link--default:hover{color:#409eff}.el-link.el-link--default.is-disabled{color:#c0c4cc}.el-link.el-link--primary{color:#409eff}.el-link.el-link--primary:hover{color:#66b1ff}.el-link.el-link--primary.is-disabled{color:#a0cfff}.el-link.el-link--danger.is-underline:hover:after,.el-link.el-link--danger:after{border-color:#f56c6c}.el-link.el-link--danger{color:#f56c6c}.el-link.el-link--danger:hover{color:#f78989}.el-link.el-link--danger.is-disabled{color:#fab6b6}.el-link.el-link--success.is-underline:hover:after,.el-link.el-link--success:after{border-color:#67c23a}.el-link.el-link--success{color:#67c23a}.el-link.el-link--success:hover{color:#85ce61}.el-link.el-link--success.is-disabled{color:#b3e19d}.el-link.el-link--warning.is-underline:hover:after,.el-link.el-link--warning:after{border-color:#e6a23c}.el-link.el-link--warning{color:#e6a23c}.el-link.el-link--warning:hover{color:#ebb563}.el-link.el-link--warning.is-disabled{color:#f3d19e}.el-link.el-link--info.is-underline:hover:after,.el-link.el-link--info:after{border-color:#909399}.el-link.el-link--info{color:#909399}.el-link.el-link--info:hover{color:#a6a9ad}.el-link.el-link--info.is-disabled{color:#c8c9cc}.el-divider{background-color:#dcdfe6;position:relative}.el-divider--horizontal{display:block;height:1px;width:100%;margin:24px 0}.el-divider--vertical{display:inline-block;width:1px;height:1em;margin:0 8px;vertical-align:middle;position:relative}.el-divider__text{position:absolute;background-color:#fff;padding:0 20px;color:#303133}.el-image__error,.el-image__placeholder{background:#f5f7fa}.el-divider__text.is-left{left:20px;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-divider__text.is-center{left:50%;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%)}.el-divider__text.is-right{right:20px;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-image__error,.el-image__inner,.el-image__placeholder{width:100%;height:100%}.el-image{position:relative;display:inline-block;overflow:hidden}.el-image__inner{vertical-align:top}.el-image__inner--center{position:relative;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);display:block}.el-image__error{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:14px;color:#c0c4cc;vertical-align:middle}.el-image__preview{cursor:pointer}.el-image-viewer__wrapper{position:fixed;top:0;right:0;bottom:0;left:0}.el-image-viewer__btn{position:absolute;z-index:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;border-radius:50%;opacity:.8;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.el-image-viewer__close{top:40px;right:40px;width:40px;height:40px;font-size:40px}.el-image-viewer__canvas{width:100%;height:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-image-viewer__actions{left:50%;bottom:30px;-webkit-transform:translateX(-50%);transform:translateX(-50%);width:282px;height:44px;padding:0 23px;background-color:#606266;border-color:#fff;border-radius:22px}.el-image-viewer__actions__inner{width:100%;height:100%;text-align:justify;cursor:default;font-size:23px;color:#fff;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-pack:distribute;justify-content:space-around}.el-image-viewer__next,.el-image-viewer__prev{top:50%;width:44px;height:44px;font-size:24px;color:#fff;background-color:#606266;border-color:#fff}.el-image-viewer__prev{left:40px}.el-image-viewer__next,.el-image-viewer__prev{-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-image-viewer__next{right:40px;text-indent:2px}.el-image-viewer__mask{position:absolute;width:100%;height:100%;top:0;left:0;opacity:.5;background:#000}.viewer-fade-enter-active{-webkit-animation:viewer-fade-in .3s;animation:viewer-fade-in .3s}.viewer-fade-leave-active{-webkit-animation:viewer-fade-out .3s;animation:viewer-fade-out .3s}@-webkit-keyframes viewer-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes viewer-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@-webkit-keyframes viewer-fade-out{0%{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}to{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes viewer-fade-out{0%{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}to{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.el-calendar{background-color:#fff}.el-calendar__header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:12px 20px;border-bottom:1px solid #ebeef5}.el-backtop,.el-page-header{display:-webkit-box;display:-ms-flexbox}.el-calendar__title{color:#000;-ms-flex-item-align:center;align-self:center}.el-calendar__body{padding:12px 20px 35px}.el-calendar-table{table-layout:fixed;width:100%}.el-calendar-table thead th{padding:12px 0;color:#606266;font-weight:400}.el-calendar-table:not(.is-range) td.next,.el-calendar-table:not(.is-range) td.prev{color:#c0c4cc}.el-backtop,.el-calendar-table td.is-today{color:#409eff}.el-calendar-table td{border-bottom:1px solid #ebeef5;border-right:1px solid #ebeef5;vertical-align:top;-webkit-transition:background-color .2s ease;transition:background-color .2s ease}.el-calendar-table td.is-selected{background-color:#f2f8fe}.el-calendar-table tr:first-child td{border-top:1px solid #ebeef5}.el-calendar-table tr td:first-child{border-left:1px solid #ebeef5}.el-calendar-table tr.el-calendar-table__row--hide-border td{border-top:none}.el-calendar-table .el-calendar-day{-webkit-box-sizing:border-box;box-sizing:border-box;padding:8px;height:85px}.el-calendar-table .el-calendar-day:hover{cursor:pointer;background-color:#f2f8fe}.el-backtop{position:fixed;background-color:#fff;width:40px;height:40px;border-radius:50%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;font-size:20px;-webkit-box-shadow:0 0 6px rgba(0,0,0,.12);box-shadow:0 0 6px rgba(0,0,0,.12);cursor:pointer;z-index:5}.el-backtop:hover{background-color:#f2f6fc}.el-page-header{line-height:24px}.el-page-header,.el-page-header__left{display:-webkit-box;display:-ms-flexbox;display:flex}.el-page-header__left{cursor:pointer;margin-right:40px;position:relative}.el-page-header__left:after{content:"";position:absolute;width:1px;height:16px;right:-20px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);background-color:#dcdfe6}.el-checkbox,.el-checkbox__input{display:inline-block;position:relative;white-space:nowrap}.el-page-header__left .el-icon-back{font-size:18px;margin-right:6px;-ms-flex-item-align:center;align-self:center}.el-page-header__title{font-size:14px;font-weight:500}.el-page-header__content{font-size:18px;color:#303133}.el-checkbox{color:#606266;font-size:14px;cursor:pointer;user-select:none;margin-right:30px}.el-checkbox,.el-checkbox-button__inner,.el-radio{font-weight:500;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.el-checkbox.is-bordered{padding:9px 20px 9px 10px;border-radius:4px;border:1px solid #dcdfe6;-webkit-box-sizing:border-box;box-sizing:border-box;line-height:normal;height:40px}.el-checkbox.is-bordered.is-checked{border-color:#409eff}.el-checkbox.is-bordered.is-disabled{border-color:#ebeef5;cursor:not-allowed}.el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.el-checkbox.is-bordered.el-checkbox--medium{padding:7px 20px 7px 10px;border-radius:4px;height:36px}.el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__label{line-height:17px;font-size:14px}.el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__inner{height:14px;width:14px}.el-checkbox.is-bordered.el-checkbox--small{padding:5px 15px 5px 10px;border-radius:3px;height:32px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__label{line-height:15px;font-size:12px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner{height:12px;width:12px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner:after{height:6px;width:2px}.el-checkbox.is-bordered.el-checkbox--mini{padding:3px 15px 3px 10px;border-radius:3px;height:28px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__label{line-height:12px;font-size:12px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner{height:12px;width:12px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner:after{height:6px;width:2px}.el-checkbox__input{cursor:pointer;outline:0;line-height:1;vertical-align:middle}.el-checkbox__input.is-disabled .el-checkbox__inner{background-color:#edf2fc;border-color:#dcdfe6;cursor:not-allowed}.el-checkbox__input.is-disabled .el-checkbox__inner:after{cursor:not-allowed;border-color:#c0c4cc}.el-checkbox__input.is-disabled .el-checkbox__inner+.el-checkbox__label{cursor:not-allowed}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{background-color:#f2f6fc;border-color:#dcdfe6}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner:after{border-color:#c0c4cc}.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner{background-color:#f2f6fc;border-color:#dcdfe6}.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner:before{background-color:#c0c4cc;border-color:#c0c4cc}.el-checkbox__input.is-checked .el-checkbox__inner,.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#409eff;border-color:#409eff}.el-checkbox__input.is-disabled+span.el-checkbox__label{color:#c0c4cc;cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner:after{-webkit-transform:rotate(45deg) scaleY(1);transform:rotate(45deg) scaleY(1)}.el-checkbox__input.is-checked+.el-checkbox__label{color:#409eff}.el-checkbox__input.is-focus .el-checkbox__inner{border-color:#409eff}.el-checkbox__input.is-indeterminate .el-checkbox__inner:before{content:"";position:absolute;display:block;background-color:#fff;height:2px;-webkit-transform:scale(.5);transform:scale(.5);left:0;right:0;top:5px}.el-checkbox__input.is-indeterminate .el-checkbox__inner:after{display:none}.el-checkbox__inner{display:inline-block;position:relative;border:1px solid #dcdfe6;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box;width:14px;height:14px;background-color:#fff;z-index:1;-webkit-transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46)}.el-checkbox__inner:hover{border-color:#409eff}.el-checkbox__inner:after{-webkit-box-sizing:content-box;box-sizing:content-box;content:"";border:1px solid #fff;border-left:0;border-top:0;height:7px;left:4px;position:absolute;top:1px;-webkit-transform:rotate(45deg) scaleY(0);transform:rotate(45deg) scaleY(0);width:3px;-webkit-transition:-webkit-transform .15s ease-in .05s;transition:-webkit-transform .15s ease-in .05s;transition:transform .15s ease-in .05s;transition:transform .15s ease-in .05s,-webkit-transform .15s ease-in .05s;-webkit-transform-origin:center;transform-origin:center}.el-checkbox__original{opacity:0;outline:0;position:absolute;margin:0;width:0;height:0;z-index:-1}.el-checkbox-button,.el-checkbox-button__inner{display:inline-block;position:relative}.el-checkbox__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.el-checkbox:last-of-type{margin-right:0}.el-checkbox-button__inner{line-height:1;white-space:nowrap;vertical-align:middle;cursor:pointer;background:#fff;border:1px solid #dcdfe6;border-left:0;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);padding:12px 20px;font-size:14px;border-radius:0}.el-checkbox-button__inner.is-round{padding:12px 20px}.el-checkbox-button__inner:hover{color:#409eff}.el-checkbox-button__inner [class*=el-icon-]{line-height:.9}.el-radio,.el-radio__input{line-height:1;outline:0;white-space:nowrap}.el-checkbox-button__inner [class*=el-icon-]+span{margin-left:5px}.el-checkbox-button__original{opacity:0;outline:0;position:absolute;margin:0;z-index:-1}.el-radio,.el-radio__inner,.el-radio__input{position:relative;display:inline-block}.el-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#409eff;border-color:#409eff;-webkit-box-shadow:-1px 0 0 0 #8cc5ff;box-shadow:-1px 0 0 0 #8cc5ff}.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner{border-left-color:#409eff}.el-checkbox-button.is-disabled .el-checkbox-button__inner{color:#c0c4cc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#ebeef5;-webkit-box-shadow:none;box-shadow:none}.el-checkbox-button.is-disabled:first-child .el-checkbox-button__inner{border-left-color:#ebeef5}.el-checkbox-button:first-child .el-checkbox-button__inner{border-left:1px solid #dcdfe6;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.el-checkbox-button.is-focus .el-checkbox-button__inner{border-color:#409eff}.el-checkbox-button:last-child .el-checkbox-button__inner{border-radius:0 4px 4px 0}.el-checkbox-button--medium .el-checkbox-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.el-checkbox-button--medium .el-checkbox-button__inner.is-round{padding:10px 20px}.el-checkbox-button--small .el-checkbox-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.el-checkbox-button--small .el-checkbox-button__inner.is-round{padding:9px 15px}.el-checkbox-button--mini .el-checkbox-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.el-checkbox-button--mini .el-checkbox-button__inner.is-round{padding:7px 15px}.el-checkbox-group{font-size:0}.el-radio,.el-radio--medium.is-bordered .el-radio__label{font-size:14px}.el-radio{color:#606266;cursor:pointer;margin-right:30px}.el-cascader-node>.el-radio,.el-radio:last-child{margin-right:0}.el-radio.is-bordered{padding:12px 20px 0 10px;border-radius:4px;border:1px solid #dcdfe6;-webkit-box-sizing:border-box;box-sizing:border-box;height:40px}.el-radio.is-bordered.is-checked{border-color:#409eff}.el-radio.is-bordered.is-disabled{cursor:not-allowed;border-color:#ebeef5}.el-radio__input.is-disabled .el-radio__inner,.el-radio__input.is-disabled.is-checked .el-radio__inner{background-color:#f5f7fa;border-color:#e4e7ed}.el-radio.is-bordered+.el-radio.is-bordered{margin-left:10px}.el-radio--medium.is-bordered{padding:10px 20px 0 10px;border-radius:4px;height:36px}.el-radio--mini.is-bordered .el-radio__label,.el-radio--small.is-bordered .el-radio__label{font-size:12px}.el-radio--medium.is-bordered .el-radio__inner{height:14px;width:14px}.el-radio--small.is-bordered{padding:8px 15px 0 10px;border-radius:3px;height:32px}.el-radio--small.is-bordered .el-radio__inner{height:12px;width:12px}.el-radio--mini.is-bordered{padding:6px 15px 0 10px;border-radius:3px;height:28px}.el-radio--mini.is-bordered .el-radio__inner{height:12px;width:12px}.el-radio__input{cursor:pointer;vertical-align:middle}.el-radio__input.is-disabled .el-radio__inner{cursor:not-allowed}.el-radio__input.is-disabled .el-radio__inner:after{cursor:not-allowed;background-color:#f5f7fa}.el-radio__input.is-disabled .el-radio__inner+.el-radio__label{cursor:not-allowed}.el-radio__input.is-disabled.is-checked .el-radio__inner:after{background-color:#c0c4cc}.el-radio__input.is-disabled+span.el-radio__label{color:#c0c4cc;cursor:not-allowed}.el-radio__input.is-checked .el-radio__inner{border-color:#409eff;background:#409eff}.el-radio__input.is-checked .el-radio__inner:after{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}.el-radio__input.is-checked+.el-radio__label{color:#409eff}.el-radio__input.is-focus .el-radio__inner{border-color:#409eff}.el-radio__inner{border:1px solid #dcdfe6;border-radius:100%;width:14px;height:14px;background-color:#fff;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box}.el-radio__inner:hover{border-color:#409eff}.el-radio__inner:after{width:4px;height:4px;border-radius:100%;background-color:#fff;content:"";position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%) scale(0);transform:translate(-50%,-50%) scale(0);-webkit-transition:-webkit-transform .15s ease-in;transition:-webkit-transform .15s ease-in;transition:transform .15s ease-in;transition:transform .15s ease-in,-webkit-transform .15s ease-in}.el-radio__original{opacity:0;outline:0;position:absolute;z-index:-1;top:0;left:0;right:0;bottom:0;margin:0}.el-radio:focus:not(.is-focus):not(:active):not(.is-disabled) .el-radio__inner{-webkit-box-shadow:0 0 2px 2px #409eff;box-shadow:0 0 2px 2px #409eff}.el-radio__label{font-size:14px;padding-left:10px}.el-scrollbar{overflow:hidden;position:relative}.el-scrollbar:active>.el-scrollbar__bar,.el-scrollbar:focus>.el-scrollbar__bar,.el-scrollbar:hover>.el-scrollbar__bar{opacity:1;-webkit-transition:opacity .34s ease-out;transition:opacity .34s ease-out}.el-scrollbar__wrap{overflow:scroll;height:100%}.el-scrollbar__wrap--hidden-default::-webkit-scrollbar{width:0;height:0}.el-scrollbar__thumb{position:relative;display:block;width:0;height:0;cursor:pointer;border-radius:inherit;background-color:rgba(144,147,153,.3);-webkit-transition:background-color .3s;transition:background-color .3s}.el-scrollbar__thumb:hover{background-color:rgba(144,147,153,.5)}.el-scrollbar__bar{position:absolute;right:2px;bottom:2px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity .12s ease-out;transition:opacity .12s ease-out}.el-scrollbar__bar.is-vertical{width:6px;top:2px}.el-scrollbar__bar.is-vertical>div{width:100%}.el-scrollbar__bar.is-horizontal{height:6px;left:2px}.el-scrollbar__bar.is-horizontal>div{height:100%}.el-cascader-panel{display:-webkit-box;display:-ms-flexbox;display:flex;border-radius:4px;font-size:14px}.el-cascader-node,.el-drawer{display:-webkit-box;display:-ms-flexbox}.el-cascader-panel.is-bordered{border:1px solid #e4e7ed;border-radius:4px}.el-cascader-menu{min-width:180px;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;border-right:1px solid #e4e7ed}.el-cascader-menu:last-child{border-right:none}.el-cascader-menu:last-child .el-cascader-node{padding-right:20px}.el-cascader-menu__wrap{height:204px}.el-cascader-menu__list{position:relative;min-height:100%;margin:0;padding:6px 0;list-style:none;-webkit-box-sizing:border-box;box-sizing:border-box}.el-avatar,.el-drawer{-webkit-box-sizing:border-box;overflow:hidden}.el-cascader-menu__hover-zone{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none}.el-cascader-menu__empty-text{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);text-align:center;color:#c0c4cc}.el-cascader-node{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:0 30px 0 20px;height:34px;line-height:34px;outline:0}.el-cascader-node.is-selectable.in-active-path{color:#606266}.el-cascader-node.in-active-path,.el-cascader-node.is-active,.el-cascader-node.is-selectable.in-checked-path{color:#409eff;font-weight:700}.el-cascader-node:not(.is-disabled){cursor:pointer}.el-cascader-node:not(.is-disabled):focus,.el-cascader-node:not(.is-disabled):hover{background:#f5f7fa}.el-cascader-node.is-disabled{color:#c0c4cc;cursor:not-allowed}.el-cascader-node__prefix{position:absolute;left:10px}.el-cascader-node__postfix{position:absolute;right:10px}.el-cascader-node__label{-webkit-box-flex:1;-ms-flex:1;flex:1;padding:0 10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.el-cascader-node>.el-radio .el-radio__label{padding-left:0}.el-avatar{display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;color:#fff;background:#c0c4cc;width:40px;height:40px;line-height:40px;font-size:14px}.el-avatar>img{display:block;height:100%;vertical-align:middle}.el-avatar--circle{border-radius:50%}.el-avatar--square{border-radius:4px}.el-avatar--icon{font-size:18px}.el-avatar--large{width:40px;height:40px;line-height:40px}.el-avatar--medium{width:36px;height:36px;line-height:36px}.el-avatar--small{width:28px;height:28px;line-height:28px}.el-drawer.btt,.el-drawer.ttb,.el-drawer__container{left:0;right:0;width:100%}.el-drawer.ltr,.el-drawer.rtl,.el-drawer__container{top:0;bottom:0;height:100%}@-webkit-keyframes el-drawer-fade-in{0%{opacity:0}to{opacity:1}}@keyframes el-drawer-fade-in{0%{opacity:0}to{opacity:1}}@-webkit-keyframes rtl-drawer-in{0%{-webkit-transform:translate(100%);transform:translate(100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@keyframes rtl-drawer-in{0%{-webkit-transform:translate(100%);transform:translate(100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@-webkit-keyframes rtl-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translate(100%);transform:translate(100%)}}@keyframes rtl-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translate(100%);transform:translate(100%)}}@-webkit-keyframes ltr-drawer-in{0%{-webkit-transform:translate(-100%);transform:translate(-100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@keyframes ltr-drawer-in{0%{-webkit-transform:translate(-100%);transform:translate(-100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@-webkit-keyframes ltr-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translate(-100%);transform:translate(-100%)}}@keyframes ltr-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translate(-100%);transform:translate(-100%)}}@-webkit-keyframes ttb-drawer-in{0%{-webkit-transform:translateY(-100%);transform:translateY(-100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@keyframes ttb-drawer-in{0%{-webkit-transform:translateY(-100%);transform:translateY(-100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@-webkit-keyframes ttb-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@keyframes ttb-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@-webkit-keyframes btt-drawer-in{0%{-webkit-transform:translateY(100%);transform:translateY(100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@keyframes btt-drawer-in{0%{-webkit-transform:translateY(100%);transform:translateY(100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@-webkit-keyframes btt-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translateY(100%);transform:translateY(100%)}}@keyframes btt-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translateY(100%);transform:translateY(100%)}}.el-drawer{position:absolute;-webkit-box-sizing:border-box;box-sizing:border-box;background-color:#fff;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-ms-flex-direction:column;flex-direction:column;-webkit-box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12)}.el-drawer.rtl{-webkit-animation:rtl-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;animation:rtl-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;right:0}.el-drawer__open .el-drawer.rtl{-webkit-animation:rtl-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s;animation:rtl-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s}.el-drawer.ltr{-webkit-animation:ltr-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;animation:ltr-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;left:0}.el-drawer__open .el-drawer.ltr{-webkit-animation:ltr-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s;animation:ltr-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s}.el-drawer.ttb{-webkit-animation:ttb-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;animation:ttb-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;top:0}.el-drawer__open .el-drawer.ttb{-webkit-animation:ttb-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s;animation:ttb-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s}.el-drawer.btt{-webkit-animation:btt-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;animation:btt-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;bottom:0}.el-drawer__open .el-drawer.btt{-webkit-animation:btt-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s;animation:btt-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s}.el-drawer__header{-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#72767b;display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:32px;padding:20px 20px 0}.el-drawer__header>:first-child,.el-drawer__title{-webkit-box-flex:1;-ms-flex:1;flex:1}.el-drawer__title{margin:0;line-height:inherit;font-size:1rem}.el-drawer__close-btn{border:none;cursor:pointer;font-size:20px;color:inherit;background-color:transparent}.el-drawer__body{-webkit-box-flex:1;-ms-flex:1;flex:1}.el-drawer__body>*{-webkit-box-sizing:border-box;box-sizing:border-box}.el-drawer__container{position:relative}.el-drawer-fade-enter-active{-webkit-animation:el-drawer-fade-in 225ms cubic-bezier(0,0,.2,1) 0s;animation:el-drawer-fade-in 225ms cubic-bezier(0,0,.2,1) 0s}.el-drawer-fade-leave-active{animation:el-drawer-fade-in 225ms cubic-bezier(0,0,.2,1) 0s reverse} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/fonts/element-icons.535877f5.woff" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/fonts/element-icons.535877f5.woff" new file mode 100644 index 0000000000000000000000000000000000000000..02b9a2539e425a7a8c244faba92527602be76212 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/fonts/element-icons.535877f5.woff" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/fonts/element-icons.732389de.ttf" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/fonts/element-icons.732389de.ttf" new file mode 100644 index 0000000000000000000000000000000000000000..91b74de36778b0ff8958d37d07ce70fb3b26f50b Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/fonts/element-icons.732389de.ttf" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/js/app.1966d06f.js" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/js/app.1966d06f.js" new file mode 100644 index 0000000000000000000000000000000000000000..32c891583272c37ab2ad66120f9212709597c019 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/js/app.1966d06f.js" @@ -0,0 +1 @@ +(function(e){function t(t){for(var o,s,i=t[0],l=t[1],c=t[2],d=0,f=[];d ").concat(o),type:"success"})}))},handleDelete:function(e,t){var n=this;this.axios.delete("/v1/todo/"+t).then((function(){n.tableData.splice(e,1),n.$message({showClose:!0,duration:1500,message:"删除待办事项成功",type:"success"})}))},handleAdd:function(){var e=this;""!=this.newTitle?(this.axios.post("/v1/todo",{title:this.newTitle}).then((function(){e.getTodoList(),e.$message({showClose:!0,duration:1500,message:"添加待办事项成功",type:"success"})})),this.newTitle=""):this.$message({showClose:!0,duration:1500,message:"title不能为空哦",type:"warning"})}}}),v=h,w=(n("ed30"),n("2877")),b=Object(w["a"])(v,f,p,!1,null,null,null),m=b.exports,g={name:"Index",components:{TodoList:m}},x=g,y=(n("8fc1"),Object(w["a"])(x,u,d,!1,null,null,null)),j=y.exports,_={name:"app",components:{Index:j}},O=_,T=(n("034f"),Object(w["a"])(O,l,c,!1,null,null,null)),P=T.exports,$=n("5c96"),k=n.n($);n("0fae");o["default"].use(k.a);var C=n("8c4f");o["default"].use(C["a"]);var D=[{path:"/",name:"index",component:j}],S=new C["a"]({routes:D}),E=S;o["default"].config.productionTip=!0,new o["default"]({router:E,render:function(e){return e(P)}}).$mount("#app")},"85ec":function(e,t,n){},"89d2":function(e,t,n){},"8fc1":function(e,t,n){"use strict";var o=n("9272"),r=n.n(o);r.a},9272:function(e,t,n){},ed30:function(e,t,n){"use strict";var o=n("89d2"),r=n.n(o);r.a}}); \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/js/chunk-vendors.ddcb6f91.js" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/js/chunk-vendors.ddcb6f91.js" new file mode 100644 index 0000000000000000000000000000000000000000..0eaef8681e553bc6eb12237a6d045ce0ea5cb5e6 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/static/js/chunk-vendors.ddcb6f91.js" @@ -0,0 +1,34 @@ +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-vendors"],{"03d6":function(e,t,n){var i=n("9c0e"),r=n("6ca1"),o=n("39ad")(!1),a=n("5a94")("IE_PROTO");e.exports=function(e,t){var n,s=r(e),l=0,c=[];for(n in s)n!=a&&i(s,n)&&c.push(n);while(t.length>l)i(s,n=t[l++])&&(~o(c,n)||c.push(n));return c}},"051b":function(e,t,n){var i=n("1a14"),r=n("10db");e.exports=n("0bad")?function(e,t,n){return i.f(e,t,r(1,n))}:function(e,t,n){return e[t]=n,e}},"05f5":function(e,t,n){var i=n("7a41"),r=n("ef08").document,o=i(r)&&i(r.createElement);e.exports=function(e){return o?r.createElement(e):{}}},"06cf":function(e,t,n){var i=n("83ab"),r=n("d1e7"),o=n("5c6c"),a=n("fc6a"),s=n("c04e"),l=n("5135"),c=n("0cfb"),u=Object.getOwnPropertyDescriptor;t.f=i?u:function(e,t){if(e=a(e),t=s(t,!0),c)try{return u(e,t)}catch(n){}if(l(e,t))return o(!r.f.call(e,t),e[t])}},"072d":function(e,t,n){"use strict";var i=n("0bad"),r=n("9876"),o=n("fed5"),a=n("1917"),s=n("0983"),l=n("9fbb"),c=Object.assign;e.exports=!c||n("4b8b")((function(){var e={},t={},n=Symbol(),i="abcdefghijklmnopqrst";return e[n]=7,i.split("").forEach((function(e){t[e]=e})),7!=c({},e)[n]||Object.keys(c({},t)).join("")!=i}))?function(e,t){var n=s(e),c=arguments.length,u=1,d=o.f,h=a.f;while(c>u){var f,p=l(arguments[u++]),m=d?r(p).concat(d(p)):r(p),v=m.length,g=0;while(v>g)f=m[g++],i&&!h.call(p,f)||(n[f]=p[f])}return n}:c},"0983":function(e,t,n){var i=n("c901");e.exports=function(e){return Object(i(e))}},"0a06":function(e,t,n){"use strict";var i=n("2444"),r=n("c532"),o=n("f6b4"),a=n("5270");function s(e){this.defaults=e,this.interceptors={request:new o,response:new o}}s.prototype.request=function(e){"string"===typeof e&&(e=r.merge({url:arguments[0]},arguments[1])),e=r.merge(i,{method:"get"},this.defaults,e),e.method=e.method.toLowerCase();var t=[a,void 0],n=Promise.resolve(e);this.interceptors.request.forEach((function(e){t.unshift(e.fulfilled,e.rejected)})),this.interceptors.response.forEach((function(e){t.push(e.fulfilled,e.rejected)}));while(t.length)n=n.then(t.shift(),t.shift());return n},r.forEach(["delete","get","head","options"],(function(e){s.prototype[e]=function(t,n){return this.request(r.merge(n||{},{method:e,url:t}))}})),r.forEach(["post","put","patch"],(function(e){s.prototype[e]=function(t,n,i){return this.request(r.merge(i||{},{method:e,url:t,data:n}))}})),e.exports=s},"0ae2":function(e,t,n){var i=n("9876"),r=n("fed5"),o=n("1917");e.exports=function(e){var t=i(e),n=r.f;if(n){var a,s=n(e),l=o.f,c=0;while(s.length>c)l.call(e,a=s[c++])&&t.push(a)}return t}},"0b99":function(e,t,n){"use strict";var i=n("19fa")(!0);n("393a")(String,"String",(function(e){this._t=String(e),this._i=0}),(function(){var e,t=this._t,n=this._i;return n>=t.length?{value:void 0,done:!0}:(e=i(t,n),this._i+=e.length,{value:e,done:!1})}))},"0bad":function(e,t,n){e.exports=!n("4b8b")((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},"0cfb":function(e,t,n){var i=n("83ab"),r=n("d039"),o=n("cc12");e.exports=!i&&!r((function(){return 7!=Object.defineProperty(o("div"),"a",{get:function(){return 7}}).a}))},"0df6":function(e,t,n){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}},"0e15":function(e,t,n){var i=n("597f");e.exports=function(e,t,n){return void 0===n?i(e,t,!1):i(e,n,!1!==t)}},"0fae":function(e,t,n){},1098:function(e,t,n){"use strict";t.__esModule=!0;var i=n("17ed"),r=l(i),o=n("f893"),a=l(o),s="function"===typeof a.default&&"symbol"===typeof r.default?function(e){return typeof e}:function(e){return e&&"function"===typeof a.default&&e.constructor===a.default&&e!==a.default.prototype?"symbol":typeof e};function l(e){return e&&e.__esModule?e:{default:e}}t.default="function"===typeof a.default&&"symbol"===s(r.default)?function(e){return"undefined"===typeof e?"undefined":s(e)}:function(e){return e&&"function"===typeof a.default&&e.constructor===a.default&&e!==a.default.prototype?"symbol":"undefined"===typeof e?"undefined":s(e)}},"10db":function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},"12f2":function(e,t,n){"use strict";t.__esModule=!0,t.default=function(e){return{methods:{focus:function(){this.$refs[e].focus()}}}}},"14e9":function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=122)}({122:function(e,t,n){"use strict";n.r(t);var i=n(15),r=n(37),o=n.n(r),a=n(3),s=n(2),l={vertical:{offset:"offsetHeight",scroll:"scrollTop",scrollSize:"scrollHeight",size:"height",key:"vertical",axis:"Y",client:"clientY",direction:"top"},horizontal:{offset:"offsetWidth",scroll:"scrollLeft",scrollSize:"scrollWidth",size:"width",key:"horizontal",axis:"X",client:"clientX",direction:"left"}};function c(e){var t=e.move,n=e.size,i=e.bar,r={},o="translate"+i.axis+"("+t+"%)";return r[i.size]=n,r.transform=o,r.msTransform=o,r.webkitTransform=o,r}var u={name:"Bar",props:{vertical:Boolean,size:String,move:Number},computed:{bar:function(){return l[this.vertical?"vertical":"horizontal"]},wrap:function(){return this.$parent.wrap}},render:function(e){var t=this.size,n=this.move,i=this.bar;return e("div",{class:["el-scrollbar__bar","is-"+i.key],on:{mousedown:this.clickTrackHandler}},[e("div",{ref:"thumb",class:"el-scrollbar__thumb",on:{mousedown:this.clickThumbHandler},style:c({size:t,move:n,bar:i})})])},methods:{clickThumbHandler:function(e){e.ctrlKey||2===e.button||(this.startDrag(e),this[this.bar.axis]=e.currentTarget[this.bar.offset]-(e[this.bar.client]-e.currentTarget.getBoundingClientRect()[this.bar.direction]))},clickTrackHandler:function(e){var t=Math.abs(e.target.getBoundingClientRect()[this.bar.direction]-e[this.bar.client]),n=this.$refs.thumb[this.bar.offset]/2,i=100*(t-n)/this.$el[this.bar.offset];this.wrap[this.bar.scroll]=i*this.wrap[this.bar.scrollSize]/100},startDrag:function(e){e.stopImmediatePropagation(),this.cursorDown=!0,Object(s["on"])(document,"mousemove",this.mouseMoveDocumentHandler),Object(s["on"])(document,"mouseup",this.mouseUpDocumentHandler),document.onselectstart=function(){return!1}},mouseMoveDocumentHandler:function(e){if(!1!==this.cursorDown){var t=this[this.bar.axis];if(t){var n=-1*(this.$el.getBoundingClientRect()[this.bar.direction]-e[this.bar.client]),i=this.$refs.thumb[this.bar.offset]-t,r=100*(n-i)/this.$el[this.bar.offset];this.wrap[this.bar.scroll]=r*this.wrap[this.bar.scrollSize]/100}}},mouseUpDocumentHandler:function(e){this.cursorDown=!1,this[this.bar.axis]=0,Object(s["off"])(document,"mousemove",this.mouseMoveDocumentHandler),document.onselectstart=null}},destroyed:function(){Object(s["off"])(document,"mouseup",this.mouseUpDocumentHandler)}},d={name:"ElScrollbar",components:{Bar:u},props:{native:Boolean,wrapStyle:{},wrapClass:{},viewClass:{},viewStyle:{},noresize:Boolean,tag:{type:String,default:"div"}},data:function(){return{sizeWidth:"0",sizeHeight:"0",moveX:0,moveY:0}},computed:{wrap:function(){return this.$refs.wrap}},render:function(e){var t=o()(),n=this.wrapStyle;if(t){var i="-"+t+"px",r="margin-bottom: "+i+"; margin-right: "+i+";";Array.isArray(this.wrapStyle)?(n=Object(a["toObject"])(this.wrapStyle),n.marginRight=n.marginBottom=i):"string"===typeof this.wrapStyle?n+=r:n=r}var s=e(this.tag,{class:["el-scrollbar__view",this.viewClass],style:this.viewStyle,ref:"resize"},this.$slots.default),l=e("div",{ref:"wrap",style:n,on:{scroll:this.handleScroll},class:[this.wrapClass,"el-scrollbar__wrap",t?"":"el-scrollbar__wrap--hidden-default"]},[[s]]),c=void 0;return c=this.native?[e("div",{ref:"wrap",class:[this.wrapClass,"el-scrollbar__wrap"],style:n},[[s]])]:[l,e(u,{attrs:{move:this.moveX,size:this.sizeWidth}}),e(u,{attrs:{vertical:!0,move:this.moveY,size:this.sizeHeight}})],e("div",{class:"el-scrollbar"},c)},methods:{handleScroll:function(){var e=this.wrap;this.moveY=100*e.scrollTop/e.clientHeight,this.moveX=100*e.scrollLeft/e.clientWidth},update:function(){var e=void 0,t=void 0,n=this.wrap;n&&(e=100*n.clientHeight/n.scrollHeight,t=100*n.clientWidth/n.scrollWidth,this.sizeHeight=e<100?e+"%":"",this.sizeWidth=t<100?t+"%":"")}},mounted:function(){this.native||(this.$nextTick(this.update),!this.noresize&&Object(i["addResizeListener"])(this.$refs.resize,this.update))},beforeDestroy:function(){this.native||!this.noresize&&Object(i["removeResizeListener"])(this.$refs.resize,this.update)},install:function(e){e.component(d.name,d)}};t["default"]=d},15:function(e,t){e.exports=n("4010")},2:function(e,t){e.exports=n("5924")},3:function(e,t){e.exports=n("8122")},37:function(e,t){e.exports=n("e62d")}})},1609:function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},"17ed":function(e,t,n){e.exports={default:n("511f"),__esModule:!0}},1836:function(e,t,n){var i=n("6ca1"),r=n("6438").f,o={}.toString,a="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(e){try{return r(e)}catch(t){return a.slice()}};e.exports.f=function(e){return a&&"[object Window]"==o.call(e)?s(e):r(i(e))}},1917:function(e,t){t.f={}.propertyIsEnumerable},"19aa":function(e,t){e.exports=function(e,t,n){if(!(e instanceof t))throw TypeError("Incorrect "+(n?n+" ":"")+"invocation");return e}},"19fa":function(e,t,n){var i=n("fc5e"),r=n("c901");e.exports=function(e){return function(t,n){var o,a,s=String(r(t)),l=i(n),c=s.length;return l<0||l>=c?e?"":void 0:(o=s.charCodeAt(l),o<55296||o>56319||l+1===c||(a=s.charCodeAt(l+1))<56320||a>57343?e?s.charAt(l):o:e?s.slice(l,l+2):a-56320+(o-55296<<10)+65536)}}},"1a14":function(e,t,n){var i=n("77e9"),r=n("faf5"),o=n("3397"),a=Object.defineProperty;t.f=n("0bad")?Object.defineProperty:function(e,t,n){if(i(e),t=o(t,!0),i(n),r)try{return a(e,t,n)}catch(s){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},"1be4":function(e,t,n){var i=n("d066");e.exports=i("document","documentElement")},"1c0b":function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(String(e)+" is not a function");return e}},"1c7e":function(e,t,n){var i=n("b622"),r=i("iterator"),o=!1;try{var a=0,s={next:function(){return{done:!!a++}},return:function(){o=!0}};s[r]=function(){return this},Array.from(s,(function(){throw 2}))}catch(l){}e.exports=function(e,t){if(!t&&!o)return!1;var n=!1;try{var i={};i[r]=function(){return{next:function(){return{done:n=!0}}}},e(i)}catch(l){}return n}},"1d2b":function(e,t,n){"use strict";e.exports=function(e,t){return function(){for(var n=new Array(arguments.length),i=0;i=51||!i((function(){var t=[],n=t.constructor={};return n[a]=function(){return{foo:1}},1!==t[e](Boolean).foo}))}},2266:function(e,t,n){var i=n("825a"),r=n("e95a"),o=n("50c4"),a=n("f8c2"),s=n("35a1"),l=n("9bdd"),c=function(e,t){this.stopped=e,this.result=t},u=e.exports=function(e,t,n,u,d){var h,f,p,m,v,g,b,y=a(t,n,u?2:1);if(d)h=e;else{if(f=s(e),"function"!=typeof f)throw TypeError("Target is not iterable");if(r(f)){for(p=0,m=o(e.length);m>p;p++)if(v=u?y(i(b=e[p])[0],b[1]):y(e[p]),v&&v instanceof c)return v;return new c(!1)}h=f.call(e)}g=h.next;while(!(b=g.call(h)).done)if(v=l(h,y,b.value,u),"object"==typeof v&&v&&v instanceof c)return v;return new c(!1)};u.stop=function(e){return new c(!0,e)}},"23cb":function(e,t,n){var i=n("a691"),r=Math.max,o=Math.min;e.exports=function(e,t){var n=i(e);return n<0?r(n+t,0):o(n,t)}},"23e7":function(e,t,n){var i=n("da84"),r=n("06cf").f,o=n("9112"),a=n("6eeb"),s=n("ce4e"),l=n("e893"),c=n("94ca");e.exports=function(e,t){var n,u,d,h,f,p,m=e.target,v=e.global,g=e.stat;if(u=v?i:g?i[m]||s(m,{}):(i[m]||{}).prototype,u)for(d in t){if(f=t[d],e.noTargetGet?(p=r(u,d),h=p&&p.value):h=u[d],n=c(v?d:m+(g?".":"#")+d,e.forced),!n&&void 0!==h){if(typeof f===typeof h)continue;l(f,h)}(e.sham||h&&h.sham)&&o(f,"sham",!0),a(u,d,f,e)}}},"241c":function(e,t,n){var i=n("ca84"),r=n("7839"),o=r.concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return i(e,o)}},2444:function(e,t,n){"use strict";(function(t){var i=n("c532"),r=n("c8af"),o={"Content-Type":"application/x-www-form-urlencoded"};function a(e,t){!i.isUndefined(e)&&i.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}function s(){var e;return"undefined"!==typeof XMLHttpRequest?e=n("b50d"):"undefined"!==typeof t&&(e=n("b50d")),e}var l={adapter:s(),transformRequest:[function(e,t){return r(t,"Content-Type"),i.isFormData(e)||i.isArrayBuffer(e)||i.isBuffer(e)||i.isStream(e)||i.isFile(e)||i.isBlob(e)?e:i.isArrayBufferView(e)?e.buffer:i.isURLSearchParams(e)?(a(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):i.isObject(e)?(a(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"===typeof e)try{e=JSON.parse(e)}catch(t){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*"}}};i.forEach(["delete","get","head"],(function(e){l.headers[e]={}})),i.forEach(["post","put","patch"],(function(e){l.headers[e]=i.merge(o)})),e.exports=l}).call(this,n("4362"))},2626:function(e,t,n){"use strict";var i=n("d066"),r=n("9bf2"),o=n("b622"),a=n("83ab"),s=o("species");e.exports=function(e){var t=i(e),n=r.f;a&&t&&!t[s]&&n(t,s,{configurable:!0,get:function(){return this}})}},"26dd":function(e,t,n){"use strict";var i=n("6f4f"),r=n("10db"),o=n("92f0"),a={};n("051b")(a,n("cc15")("iterator"),(function(){return this})),e.exports=function(e,t,n){e.prototype=i(a,{next:r(1,n)}),o(e,t+" Iterator")}},2877:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},"299c":function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=129)}({129:function(e,t,n){"use strict";n.r(t);var i=n(5),r=n.n(i),o=n(16),a=n.n(o),s=n(2),l=n(3),c=n(7),u=n.n(c),d={name:"ElTooltip",mixins:[r.a],props:{openDelay:{type:Number,default:0},disabled:Boolean,manual:Boolean,effect:{type:String,default:"dark"},arrowOffset:{type:Number,default:0},popperClass:String,content:String,visibleArrow:{default:!0},transition:{type:String,default:"el-fade-in-linear"},popperOptions:{default:function(){return{boundariesPadding:10,gpuAcceleration:!1}}},enterable:{type:Boolean,default:!0},hideAfter:{type:Number,default:0},tabindex:{type:Number,default:0}},data:function(){return{tooltipId:"el-tooltip-"+Object(l["generateId"])(),timeoutPending:null,focusing:!1}},beforeCreate:function(){var e=this;this.$isServer||(this.popperVM=new u.a({data:{node:""},render:function(e){return this.node}}).$mount(),this.debounceClose=a()(200,(function(){return e.handleClosePopper()})))},render:function(e){var t=this;this.popperVM&&(this.popperVM.node=e("transition",{attrs:{name:this.transition},on:{afterLeave:this.doDestroy}},[e("div",{on:{mouseleave:function(){t.setExpectedState(!1),t.debounceClose()},mouseenter:function(){t.setExpectedState(!0)}},ref:"popper",attrs:{role:"tooltip",id:this.tooltipId,"aria-hidden":this.disabled||!this.showPopper?"true":"false"},directives:[{name:"show",value:!this.disabled&&this.showPopper}],class:["el-tooltip__popper","is-"+this.effect,this.popperClass]},[this.$slots.content||this.content])]));var n=this.getFirstElement();if(!n)return null;var i=n.data=n.data||{};return i.staticClass=this.addTooltipClass(i.staticClass),n},mounted:function(){var e=this;this.referenceElm=this.$el,1===this.$el.nodeType&&(this.$el.setAttribute("aria-describedby",this.tooltipId),this.$el.setAttribute("tabindex",this.tabindex),Object(s["on"])(this.referenceElm,"mouseenter",this.show),Object(s["on"])(this.referenceElm,"mouseleave",this.hide),Object(s["on"])(this.referenceElm,"focus",(function(){if(e.$slots.default&&e.$slots.default.length){var t=e.$slots.default[0].componentInstance;t&&t.focus?t.focus():e.handleFocus()}else e.handleFocus()})),Object(s["on"])(this.referenceElm,"blur",this.handleBlur),Object(s["on"])(this.referenceElm,"click",this.removeFocusing)),this.value&&this.popperVM&&this.popperVM.$nextTick((function(){e.value&&e.updatePopper()}))},watch:{focusing:function(e){e?Object(s["addClass"])(this.referenceElm,"focusing"):Object(s["removeClass"])(this.referenceElm,"focusing")}},methods:{show:function(){this.setExpectedState(!0),this.handleShowPopper()},hide:function(){this.setExpectedState(!1),this.debounceClose()},handleFocus:function(){this.focusing=!0,this.show()},handleBlur:function(){this.focusing=!1,this.hide()},removeFocusing:function(){this.focusing=!1},addTooltipClass:function(e){return e?"el-tooltip "+e.replace("el-tooltip",""):"el-tooltip"},handleShowPopper:function(){var e=this;this.expectedState&&!this.manual&&(clearTimeout(this.timeout),this.timeout=setTimeout((function(){e.showPopper=!0}),this.openDelay),this.hideAfter>0&&(this.timeoutPending=setTimeout((function(){e.showPopper=!1}),this.hideAfter)))},handleClosePopper:function(){this.enterable&&this.expectedState||this.manual||(clearTimeout(this.timeout),this.timeoutPending&&clearTimeout(this.timeoutPending),this.showPopper=!1,this.disabled&&this.doDestroy())},setExpectedState:function(e){!1===e&&clearTimeout(this.timeoutPending),this.expectedState=e},getFirstElement:function(){var e=this.$slots.default;if(!Array.isArray(e))return null;for(var t=null,n=0;nl&&(e.scrollTop=a-e.clientHeight)}else e.scrollTop=0}},"2b0e":function(e,t,n){"use strict";n.r(t),function(e){ +/*! + * Vue.js v2.6.10 + * (c) 2014-2019 Evan You + * Released under the MIT License. + */ +var n=Object.freeze({});function i(e){return void 0===e||null===e}function r(e){return void 0!==e&&null!==e}function o(e){return!0===e}function a(e){return!1===e}function s(e){return"string"===typeof e||"number"===typeof e||"symbol"===typeof e||"boolean"===typeof e}function l(e){return null!==e&&"object"===typeof e}var c=Object.prototype.toString;function u(e){return"[object Object]"===c.call(e)}function d(e){return"[object RegExp]"===c.call(e)}function h(e){var t=parseFloat(String(e));return t>=0&&Math.floor(t)===t&&isFinite(e)}function f(e){return r(e)&&"function"===typeof e.then&&"function"===typeof e.catch}function p(e){return null==e?"":Array.isArray(e)||u(e)&&e.toString===c?JSON.stringify(e,null,2):String(e)}function m(e){var t=parseFloat(e);return isNaN(t)?e:t}function v(e,t){for(var n=Object.create(null),i=e.split(","),r=0;r-1)return e.splice(n,1)}}var y=Object.prototype.hasOwnProperty;function _(e,t){return y.call(e,t)}function x(e){var t=Object.create(null);return function(n){var i=t[n];return i||(t[n]=e(n))}}var w=/-(\w)/g,C=x((function(e){return e.replace(w,(function(e,t){return t?t.toUpperCase():""}))})),k=x((function(e){return e.charAt(0).toUpperCase()+e.slice(1)})),S=/\B([A-Z])/g,O=x((function(e){return e.replace(S,"-$1").toLowerCase()}));function $(e,t){function n(n){var i=arguments.length;return i?i>1?e.apply(t,arguments):e.call(t,n):e.call(t)}return n._length=e.length,n}function D(e,t){return e.bind(t)}var E=Function.prototype.bind?D:$;function T(e,t){t=t||0;var n=e.length-t,i=new Array(n);while(n--)i[n]=e[n+t];return i}function P(e,t){for(var n in t)e[n]=t[n];return e}function M(e){for(var t={},n=0;n0,ne=Q&&Q.indexOf("edge/")>0,ie=(Q&&Q.indexOf("android"),Q&&/iphone|ipad|ipod|ios/.test(Q)||"ios"===J),re=(Q&&/chrome\/\d+/.test(Q),Q&&/phantomjs/.test(Q),Q&&Q.match(/firefox\/(\d+)/)),oe={}.watch,ae=!1;if(X)try{var se={};Object.defineProperty(se,"passive",{get:function(){ae=!0}}),window.addEventListener("test-passive",null,se)}catch(Ca){}var le=function(){return void 0===K&&(K=!X&&!Z&&"undefined"!==typeof e&&(e["process"]&&"server"===e["process"].env.VUE_ENV)),K},ce=X&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function ue(e){return"function"===typeof e&&/native code/.test(e.toString())}var de,he="undefined"!==typeof Symbol&&ue(Symbol)&&"undefined"!==typeof Reflect&&ue(Reflect.ownKeys);de="undefined"!==typeof Set&&ue(Set)?Set:function(){function e(){this.set=Object.create(null)}return e.prototype.has=function(e){return!0===this.set[e]},e.prototype.add=function(e){this.set[e]=!0},e.prototype.clear=function(){this.set=Object.create(null)},e}();var fe=I,pe=0,me=function(){this.id=pe++,this.subs=[]};me.prototype.addSub=function(e){this.subs.push(e)},me.prototype.removeSub=function(e){b(this.subs,e)},me.prototype.depend=function(){me.target&&me.target.addDep(this)},me.prototype.notify=function(){var e=this.subs.slice();for(var t=0,n=e.length;t-1)if(o&&!_(r,"default"))a=!1;else if(""===a||a===O(e)){var l=et(String,r.type);(l<0||s0&&(a=$t(a,(t||"")+"_"+n),Ot(a[0])&&Ot(c)&&(u[l]=we(c.text+a[0].text),a.shift()),u.push.apply(u,a)):s(a)?Ot(c)?u[l]=we(c.text+a):""!==a&&u.push(we(a)):Ot(a)&&Ot(c)?u[l]=we(c.text+a.text):(o(e._isVList)&&r(a.tag)&&i(a.key)&&r(t)&&(a.key="__vlist"+t+"_"+n+"__"),u.push(a)));return u}function Dt(e){var t=e.$options.provide;t&&(e._provided="function"===typeof t?t.call(e):t)}function Et(e){var t=Tt(e.$options.inject,e);t&&(Ee(!1),Object.keys(t).forEach((function(n){Ne(e,n,t[n])})),Ee(!0))}function Tt(e,t){if(e){for(var n=Object.create(null),i=he?Reflect.ownKeys(e):Object.keys(e),r=0;r0,a=e?!!e.$stable:!o,s=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(a&&i&&i!==n&&s===i.$key&&!o&&!i.$hasNormal)return i;for(var l in r={},e)e[l]&&"$"!==l[0]&&(r[l]=Nt(t,l,e[l]))}else r={};for(var c in t)c in r||(r[c]=jt(t,c));return e&&Object.isExtensible(e)&&(e._normalized=r),q(r,"$stable",a),q(r,"$key",s),q(r,"$hasNormal",o),r}function Nt(e,t,n){var i=function(){var e=arguments.length?n.apply(null,arguments):n({});return e=e&&"object"===typeof e&&!Array.isArray(e)?[e]:St(e),e&&(0===e.length||1===e.length&&e[0].isComment)?void 0:e};return n.proxy&&Object.defineProperty(e,t,{get:i,enumerable:!0,configurable:!0}),i}function jt(e,t){return function(){return e[t]}}function At(e,t){var n,i,o,a,s;if(Array.isArray(e)||"string"===typeof e)for(n=new Array(e.length),i=0,o=e.length;i1?T(n):n;for(var i=T(arguments,1),r='event handler for "'+e+'"',o=0,a=n.length;odocument.createEvent("Event").timeStamp&&(Kn=function(){return Gn.now()})}function Xn(){var e,t;for(Yn=Kn(),Wn=!0,zn.sort((function(e,t){return e.id-t.id})),qn=0;qnqn&&zn[n].id>e.id)n--;zn.splice(n+1,0,e)}else zn.push(e);Hn||(Hn=!0,pt(Xn))}}var ti=0,ni=function(e,t,n,i,r){this.vm=e,r&&(e._watcher=this),e._watchers.push(this),i?(this.deep=!!i.deep,this.user=!!i.user,this.lazy=!!i.lazy,this.sync=!!i.sync,this.before=i.before):this.deep=this.user=this.lazy=this.sync=!1,this.cb=n,this.id=++ti,this.active=!0,this.dirty=this.lazy,this.deps=[],this.newDeps=[],this.depIds=new de,this.newDepIds=new de,this.expression="","function"===typeof t?this.getter=t:(this.getter=Y(t),this.getter||(this.getter=I)),this.value=this.lazy?void 0:this.get()};ni.prototype.get=function(){var e;ge(this);var t=this.vm;try{e=this.getter.call(t,t)}catch(Ca){if(!this.user)throw Ca;tt(Ca,t,'getter for watcher "'+this.expression+'"')}finally{this.deep&&vt(e),be(),this.cleanupDeps()}return e},ni.prototype.addDep=function(e){var t=e.id;this.newDepIds.has(t)||(this.newDepIds.add(t),this.newDeps.push(e),this.depIds.has(t)||e.addSub(this))},ni.prototype.cleanupDeps=function(){var e=this.deps.length;while(e--){var t=this.deps[e];this.newDepIds.has(t.id)||t.removeSub(this)}var n=this.depIds;this.depIds=this.newDepIds,this.newDepIds=n,this.newDepIds.clear(),n=this.deps,this.deps=this.newDeps,this.newDeps=n,this.newDeps.length=0},ni.prototype.update=function(){this.lazy?this.dirty=!0:this.sync?this.run():ei(this)},ni.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||l(e)||this.deep){var t=this.value;if(this.value=e,this.user)try{this.cb.call(this.vm,e,t)}catch(Ca){tt(Ca,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,e,t)}}},ni.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},ni.prototype.depend=function(){var e=this.deps.length;while(e--)this.deps[e].depend()},ni.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||b(this.vm._watchers,this);var e=this.deps.length;while(e--)this.deps[e].removeSub(this);this.active=!1}};var ii={enumerable:!0,configurable:!0,get:I,set:I};function ri(e,t,n){ii.get=function(){return this[t][n]},ii.set=function(e){this[t][n]=e},Object.defineProperty(e,n,ii)}function oi(e){e._watchers=[];var t=e.$options;t.props&&ai(e,t.props),t.methods&&pi(e,t.methods),t.data?si(e):Ie(e._data={},!0),t.computed&&ui(e,t.computed),t.watch&&t.watch!==oe&&mi(e,t.watch)}function ai(e,t){var n=e.$options.propsData||{},i=e._props={},r=e.$options._propKeys=[],o=!e.$parent;o||Ee(!1);var a=function(o){r.push(o);var a=Xe(o,t,n,e);Ne(i,o,a),o in e||ri(e,"_props",o)};for(var s in t)a(s);Ee(!0)}function si(e){var t=e.$options.data;t=e._data="function"===typeof t?li(t,e):t||{},u(t)||(t={});var n=Object.keys(t),i=e.$options.props,r=(e.$options.methods,n.length);while(r--){var o=n[r];0,i&&_(i,o)||W(o)||ri(e,"_data",o)}Ie(t,!0)}function li(e,t){ge();try{return e.call(t,t)}catch(Ca){return tt(Ca,t,"data()"),{}}finally{be()}}var ci={lazy:!0};function ui(e,t){var n=e._computedWatchers=Object.create(null),i=le();for(var r in t){var o=t[r],a="function"===typeof o?o:o.get;0,i||(n[r]=new ni(e,a||I,I,ci)),r in e||di(e,r,o)}}function di(e,t,n){var i=!le();"function"===typeof n?(ii.get=i?hi(t):fi(n),ii.set=I):(ii.get=n.get?i&&!1!==n.cache?hi(t):fi(n.get):I,ii.set=n.set||I),Object.defineProperty(e,t,ii)}function hi(e){return function(){var t=this._computedWatchers&&this._computedWatchers[e];if(t)return t.dirty&&t.evaluate(),me.target&&t.depend(),t.value}}function fi(e){return function(){return e.call(this,this)}}function pi(e,t){e.$options.props;for(var n in t)e[n]="function"!==typeof t[n]?I:E(t[n],e)}function mi(e,t){for(var n in t){var i=t[n];if(Array.isArray(i))for(var r=0;r-1)return this;var n=T(arguments,1);return n.unshift(this),"function"===typeof e.install?e.install.apply(e,n):"function"===typeof e&&e.apply(null,n),t.push(e),this}}function Si(e){e.mixin=function(e){return this.options=Ke(this.options,e),this}}function Oi(e){e.cid=0;var t=1;e.extend=function(e){e=e||{};var n=this,i=n.cid,r=e._Ctor||(e._Ctor={});if(r[i])return r[i];var o=e.name||n.options.name;var a=function(e){this._init(e)};return a.prototype=Object.create(n.prototype),a.prototype.constructor=a,a.cid=t++,a.options=Ke(n.options,e),a["super"]=n,a.options.props&&$i(a),a.options.computed&&Di(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,z.forEach((function(e){a[e]=n[e]})),o&&(a.options.components[o]=a),a.superOptions=n.options,a.extendOptions=e,a.sealedOptions=P({},a.options),r[i]=a,a}}function $i(e){var t=e.options.props;for(var n in t)ri(e.prototype,"_props",n)}function Di(e){var t=e.options.computed;for(var n in t)di(e.prototype,n,t[n])}function Ei(e){z.forEach((function(t){e[t]=function(e,n){return n?("component"===t&&u(n)&&(n.name=n.name||e,n=this.options._base.extend(n)),"directive"===t&&"function"===typeof n&&(n={bind:n,update:n}),this.options[t+"s"][e]=n,n):this.options[t+"s"][e]}}))}function Ti(e){return e&&(e.Ctor.options.name||e.tag)}function Pi(e,t){return Array.isArray(e)?e.indexOf(t)>-1:"string"===typeof e?e.split(",").indexOf(t)>-1:!!d(e)&&e.test(t)}function Mi(e,t){var n=e.cache,i=e.keys,r=e._vnode;for(var o in n){var a=n[o];if(a){var s=Ti(a.componentOptions);s&&!t(s)&&Ii(n,o,i,r)}}}function Ii(e,t,n,i){var r=e[t];!r||i&&r.tag===i.tag||r.componentInstance.$destroy(),e[t]=null,b(n,t)}yi(Ci),gi(Ci),En(Ci),In(Ci),bn(Ci);var Ni=[String,RegExp,Array],ji={name:"keep-alive",abstract:!0,props:{include:Ni,exclude:Ni,max:[String,Number]},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var e in this.cache)Ii(this.cache,e,this.keys)},mounted:function(){var e=this;this.$watch("include",(function(t){Mi(e,(function(e){return Pi(t,e)}))})),this.$watch("exclude",(function(t){Mi(e,(function(e){return!Pi(t,e)}))}))},render:function(){var e=this.$slots.default,t=Cn(e),n=t&&t.componentOptions;if(n){var i=Ti(n),r=this,o=r.include,a=r.exclude;if(o&&(!i||!Pi(o,i))||a&&i&&Pi(a,i))return t;var s=this,l=s.cache,c=s.keys,u=null==t.key?n.Ctor.cid+(n.tag?"::"+n.tag:""):t.key;l[u]?(t.componentInstance=l[u].componentInstance,b(c,u),c.push(u)):(l[u]=t,c.push(u),this.max&&c.length>parseInt(this.max)&&Ii(l,c[0],c,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}},Ai={KeepAlive:ji};function Fi(e){var t={get:function(){return R}};Object.defineProperty(e,"config",t),e.util={warn:fe,extend:P,mergeOptions:Ke,defineReactive:Ne},e.set=je,e.delete=Ae,e.nextTick=pt,e.observable=function(e){return Ie(e),e},e.options=Object.create(null),z.forEach((function(t){e.options[t+"s"]=Object.create(null)})),e.options._base=e,P(e.options.components,Ai),ki(e),Si(e),Oi(e),Ei(e)}Fi(Ci),Object.defineProperty(Ci.prototype,"$isServer",{get:le}),Object.defineProperty(Ci.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Ci,"FunctionalRenderContext",{value:Zt}),Ci.version="2.6.10";var Li=v("style,class"),Vi=v("input,textarea,option,select,progress"),zi=function(e,t,n){return"value"===n&&Vi(e)&&"button"!==t||"selected"===n&&"option"===e||"checked"===n&&"input"===e||"muted"===n&&"video"===e},Bi=v("contenteditable,draggable,spellcheck"),Ri=v("events,caret,typing,plaintext-only"),Hi=function(e,t){return Ki(t)||"false"===t?"false":"contenteditable"===e&&Ri(t)?t:"true"},Wi=v("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),qi="http://www.w3.org/1999/xlink",Ui=function(e){return":"===e.charAt(5)&&"xlink"===e.slice(0,5)},Yi=function(e){return Ui(e)?e.slice(6,e.length):""},Ki=function(e){return null==e||!1===e};function Gi(e){var t=e.data,n=e,i=e;while(r(i.componentInstance))i=i.componentInstance._vnode,i&&i.data&&(t=Xi(i.data,t));while(r(n=n.parent))n&&n.data&&(t=Xi(t,n.data));return Zi(t.staticClass,t.class)}function Xi(e,t){return{staticClass:Ji(e.staticClass,t.staticClass),class:r(e.class)?[e.class,t.class]:t.class}}function Zi(e,t){return r(e)||r(t)?Ji(e,Qi(t)):""}function Ji(e,t){return e?t?e+" "+t:e:t||""}function Qi(e){return Array.isArray(e)?er(e):l(e)?tr(e):"string"===typeof e?e:""}function er(e){for(var t,n="",i=0,o=e.length;i-1?sr[e]=t.constructor===window.HTMLUnknownElement||t.constructor===window.HTMLElement:sr[e]=/HTMLUnknownElement/.test(t.toString())}var cr=v("text,number,password,search,email,tel,url");function ur(e){if("string"===typeof e){var t=document.querySelector(e);return t||document.createElement("div")}return e}function dr(e,t){var n=document.createElement(e);return"select"!==e?n:(t.data&&t.data.attrs&&void 0!==t.data.attrs.multiple&&n.setAttribute("multiple","multiple"),n)}function hr(e,t){return document.createElementNS(nr[e],t)}function fr(e){return document.createTextNode(e)}function pr(e){return document.createComment(e)}function mr(e,t,n){e.insertBefore(t,n)}function vr(e,t){e.removeChild(t)}function gr(e,t){e.appendChild(t)}function br(e){return e.parentNode}function yr(e){return e.nextSibling}function _r(e){return e.tagName}function xr(e,t){e.textContent=t}function wr(e,t){e.setAttribute(t,"")}var Cr=Object.freeze({createElement:dr,createElementNS:hr,createTextNode:fr,createComment:pr,insertBefore:mr,removeChild:vr,appendChild:gr,parentNode:br,nextSibling:yr,tagName:_r,setTextContent:xr,setStyleScope:wr}),kr={create:function(e,t){Sr(t)},update:function(e,t){e.data.ref!==t.data.ref&&(Sr(e,!0),Sr(t))},destroy:function(e){Sr(e,!0)}};function Sr(e,t){var n=e.data.ref;if(r(n)){var i=e.context,o=e.componentInstance||e.elm,a=i.$refs;t?Array.isArray(a[n])?b(a[n],o):a[n]===o&&(a[n]=void 0):e.data.refInFor?Array.isArray(a[n])?a[n].indexOf(o)<0&&a[n].push(o):a[n]=[o]:a[n]=o}}var Or=new ye("",{},[]),$r=["create","activate","update","remove","destroy"];function Dr(e,t){return e.key===t.key&&(e.tag===t.tag&&e.isComment===t.isComment&&r(e.data)===r(t.data)&&Er(e,t)||o(e.isAsyncPlaceholder)&&e.asyncFactory===t.asyncFactory&&i(t.asyncFactory.error))}function Er(e,t){if("input"!==e.tag)return!0;var n,i=r(n=e.data)&&r(n=n.attrs)&&n.type,o=r(n=t.data)&&r(n=n.attrs)&&n.type;return i===o||cr(i)&&cr(o)}function Tr(e,t,n){var i,o,a={};for(i=t;i<=n;++i)o=e[i].key,r(o)&&(a[o]=i);return a}function Pr(e){var t,n,a={},l=e.modules,c=e.nodeOps;for(t=0;t<$r.length;++t)for(a[$r[t]]=[],n=0;nm?(d=i(n[b+1])?null:n[b+1].elm,C(e,d,n,p,b,o)):p>b&&S(e,t,h,m)}function D(e,t,n,i){for(var o=n;o-1?Rr(e,t,n):Wi(t)?Ki(n)?e.removeAttribute(t):(n="allowfullscreen"===t&&"EMBED"===e.tagName?"true":t,e.setAttribute(t,n)):Bi(t)?e.setAttribute(t,Hi(t,n)):Ui(t)?Ki(n)?e.removeAttributeNS(qi,Yi(t)):e.setAttributeNS(qi,t,n):Rr(e,t,n)}function Rr(e,t,n){if(Ki(n))e.removeAttribute(t);else{if(ee&&!te&&"TEXTAREA"===e.tagName&&"placeholder"===t&&""!==n&&!e.__ieph){var i=function(t){t.stopImmediatePropagation(),e.removeEventListener("input",i)};e.addEventListener("input",i),e.__ieph=!0}e.setAttribute(t,n)}}var Hr={create:zr,update:zr};function Wr(e,t){var n=t.elm,o=t.data,a=e.data;if(!(i(o.staticClass)&&i(o.class)&&(i(a)||i(a.staticClass)&&i(a.class)))){var s=Gi(t),l=n._transitionClasses;r(l)&&(s=Ji(s,Qi(l))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}var qr,Ur={create:Wr,update:Wr},Yr="__r",Kr="__c";function Gr(e){if(r(e[Yr])){var t=ee?"change":"input";e[t]=[].concat(e[Yr],e[t]||[]),delete e[Yr]}r(e[Kr])&&(e.change=[].concat(e[Kr],e.change||[]),delete e[Kr])}function Xr(e,t,n){var i=qr;return function r(){var o=t.apply(null,arguments);null!==o&&Qr(e,r,n,i)}}var Zr=at&&!(re&&Number(re[1])<=53);function Jr(e,t,n,i){if(Zr){var r=Yn,o=t;t=o._wrapper=function(e){if(e.target===e.currentTarget||e.timeStamp>=r||e.timeStamp<=0||e.target.ownerDocument!==document)return o.apply(this,arguments)}}qr.addEventListener(e,t,ae?{capture:n,passive:i}:n)}function Qr(e,t,n,i){(i||qr).removeEventListener(e,t._wrapper||t,n)}function eo(e,t){if(!i(e.data.on)||!i(t.data.on)){var n=t.data.on||{},r=e.data.on||{};qr=t.elm,Gr(n),_t(n,r,Jr,Qr,Xr,t.context),qr=void 0}}var to,no={create:eo,update:eo};function io(e,t){if(!i(e.data.domProps)||!i(t.data.domProps)){var n,o,a=t.elm,s=e.data.domProps||{},l=t.data.domProps||{};for(n in r(l.__ob__)&&(l=t.data.domProps=P({},l)),s)n in l||(a[n]="");for(n in l){if(o=l[n],"textContent"===n||"innerHTML"===n){if(t.children&&(t.children.length=0),o===s[n])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===n&&"PROGRESS"!==a.tagName){a._value=o;var c=i(o)?"":String(o);ro(a,c)&&(a.value=c)}else if("innerHTML"===n&&rr(a.tagName)&&i(a.innerHTML)){to=to||document.createElement("div"),to.innerHTML=""+o+"";var u=to.firstChild;while(a.firstChild)a.removeChild(a.firstChild);while(u.firstChild)a.appendChild(u.firstChild)}else if(o!==s[n])try{a[n]=o}catch(Ca){}}}}function ro(e,t){return!e.composing&&("OPTION"===e.tagName||oo(e,t)||ao(e,t))}function oo(e,t){var n=!0;try{n=document.activeElement!==e}catch(Ca){}return n&&e.value!==t}function ao(e,t){var n=e.value,i=e._vModifiers;if(r(i)){if(i.number)return m(n)!==m(t);if(i.trim)return n.trim()!==t.trim()}return n!==t}var so={create:io,update:io},lo=x((function(e){var t={},n=/;(?![^(]*\))/g,i=/:(.+)/;return e.split(n).forEach((function(e){if(e){var n=e.split(i);n.length>1&&(t[n[0].trim()]=n[1].trim())}})),t}));function co(e){var t=uo(e.style);return e.staticStyle?P(e.staticStyle,t):t}function uo(e){return Array.isArray(e)?M(e):"string"===typeof e?lo(e):e}function ho(e,t){var n,i={};if(t){var r=e;while(r.componentInstance)r=r.componentInstance._vnode,r&&r.data&&(n=co(r.data))&&P(i,n)}(n=co(e.data))&&P(i,n);var o=e;while(o=o.parent)o.data&&(n=co(o.data))&&P(i,n);return i}var fo,po=/^--/,mo=/\s*!important$/,vo=function(e,t,n){if(po.test(t))e.style.setProperty(t,n);else if(mo.test(n))e.style.setProperty(O(t),n.replace(mo,""),"important");else{var i=bo(t);if(Array.isArray(n))for(var r=0,o=n.length;r-1?t.split(xo).forEach((function(t){return e.classList.add(t)})):e.classList.add(t);else{var n=" "+(e.getAttribute("class")||"")+" ";n.indexOf(" "+t+" ")<0&&e.setAttribute("class",(n+t).trim())}}function Co(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(xo).forEach((function(t){return e.classList.remove(t)})):e.classList.remove(t),e.classList.length||e.removeAttribute("class");else{var n=" "+(e.getAttribute("class")||"")+" ",i=" "+t+" ";while(n.indexOf(i)>=0)n=n.replace(i," ");n=n.trim(),n?e.setAttribute("class",n):e.removeAttribute("class")}}function ko(e){if(e){if("object"===typeof e){var t={};return!1!==e.css&&P(t,So(e.name||"v")),P(t,e),t}return"string"===typeof e?So(e):void 0}}var So=x((function(e){return{enterClass:e+"-enter",enterToClass:e+"-enter-to",enterActiveClass:e+"-enter-active",leaveClass:e+"-leave",leaveToClass:e+"-leave-to",leaveActiveClass:e+"-leave-active"}})),Oo=X&&!te,$o="transition",Do="animation",Eo="transition",To="transitionend",Po="animation",Mo="animationend";Oo&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(Eo="WebkitTransition",To="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(Po="WebkitAnimation",Mo="webkitAnimationEnd"));var Io=X?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(e){return e()};function No(e){Io((function(){Io(e)}))}function jo(e,t){var n=e._transitionClasses||(e._transitionClasses=[]);n.indexOf(t)<0&&(n.push(t),wo(e,t))}function Ao(e,t){e._transitionClasses&&b(e._transitionClasses,t),Co(e,t)}function Fo(e,t,n){var i=Vo(e,t),r=i.type,o=i.timeout,a=i.propCount;if(!r)return n();var s=r===$o?To:Mo,l=0,c=function(){e.removeEventListener(s,u),n()},u=function(t){t.target===e&&++l>=a&&c()};setTimeout((function(){l0&&(n=$o,u=a,d=o.length):t===Do?c>0&&(n=Do,u=c,d=l.length):(u=Math.max(a,c),n=u>0?a>c?$o:Do:null,d=n?n===$o?o.length:l.length:0);var h=n===$o&&Lo.test(i[Eo+"Property"]);return{type:n,timeout:u,propCount:d,hasTransform:h}}function zo(e,t){while(e.length1}function Uo(e,t){!0!==t.data.show&&Ro(t)}var Yo=X?{create:Uo,activate:Uo,remove:function(e,t){!0!==e.data.show?Ho(e,t):t()}}:{},Ko=[Hr,Ur,no,so,_o,Yo],Go=Ko.concat(Vr),Xo=Pr({nodeOps:Cr,modules:Go});te&&document.addEventListener("selectionchange",(function(){var e=document.activeElement;e&&e.vmodel&&ra(e,"input")}));var Zo={inserted:function(e,t,n,i){"select"===n.tag?(i.elm&&!i.elm._vOptions?xt(n,"postpatch",(function(){Zo.componentUpdated(e,t,n)})):Jo(e,t,n.context),e._vOptions=[].map.call(e.options,ta)):("textarea"===n.tag||cr(e.type))&&(e._vModifiers=t.modifiers,t.modifiers.lazy||(e.addEventListener("compositionstart",na),e.addEventListener("compositionend",ia),e.addEventListener("change",ia),te&&(e.vmodel=!0)))},componentUpdated:function(e,t,n){if("select"===n.tag){Jo(e,t,n.context);var i=e._vOptions,r=e._vOptions=[].map.call(e.options,ta);if(r.some((function(e,t){return!A(e,i[t])}))){var o=e.multiple?t.value.some((function(e){return ea(e,r)})):t.value!==t.oldValue&&ea(t.value,r);o&&ra(e,"change")}}}};function Jo(e,t,n){Qo(e,t,n),(ee||ne)&&setTimeout((function(){Qo(e,t,n)}),0)}function Qo(e,t,n){var i=t.value,r=e.multiple;if(!r||Array.isArray(i)){for(var o,a,s=0,l=e.options.length;s-1,a.selected!==o&&(a.selected=o);else if(A(ta(a),i))return void(e.selectedIndex!==s&&(e.selectedIndex=s));r||(e.selectedIndex=-1)}}function ea(e,t){return t.every((function(t){return!A(t,e)}))}function ta(e){return"_value"in e?e._value:e.value}function na(e){e.target.composing=!0}function ia(e){e.target.composing&&(e.target.composing=!1,ra(e.target,"input"))}function ra(e,t){var n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)}function oa(e){return!e.componentInstance||e.data&&e.data.transition?e:oa(e.componentInstance._vnode)}var aa={bind:function(e,t,n){var i=t.value;n=oa(n);var r=n.data&&n.data.transition,o=e.__vOriginalDisplay="none"===e.style.display?"":e.style.display;i&&r?(n.data.show=!0,Ro(n,(function(){e.style.display=o}))):e.style.display=i?o:"none"},update:function(e,t,n){var i=t.value,r=t.oldValue;if(!i!==!r){n=oa(n);var o=n.data&&n.data.transition;o?(n.data.show=!0,i?Ro(n,(function(){e.style.display=e.__vOriginalDisplay})):Ho(n,(function(){e.style.display="none"}))):e.style.display=i?e.__vOriginalDisplay:"none"}},unbind:function(e,t,n,i,r){r||(e.style.display=e.__vOriginalDisplay)}},sa={model:Zo,show:aa},la={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function ca(e){var t=e&&e.componentOptions;return t&&t.Ctor.options.abstract?ca(Cn(t.children)):e}function ua(e){var t={},n=e.$options;for(var i in n.propsData)t[i]=e[i];var r=n._parentListeners;for(var o in r)t[C(o)]=r[o];return t}function da(e,t){if(/\d-keep-alive$/.test(t.tag))return e("keep-alive",{props:t.componentOptions.propsData})}function ha(e){while(e=e.parent)if(e.data.transition)return!0}function fa(e,t){return t.key===e.key&&t.tag===e.tag}var pa=function(e){return e.tag||wn(e)},ma=function(e){return"show"===e.name},va={name:"transition",props:la,abstract:!0,render:function(e){var t=this,n=this.$slots.default;if(n&&(n=n.filter(pa),n.length)){0;var i=this.mode;0;var r=n[0];if(ha(this.$vnode))return r;var o=ca(r);if(!o)return r;if(this._leaving)return da(e,r);var a="__transition-"+this._uid+"-";o.key=null==o.key?o.isComment?a+"comment":a+o.tag:s(o.key)?0===String(o.key).indexOf(a)?o.key:a+o.key:o.key;var l=(o.data||(o.data={})).transition=ua(this),c=this._vnode,u=ca(c);if(o.data.directives&&o.data.directives.some(ma)&&(o.data.show=!0),u&&u.data&&!fa(o,u)&&!wn(u)&&(!u.componentInstance||!u.componentInstance._vnode.isComment)){var d=u.data.transition=P({},l);if("out-in"===i)return this._leaving=!0,xt(d,"afterLeave",(function(){t._leaving=!1,t.$forceUpdate()})),da(e,r);if("in-out"===i){if(wn(o))return c;var h,f=function(){h()};xt(l,"afterEnter",f),xt(l,"enterCancelled",f),xt(d,"delayLeave",(function(e){h=e}))}}return r}}},ga=P({tag:String,moveClass:String},la);delete ga.mode;var ba={props:ga,beforeMount:function(){var e=this,t=this._update;this._update=function(n,i){var r=Pn(e);e.__patch__(e._vnode,e.kept,!1,!0),e._vnode=e.kept,r(),t.call(e,n,i)}},render:function(e){for(var t=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),i=this.prevChildren=this.children,r=this.$slots.default||[],o=this.children=[],a=ua(this),s=0;sn)t.push(arguments[n++]);return _[++y]=function(){("function"==typeof e?e:Function(e)).apply(void 0,t)},i(y),y},m=function(e){delete _[e]},"process"==l(v)?i=function(e){v.nextTick(C(e))}:b&&b.now?i=function(e){b.now(C(e))}:g&&!/(iphone|ipod|ipad).*applewebkit/i.test(h)?(r=new g,o=r.port2,r.port1.onmessage=k,i=c(o.postMessage,o,1)):!a.addEventListener||"function"!=typeof postMessage||a.importScripts||s(S)?i=x in d("script")?function(e){u.appendChild(d("script"))[x]=function(){u.removeChild(this),w(e)}}:function(e){setTimeout(C(e),0)}:(i=S,a.addEventListener("message",k,!1))),e.exports={set:p,clear:m}},"2d83":function(e,t,n){"use strict";var i=n("387f");e.exports=function(e,t,n,r,o){var a=new Error(e);return i(a,t,n,r,o)}},"2e67":function(e,t,n){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},"2f9a":function(e,t){e.exports=function(){}},"301c":function(e,t,n){n("e198")("asyncIterator")},"30b5":function(e,t,n){"use strict";var i=n("c532");function r(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}e.exports=function(e,t,n){if(!t)return e;var o;if(n)o=n(t);else if(i.isURLSearchParams(t))o=t.toString();else{var a=[];i.forEach(t,(function(e,t){null!==e&&"undefined"!==typeof e&&(i.isArray(e)?t+="[]":e=[e],i.forEach(e,(function(e){i.isDate(e)?e=e.toISOString():i.isObject(e)&&(e=JSON.stringify(e)),a.push(r(t)+"="+r(e))})))})),o=a.join("&")}return o&&(e+=(-1===e.indexOf("?")?"?":"&")+o),e}},3397:function(e,t,n){var i=n("7a41");e.exports=function(e,t){if(!i(e))return e;var n,r;if(t&&"function"==typeof(n=e.toString)&&!i(r=n.call(e)))return r;if("function"==typeof(n=e.valueOf)&&!i(r=n.call(e)))return r;if(!t&&"function"==typeof(n=e.toString)&&!i(r=n.call(e)))return r;throw TypeError("Can't convert object to primitive value")}},"35a1":function(e,t,n){var i=n("f5df"),r=n("3f8c"),o=n("b622"),a=o("iterator");e.exports=function(e){if(void 0!=e)return e[a]||e["@@iterator"]||r[i(e)]}},"37e8":function(e,t,n){var i=n("83ab"),r=n("9bf2"),o=n("825a"),a=n("df75");e.exports=i?Object.defineProperties:function(e,t){o(e);var n,i=a(t),s=i.length,l=0;while(s>l)r.f(e,n=i[l++],t[n]);return e}},"387f":function(e,t,n){"use strict";e.exports=function(e,t,n,i,r){return e.config=t,n&&(e.code=n),e.request=i,e.response=r,e}},3934:function(e,t,n){"use strict";var i=n("c532");e.exports=i.isStandardBrowserEnv()?function(){var e,t=/(msie|trident)/i.test(navigator.userAgent),n=document.createElement("a");function r(e){var i=e;return t&&(n.setAttribute("href",i),i=n.href),n.setAttribute("href",i),{href:n.href,protocol:n.protocol?n.protocol.replace(/:$/,""):"",host:n.host,search:n.search?n.search.replace(/^\?/,""):"",hash:n.hash?n.hash.replace(/^#/,""):"",hostname:n.hostname,port:n.port,pathname:"/"===n.pathname.charAt(0)?n.pathname:"/"+n.pathname}}return e=r(window.location.href),function(t){var n=i.isString(t)?r(t):t;return n.protocol===e.protocol&&n.host===e.host}}():function(){return function(){return!0}}()},"393a":function(e,t,n){"use strict";var i=n("e444"),r=n("512c"),o=n("ba01"),a=n("051b"),s=n("8a0d"),l=n("26dd"),c=n("92f0"),u=n("ce7a"),d=n("cc15")("iterator"),h=!([].keys&&"next"in[].keys()),f="@@iterator",p="keys",m="values",v=function(){return this};e.exports=function(e,t,n,g,b,y,_){l(n,t,g);var x,w,C,k=function(e){if(!h&&e in D)return D[e];switch(e){case p:return function(){return new n(this,e)};case m:return function(){return new n(this,e)}}return function(){return new n(this,e)}},S=t+" Iterator",O=b==m,$=!1,D=e.prototype,E=D[d]||D[f]||b&&D[b],T=E||k(b),P=b?O?k("entries"):T:void 0,M="Array"==t&&D.entries||E;if(M&&(C=u(M.call(new e)),C!==Object.prototype&&C.next&&(c(C,S,!0),i||"function"==typeof C[d]||a(C,d,v))),O&&E&&E.name!==m&&($=!0,T=function(){return E.call(this)}),i&&!_||!h&&!$&&D[d]||a(D,d,T),s[t]=T,s[S]=v,b)if(x={values:O?T:k(m),keys:y?T:k(p),entries:P},_)for(w in x)w in D||o(D,w,x[w]);else r(r.P+r.F*(h||$),t,x);return x}},"39ad":function(e,t,n){var i=n("6ca1"),r=n("d16a"),o=n("9d11");e.exports=function(e){return function(t,n,a){var s,l=i(t),c=r(l.length),u=o(a,c);if(e&&n!=n){while(c>u)if(s=l[u++],s!=s)return!0}else for(;c>u;u++)if((e||u in l)&&l[u]===n)return e||u||0;return!e&&-1}}},"3bbe":function(e,t,n){var i=n("861d");e.exports=function(e){if(!i(e)&&null!==e)throw TypeError("Can't set "+String(e)+" as a prototype");return e}},"3c4e":function(e,t,n){"use strict";var i=function(e){return r(e)&&!o(e)};function r(e){return!!e&&"object"===typeof e}function o(e){var t=Object.prototype.toString.call(e);return"[object RegExp]"===t||"[object Date]"===t||l(e)}var a="function"===typeof Symbol&&Symbol.for,s=a?Symbol.for("react.element"):60103;function l(e){return e.$$typeof===s}function c(e){return Array.isArray(e)?[]:{}}function u(e,t){var n=t&&!0===t.clone;return n&&i(e)?f(c(e),e,t):e}function d(e,t,n){var r=e.slice();return t.forEach((function(t,o){"undefined"===typeof r[o]?r[o]=u(t,n):i(t)?r[o]=f(e[o],t,n):-1===e.indexOf(t)&&r.push(u(t,n))})),r}function h(e,t,n){var r={};return i(e)&&Object.keys(e).forEach((function(t){r[t]=u(e[t],n)})),Object.keys(t).forEach((function(o){i(t[o])&&e[o]?r[o]=f(e[o],t[o],n):r[o]=u(t[o],n)})),r}function f(e,t,n){var i=Array.isArray(t),r=Array.isArray(e),o=n||{arrayMerge:d},a=i===r;if(a){if(i){var s=o.arrayMerge||d;return s(e,t,n)}return h(e,t,n)}return u(t,n)}f.all=function(e,t){if(!Array.isArray(e)||e.length<2)throw new Error("first argument should be an array with at least two elements");return e.reduce((function(e,n){return f(e,n,t)}))};var p=f;e.exports=p},"3f6b":function(e,t,n){e.exports={default:n("b9c7"),__esModule:!0}},"3f8c":function(e,t){e.exports={}},4010:function(e,t,n){"use strict";t.__esModule=!0,t.removeResizeListener=t.addResizeListener=void 0;var i=n("6dd8"),r=o(i);function o(e){return e&&e.__esModule?e:{default:e}}var a="undefined"===typeof window,s=function(e){var t=e,n=Array.isArray(t),i=0;for(t=n?t:t[Symbol.iterator]();;){var r;if(n){if(i>=t.length)break;r=t[i++]}else{if(i=t.next(),i.done)break;r=i.value}var o=r,a=o.target.__resizeListeners__||[];a.length&&a.forEach((function(e){e()}))}};t.addResizeListener=function(e,t){a||(e.__resizeListeners__||(e.__resizeListeners__=[],e.__ro__=new r.default(s),e.__ro__.observe(e)),e.__resizeListeners__.push(t))},t.removeResizeListener=function(e,t){e&&e.__resizeListeners__&&(e.__resizeListeners__.splice(e.__resizeListeners__.indexOf(t),1),e.__resizeListeners__.length||e.__ro__.disconnect())}},"417f":function(e,t,n){"use strict";t.__esModule=!0;var i=n("2b0e"),r=a(i),o=n("5924");function a(e){return e&&e.__esModule?e:{default:e}}var s=[],l="@@clickoutsideContext",c=void 0,u=0;function d(e,t,n){return function(){var i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};!(n&&n.context&&i.target&&r.target)||e.contains(i.target)||e.contains(r.target)||e===i.target||n.context.popperElm&&(n.context.popperElm.contains(i.target)||n.context.popperElm.contains(r.target))||(t.expression&&e[l].methodName&&n.context[e[l].methodName]?n.context[e[l].methodName]():e[l].bindingFn&&e[l].bindingFn())}}!r.default.prototype.$isServer&&(0,o.on)(document,"mousedown",(function(e){return c=e})),!r.default.prototype.$isServer&&(0,o.on)(document,"mouseup",(function(e){s.forEach((function(t){return t[l].documentHandler(e,c)}))})),t.default={bind:function(e,t,n){s.push(e);var i=u++;e[l]={id:i,documentHandler:d(e,t,n),methodName:t.expression,bindingFn:t.value}},update:function(e,t,n){e[l].documentHandler=d(e,t,n),e[l].methodName=t.expression,e[l].bindingFn=t.value},unbind:function(e){for(var t=s.length,n=0;n\n \n '}else n||(this.hoverTimer=setTimeout(this.clearHoverZone,this.panel.config.hoverThreshold))},clearHoverZone:function(){var e=this.$refs.hoverZone;e&&(e.innerHTML="")},renderEmptyText:function(e){return e("div",{class:"el-cascader-menu__empty-text"},[this.t("el.cascader.noData")])},renderNodeList:function(e){var t=this.menuId,n=this.panel.isHoverMenu,i={on:{}};n&&(i.on.expand=this.handleExpand);var r=this.nodes.map((function(n,r){var o=n.hasChildren;return e("cascader-node",l()([{key:n.uid,attrs:{node:n,"node-id":t+"-"+r,"aria-haspopup":o,"aria-owns":o?t:null}},i]))}));return[].concat(r,[n?e("svg",{ref:"hoverZone",class:"el-cascader-menu__hover-zone"}):null])}},render:function(e){var t=this.isEmpty,n=this.menuId,i={nativeOn:{}};return this.panel.isHoverMenu&&(i.nativeOn.mousemove=this.handleMouseMove),e("el-scrollbar",l()([{attrs:{tag:"ul",role:"menu",id:n,"wrap-class":"el-cascader-menu__wrap","view-class":{"el-cascader-menu__list":!0,"is-empty":t}},class:"el-cascader-menu"},i]),[t?this.renderEmptyText(e):this.renderNodeList(e)])}},$=O,D=Object(y["a"])($,x,w,!1,null,null,null);D.options.__file="packages/cascader-panel/src/cascader-menu.vue";var E=D.exports,T=n(21),P=function(){function e(e,t){for(var n=0;n1?t-1:0),i=1;i1?i-1:0),o=1;o0},e.prototype.syncCheckState=function(e){var t=this.getValueByOption(),n=this.isSameNode(e,t);this.doCheck(n)},e.prototype.doCheck=function(e){this.checked!==e&&(this.config.checkStrictly?this.checked=e:(this.broadcast("check",e),this.setCheckState(e),this.emit("check")))},P(e,[{key:"isDisabled",get:function(){var e=this.data,t=this.parent,n=this.config,i=n.disabled,r=n.checkStrictly;return e[i]||!r&&t&&t.isDisabled}},{key:"isLeaf",get:function(){var e=this.data,t=this.loaded,n=this.hasChildren,i=this.children,r=this.config,o=r.lazy,a=r.leaf;if(o){var s=Object(T["isDef"])(e[a])?e[a]:!!t&&!i.length;return this.hasChildren=!s,s}return!n}}]),e}(),j=N;function A(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var F=function e(t,n){return t.reduce((function(t,i){return i.isLeaf?t.push(i):(!n&&t.push(i),t=t.concat(e(i.children,n))),t}),[])},L=function(){function e(t,n){A(this,e),this.config=n,this.initNodes(t)}return e.prototype.initNodes=function(e){var t=this;e=Object(m["coerceTruthyValueToArray"])(e),this.nodes=e.map((function(e){return new j(e,t.config)})),this.flattedNodes=this.getFlattedNodes(!1,!1),this.leafNodes=this.getFlattedNodes(!0,!1)},e.prototype.appendNode=function(e,t){var n=new j(e,this.config,t),i=t?t.children:this.nodes;i.push(n)},e.prototype.appendNodes=function(e,t){var n=this;e=Object(m["coerceTruthyValueToArray"])(e),e.forEach((function(e){return n.appendNode(e,t)}))},e.prototype.getNodes=function(){return this.nodes},e.prototype.getFlattedNodes=function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=e?this.leafNodes:this.flattedNodes;return t?n:F(this.nodes,e)},e.prototype.getNodeByValue=function(e){if(e){var t=this.getFlattedNodes(!1,!this.config.lazy).filter((function(t){return Object(m["valueEquals"])(t.path,e)||t.value===e}));return t&&t.length?t[0]:null}return null},e}(),V=L,z=n(9),B=n.n(z),R=n(39),H=n.n(R),W=n(31),q=n.n(W),U=Object.assign||function(e){for(var t=1;t0){var l=n.store.getNodeByValue(o);l.data[s]||n.lazyLoad(l,(function(){n.handleExpand(l)})),n.loadCount===n.checkedValue.length&&n.$parent.computePresentText()}}t&&t(i)};i.lazyLoad(e,r)},calculateMultiCheckedValue:function(){this.checkedValue=this.getCheckedNodes(this.leafOnly).map((function(e){return e.getValueByOption()}))},scrollIntoView:function(){if(!this.$isServer){var e=this.$refs.menu||[];e.forEach((function(e){var t=e.$el;if(t){var n=t.querySelector(".el-scrollbar__wrap"),i=t.querySelector(".el-cascader-node.is-active")||t.querySelector(".el-cascader-node.in-active-path");q()(n,i)}}))}},getNodeByValue:function(e){return this.store.getNodeByValue(e)},getFlattedNodes:function(e){var t=!this.config.lazy;return this.store.getFlattedNodes(e,t)},getCheckedNodes:function(e){var t=this.checkedValue,n=this.multiple;if(n){var i=this.getFlattedNodes(e);return i.filter((function(e){return e.checked}))}return Object(m["isEmpty"])(t)?[]:[this.getNodeByValue(t)]},clearCheckedNodes:function(){var e=this.config,t=this.leafOnly,n=e.multiple,i=e.emitPath;n?(this.getCheckedNodes(t).filter((function(e){return!e.isDisabled})).forEach((function(e){return e.doCheck(!1)})),this.calculateMultiCheckedValue()):this.checkedValue=i?[]:null}}},te=ee,ne=Object(y["a"])(te,i,r,!1,null,null,null);ne.options.__file="packages/cascader-panel/src/cascader-panel.vue";var ie=ne.exports;ie.install=function(e){e.component(ie.name,ie)};t["default"]=ie},6:function(e,t){e.exports=n("6b7c")},9:function(e,t){e.exports=n("7f4d")}})},4840:function(e,t,n){var i=n("825a"),r=n("1c0b"),o=n("b622"),a=o("species");e.exports=function(e,t){var n,o=i(e).constructor;return void 0===o||void 0==(n=i(o)[a])?t:r(n)}},4897:function(e,t,n){"use strict";t.__esModule=!0,t.i18n=t.use=t.t=void 0;var i=n("f0d9"),r=d(i),o=n("2b0e"),a=d(o),s=n("3c4e"),l=d(s),c=n("9d7e"),u=d(c);function d(e){return e&&e.__esModule?e:{default:e}}var h=(0,u.default)(a.default),f=r.default,p=!1,m=function(){var e=Object.getPrototypeOf(this||a.default).$t;if("function"===typeof e&&a.default.locale)return p||(p=!0,a.default.locale(a.default.config.lang,(0,l.default)(f,a.default.locale(a.default.config.lang)||{},{clone:!0}))),e.apply(this,arguments)},v=t.t=function(e,t){var n=m.apply(this,arguments);if(null!==n&&void 0!==n)return n;for(var i=e.split("."),r=f,o=0,a=i.length;o0){var i=t[t.length-1];if(i.id===e){if(i.modalClass){var r=i.modalClass.trim().split(/\s+/);r.forEach((function(e){return(0,o.removeClass)(n,e)}))}t.pop(),t.length>0&&(n.style.zIndex=t[t.length-1].zIndex)}else for(var a=t.length-1;a>=0;a--)if(t[a].id===e){t.splice(a,1);break}}0===t.length&&(this.modalFade&&(0,o.addClass)(n,"v-modal-leave"),setTimeout((function(){0===t.length&&(n.parentNode&&n.parentNode.removeChild(n),n.style.display="none",h.modalDom=void 0),(0,o.removeClass)(n,"v-modal-leave")}),200))}};Object.defineProperty(h,"zIndex",{configurable:!0,get:function(){return l||(c=c||(r.default.prototype.$ELEMENT||{}).zIndex||2e3,l=!0),c},set:function(e){c=e}});var f=function(){if(!r.default.prototype.$isServer&&h.modalStack.length>0){var e=h.modalStack[h.modalStack.length-1];if(!e)return;var t=h.getInstance(e.id);return t}};r.default.prototype.$isServer||window.addEventListener("keydown",(function(e){if(27===e.keyCode){var t=f();t&&t.closeOnPressEscape&&(t.handleClose?t.handleClose():t.handleAction?t.handleAction("cancel"):t.close())}})),t.default=h},"4b8b":function(e,t){e.exports=function(e){try{return!!e()}catch(t){return!0}}},"4d20":function(e,t,n){var i=n("1917"),r=n("10db"),o=n("6ca1"),a=n("3397"),s=n("9c0e"),l=n("faf5"),c=Object.getOwnPropertyDescriptor;t.f=n("0bad")?c:function(e,t){if(e=o(e),t=a(t,!0),l)try{return c(e,t)}catch(n){}if(s(e,t))return r(!i.f.call(e,t),e[t])}},"4d64":function(e,t,n){var i=n("fc6a"),r=n("50c4"),o=n("23cb"),a=function(e){return function(t,n,a){var s,l=i(t),c=r(l.length),u=o(a,c);if(e&&n!=n){while(c>u)if(s=l[u++],s!=s)return!0}else for(;c>u;u++)if((e||u in l)&&l[u]===n)return e||u||0;return!e&&-1}};e.exports={includes:a(!0),indexOf:a(!1)}},"4d88":function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},"4e4b":function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=60)}([function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},,,function(e,t){e.exports=n("8122")},function(e,t){e.exports=n("d010")},function(e,t){e.exports=n("e974")},function(e,t){e.exports=n("6b7c")},,,,,function(e,t){e.exports=n("f3ad")},function(e,t){e.exports=n("417f")},function(e,t){e.exports=n("14e9")},,function(e,t){e.exports=n("4010")},function(e,t){e.exports=n("0e15")},,,,function(e,t){e.exports=n("4897")},function(e,t){e.exports=n("d397")},function(e,t){e.exports=n("12f2")},,,,,,,,,function(e,t){e.exports=n("2a5e")},,function(e,t,n){"use strict";var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-select-dropdown__item",class:{selected:e.itemSelected,"is-disabled":e.disabled||e.groupDisabled||e.limitReached,hover:e.hover},on:{mouseenter:e.hoverItem,click:function(t){return t.stopPropagation(),e.selectOptionClick(t)}}},[e._t("default",[n("span",[e._v(e._s(e.currentLabel))])])],2)},r=[];i._withStripped=!0;var o=n(4),a=n.n(o),s=n(3),l="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c={mixins:[a.a],name:"ElOption",componentName:"ElOption",inject:["select"],props:{value:{required:!0},label:[String,Number],created:Boolean,disabled:{type:Boolean,default:!1}},data:function(){return{index:-1,groupDisabled:!1,visible:!0,hitState:!1,hover:!1}},computed:{isObject:function(){return"[object object]"===Object.prototype.toString.call(this.value).toLowerCase()},currentLabel:function(){return this.label||(this.isObject?"":this.value)},currentValue:function(){return this.value||this.label||""},itemSelected:function(){return this.select.multiple?this.contains(this.select.value,this.value):this.isEqual(this.value,this.select.value)},limitReached:function(){return!!this.select.multiple&&(!this.itemSelected&&(this.select.value||[]).length>=this.select.multipleLimit&&this.select.multipleLimit>0)}},watch:{currentLabel:function(){this.created||this.select.remote||this.dispatch("ElSelect","setSelected")},value:function(e,t){var n=this.select,i=n.remote,r=n.valueKey;if(!this.created&&!i){if(r&&"object"===("undefined"===typeof e?"undefined":l(e))&&"object"===("undefined"===typeof t?"undefined":l(t))&&e[r]===t[r])return;this.dispatch("ElSelect","setSelected")}}},methods:{isEqual:function(e,t){if(this.isObject){var n=this.select.valueKey;return Object(s["getValueByPath"])(e,n)===Object(s["getValueByPath"])(t,n)}return e===t},contains:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1];if(this.isObject){var n=this.select.valueKey;return e&&e.some((function(e){return Object(s["getValueByPath"])(e,n)===Object(s["getValueByPath"])(t,n)}))}return e&&e.indexOf(t)>-1},handleGroupDisabled:function(e){this.groupDisabled=e},hoverItem:function(){this.disabled||this.groupDisabled||(this.select.hoverIndex=this.select.options.indexOf(this))},selectOptionClick:function(){!0!==this.disabled&&!0!==this.groupDisabled&&this.dispatch("ElSelect","handleOptionClick",[this,!0])},queryChange:function(e){this.visible=new RegExp(Object(s["escapeRegexpString"])(e),"i").test(this.currentLabel)||this.created,this.visible||this.select.filteredOptionsCount--}},created:function(){this.select.options.push(this),this.select.cachedOptions.push(this),this.select.optionsCount++,this.select.filteredOptionsCount++,this.$on("queryChange",this.queryChange),this.$on("handleGroupDisabled",this.handleGroupDisabled)},beforeDestroy:function(){var e=this.select.cachedOptions.indexOf(this);e>-1&&this.select.cachedOptions.splice(e,1),this.select.onOptionDestroy(this.select.options.indexOf(this))}},u=c,d=n(0),h=Object(d["a"])(u,i,r,!1,null,null,null);h.options.__file="packages/select/src/option.vue";t["a"]=h.exports},,,function(e,t){e.exports=n("8bbc")},,,,,,,,,,,,,,,,,,,,,,,,function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleClose,expression:"handleClose"}],staticClass:"el-select",class:[e.selectSize?"el-select--"+e.selectSize:""],on:{click:function(t){return t.stopPropagation(),e.toggleMenu(t)}}},[e.multiple?n("div",{ref:"tags",staticClass:"el-select__tags",style:{"max-width":e.inputWidth-32+"px",width:"100%"}},[e.collapseTags&&e.selected.length?n("span",[n("el-tag",{attrs:{closable:!e.selectDisabled,size:e.collapseTagSize,hit:e.selected[0].hitState,type:"info","disable-transitions":""},on:{close:function(t){e.deleteTag(t,e.selected[0])}}},[n("span",{staticClass:"el-select__tags-text"},[e._v(e._s(e.selected[0].currentLabel))])]),e.selected.length>1?n("el-tag",{attrs:{closable:!1,size:e.collapseTagSize,type:"info","disable-transitions":""}},[n("span",{staticClass:"el-select__tags-text"},[e._v("+ "+e._s(e.selected.length-1))])]):e._e()],1):e._e(),e.collapseTags?e._e():n("transition-group",{on:{"after-leave":e.resetInputHeight}},e._l(e.selected,(function(t){return n("el-tag",{key:e.getValueKey(t),attrs:{closable:!e.selectDisabled,size:e.collapseTagSize,hit:t.hitState,type:"info","disable-transitions":""},on:{close:function(n){e.deleteTag(n,t)}}},[n("span",{staticClass:"el-select__tags-text"},[e._v(e._s(t.currentLabel))])])})),1),e.filterable?n("input",{directives:[{name:"model",rawName:"v-model",value:e.query,expression:"query"}],ref:"input",staticClass:"el-select__input",class:[e.selectSize?"is-"+e.selectSize:""],style:{"flex-grow":"1",width:e.inputLength/(e.inputWidth-32)+"%","max-width":e.inputWidth-42+"px"},attrs:{type:"text",disabled:e.selectDisabled,autocomplete:e.autoComplete||e.autocomplete},domProps:{value:e.query},on:{focus:e.handleFocus,blur:function(t){e.softFocus=!1},keyup:e.managePlaceholder,keydown:[e.resetInputState,function(t){if(!("button"in t)&&e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"]))return null;t.preventDefault(),e.navigateOptions("next")},function(t){if(!("button"in t)&&e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"]))return null;t.preventDefault(),e.navigateOptions("prev")},function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?(t.preventDefault(),e.selectOption(t)):null},function(t){if(!("button"in t)&&e._k(t.keyCode,"esc",27,t.key,["Esc","Escape"]))return null;t.stopPropagation(),t.preventDefault(),e.visible=!1},function(t){return"button"in t||!e._k(t.keyCode,"delete",[8,46],t.key,["Backspace","Delete","Del"])?e.deletePrevTag(t):null},function(t){if(!("button"in t)&&e._k(t.keyCode,"tab",9,t.key,"Tab"))return null;e.visible=!1}],compositionstart:e.handleComposition,compositionupdate:e.handleComposition,compositionend:e.handleComposition,input:[function(t){t.target.composing||(e.query=t.target.value)},e.debouncedQueryChange]}}):e._e()],1):e._e(),n("el-input",{ref:"reference",class:{"is-focus":e.visible},attrs:{type:"text",placeholder:e.currentPlaceholder,name:e.name,id:e.id,autocomplete:e.autoComplete||e.autocomplete,size:e.selectSize,disabled:e.selectDisabled,readonly:e.readonly,"validate-event":!1,tabindex:e.multiple&&e.filterable?"-1":null},on:{focus:e.handleFocus,blur:e.handleBlur},nativeOn:{keyup:function(t){return e.debouncedOnInputChange(t)},keydown:[function(t){if(!("button"in t)&&e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"]))return null;t.stopPropagation(),t.preventDefault(),e.navigateOptions("next")},function(t){if(!("button"in t)&&e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"]))return null;t.stopPropagation(),t.preventDefault(),e.navigateOptions("prev")},function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?(t.preventDefault(),e.selectOption(t)):null},function(t){if(!("button"in t)&&e._k(t.keyCode,"esc",27,t.key,["Esc","Escape"]))return null;t.stopPropagation(),t.preventDefault(),e.visible=!1},function(t){if(!("button"in t)&&e._k(t.keyCode,"tab",9,t.key,"Tab"))return null;e.visible=!1}],paste:function(t){return e.debouncedOnInputChange(t)},mouseenter:function(t){e.inputHovering=!0},mouseleave:function(t){e.inputHovering=!1}},model:{value:e.selectedLabel,callback:function(t){e.selectedLabel=t},expression:"selectedLabel"}},[e.$slots.prefix?n("template",{slot:"prefix"},[e._t("prefix")],2):e._e(),n("template",{slot:"suffix"},[n("i",{directives:[{name:"show",rawName:"v-show",value:!e.showClose,expression:"!showClose"}],class:["el-select__caret","el-input__icon","el-icon-"+e.iconClass]}),e.showClose?n("i",{staticClass:"el-select__caret el-input__icon el-icon-circle-close",on:{click:e.handleClearClick}}):e._e()])],2),n("transition",{attrs:{name:"el-zoom-in-top"},on:{"before-enter":e.handleMenuEnter,"after-leave":e.doDestroy}},[n("el-select-menu",{directives:[{name:"show",rawName:"v-show",value:e.visible&&!1!==e.emptyText,expression:"visible && emptyText !== false"}],ref:"popper",attrs:{"append-to-body":e.popperAppendToBody}},[n("el-scrollbar",{directives:[{name:"show",rawName:"v-show",value:e.options.length>0&&!e.loading,expression:"options.length > 0 && !loading"}],ref:"scrollbar",class:{"is-empty":!e.allowCreate&&e.query&&0===e.filteredOptionsCount},attrs:{tag:"ul","wrap-class":"el-select-dropdown__wrap","view-class":"el-select-dropdown__list"}},[e.showNewOption?n("el-option",{attrs:{value:e.query,created:""}}):e._e(),e._t("default")],2),e.emptyText&&(!e.allowCreate||e.loading||e.allowCreate&&0===e.options.length)?[e.$slots.empty?e._t("empty"):n("p",{staticClass:"el-select-dropdown__empty"},[e._v("\n "+e._s(e.emptyText)+"\n ")])]:e._e()],2)],1)],1)},r=[];i._withStripped=!0;var o=n(4),a=n.n(o),s=n(22),l=n.n(s),c=n(6),u=n.n(c),d=n(11),h=n.n(d),f=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-select-dropdown el-popper",class:[{"is-multiple":e.$parent.multiple},e.popperClass],style:{minWidth:e.minWidth}},[e._t("default")],2)},p=[];f._withStripped=!0;var m=n(5),v=n.n(m),g={name:"ElSelectDropdown",componentName:"ElSelectDropdown",mixins:[v.a],props:{placement:{default:"bottom-start"},boundariesPadding:{default:0},popperOptions:{default:function(){return{gpuAcceleration:!1}}},visibleArrow:{default:!0},appendToBody:{type:Boolean,default:!0}},data:function(){return{minWidth:""}},computed:{popperClass:function(){return this.$parent.popperClass}},watch:{"$parent.inputWidth":function(){this.minWidth=this.$parent.$el.getBoundingClientRect().width+"px"}},mounted:function(){var e=this;this.referenceElm=this.$parent.$refs.reference.$el,this.$parent.popperElm=this.popperElm=this.$el,this.$on("updatePopper",(function(){e.$parent.visible&&e.updatePopper()})),this.$on("destroyPopper",this.destroyPopper)}},b=g,y=n(0),_=Object(y["a"])(b,f,p,!1,null,null,null);_.options.__file="packages/select/src/select-dropdown.vue";var x=_.exports,w=n(33),C=n(36),k=n.n(C),S=n(13),O=n.n(S),$=n(16),D=n.n($),E=n(12),T=n.n(E),P=n(15),M=n(20),I=n(31),N=n.n(I),j=n(3),A={data:function(){return{hoverOption:-1}},computed:{optionsAllDisabled:function(){return this.options.filter((function(e){return e.visible})).every((function(e){return e.disabled}))}},watch:{hoverIndex:function(e){var t=this;"number"===typeof e&&e>-1&&(this.hoverOption=this.options[e]||{}),this.options.forEach((function(e){e.hover=t.hoverOption===e}))}},methods:{navigateOptions:function(e){var t=this;if(this.visible){if(0!==this.options.length&&0!==this.filteredOptionsCount&&!this.optionsAllDisabled){"next"===e?(this.hoverIndex++,this.hoverIndex===this.options.length&&(this.hoverIndex=0)):"prev"===e&&(this.hoverIndex--,this.hoverIndex<0&&(this.hoverIndex=this.options.length-1));var n=this.options[this.hoverIndex];!0!==n.disabled&&!0!==n.groupDisabled&&n.visible||this.navigateOptions(e),this.$nextTick((function(){return t.scrollToOption(t.hoverOption)}))}}else this.visible=!0}}},F=n(21),L={mixins:[a.a,u.a,l()("reference"),A],name:"ElSelect",componentName:"ElSelect",inject:{elForm:{default:""},elFormItem:{default:""}},provide:function(){return{select:this}},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},readonly:function(){return!this.filterable||this.multiple||!Object(j["isIE"])()&&!Object(j["isEdge"])()&&!this.visible},showClose:function(){var e=this.multiple?Array.isArray(this.value)&&this.value.length>0:void 0!==this.value&&null!==this.value&&""!==this.value,t=this.clearable&&!this.selectDisabled&&this.inputHovering&&e;return t},iconClass:function(){return this.remote&&this.filterable?"":this.visible?"arrow-up is-reverse":"arrow-up"},debounce:function(){return this.remote?300:0},emptyText:function(){return this.loading?this.loadingText||this.t("el.select.loading"):(!this.remote||""!==this.query||0!==this.options.length)&&(this.filterable&&this.query&&this.options.length>0&&0===this.filteredOptionsCount?this.noMatchText||this.t("el.select.noMatch"):0===this.options.length?this.noDataText||this.t("el.select.noData"):null)},showNewOption:function(){var e=this,t=this.options.filter((function(e){return!e.created})).some((function(t){return t.currentLabel===e.query}));return this.filterable&&this.allowCreate&&""!==this.query&&!t},selectSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},selectDisabled:function(){return this.disabled||(this.elForm||{}).disabled},collapseTagSize:function(){return["small","mini"].indexOf(this.selectSize)>-1?"mini":"small"}},components:{ElInput:h.a,ElSelectMenu:x,ElOption:w["a"],ElTag:k.a,ElScrollbar:O.a},directives:{Clickoutside:T.a},props:{name:String,id:String,value:{required:!0},autocomplete:{type:String,default:"off"},autoComplete:{type:String,validator:function(e){return!0}},automaticDropdown:Boolean,size:String,disabled:Boolean,clearable:Boolean,filterable:Boolean,allowCreate:Boolean,loading:Boolean,popperClass:String,remote:Boolean,loadingText:String,noMatchText:String,noDataText:String,remoteMethod:Function,filterMethod:Function,multiple:Boolean,multipleLimit:{type:Number,default:0},placeholder:{type:String,default:function(){return Object(M["t"])("el.select.placeholder")}},defaultFirstOption:Boolean,reserveKeyword:Boolean,valueKey:{type:String,default:"value"},collapseTags:Boolean,popperAppendToBody:{type:Boolean,default:!0}},data:function(){return{options:[],cachedOptions:[],createdLabel:null,createdSelected:!1,selected:this.multiple?[]:{},inputLength:20,inputWidth:0,initialInputHeight:0,cachedPlaceHolder:"",optionsCount:0,filteredOptionsCount:0,visible:!1,softFocus:!1,selectedLabel:"",hoverIndex:-1,query:"",previousQuery:null,inputHovering:!1,currentPlaceholder:"",menuVisibleOnFocus:!1,isOnComposition:!1,isSilentBlur:!1}},watch:{selectDisabled:function(){var e=this;this.$nextTick((function(){e.resetInputHeight()}))},placeholder:function(e){this.cachedPlaceHolder=this.currentPlaceholder=e},value:function(e,t){this.multiple&&(this.resetInputHeight(),e&&e.length>0||this.$refs.input&&""!==this.query?this.currentPlaceholder="":this.currentPlaceholder=this.cachedPlaceHolder,this.filterable&&!this.reserveKeyword&&(this.query="",this.handleQueryChange(this.query))),this.setSelected(),this.filterable&&!this.multiple&&(this.inputLength=20),Object(j["valueEquals"])(e,t)||this.dispatch("ElFormItem","el.form.change",e)},visible:function(e){var t=this;e?(this.broadcast("ElSelectDropdown","updatePopper"),this.filterable&&(this.query=this.remote?"":this.selectedLabel,this.handleQueryChange(this.query),this.multiple?this.$refs.input.focus():(this.remote||(this.broadcast("ElOption","queryChange",""),this.broadcast("ElOptionGroup","queryChange")),this.selectedLabel&&(this.currentPlaceholder=this.selectedLabel,this.selectedLabel="")))):(this.broadcast("ElSelectDropdown","destroyPopper"),this.$refs.input&&this.$refs.input.blur(),this.query="",this.previousQuery=null,this.selectedLabel="",this.inputLength=20,this.menuVisibleOnFocus=!1,this.resetHoverIndex(),this.$nextTick((function(){t.$refs.input&&""===t.$refs.input.value&&0===t.selected.length&&(t.currentPlaceholder=t.cachedPlaceHolder)})),this.multiple||(this.selected&&(this.filterable&&this.allowCreate&&this.createdSelected&&this.createdLabel?this.selectedLabel=this.createdLabel:this.selectedLabel=this.selected.currentLabel,this.filterable&&(this.query=this.selectedLabel)),this.filterable&&(this.currentPlaceholder=this.cachedPlaceHolder))),this.$emit("visible-change",e)},options:function(){var e=this;if(!this.$isServer){this.$nextTick((function(){e.broadcast("ElSelectDropdown","updatePopper")})),this.multiple&&this.resetInputHeight();var t=this.$el.querySelectorAll("input");-1===[].indexOf.call(t,document.activeElement)&&this.setSelected(),this.defaultFirstOption&&(this.filterable||this.remote)&&this.filteredOptionsCount&&this.checkDefaultFirstOption()}}},methods:{handleComposition:function(e){var t=this,n=e.target.value;if("compositionend"===e.type)this.isOnComposition=!1,this.$nextTick((function(e){return t.handleQueryChange(n)}));else{var i=n[n.length-1]||"";this.isOnComposition=!Object(F["isKorean"])(i)}},handleQueryChange:function(e){var t=this;this.previousQuery===e||this.isOnComposition||(null!==this.previousQuery||"function"!==typeof this.filterMethod&&"function"!==typeof this.remoteMethod?(this.previousQuery=e,this.$nextTick((function(){t.visible&&t.broadcast("ElSelectDropdown","updatePopper")})),this.hoverIndex=-1,this.multiple&&this.filterable&&this.$nextTick((function(){var e=15*t.$refs.input.value.length+20;t.inputLength=t.collapseTags?Math.min(50,e):e,t.managePlaceholder(),t.resetInputHeight()})),this.remote&&"function"===typeof this.remoteMethod?(this.hoverIndex=-1,this.remoteMethod(e)):"function"===typeof this.filterMethod?(this.filterMethod(e),this.broadcast("ElOptionGroup","queryChange")):(this.filteredOptionsCount=this.optionsCount,this.broadcast("ElOption","queryChange",e),this.broadcast("ElOptionGroup","queryChange")),this.defaultFirstOption&&(this.filterable||this.remote)&&this.filteredOptionsCount&&this.checkDefaultFirstOption()):this.previousQuery=e)},scrollToOption:function(e){var t=Array.isArray(e)&&e[0]?e[0].$el:e.$el;if(this.$refs.popper&&t){var n=this.$refs.popper.$el.querySelector(".el-select-dropdown__wrap");N()(n,t)}this.$refs.scrollbar&&this.$refs.scrollbar.handleScroll()},handleMenuEnter:function(){var e=this;this.$nextTick((function(){return e.scrollToOption(e.selected)}))},emitChange:function(e){Object(j["valueEquals"])(this.value,e)||this.$emit("change",e)},getOption:function(e){for(var t=void 0,n="[object object]"===Object.prototype.toString.call(e).toLowerCase(),i="[object null]"===Object.prototype.toString.call(e).toLowerCase(),r="[object undefined]"===Object.prototype.toString.call(e).toLowerCase(),o=this.cachedOptions.length-1;o>=0;o--){var a=this.cachedOptions[o],s=n?Object(j["getValueByPath"])(a.value,this.valueKey)===Object(j["getValueByPath"])(e,this.valueKey):a.value===e;if(s){t=a;break}}if(t)return t;var l=n||i||r?"":e,c={value:e,currentLabel:l};return this.multiple&&(c.hitState=!1),c},setSelected:function(){var e=this;if(!this.multiple){var t=this.getOption(this.value);return t.created?(this.createdLabel=t.currentLabel,this.createdSelected=!0):this.createdSelected=!1,this.selectedLabel=t.currentLabel,this.selected=t,void(this.filterable&&(this.query=this.selectedLabel))}var n=[];Array.isArray(this.value)&&this.value.forEach((function(t){n.push(e.getOption(t))})),this.selected=n,this.$nextTick((function(){e.resetInputHeight()}))},handleFocus:function(e){this.softFocus?this.softFocus=!1:((this.automaticDropdown||this.filterable)&&(this.visible=!0,this.filterable&&(this.menuVisibleOnFocus=!0)),this.$emit("focus",e))},blur:function(){this.visible=!1,this.$refs.reference.blur()},handleBlur:function(e){var t=this;setTimeout((function(){t.isSilentBlur?t.isSilentBlur=!1:t.$emit("blur",e)}),50),this.softFocus=!1},handleClearClick:function(e){this.deleteSelected(e)},doDestroy:function(){this.$refs.popper&&this.$refs.popper.doDestroy()},handleClose:function(){this.visible=!1},toggleLastOptionHitState:function(e){if(Array.isArray(this.selected)){var t=this.selected[this.selected.length-1];if(t)return!0===e||!1===e?(t.hitState=e,e):(t.hitState=!t.hitState,t.hitState)}},deletePrevTag:function(e){if(e.target.value.length<=0&&!this.toggleLastOptionHitState()){var t=this.value.slice();t.pop(),this.$emit("input",t),this.emitChange(t)}},managePlaceholder:function(){""!==this.currentPlaceholder&&(this.currentPlaceholder=this.$refs.input.value?"":this.cachedPlaceHolder)},resetInputState:function(e){8!==e.keyCode&&this.toggleLastOptionHitState(!1),this.inputLength=15*this.$refs.input.value.length+20,this.resetInputHeight()},resetInputHeight:function(){var e=this;this.collapseTags&&!this.filterable||this.$nextTick((function(){if(e.$refs.reference){var t=e.$refs.reference.$el.childNodes,n=[].filter.call(t,(function(e){return"INPUT"===e.tagName}))[0],i=e.$refs.tags,r=e.initialInputHeight||40;n.style.height=0===e.selected.length?r+"px":Math.max(i?i.clientHeight+(i.clientHeight>r?6:0):0,r)+"px",e.visible&&!1!==e.emptyText&&e.broadcast("ElSelectDropdown","updatePopper")}}))},resetHoverIndex:function(){var e=this;setTimeout((function(){e.multiple?e.selected.length>0?e.hoverIndex=Math.min.apply(null,e.selected.map((function(t){return e.options.indexOf(t)}))):e.hoverIndex=-1:e.hoverIndex=e.options.indexOf(e.selected)}),300)},handleOptionSelect:function(e,t){var n=this;if(this.multiple){var i=(this.value||[]).slice(),r=this.getValueIndex(i,e.value);r>-1?i.splice(r,1):(this.multipleLimit<=0||i.length0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1],n="[object object]"===Object.prototype.toString.call(t).toLowerCase();if(n){var i=this.valueKey,r=-1;return e.some((function(e,n){return Object(j["getValueByPath"])(e,i)===Object(j["getValueByPath"])(t,i)&&(r=n,!0)})),r}return e.indexOf(t)},toggleMenu:function(){this.selectDisabled||(this.menuVisibleOnFocus?this.menuVisibleOnFocus=!1:this.visible=!this.visible,this.visible&&(this.$refs.input||this.$refs.reference).focus())},selectOption:function(){this.visible?this.options[this.hoverIndex]&&this.handleOptionSelect(this.options[this.hoverIndex]):this.toggleMenu()},deleteSelected:function(e){e.stopPropagation();var t=this.multiple?[]:"";this.$emit("input",t),this.emitChange(t),this.visible=!1,this.$emit("clear")},deleteTag:function(e,t){var n=this.selected.indexOf(t);if(n>-1&&!this.selectDisabled){var i=this.value.slice();i.splice(n,1),this.$emit("input",i),this.emitChange(i),this.$emit("remove-tag",t.value)}e.stopPropagation()},onInputChange:function(){this.filterable&&this.query!==this.selectedLabel&&(this.query=this.selectedLabel,this.handleQueryChange(this.query))},onOptionDestroy:function(e){e>-1&&(this.optionsCount--,this.filteredOptionsCount--,this.options.splice(e,1))},resetInputWidth:function(){this.inputWidth=this.$refs.reference.$el.getBoundingClientRect().width},handleResize:function(){this.resetInputWidth(),this.multiple&&this.resetInputHeight()},checkDefaultFirstOption:function(){this.hoverIndex=-1;for(var e=!1,t=this.options.length-1;t>=0;t--)if(this.options[t].created){e=!0,this.hoverIndex=t;break}if(!e)for(var n=0;n!==this.options.length;++n){var i=this.options[n];if(this.query){if(!i.disabled&&!i.groupDisabled&&i.visible){this.hoverIndex=n;break}}else if(i.itemSelected){this.hoverIndex=n;break}}},getValueKey:function(e){return"[object object]"!==Object.prototype.toString.call(e.value).toLowerCase()?e.value:Object(j["getValueByPath"])(e.value,this.valueKey)}},created:function(){var e=this;this.cachedPlaceHolder=this.currentPlaceholder=this.placeholder,this.multiple&&!Array.isArray(this.value)&&this.$emit("input",[]),!this.multiple&&Array.isArray(this.value)&&this.$emit("input",""),this.debouncedOnInputChange=D()(this.debounce,(function(){e.onInputChange()})),this.debouncedQueryChange=D()(this.debounce,(function(t){e.handleQueryChange(t.target.value)})),this.$on("handleOptionClick",this.handleOptionSelect),this.$on("setSelected",this.setSelected)},mounted:function(){var e=this;this.multiple&&Array.isArray(this.value)&&this.value.length>0&&(this.currentPlaceholder=""),Object(P["addResizeListener"])(this.$el,this.handleResize);var t=this.$refs.reference;if(t&&t.$el){var n={medium:36,small:32,mini:28},i=t.$el.querySelector("input");this.initialInputHeight=i.getBoundingClientRect().height||n[this.selectSize]}this.remote&&this.multiple&&this.resetInputHeight(),this.$nextTick((function(){t&&t.$el&&(e.inputWidth=t.$el.getBoundingClientRect().width)})),this.setSelected()},beforeDestroy:function(){this.$el&&this.handleResize&&Object(P["removeResizeListener"])(this.$el,this.handleResize)}},V=L,z=Object(y["a"])(V,i,r,!1,null,null,null);z.options.__file="packages/select/src/select.vue";var B=z.exports;B.install=function(e){e.component(B.name,B)};t["default"]=B}])},"4e71":function(e,t,n){n("e198")("observable")},"4ebc":function(e,t,n){var i=n("4d88");e.exports=Array.isArray||function(e){return"Array"==i(e)}},"50c4":function(e,t,n){var i=n("a691"),r=Math.min;e.exports=function(e){return e>0?r(i(e),9007199254740991):0}},"511f":function(e,t,n){n("0b99"),n("658f"),e.exports=n("fcd4").f("iterator")},5128:function(e,t,n){"use strict";t.__esModule=!0,t.PopupManager=void 0;var i=n("2b0e"),r=h(i),o=n("7f4d"),a=h(o),s=n("4b26"),l=h(s),c=n("e62d"),u=h(c),d=n("5924");function h(e){return e&&e.__esModule?e:{default:e}}var f=1,p=void 0;t.default={props:{visible:{type:Boolean,default:!1},openDelay:{},closeDelay:{},zIndex:{},modal:{type:Boolean,default:!1},modalFade:{type:Boolean,default:!0},modalClass:{},modalAppendToBody:{type:Boolean,default:!1},lockScroll:{type:Boolean,default:!0},closeOnPressEscape:{type:Boolean,default:!1},closeOnClickModal:{type:Boolean,default:!1}},beforeMount:function(){this._popupId="popup-"+f++,l.default.register(this._popupId,this)},beforeDestroy:function(){l.default.deregister(this._popupId),l.default.closeModal(this._popupId),this.restoreBodyStyle()},data:function(){return{opened:!1,bodyPaddingRight:null,computedBodyPaddingRight:0,withoutHiddenClass:!0,rendered:!1}},watch:{visible:function(e){var t=this;if(e){if(this._opening)return;this.rendered?this.open():(this.rendered=!0,r.default.nextTick((function(){t.open()})))}else this.close()}},methods:{open:function(e){var t=this;this.rendered||(this.rendered=!0);var n=(0,a.default)({},this.$props||this,e);this._closeTimer&&(clearTimeout(this._closeTimer),this._closeTimer=null),clearTimeout(this._openTimer);var i=Number(n.openDelay);i>0?this._openTimer=setTimeout((function(){t._openTimer=null,t.doOpen(n)}),i):this.doOpen(n)},doOpen:function(e){if(!this.$isServer&&(!this.willOpen||this.willOpen())&&!this.opened){this._opening=!0;var t=this.$el,n=e.modal,i=e.zIndex;if(i&&(l.default.zIndex=i),n&&(this._closing&&(l.default.closeModal(this._popupId),this._closing=!1),l.default.openModal(this._popupId,l.default.nextZIndex(),this.modalAppendToBody?void 0:t,e.modalClass,e.modalFade),e.lockScroll)){this.withoutHiddenClass=!(0,d.hasClass)(document.body,"el-popup-parent--hidden"),this.withoutHiddenClass&&(this.bodyPaddingRight=document.body.style.paddingRight,this.computedBodyPaddingRight=parseInt((0,d.getStyle)(document.body,"paddingRight"),10)),p=(0,u.default)();var r=document.documentElement.clientHeight0&&(r||"scroll"===o)&&this.withoutHiddenClass&&(document.body.style.paddingRight=this.computedBodyPaddingRight+p+"px"),(0,d.addClass)(document.body,"el-popup-parent--hidden")}"static"===getComputedStyle(t).position&&(t.style.position="absolute"),t.style.zIndex=l.default.nextZIndex(),this.opened=!0,this.onOpen&&this.onOpen(),this.doAfterOpen()}},doAfterOpen:function(){this._opening=!1},close:function(){var e=this;if(!this.willClose||this.willClose()){null!==this._openTimer&&(clearTimeout(this._openTimer),this._openTimer=null),clearTimeout(this._closeTimer);var t=Number(this.closeDelay);t>0?this._closeTimer=setTimeout((function(){e._closeTimer=null,e.doClose()}),t):this.doClose()}},doClose:function(){this._closing=!0,this.onClose&&this.onClose(),this.lockScroll&&setTimeout(this.restoreBodyStyle,200),this.opened=!1,this.doAfterClose()},doAfterClose:function(){l.default.closeModal(this._popupId),this._closing=!1},restoreBodyStyle:function(){this.modal&&this.withoutHiddenClass&&(document.body.style.paddingRight=this.bodyPaddingRight,(0,d.removeClass)(document.body,"el-popup-parent--hidden")),this.withoutHiddenClass=!0}}},t.PopupManager=l.default},"512c":function(e,t,n){var i=n("ef08"),r=n("5524"),o=n("9c0c"),a=n("051b"),s=n("9c0e"),l="prototype",c=function(e,t,n){var u,d,h,f=e&c.F,p=e&c.G,m=e&c.S,v=e&c.P,g=e&c.B,b=e&c.W,y=p?r:r[t]||(r[t]={}),_=y[l],x=p?i:m?i[t]:(i[t]||{})[l];for(u in p&&(n=t),n)d=!f&&x&&void 0!==x[u],d&&s(y,u)||(h=d?x[u]:n[u],y[u]=p&&"function"!=typeof x[u]?n[u]:g&&d?o(h,i):b&&x[u]==h?function(e){var t=function(t,n,i){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,i)}return e.apply(this,arguments)};return t[l]=e[l],t}(h):v&&"function"==typeof h?o(Function.call,h):h,v&&((y.virtual||(y.virtual={}))[u]=h,e&c.R&&_&&!_[u]&&a(_,u,h)))};c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,e.exports=c},5135:function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},5270:function(e,t,n){"use strict";var i=n("c532"),r=n("c401"),o=n("2e67"),a=n("2444"),s=n("d925"),l=n("e683");function c(e){e.cancelToken&&e.cancelToken.throwIfRequested()}e.exports=function(e){c(e),e.baseURL&&!s(e.url)&&(e.url=l(e.baseURL,e.url)),e.headers=e.headers||{},e.data=r(e.data,e.headers,e.transformRequest),e.headers=i.merge(e.headers.common||{},e.headers[e.method]||{},e.headers||{}),i.forEach(["delete","get","head","post","put","patch","common"],(function(t){delete e.headers[t]}));var t=e.adapter||a.adapter;return t(e).then((function(t){return c(e),t.data=r(t.data,t.headers,e.transformResponse),t}),(function(t){return o(t)||(c(e),t&&t.response&&(t.response.data=r(t.response.data,t.response.headers,e.transformResponse))),Promise.reject(t)}))}},5488:function(e,t,n){"use strict";t.__esModule=!0;var i=n("5924");function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(){r(this,e)}return e.prototype.beforeEnter=function(e){(0,i.addClass)(e,"collapse-transition"),e.dataset||(e.dataset={}),e.dataset.oldPaddingTop=e.style.paddingTop,e.dataset.oldPaddingBottom=e.style.paddingBottom,e.style.height="0",e.style.paddingTop=0,e.style.paddingBottom=0},e.prototype.enter=function(e){e.dataset.oldOverflow=e.style.overflow,0!==e.scrollHeight?(e.style.height=e.scrollHeight+"px",e.style.paddingTop=e.dataset.oldPaddingTop,e.style.paddingBottom=e.dataset.oldPaddingBottom):(e.style.height="",e.style.paddingTop=e.dataset.oldPaddingTop,e.style.paddingBottom=e.dataset.oldPaddingBottom),e.style.overflow="hidden"},e.prototype.afterEnter=function(e){(0,i.removeClass)(e,"collapse-transition"),e.style.height="",e.style.overflow=e.dataset.oldOverflow},e.prototype.beforeLeave=function(e){e.dataset||(e.dataset={}),e.dataset.oldPaddingTop=e.style.paddingTop,e.dataset.oldPaddingBottom=e.style.paddingBottom,e.dataset.oldOverflow=e.style.overflow,e.style.height=e.scrollHeight+"px",e.style.overflow="hidden"},e.prototype.leave=function(e){0!==e.scrollHeight&&((0,i.addClass)(e,"collapse-transition"),e.style.height=0,e.style.paddingTop=0,e.style.paddingBottom=0)},e.prototype.afterLeave=function(e){(0,i.removeClass)(e,"collapse-transition"),e.style.height="",e.style.overflow=e.dataset.oldOverflow,e.style.paddingTop=e.dataset.oldPaddingTop,e.style.paddingBottom=e.dataset.oldPaddingBottom},e}();t.default={name:"ElCollapseTransition",functional:!0,render:function(e,t){var n=t.children,i={on:new o};return e("transition",i,n)}}},5524:function(e,t){var n=e.exports={version:"2.6.10"};"number"==typeof __e&&(__e=n)},5692:function(e,t,n){var i=n("c430"),r=n("c6cd");(e.exports=function(e,t){return r[e]||(r[e]=void 0!==t?t:{})})("versions",[]).push({version:"3.3.5",mode:i?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},"56ef":function(e,t,n){var i=n("d066"),r=n("241c"),o=n("7418"),a=n("825a");e.exports=i("Reflect","ownKeys")||function(e){var t=r.f(a(e)),n=o.f;return n?t.concat(n(e)):t}},5924:function(e,t,n){"use strict";t.__esModule=!0,t.isInContainer=t.getScrollContainer=t.isScroll=t.getStyle=t.once=t.off=t.on=void 0;var i="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};t.hasClass=m,t.addClass=v,t.removeClass=g,t.setStyle=y;var r=n("2b0e"),o=a(r);function a(e){return e&&e.__esModule?e:{default:e}}var s=o.default.prototype.$isServer,l=/([\:\-\_]+(.))/g,c=/^moz([A-Z])/,u=s?0:Number(document.documentMode),d=function(e){return(e||"").replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g,"")},h=function(e){return e.replace(l,(function(e,t,n,i){return i?n.toUpperCase():n})).replace(c,"Moz$1")},f=t.on=function(){return!s&&document.addEventListener?function(e,t,n){e&&t&&n&&e.addEventListener(t,n,!1)}:function(e,t,n){e&&t&&n&&e.attachEvent("on"+t,n)}}(),p=t.off=function(){return!s&&document.removeEventListener?function(e,t,n){e&&t&&e.removeEventListener(t,n,!1)}:function(e,t,n){e&&t&&e.detachEvent("on"+t,n)}}();t.once=function(e,t,n){var i=function i(){n&&n.apply(this,arguments),p(e,t,i)};f(e,t,i)};function m(e,t){if(!e||!t)return!1;if(-1!==t.indexOf(" "))throw new Error("className should not contain space.");return e.classList?e.classList.contains(t):(" "+e.className+" ").indexOf(" "+t+" ")>-1}function v(e,t){if(e){for(var n=e.className,i=(t||"").split(" "),r=0,o=i.length;ri.top&&n.right>i.left&&n.lefte?c():!0!==t&&(r=setTimeout(i?u:c,void 0===i?e-s:e))}return("boolean"!==typeof t&&(i=n,n=t,t=void 0),a)}},"5a94":function(e,t,n){var i=n("b367")("keys"),r=n("8b1a");e.exports=function(e){return i[e]||(i[e]=r(e))}},"5c6c":function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},"5c96":function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=44)}([function(e,t){e.exports=n("d940")},function(e,t){e.exports=n("5924")},function(e,t){e.exports=n("8122")},function(e,t){e.exports=n("d010")},function(e,t){e.exports=n("6b7c")},function(e,t){e.exports=n("e974")},function(e,t){e.exports=n("2b0e")},function(e,t){e.exports=n("7f4d")},function(e,t){e.exports=n("2bb5")},function(e,t){e.exports=n("f3ad")},function(e,t){e.exports=n("417f")},function(e,t){e.exports=n("4010")},function(e,t){e.exports=n("5128")},function(e,t){e.exports=n("0e15")},function(e,t){e.exports=n("dcdc")},function(e,t){e.exports=n("4897")},function(e,t){e.exports=n("14e9")},function(e,t){e.exports=n("eedf")},function(e,t){e.exports=n("a742")},function(e,t){e.exports=n("d397")},function(e,t){e.exports=n("d7d1")},function(e,t){e.exports=n("5488")},function(e,t){e.exports=n("12f2")},function(e,t){e.exports=n("41f8")},function(e,t){e.exports=n("92fa")},function(e,t){e.exports=n("597f")},function(e,t){e.exports=n("299c")},function(e,t){e.exports=n("2a5e")},function(e,t){e.exports=n("8bbc")},function(e,t){e.exports=n("e62d")},function(e,t){e.exports=n("7fc1")},function(e,t){e.exports=n("c56a")},function(e,t){e.exports=n("c284")},function(e,t){e.exports=n("e452")},function(e,t){e.exports=n("9619")},function(e,t){e.exports=n("4e4b")},function(e,t){e.exports=n("e772")},function(e,t){e.exports=n("845f")},function(e,t){e.exports=n("c098")},function(e,t){e.exports=n("722f")},function(e,t){e.exports=n("a15e")},function(e,t){e.exports=n("e450")},function(e,t){e.exports=n("4726")},function(e,t){e.exports=n("f494")},function(e,t,n){e.exports=n(45)},function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("ul",{staticClass:"el-pager",on:{click:e.onPagerClick}},[e.pageCount>0?n("li",{staticClass:"number",class:{active:1===e.currentPage,disabled:e.disabled}},[e._v("1")]):e._e(),e.showPrevMore?n("li",{staticClass:"el-icon more btn-quickprev",class:[e.quickprevIconClass,{disabled:e.disabled}],on:{mouseenter:function(t){e.onMouseenter("left")},mouseleave:function(t){e.quickprevIconClass="el-icon-more"}}}):e._e(),e._l(e.pagers,(function(t){return n("li",{key:t,staticClass:"number",class:{active:e.currentPage===t,disabled:e.disabled}},[e._v(e._s(t))])})),e.showNextMore?n("li",{staticClass:"el-icon more btn-quicknext",class:[e.quicknextIconClass,{disabled:e.disabled}],on:{mouseenter:function(t){e.onMouseenter("right")},mouseleave:function(t){e.quicknextIconClass="el-icon-more"}}}):e._e(),e.pageCount>1?n("li",{staticClass:"number",class:{active:e.currentPage===e.pageCount,disabled:e.disabled}},[e._v(e._s(e.pageCount))]):e._e()],2)},r=[];i._withStripped=!0;var o={name:"ElPager",props:{currentPage:Number,pageCount:Number,pagerCount:Number,disabled:Boolean},watch:{showPrevMore:function(e){e||(this.quickprevIconClass="el-icon-more")},showNextMore:function(e){e||(this.quicknextIconClass="el-icon-more")}},methods:{onPagerClick:function(e){var t=e.target;if("UL"!==t.tagName&&!this.disabled){var n=Number(e.target.textContent),i=this.pageCount,r=this.currentPage,o=this.pagerCount-2;-1!==t.className.indexOf("more")&&(-1!==t.className.indexOf("quickprev")?n=r-o:-1!==t.className.indexOf("quicknext")&&(n=r+o)),isNaN(n)||(n<1&&(n=1),n>i&&(n=i)),n!==r&&this.$emit("change",n)}},onMouseenter:function(e){this.disabled||("left"===e?this.quickprevIconClass="el-icon-d-arrow-left":this.quicknextIconClass="el-icon-d-arrow-right")}},computed:{pagers:function(){var e=this.pagerCount,t=(e-1)/2,n=Number(this.currentPage),i=Number(this.pageCount),r=!1,o=!1;i>e&&(n>e-t&&(r=!0),n4&&e<22&&e%2===1},default:7},currentPage:{type:Number,default:1},layout:{default:"prev, pager, next, jumper, ->, total"},pageSizes:{type:Array,default:function(){return[10,20,30,40,50,100]}},popperClass:String,prevText:String,nextText:String,background:Boolean,disabled:Boolean,hideOnSinglePage:Boolean},data:function(){return{internalCurrentPage:1,internalPageSize:0,lastEmittedPage:-1,userChangePageSize:!1}},render:function(e){var t=this.layout;if(!t)return null;if(this.hideOnSinglePage&&(!this.internalPageCount||1===this.internalPageCount))return null;var n=e("div",{class:["el-pagination",{"is-background":this.background,"el-pagination--small":this.small}]}),i={prev:e("prev"),jumper:e("jumper"),pager:e("pager",{attrs:{currentPage:this.internalCurrentPage,pageCount:this.internalPageCount,pagerCount:this.pagerCount,disabled:this.disabled},on:{change:this.handleCurrentChange}}),next:e("next"),sizes:e("sizes",{attrs:{pageSizes:this.pageSizes}}),slot:e("slot",[this.$slots.default?this.$slots.default:""]),total:e("total")},r=t.split(",").map((function(e){return e.trim()})),o=e("div",{class:"el-pagination__rightwrapper"}),a=!1;return n.children=n.children||[],o.children=o.children||[],r.forEach((function(e){"->"!==e?a?o.children.push(i[e]):n.children.push(i[e]):a=!0})),a&&n.children.unshift(o),n},components:{Prev:{render:function(e){return e("button",{attrs:{type:"button",disabled:this.$parent.disabled||this.$parent.internalCurrentPage<=1},class:"btn-prev",on:{click:this.$parent.prev}},[this.$parent.prevText?e("span",[this.$parent.prevText]):e("i",{class:"el-icon el-icon-arrow-left"})])}},Next:{render:function(e){return e("button",{attrs:{type:"button",disabled:this.$parent.disabled||this.$parent.internalCurrentPage===this.$parent.internalPageCount||0===this.$parent.internalPageCount},class:"btn-next",on:{click:this.$parent.next}},[this.$parent.nextText?e("span",[this.$parent.nextText]):e("i",{class:"el-icon el-icon-arrow-right"})])}},Sizes:{mixins:[g.a],props:{pageSizes:Array},watch:{pageSizes:{immediate:!0,handler:function(e,t){Object(b["valueEquals"])(e,t)||Array.isArray(e)&&(this.$parent.internalPageSize=e.indexOf(this.$parent.pageSize)>-1?this.$parent.pageSize:this.pageSizes[0])}}},render:function(e){var t=this;return e("span",{class:"el-pagination__sizes"},[e("el-select",{attrs:{value:this.$parent.internalPageSize,popperClass:this.$parent.popperClass||"",size:"mini",disabled:this.$parent.disabled},on:{input:this.handleChange}},[this.pageSizes.map((function(n){return e("el-option",{attrs:{value:n,label:n+t.t("el.pagination.pagesize")}})}))])])},components:{ElSelect:d.a,ElOption:f.a},methods:{handleChange:function(e){e!==this.$parent.internalPageSize&&(this.$parent.internalPageSize=e=parseInt(e,10),this.$parent.userChangePageSize=!0,this.$parent.$emit("update:pageSize",e),this.$parent.$emit("size-change",e))}}},Jumper:{mixins:[g.a],components:{ElInput:m.a},data:function(){return{userInput:null}},watch:{"$parent.internalCurrentPage":function(){this.userInput=null}},methods:{handleKeyup:function(e){var t=e.keyCode,n=e.target;13===t&&this.handleChange(n.value)},handleInput:function(e){this.userInput=e},handleChange:function(e){this.$parent.internalCurrentPage=this.$parent.getValidCurrentPage(e),this.$parent.emitChange(),this.userInput=null}},render:function(e){return e("span",{class:"el-pagination__jump"},[this.t("el.pagination.goto"),e("el-input",{class:"el-pagination__editor is-in-pagination",attrs:{min:1,max:this.$parent.internalPageCount,value:null!==this.userInput?this.userInput:this.$parent.internalCurrentPage,type:"number",disabled:this.$parent.disabled},nativeOn:{keyup:this.handleKeyup},on:{input:this.handleInput,change:this.handleChange}}),this.t("el.pagination.pageClassifier")])}},Total:{mixins:[g.a],render:function(e){return"number"===typeof this.$parent.total?e("span",{class:"el-pagination__total"},[this.t("el.pagination.total",{total:this.$parent.total})]):""}},Pager:c},methods:{handleCurrentChange:function(e){this.internalCurrentPage=this.getValidCurrentPage(e),this.userChangePageSize=!0,this.emitChange()},prev:function(){if(!this.disabled){var e=this.internalCurrentPage-1;this.internalCurrentPage=this.getValidCurrentPage(e),this.$emit("prev-click",this.internalCurrentPage),this.emitChange()}},next:function(){if(!this.disabled){var e=this.internalCurrentPage+1;this.internalCurrentPage=this.getValidCurrentPage(e),this.$emit("next-click",this.internalCurrentPage),this.emitChange()}},getValidCurrentPage:function(e){e=parseInt(e,10);var t="number"===typeof this.internalPageCount,n=void 0;return t?e<1?n=1:e>this.internalPageCount&&(n=this.internalPageCount):(isNaN(e)||e<1)&&(n=1),void 0===n&&isNaN(e)?n=1:0===n&&(n=1),void 0===n?e:n},emitChange:function(){var e=this;this.$nextTick((function(){(e.internalCurrentPage!==e.lastEmittedPage||e.userChangePageSize)&&(e.$emit("current-change",e.internalCurrentPage),e.lastEmittedPage=e.internalCurrentPage,e.userChangePageSize=!1)}))}},computed:{internalPageCount:function(){return"number"===typeof this.total?Math.max(1,Math.ceil(this.total/this.internalPageSize)):"number"===typeof this.pageCount?Math.max(1,this.pageCount):null}},watch:{currentPage:{immediate:!0,handler:function(e){this.internalCurrentPage=this.getValidCurrentPage(e)}},pageSize:{immediate:!0,handler:function(e){this.internalPageSize=isNaN(e)?10:e}},internalCurrentPage:{immediate:!0,handler:function(e){this.$emit("update:currentPage",e),this.lastEmittedPage=-1}},internalPageCount:function(e){var t=this.internalCurrentPage;e>0&&0===t?this.internalCurrentPage=1:t>e&&(this.internalCurrentPage=0===e?1:e,this.userChangePageSize&&this.emitChange()),this.userChangePageSize=!1}},install:function(e){e.component(y.name,y)}},_=y,x=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"dialog-fade"},on:{"after-enter":e.afterEnter,"after-leave":e.afterLeave}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-dialog__wrapper",on:{click:function(t){return t.target!==t.currentTarget?null:e.handleWrapperClick(t)}}},[n("div",{key:e.key,ref:"dialog",class:["el-dialog",{"is-fullscreen":e.fullscreen,"el-dialog--center":e.center},e.customClass],style:e.style,attrs:{role:"dialog","aria-modal":"true","aria-label":e.title||"dialog"}},[n("div",{staticClass:"el-dialog__header"},[e._t("title",[n("span",{staticClass:"el-dialog__title"},[e._v(e._s(e.title))])]),e.showClose?n("button",{staticClass:"el-dialog__headerbtn",attrs:{type:"button","aria-label":"Close"},on:{click:e.handleClose}},[n("i",{staticClass:"el-dialog__close el-icon el-icon-close"})]):e._e()],2),e.rendered?n("div",{staticClass:"el-dialog__body"},[e._t("default")],2):e._e(),e.$slots.footer?n("div",{staticClass:"el-dialog__footer"},[e._t("footer")],2):e._e()])])])},w=[];x._withStripped=!0;var C=n(12),k=n.n(C),S=n(8),O=n.n(S),$=n(3),D=n.n($),E={name:"ElDialog",mixins:[k.a,D.a,O.a],props:{title:{type:String,default:""},modal:{type:Boolean,default:!0},modalAppendToBody:{type:Boolean,default:!0},appendToBody:{type:Boolean,default:!1},lockScroll:{type:Boolean,default:!0},closeOnClickModal:{type:Boolean,default:!0},closeOnPressEscape:{type:Boolean,default:!0},showClose:{type:Boolean,default:!0},width:String,fullscreen:Boolean,customClass:{type:String,default:""},top:{type:String,default:"15vh"},beforeClose:Function,center:{type:Boolean,default:!1},destroyOnClose:Boolean},data:function(){return{closed:!1,key:0}},watch:{visible:function(e){var t=this;e?(this.closed=!1,this.$emit("open"),this.$el.addEventListener("scroll",this.updatePopper),this.$nextTick((function(){t.$refs.dialog.scrollTop=0})),this.appendToBody&&document.body.appendChild(this.$el)):(this.$el.removeEventListener("scroll",this.updatePopper),this.closed||this.$emit("close"),this.destroyOnClose&&this.$nextTick((function(){t.key++})))}},computed:{style:function(){var e={};return this.fullscreen||(e.marginTop=this.top,this.width&&(e.width=this.width)),e}},methods:{getMigratingConfig:function(){return{props:{size:"size is removed."}}},handleWrapperClick:function(){this.closeOnClickModal&&this.handleClose()},handleClose:function(){"function"===typeof this.beforeClose?this.beforeClose(this.hide):this.hide()},hide:function(e){!1!==e&&(this.$emit("update:visible",!1),this.$emit("close"),this.closed=!0)},updatePopper:function(){this.broadcast("ElSelectDropdown","updatePopper"),this.broadcast("ElDropdownMenu","updatePopper")},afterEnter:function(){this.$emit("opened")},afterLeave:function(){this.$emit("closed")}},mounted:function(){this.visible&&(this.rendered=!0,this.open(),this.appendToBody&&document.body.appendChild(this.$el))},destroyed:function(){this.appendToBody&&this.$el&&this.$el.parentNode&&this.$el.parentNode.removeChild(this.$el)}},T=E,P=s(T,x,w,!1,null,null,null);P.options.__file="packages/dialog/src/component.vue";var M=P.exports;M.install=function(e){e.component(M.name,M)};var I=M,N=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.close,expression:"close"}],staticClass:"el-autocomplete",attrs:{"aria-haspopup":"listbox",role:"combobox","aria-expanded":e.suggestionVisible,"aria-owns":e.id}},[n("el-input",e._b({ref:"input",on:{input:e.handleChange,focus:e.handleFocus,blur:e.handleBlur,clear:e.handleClear},nativeOn:{keydown:[function(t){if(!("button"in t)&&e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"]))return null;t.preventDefault(),e.highlight(e.highlightedIndex-1)},function(t){if(!("button"in t)&&e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"]))return null;t.preventDefault(),e.highlight(e.highlightedIndex+1)},function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.handleKeyEnter(t):null},function(t){return"button"in t||!e._k(t.keyCode,"tab",9,t.key,"Tab")?e.close(t):null}]}},"el-input",[e.$props,e.$attrs],!1),[e.$slots.prepend?n("template",{slot:"prepend"},[e._t("prepend")],2):e._e(),e.$slots.append?n("template",{slot:"append"},[e._t("append")],2):e._e(),e.$slots.prefix?n("template",{slot:"prefix"},[e._t("prefix")],2):e._e(),e.$slots.suffix?n("template",{slot:"suffix"},[e._t("suffix")],2):e._e()],2),n("el-autocomplete-suggestions",{ref:"suggestions",class:[e.popperClass?e.popperClass:""],attrs:{"visible-arrow":"","popper-options":e.popperOptions,"append-to-body":e.popperAppendToBody,placement:e.placement,id:e.id}},e._l(e.suggestions,(function(t,i){return n("li",{key:i,class:{highlighted:e.highlightedIndex===i},attrs:{id:e.id+"-item-"+i,role:"option","aria-selected":e.highlightedIndex===i},on:{click:function(n){e.select(t)}}},[e._t("default",[e._v("\n "+e._s(t[e.valueKey])+"\n ")],{item:t})],2)})),0)],1)},j=[];N._withStripped=!0;var A=n(13),F=n.n(A),L=n(10),V=n.n(L),z=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":e.doDestroy}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.showPopper,expression:"showPopper"}],staticClass:"el-autocomplete-suggestion el-popper",class:{"is-loading":!e.parent.hideLoading&&e.parent.loading},style:{width:e.dropdownWidth},attrs:{role:"region"}},[n("el-scrollbar",{attrs:{tag:"ul","wrap-class":"el-autocomplete-suggestion__wrap","view-class":"el-autocomplete-suggestion__list"}},[!e.parent.hideLoading&&e.parent.loading?n("li",[n("i",{staticClass:"el-icon-loading"})]):e._t("default")],2)],1)])},B=[];z._withStripped=!0;var R=n(5),H=n.n(R),W=n(16),q=n.n(W),U={components:{ElScrollbar:q.a},mixins:[H.a,D.a],componentName:"ElAutocompleteSuggestions",data:function(){return{parent:this.$parent,dropdownWidth:""}},props:{options:{default:function(){return{gpuAcceleration:!1}}},id:String},methods:{select:function(e){this.dispatch("ElAutocomplete","item-click",e)}},updated:function(){var e=this;this.$nextTick((function(t){e.popperJS&&e.updatePopper()}))},mounted:function(){this.$parent.popperElm=this.popperElm=this.$el,this.referenceElm=this.$parent.$refs.input.$refs.input,this.referenceList=this.$el.querySelector(".el-autocomplete-suggestion__list"),this.referenceList.setAttribute("role","listbox"),this.referenceList.setAttribute("id",this.id)},created:function(){var e=this;this.$on("visible",(function(t,n){e.dropdownWidth=n+"px",e.showPopper=t}))}},Y=U,K=s(Y,z,B,!1,null,null,null);K.options.__file="packages/autocomplete/src/autocomplete-suggestions.vue";var G=K.exports,X=n(22),Z=n.n(X),J={name:"ElAutocomplete",mixins:[D.a,Z()("input"),O.a],inheritAttrs:!1,componentName:"ElAutocomplete",components:{ElInput:m.a,ElAutocompleteSuggestions:G},directives:{Clickoutside:V.a},props:{valueKey:{type:String,default:"value"},popperClass:String,popperOptions:Object,placeholder:String,clearable:{type:Boolean,default:!1},disabled:Boolean,name:String,size:String,value:String,maxlength:Number,minlength:Number,autofocus:Boolean,fetchSuggestions:Function,triggerOnFocus:{type:Boolean,default:!0},customItem:String,selectWhenUnmatched:{type:Boolean,default:!1},prefixIcon:String,suffixIcon:String,label:String,debounce:{type:Number,default:300},placement:{type:String,default:"bottom-start"},hideLoading:Boolean,popperAppendToBody:{type:Boolean,default:!0},highlightFirstItem:{type:Boolean,default:!1}},data:function(){return{activated:!1,suggestions:[],loading:!1,highlightedIndex:-1,suggestionDisabled:!1}},computed:{suggestionVisible:function(){var e=this.suggestions,t=Array.isArray(e)&&e.length>0;return(t||this.loading)&&this.activated},id:function(){return"el-autocomplete-"+Object(b["generateId"])()}},watch:{suggestionVisible:function(e){var t=this.getInput();t&&this.broadcast("ElAutocompleteSuggestions","visible",[e,t.offsetWidth])}},methods:{getMigratingConfig:function(){return{props:{"custom-item":"custom-item is removed, use scoped slot instead.",props:"props is removed, use value-key instead."}}},getData:function(e){var t=this;this.suggestionDisabled||(this.loading=!0,this.fetchSuggestions(e,(function(e){t.loading=!1,t.suggestionDisabled||(Array.isArray(e)?(t.suggestions=e,t.highlightedIndex=t.highlightFirstItem?0:-1):console.error("[Element Error][Autocomplete]autocomplete suggestions must be an array"))})))},handleChange:function(e){if(this.$emit("input",e),this.suggestionDisabled=!1,!this.triggerOnFocus&&!e)return this.suggestionDisabled=!0,void(this.suggestions=[]);this.debouncedGetData(e)},handleFocus:function(e){this.activated=!0,this.$emit("focus",e),this.triggerOnFocus&&this.debouncedGetData(this.value)},handleBlur:function(e){this.$emit("blur",e)},handleClear:function(){this.activated=!1,this.$emit("clear")},close:function(e){this.activated=!1},handleKeyEnter:function(e){var t=this;this.suggestionVisible&&this.highlightedIndex>=0&&this.highlightedIndex=this.suggestions.length&&(e=this.suggestions.length-1);var t=this.$refs.suggestions.$el.querySelector(".el-autocomplete-suggestion__wrap"),n=t.querySelectorAll(".el-autocomplete-suggestion__list li"),i=n[e],r=t.scrollTop,o=i.offsetTop;o+i.scrollHeight>r+t.clientHeight&&(t.scrollTop+=i.scrollHeight),o=0&&this.resetTabindex(this.triggerElm),clearTimeout(this.timeout),this.timeout=setTimeout((function(){e.visible=!1}),"click"===this.trigger?0:this.hideTimeout))},handleClick:function(){this.triggerElm.disabled||(this.visible?this.hide():this.show())},handleTriggerKeyDown:function(e){var t=e.keyCode;[38,40].indexOf(t)>-1?(this.removeTabindex(),this.resetTabindex(this.menuItems[0]),this.menuItems[0].focus(),e.preventDefault(),e.stopPropagation()):13===t?this.handleClick():[9,27].indexOf(t)>-1&&this.hide()},handleItemKeyDown:function(e){var t=e.keyCode,n=e.target,i=this.menuItemsArray.indexOf(n),r=this.menuItemsArray.length-1,o=void 0;[38,40].indexOf(t)>-1?(o=38===t?0!==i?i-1:0:i-1&&(this.hide(),this.triggerElmFocus())},resetTabindex:function(e){this.removeTabindex(),e.setAttribute("tabindex","0")},removeTabindex:function(){this.triggerElm.setAttribute("tabindex","-1"),this.menuItemsArray.forEach((function(e){e.setAttribute("tabindex","-1")}))},initAria:function(){this.dropdownElm.setAttribute("id",this.listId),this.triggerElm.setAttribute("aria-haspopup","list"),this.triggerElm.setAttribute("aria-controls",this.listId),this.splitButton||(this.triggerElm.setAttribute("role","button"),this.triggerElm.setAttribute("tabindex",this.tabindex),this.triggerElm.setAttribute("class",(this.triggerElm.getAttribute("class")||"")+" el-dropdown-selfdefine"))},initEvent:function(){var e=this,t=this.trigger,n=this.show,i=this.hide,r=this.handleClick,o=this.splitButton,a=this.handleTriggerKeyDown,s=this.handleItemKeyDown;this.triggerElm=o?this.$refs.trigger.$el:this.$slots.default[0].elm;var l=this.dropdownElm;this.triggerElm.addEventListener("keydown",a),l.addEventListener("keydown",s,!0),o||(this.triggerElm.addEventListener("focus",(function(){e.focusing=!0})),this.triggerElm.addEventListener("blur",(function(){e.focusing=!1})),this.triggerElm.addEventListener("click",(function(){e.focusing=!1}))),"hover"===t?(this.triggerElm.addEventListener("mouseenter",n),this.triggerElm.addEventListener("mouseleave",i),l.addEventListener("mouseenter",n),l.addEventListener("mouseleave",i)):"click"===t&&this.triggerElm.addEventListener("click",r)},handleMenuItemClick:function(e,t){this.hideOnClick&&(this.visible=!1),this.$emit("command",e,t)},triggerElmFocus:function(){this.triggerElm.focus&&this.triggerElm.focus()},initDomOperation:function(){this.dropdownElm=this.popperElm,this.menuItems=this.dropdownElm.querySelectorAll("[tabindex='-1']"),this.menuItemsArray=[].slice.call(this.menuItems),this.initEvent(),this.initAria()}},render:function(e){var t=this,n=this.hide,i=this.splitButton,r=this.type,o=this.dropdownSize,a=function(e){t.$emit("click",e),n()},s=i?e("el-button-group",[e("el-button",{attrs:{type:r,size:o},nativeOn:{click:a}},[this.$slots.default]),e("el-button",{ref:"trigger",attrs:{type:r,size:o},class:"el-dropdown__caret-button"},[e("i",{class:"el-dropdown__icon el-icon-arrow-down"})])]):this.$slots.default;return e("div",{class:"el-dropdown",directives:[{name:"clickoutside",value:n}]},[s,this.$slots.dropdown])}},ue=ce,de=s(ue,ne,ie,!1,null,null,null);de.options.__file="packages/dropdown/src/dropdown.vue";var he=de.exports;he.install=function(e){e.component(he.name,he)};var fe=he,pe=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":e.doDestroy}},[n("ul",{directives:[{name:"show",rawName:"v-show",value:e.showPopper,expression:"showPopper"}],staticClass:"el-dropdown-menu el-popper",class:[e.size&&"el-dropdown-menu--"+e.size]},[e._t("default")],2)])},me=[];pe._withStripped=!0;var ve={name:"ElDropdownMenu",componentName:"ElDropdownMenu",mixins:[H.a],props:{visibleArrow:{type:Boolean,default:!0},arrowOffset:{type:Number,default:0}},data:function(){return{size:this.dropdown.dropdownSize}},inject:["dropdown"],created:function(){var e=this;this.$on("updatePopper",(function(){e.showPopper&&e.updatePopper()})),this.$on("visible",(function(t){e.showPopper=t}))},mounted:function(){this.dropdown.popperElm=this.popperElm=this.$el,this.referenceElm=this.dropdown.$el,this.dropdown.initDomOperation()},watch:{"dropdown.placement":{immediate:!0,handler:function(e){this.currentPlacement=e}}}},ge=ve,be=s(ge,pe,me,!1,null,null,null);be.options.__file="packages/dropdown/src/dropdown-menu.vue";var ye=be.exports;ye.install=function(e){e.component(ye.name,ye)};var _e=ye,xe=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{staticClass:"el-dropdown-menu__item",class:{"is-disabled":e.disabled,"el-dropdown-menu__item--divided":e.divided},attrs:{"aria-disabled":e.disabled,tabindex:e.disabled?null:-1},on:{click:e.handleClick}},[e.icon?n("i",{class:e.icon}):e._e(),e._t("default")],2)},we=[];xe._withStripped=!0;var Ce={name:"ElDropdownItem",mixins:[D.a],props:{command:{},disabled:Boolean,divided:Boolean,icon:String},methods:{handleClick:function(e){this.dispatch("ElDropdown","menu-item-click",[this.command,this])}}},ke=Ce,Se=s(ke,xe,we,!1,null,null,null);Se.options.__file="packages/dropdown/src/dropdown-item.vue";var Oe=Se.exports;Oe.install=function(e){e.component(Oe.name,Oe)};var $e=Oe,De=De||{};De.Utils=De.Utils||{},De.Utils.focusFirstDescendant=function(e){for(var t=0;t=0;t--){var n=e.childNodes[t];if(De.Utils.attemptFocus(n)||De.Utils.focusLastDescendant(n))return!0}return!1},De.Utils.attemptFocus=function(e){if(!De.Utils.isFocusable(e))return!1;De.Utils.IgnoreUtilFocusChanges=!0;try{e.focus()}catch(t){}return De.Utils.IgnoreUtilFocusChanges=!1,document.activeElement===e},De.Utils.isFocusable=function(e){if(e.tabIndex>0||0===e.tabIndex&&null!==e.getAttribute("tabIndex"))return!0;if(e.disabled)return!1;switch(e.nodeName){case"A":return!!e.href&&"ignore"!==e.rel;case"INPUT":return"hidden"!==e.type&&"file"!==e.type;case"BUTTON":case"SELECT":case"TEXTAREA":return!0;default:return!1}},De.Utils.triggerEvent=function(e,t){var n=void 0;n=/^mouse|click/.test(t)?"MouseEvents":/^key/.test(t)?"KeyboardEvent":"HTMLEvents";for(var i=document.createEvent(n),r=arguments.length,o=Array(r>2?r-2:0),a=2;a=0;t--)e.splice(t,0,e[t]);e=e.join("")}return/^[0-9a-fA-F]{6}$/.test(e)?{red:parseInt(e.slice(0,2),16),green:parseInt(e.slice(2,4),16),blue:parseInt(e.slice(4,6),16)}:{red:255,green:255,blue:255}},mixColor:function(e,t){var n=this.getColorChannels(e),i=n.red,r=n.green,o=n.blue;return t>0?(i*=1-t,r*=1-t,o*=1-t):(i+=(255-i)*t,r+=(255-r)*t,o+=(255-o)*t),"rgb("+Math.round(i)+", "+Math.round(r)+", "+Math.round(o)+")"},addItem:function(e){this.$set(this.items,e.index,e)},removeItem:function(e){delete this.items[e.index]},addSubmenu:function(e){this.$set(this.submenus,e.index,e)},removeSubmenu:function(e){delete this.submenus[e.index]},openMenu:function(e,t){var n=this.openedMenus;-1===n.indexOf(e)&&(this.uniqueOpened&&(this.openedMenus=n.filter((function(e){return-1!==t.indexOf(e)}))),this.openedMenus.push(e))},closeMenu:function(e){var t=this.openedMenus.indexOf(e);-1!==t&&this.openedMenus.splice(t,1)},handleSubmenuClick:function(e){var t=e.index,n=e.indexPath,i=-1!==this.openedMenus.indexOf(t);i?(this.closeMenu(t),this.$emit("close",t,n)):(this.openMenu(t,n),this.$emit("open",t,n))},handleItemClick:function(e){var t=this,n=e.index,i=e.indexPath,r=this.activeIndex,o=null!==e.index;o&&(this.activeIndex=e.index),this.$emit("select",n,i,e),("horizontal"===this.mode||this.collapse)&&(this.openedMenus=[]),this.router&&o&&this.routeToItem(e,(function(e){t.activeIndex=r,e&&console.error(e)}))},initOpenedMenu:function(){var e=this,t=this.activeIndex,n=this.items[t];if(n&&"horizontal"!==this.mode&&!this.collapse){var i=n.indexPath;i.forEach((function(t){var n=e.submenus[t];n&&e.openMenu(t,n.indexPath)}))}},routeToItem:function(e,t){var n=e.route||e.index;try{this.$router.push(n,(function(){}),t)}catch(i){console.error(i)}},open:function(e){var t=this,n=this.submenus[e.toString()].indexPath;n.forEach((function(e){return t.openMenu(e,n)}))},close:function(e){this.closeMenu(e)}},mounted:function(){this.initOpenedMenu(),this.$on("item-click",this.handleItemClick),this.$on("submenu-click",this.handleSubmenuClick),"horizontal"===this.mode&&new Fe(this.$el),this.$watch("items",this.updateActiveIndex)}},ze=Ve,Be=s(ze,je,Ae,!1,null,null,null);Be.options.__file="packages/menu/src/menu.vue";var Re=Be.exports;Re.install=function(e){e.component(Re.name,Re)};var He,We,qe=Re,Ue=n(21),Ye=n.n(Ue),Ke={inject:["rootMenu"],computed:{indexPath:function(){var e=[this.index],t=this.$parent;while("ElMenu"!==t.$options.componentName)t.index&&e.unshift(t.index),t=t.$parent;return e},parentMenu:function(){var e=this.$parent;while(e&&-1===["ElMenu","ElSubmenu"].indexOf(e.$options.componentName))e=e.$parent;return e},paddingStyle:function(){if("vertical"!==this.rootMenu.mode)return{};var e=20,t=this.$parent;if(this.rootMenu.collapse)e=20;else while(t&&"ElMenu"!==t.$options.componentName)"ElSubmenu"===t.$options.componentName&&(e+=20),t=t.$parent;return{paddingLeft:e+"px"}}}},Ge={props:{transformOrigin:{type:[Boolean,String],default:!1},offset:H.a.props.offset,boundariesPadding:H.a.props.boundariesPadding,popperOptions:H.a.props.popperOptions},data:H.a.data,methods:H.a.methods,beforeDestroy:H.a.beforeDestroy,deactivated:H.a.deactivated},Xe={name:"ElSubmenu",componentName:"ElSubmenu",mixins:[Ke,D.a,Ge],components:{ElCollapseTransition:Ye.a},props:{index:{type:String,required:!0},showTimeout:{type:Number,default:300},hideTimeout:{type:Number,default:300},popperClass:String,disabled:Boolean,popperAppendToBody:{type:Boolean,default:void 0}},data:function(){return{popperJS:null,timeout:null,items:{},submenus:{},mouseInChild:!1}},watch:{opened:function(e){var t=this;this.isMenuPopup&&this.$nextTick((function(e){t.updatePopper()}))}},computed:{appendToBody:function(){return void 0===this.popperAppendToBody?this.isFirstLevel:this.popperAppendToBody},menuTransitionName:function(){return this.rootMenu.collapse?"el-zoom-in-left":"el-zoom-in-top"},opened:function(){return this.rootMenu.openedMenus.indexOf(this.index)>-1},active:function(){var e=!1,t=this.submenus,n=this.items;return Object.keys(n).forEach((function(t){n[t].active&&(e=!0)})),Object.keys(t).forEach((function(n){t[n].active&&(e=!0)})),e},hoverBackground:function(){return this.rootMenu.hoverBackground},backgroundColor:function(){return this.rootMenu.backgroundColor||""},activeTextColor:function(){return this.rootMenu.activeTextColor||""},textColor:function(){return this.rootMenu.textColor||""},mode:function(){return this.rootMenu.mode},isMenuPopup:function(){return this.rootMenu.isMenuPopup},titleStyle:function(){return"horizontal"!==this.mode?{color:this.textColor}:{borderBottomColor:this.active?this.rootMenu.activeTextColor?this.activeTextColor:"":"transparent",color:this.active?this.activeTextColor:this.textColor}},isFirstLevel:function(){var e=!0,t=this.$parent;while(t&&t!==this.rootMenu){if(["ElSubmenu","ElMenuItemGroup"].indexOf(t.$options.componentName)>-1){e=!1;break}t=t.$parent}return e}},methods:{handleCollapseToggle:function(e){e?this.initPopper():this.doDestroy()},addItem:function(e){this.$set(this.items,e.index,e)},removeItem:function(e){delete this.items[e.index]},addSubmenu:function(e){this.$set(this.submenus,e.index,e)},removeSubmenu:function(e){delete this.submenus[e.index]},handleClick:function(){var e=this.rootMenu,t=this.disabled;"hover"===e.menuTrigger&&"horizontal"===e.mode||e.collapse&&"vertical"===e.mode||t||this.dispatch("ElMenu","submenu-click",this)},handleMouseenter:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.showTimeout;if("ActiveXObject"in window||"focus"!==e.type||e.relatedTarget){var i=this.rootMenu,r=this.disabled;"click"===i.menuTrigger&&"horizontal"===i.mode||!i.collapse&&"vertical"===i.mode||r||(this.dispatch("ElSubmenu","mouse-enter-child"),clearTimeout(this.timeout),this.timeout=setTimeout((function(){t.rootMenu.openMenu(t.index,t.indexPath)}),n),this.appendToBody&&this.$parent.$el.dispatchEvent(new MouseEvent("mouseenter")))}},handleMouseleave:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],n=this.rootMenu;"click"===n.menuTrigger&&"horizontal"===n.mode||!n.collapse&&"vertical"===n.mode||(this.dispatch("ElSubmenu","mouse-leave-child"),clearTimeout(this.timeout),this.timeout=setTimeout((function(){!e.mouseInChild&&e.rootMenu.closeMenu(e.index)}),this.hideTimeout),this.appendToBody&&t&&"ElSubmenu"===this.$parent.$options.name&&this.$parent.handleMouseleave(!0))},handleTitleMouseenter:function(){if("horizontal"!==this.mode||this.rootMenu.backgroundColor){var e=this.$refs["submenu-title"];e&&(e.style.backgroundColor=this.rootMenu.hoverBackground)}},handleTitleMouseleave:function(){if("horizontal"!==this.mode||this.rootMenu.backgroundColor){var e=this.$refs["submenu-title"];e&&(e.style.backgroundColor=this.rootMenu.backgroundColor||"")}},updatePlacement:function(){this.currentPlacement="horizontal"===this.mode&&this.isFirstLevel?"bottom-start":"right-start"},initPopper:function(){this.referenceElm=this.$el,this.popperElm=this.$refs.menu,this.updatePlacement()}},created:function(){var e=this;this.$on("toggle-collapse",this.handleCollapseToggle),this.$on("mouse-enter-child",(function(){e.mouseInChild=!0,clearTimeout(e.timeout)})),this.$on("mouse-leave-child",(function(){e.mouseInChild=!1,clearTimeout(e.timeout)}))},mounted:function(){this.parentMenu.addSubmenu(this),this.rootMenu.addSubmenu(this),this.initPopper()},beforeDestroy:function(){this.parentMenu.removeSubmenu(this),this.rootMenu.removeSubmenu(this)},render:function(e){var t=this,n=this.active,i=this.opened,r=this.paddingStyle,o=this.titleStyle,a=this.backgroundColor,s=this.rootMenu,l=this.currentPlacement,c=this.menuTransitionName,u=this.mode,d=this.disabled,h=this.popperClass,f=this.$slots,p=this.isFirstLevel,m=e("transition",{attrs:{name:c}},[e("div",{ref:"menu",directives:[{name:"show",value:i}],class:["el-menu--"+u,h],on:{mouseenter:function(e){return t.handleMouseenter(e,100)},mouseleave:function(){return t.handleMouseleave(!0)},focus:function(e){return t.handleMouseenter(e,100)}}},[e("ul",{attrs:{role:"menu"},class:["el-menu el-menu--popup","el-menu--popup-"+l],style:{backgroundColor:s.backgroundColor||""}},[f.default])])]),v=e("el-collapse-transition",[e("ul",{attrs:{role:"menu"},class:"el-menu el-menu--inline",directives:[{name:"show",value:i}],style:{backgroundColor:s.backgroundColor||""}},[f.default])]),g="horizontal"===s.mode&&p||"vertical"===s.mode&&!s.collapse?"el-icon-arrow-down":"el-icon-arrow-right";return e("li",{class:{"el-submenu":!0,"is-active":n,"is-opened":i,"is-disabled":d},attrs:{role:"menuitem","aria-haspopup":"true","aria-expanded":i},on:{mouseenter:this.handleMouseenter,mouseleave:function(){return t.handleMouseleave(!1)},focus:this.handleMouseenter}},[e("div",{class:"el-submenu__title",ref:"submenu-title",on:{click:this.handleClick,mouseenter:this.handleTitleMouseenter,mouseleave:this.handleTitleMouseleave},style:[r,o,{backgroundColor:a}]},[f.title,e("i",{class:["el-submenu__icon-arrow",g]})]),this.isMenuPopup?m:v])}},Ze=Xe,Je=s(Ze,He,We,!1,null,null,null);Je.options.__file="packages/menu/src/submenu.vue";var Qe=Je.exports;Qe.install=function(e){e.component(Qe.name,Qe)};var et=Qe,tt=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{staticClass:"el-menu-item",class:{"is-active":e.active,"is-disabled":e.disabled},style:[e.paddingStyle,e.itemStyle,{backgroundColor:e.backgroundColor}],attrs:{role:"menuitem",tabindex:"-1"},on:{click:e.handleClick,mouseenter:e.onMouseEnter,focus:e.onMouseEnter,blur:e.onMouseLeave,mouseleave:e.onMouseLeave}},["ElMenu"===e.parentMenu.$options.componentName&&e.rootMenu.collapse&&e.$slots.title?n("el-tooltip",{attrs:{effect:"dark",placement:"right"}},[n("div",{attrs:{slot:"content"},slot:"content"},[e._t("title")],2),n("div",{staticStyle:{position:"absolute",left:"0",top:"0",height:"100%",width:"100%",display:"inline-block","box-sizing":"border-box",padding:"0 20px"}},[e._t("default")],2)]):[e._t("default"),e._t("title")]],2)},nt=[];tt._withStripped=!0;var it=n(26),rt=n.n(it),ot={name:"ElMenuItem",componentName:"ElMenuItem",mixins:[Ke,D.a],components:{ElTooltip:rt.a},props:{index:{default:null,validator:function(e){return"string"===typeof e||null===e}},route:[String,Object],disabled:Boolean},computed:{active:function(){return this.index===this.rootMenu.activeIndex},hoverBackground:function(){return this.rootMenu.hoverBackground},backgroundColor:function(){return this.rootMenu.backgroundColor||""},activeTextColor:function(){return this.rootMenu.activeTextColor||""},textColor:function(){return this.rootMenu.textColor||""},mode:function(){return this.rootMenu.mode},itemStyle:function(){var e={color:this.active?this.activeTextColor:this.textColor};return"horizontal"!==this.mode||this.isNested||(e.borderBottomColor=this.active?this.rootMenu.activeTextColor?this.activeTextColor:"":"transparent"),e},isNested:function(){return this.parentMenu!==this.rootMenu}},methods:{onMouseEnter:function(){("horizontal"!==this.mode||this.rootMenu.backgroundColor)&&(this.$el.style.backgroundColor=this.hoverBackground)},onMouseLeave:function(){("horizontal"!==this.mode||this.rootMenu.backgroundColor)&&(this.$el.style.backgroundColor=this.backgroundColor)},handleClick:function(){this.disabled||(this.dispatch("ElMenu","item-click",this),this.$emit("click",this))}},mounted:function(){this.parentMenu.addItem(this),this.rootMenu.addItem(this)},beforeDestroy:function(){this.parentMenu.removeItem(this),this.rootMenu.removeItem(this)}},at=ot,st=s(at,tt,nt,!1,null,null,null);st.options.__file="packages/menu/src/menu-item.vue";var lt=st.exports;lt.install=function(e){e.component(lt.name,lt)};var ct=lt,ut=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{staticClass:"el-menu-item-group"},[n("div",{staticClass:"el-menu-item-group__title",style:{paddingLeft:e.levelPadding+"px"}},[e.$slots.title?e._t("title"):[e._v(e._s(e.title))]],2),n("ul",[e._t("default")],2)])},dt=[];ut._withStripped=!0;var ht={name:"ElMenuItemGroup",componentName:"ElMenuItemGroup",inject:["rootMenu"],props:{title:{type:String}},data:function(){return{paddingLeft:20}},computed:{levelPadding:function(){var e=20,t=this.$parent;if(this.rootMenu.collapse)return 20;while(t&&"ElMenu"!==t.$options.componentName)"ElSubmenu"===t.$options.componentName&&(e+=20),t=t.$parent;return e}}},ft=ht,pt=s(ft,ut,dt,!1,null,null,null);pt.options.__file="packages/menu/src/menu-item-group.vue";var mt=pt.exports;mt.install=function(e){e.component(mt.name,mt)};var vt=mt,gt=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:["textarea"===e.type?"el-textarea":"el-input",e.inputSize?"el-input--"+e.inputSize:"",{"is-disabled":e.inputDisabled,"is-exceed":e.inputExceed,"el-input-group":e.$slots.prepend||e.$slots.append,"el-input-group--append":e.$slots.append,"el-input-group--prepend":e.$slots.prepend,"el-input--prefix":e.$slots.prefix||e.prefixIcon,"el-input--suffix":e.$slots.suffix||e.suffixIcon||e.clearable||e.showPassword}],on:{mouseenter:function(t){e.hovering=!0},mouseleave:function(t){e.hovering=!1}}},["textarea"!==e.type?[e.$slots.prepend?n("div",{staticClass:"el-input-group__prepend"},[e._t("prepend")],2):e._e(),"textarea"!==e.type?n("input",e._b({ref:"input",staticClass:"el-input__inner",attrs:{tabindex:e.tabindex,type:e.showPassword?e.passwordVisible?"text":"password":e.type,disabled:e.inputDisabled,readonly:e.readonly,autocomplete:e.autoComplete||e.autocomplete,"aria-label":e.label},on:{compositionstart:e.handleCompositionStart,compositionupdate:e.handleCompositionUpdate,compositionend:e.handleCompositionEnd,input:e.handleInput,focus:e.handleFocus,blur:e.handleBlur,change:e.handleChange}},"input",e.$attrs,!1)):e._e(),e.$slots.prefix||e.prefixIcon?n("span",{staticClass:"el-input__prefix"},[e._t("prefix"),e.prefixIcon?n("i",{staticClass:"el-input__icon",class:e.prefixIcon}):e._e()],2):e._e(),e.getSuffixVisible()?n("span",{staticClass:"el-input__suffix"},[n("span",{staticClass:"el-input__suffix-inner"},[e.showClear&&e.showPwdVisible&&e.isWordLimitVisible?e._e():[e._t("suffix"),e.suffixIcon?n("i",{staticClass:"el-input__icon",class:e.suffixIcon}):e._e()],e.showClear?n("i",{staticClass:"el-input__icon el-icon-circle-close el-input__clear",on:{mousedown:function(e){e.preventDefault()},click:e.clear}}):e._e(),e.showPwdVisible?n("i",{staticClass:"el-input__icon el-icon-view el-input__clear",on:{click:e.handlePasswordVisible}}):e._e(),e.isWordLimitVisible?n("span",{staticClass:"el-input__count"},[n("span",{staticClass:"el-input__count-inner"},[e._v("\n "+e._s(e.textLength)+"/"+e._s(e.upperLimit)+"\n ")])]):e._e()],2),e.validateState?n("i",{staticClass:"el-input__icon",class:["el-input__validateIcon",e.validateIcon]}):e._e()]):e._e(),e.$slots.append?n("div",{staticClass:"el-input-group__append"},[e._t("append")],2):e._e()]:n("textarea",e._b({ref:"textarea",staticClass:"el-textarea__inner",style:e.textareaStyle,attrs:{tabindex:e.tabindex,disabled:e.inputDisabled,readonly:e.readonly,autocomplete:e.autoComplete||e.autocomplete,"aria-label":e.label},on:{compositionstart:e.handleCompositionStart,compositionupdate:e.handleCompositionUpdate,compositionend:e.handleCompositionEnd,input:e.handleInput,focus:e.handleFocus,blur:e.handleBlur,change:e.handleChange}},"textarea",e.$attrs,!1)),e.isWordLimitVisible&&"textarea"===e.type?n("span",{staticClass:"el-input__count"},[e._v(e._s(e.textLength)+"/"+e._s(e.upperLimit))]):e._e()],2)},bt=[];gt._withStripped=!0;var yt=void 0,_t="\n height:0 !important;\n visibility:hidden !important;\n overflow:hidden !important;\n position:absolute !important;\n z-index:-1000 !important;\n top:0 !important;\n right:0 !important\n",xt=["letter-spacing","line-height","padding-top","padding-bottom","font-family","font-weight","font-size","text-rendering","text-transform","width","text-indent","padding-left","padding-right","border-width","box-sizing"];function wt(e){var t=window.getComputedStyle(e),n=t.getPropertyValue("box-sizing"),i=parseFloat(t.getPropertyValue("padding-bottom"))+parseFloat(t.getPropertyValue("padding-top")),r=parseFloat(t.getPropertyValue("border-bottom-width"))+parseFloat(t.getPropertyValue("border-top-width")),o=xt.map((function(e){return e+":"+t.getPropertyValue(e)})).join(";");return{contextStyle:o,paddingSize:i,borderSize:r,boxSizing:n}}function Ct(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;yt||(yt=document.createElement("textarea"),document.body.appendChild(yt));var i=wt(e),r=i.paddingSize,o=i.borderSize,a=i.boxSizing,s=i.contextStyle;yt.setAttribute("style",s+";"+_t),yt.value=e.value||e.placeholder||"";var l=yt.scrollHeight,c={};"border-box"===a?l+=o:"content-box"===a&&(l-=r),yt.value="";var u=yt.scrollHeight-r;if(null!==t){var d=u*t;"border-box"===a&&(d=d+r+o),l=Math.max(d,l),c.minHeight=d+"px"}if(null!==n){var h=u*n;"border-box"===a&&(h=h+r+o),l=Math.min(h,l)}return c.height=l+"px",yt.parentNode&&yt.parentNode.removeChild(yt),yt=null,c}var kt=n(7),St=n.n(kt),Ot=n(19),$t={name:"ElInput",componentName:"ElInput",mixins:[D.a,O.a],inheritAttrs:!1,inject:{elForm:{default:""},elFormItem:{default:""}},data:function(){return{textareaCalcStyle:{},hovering:!1,focused:!1,isComposing:!1,passwordVisible:!1}},props:{value:[String,Number],size:String,resize:String,form:String,disabled:Boolean,readonly:Boolean,type:{type:String,default:"text"},autosize:{type:[Boolean,Object],default:!1},autocomplete:{type:String,default:"off"},autoComplete:{type:String,validator:function(e){return!0}},validateEvent:{type:Boolean,default:!0},suffixIcon:String,prefixIcon:String,label:String,clearable:{type:Boolean,default:!1},showPassword:{type:Boolean,default:!1},showWordLimit:{type:Boolean,default:!1},tabindex:String},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},validateState:function(){return this.elFormItem?this.elFormItem.validateState:""},needStatusIcon:function(){return!!this.elForm&&this.elForm.statusIcon},validateIcon:function(){return{validating:"el-icon-loading",success:"el-icon-circle-check",error:"el-icon-circle-close"}[this.validateState]},textareaStyle:function(){return St()({},this.textareaCalcStyle,{resize:this.resize})},inputSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},inputDisabled:function(){return this.disabled||(this.elForm||{}).disabled},nativeInputValue:function(){return null===this.value||void 0===this.value?"":String(this.value)},showClear:function(){return this.clearable&&!this.inputDisabled&&!this.readonly&&this.nativeInputValue&&(this.focused||this.hovering)},showPwdVisible:function(){return this.showPassword&&!this.inputDisabled&&!this.readonly&&(!!this.nativeInputValue||this.focused)},isWordLimitVisible:function(){return this.showWordLimit&&this.$attrs.maxlength&&("text"===this.type||"textarea"===this.type)&&!this.inputDisabled&&!this.readonly&&!this.showPassword},upperLimit:function(){return this.$attrs.maxlength},textLength:function(){return"number"===typeof this.value?String(this.value).length:(this.value||"").length},inputExceed:function(){return this.isWordLimitVisible&&this.textLength>this.upperLimit}},watch:{value:function(e){this.$nextTick(this.resizeTextarea),this.validateEvent&&this.dispatch("ElFormItem","el.form.change",[e])},nativeInputValue:function(){this.setNativeInputValue()},type:function(){var e=this;this.$nextTick((function(){e.setNativeInputValue(),e.resizeTextarea(),e.updateIconOffset()}))}},methods:{focus:function(){this.getInput().focus()},blur:function(){this.getInput().blur()},getMigratingConfig:function(){return{props:{icon:"icon is removed, use suffix-icon / prefix-icon instead.","on-icon-click":"on-icon-click is removed."},events:{click:"click is removed."}}},handleBlur:function(e){this.focused=!1,this.$emit("blur",e),this.validateEvent&&this.dispatch("ElFormItem","el.form.blur",[this.value])},select:function(){this.getInput().select()},resizeTextarea:function(){if(!this.$isServer){var e=this.autosize,t=this.type;if("textarea"===t)if(e){var n=e.minRows,i=e.maxRows;this.textareaCalcStyle=Ct(this.$refs.textarea,n,i)}else this.textareaCalcStyle={minHeight:Ct(this.$refs.textarea).minHeight}}},setNativeInputValue:function(){var e=this.getInput();e&&e.value!==this.nativeInputValue&&(e.value=this.nativeInputValue)},handleFocus:function(e){this.focused=!0,this.$emit("focus",e)},handleCompositionStart:function(){this.isComposing=!0},handleCompositionUpdate:function(e){var t=e.target.value,n=t[t.length-1]||"";this.isComposing=!Object(Ot["isKorean"])(n)},handleCompositionEnd:function(e){this.isComposing&&(this.isComposing=!1,this.handleInput(e))},handleInput:function(e){this.isComposing||e.target.value!==this.nativeInputValue&&(this.$emit("input",e.target.value),this.$nextTick(this.setNativeInputValue))},handleChange:function(e){this.$emit("change",e.target.value)},calcIconOffset:function(e){var t=[].slice.call(this.$el.querySelectorAll(".el-input__"+e)||[]);if(t.length){for(var n=null,i=0;i=0&&e===parseInt(e,10)}}},data:function(){return{currentValue:0,userInput:null}},watch:{value:{immediate:!0,handler:function(e){var t=void 0===e?e:Number(e);if(void 0!==t){if(isNaN(t))return;if(this.stepStrictly){var n=this.getPrecision(this.step),i=Math.pow(10,n);t=Math.round(t/this.step)*i*this.step/i}void 0!==this.precision&&(t=this.toPrecision(t,this.precision))}t>=this.max&&(t=this.max),t<=this.min&&(t=this.min),this.currentValue=t,this.userInput=null,this.$emit("input",t)}}},computed:{minDisabled:function(){return this._decrease(this.value,this.step)this.max},numPrecision:function(){var e=this.value,t=this.step,n=this.getPrecision,i=this.precision,r=n(t);return void 0!==i?(r>i&&console.warn("[Element Warn][InputNumber]precision should not be less than the decimal places of step"),i):Math.max(n(e),r)},controlsAtRight:function(){return this.controls&&"right"===this.controlsPosition},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},inputNumberSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},inputNumberDisabled:function(){return this.disabled||(this.elForm||{}).disabled},displayValue:function(){if(null!==this.userInput)return this.userInput;var e=this.currentValue;if("number"===typeof e){if(this.stepStrictly){var t=this.getPrecision(this.step),n=Math.pow(10,t);e=Math.round(e/this.step)*n*this.step/n}void 0!==this.precision&&(e=e.toFixed(this.precision))}return e}},methods:{toPrecision:function(e,t){return void 0===t&&(t=this.numPrecision),parseFloat(Math.round(e*Math.pow(10,t))/Math.pow(10,t))},getPrecision:function(e){if(void 0===e)return 0;var t=e.toString(),n=t.indexOf("."),i=0;return-1!==n&&(i=t.length-n-1),i},_increase:function(e,t){if("number"!==typeof e&&void 0!==e)return this.currentValue;var n=Math.pow(10,this.numPrecision);return this.toPrecision((n*e+n*t)/n)},_decrease:function(e,t){if("number"!==typeof e&&void 0!==e)return this.currentValue;var n=Math.pow(10,this.numPrecision);return this.toPrecision((n*e-n*t)/n)},increase:function(){if(!this.inputNumberDisabled&&!this.maxDisabled){var e=this.value||0,t=this._increase(e,this.step);this.setCurrentValue(t)}},decrease:function(){if(!this.inputNumberDisabled&&!this.minDisabled){var e=this.value||0,t=this._decrease(e,this.step);this.setCurrentValue(t)}},handleBlur:function(e){this.$emit("blur",e)},handleFocus:function(e){this.$emit("focus",e)},setCurrentValue:function(e){var t=this.currentValue;"number"===typeof e&&void 0!==this.precision&&(e=this.toPrecision(e,this.precision)),e>=this.max&&(e=this.max),e<=this.min&&(e=this.min),t!==e&&(this.userInput=null,this.$emit("input",e),this.$emit("change",e,t),this.currentValue=e)},handleInput:function(e){this.userInput=e},handleInputChange:function(e){var t=""===e?void 0:Number(e);isNaN(t)&&""!==e||this.setCurrentValue(t),this.userInput=null},select:function(){this.$refs.input.select()}},mounted:function(){var e=this.$refs.input.$refs.input;e.setAttribute("role","spinbutton"),e.setAttribute("aria-valuemax",this.max),e.setAttribute("aria-valuemin",this.min),e.setAttribute("aria-valuenow",this.currentValue),e.setAttribute("aria-disabled",this.inputNumberDisabled)},updated:function(){if(this.$refs&&this.$refs.input){var e=this.$refs.input.$refs.input;e.setAttribute("aria-valuenow",this.currentValue)}}},At=jt,Ft=s(At,Mt,It,!1,null,null,null);Ft.options.__file="packages/input-number/src/input-number.vue";var Lt=Ft.exports;Lt.install=function(e){e.component(Lt.name,Lt)};var Vt=Lt,zt=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("label",{staticClass:"el-radio",class:[e.border&&e.radioSize?"el-radio--"+e.radioSize:"",{"is-disabled":e.isDisabled},{"is-focus":e.focus},{"is-bordered":e.border},{"is-checked":e.model===e.label}],attrs:{role:"radio","aria-checked":e.model===e.label,"aria-disabled":e.isDisabled,tabindex:e.tabIndex},on:{keydown:function(t){if(!("button"in t)&&e._k(t.keyCode,"space",32,t.key,[" ","Spacebar"]))return null;t.stopPropagation(),t.preventDefault(),e.model=e.isDisabled?e.model:e.label}}},[n("span",{staticClass:"el-radio__input",class:{"is-disabled":e.isDisabled,"is-checked":e.model===e.label}},[n("span",{staticClass:"el-radio__inner"}),n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],ref:"radio",staticClass:"el-radio__original",attrs:{type:"radio","aria-hidden":"true",name:e.name,disabled:e.isDisabled,tabindex:"-1"},domProps:{value:e.label,checked:e._q(e.model,e.label)},on:{focus:function(t){e.focus=!0},blur:function(t){e.focus=!1},change:[function(t){e.model=e.label},e.handleChange]}})]),n("span",{staticClass:"el-radio__label",on:{keydown:function(e){e.stopPropagation()}}},[e._t("default"),e.$slots.default?e._e():[e._v(e._s(e.label))]],2)])},Bt=[];zt._withStripped=!0;var Rt={name:"ElRadio",mixins:[D.a],inject:{elForm:{default:""},elFormItem:{default:""}},componentName:"ElRadio",props:{value:{},label:{},disabled:Boolean,name:String,border:Boolean,size:String},data:function(){return{focus:!1}},computed:{isGroup:function(){var e=this.$parent;while(e){if("ElRadioGroup"===e.$options.componentName)return this._radioGroup=e,!0;e=e.$parent}return!1},model:{get:function(){return this.isGroup?this._radioGroup.value:this.value},set:function(e){this.isGroup?this.dispatch("ElRadioGroup","input",[e]):this.$emit("input",e),this.$refs.radio&&(this.$refs.radio.checked=this.model===this.label)}},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},radioSize:function(){var e=this.size||this._elFormItemSize||(this.$ELEMENT||{}).size;return this.isGroup&&this._radioGroup.radioGroupSize||e},isDisabled:function(){return this.isGroup?this._radioGroup.disabled||this.disabled||(this.elForm||{}).disabled:this.disabled||(this.elForm||{}).disabled},tabIndex:function(){return this.isDisabled||this.isGroup&&this.model!==this.label?-1:0}},methods:{handleChange:function(){var e=this;this.$nextTick((function(){e.$emit("change",e.model),e.isGroup&&e.dispatch("ElRadioGroup","handleChange",e.model)}))}}},Ht=Rt,Wt=s(Ht,zt,Bt,!1,null,null,null);Wt.options.__file="packages/radio/src/radio.vue";var qt=Wt.exports;qt.install=function(e){e.component(qt.name,qt)};var Ut=qt,Yt=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n(e._elTag,{tag:"component",staticClass:"el-radio-group",attrs:{role:"radiogroup"},on:{keydown:e.handleKeydown}},[e._t("default")],2)},Kt=[];Yt._withStripped=!0;var Gt=Object.freeze({LEFT:37,UP:38,RIGHT:39,DOWN:40}),Xt={name:"ElRadioGroup",componentName:"ElRadioGroup",inject:{elFormItem:{default:""}},mixins:[D.a],props:{value:{},size:String,fill:String,textColor:String,disabled:Boolean},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},_elTag:function(){return(this.$vnode.data||{}).tag||"div"},radioGroupSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size}},created:function(){var e=this;this.$on("handleChange",(function(t){e.$emit("change",t)}))},mounted:function(){var e=this.$el.querySelectorAll("[type=radio]"),t=this.$el.querySelectorAll("[role=radio]")[0];![].some.call(e,(function(e){return e.checked}))&&t&&(t.tabIndex=0)},methods:{handleKeydown:function(e){var t=e.target,n="INPUT"===t.nodeName?"[type=radio]":"[role=radio]",i=this.$el.querySelectorAll(n),r=i.length,o=[].indexOf.call(i,t),a=this.$el.querySelectorAll("[role=radio]");switch(e.keyCode){case Gt.LEFT:case Gt.UP:e.stopPropagation(),e.preventDefault(),0===o?(a[r-1].click(),a[r-1].focus()):(a[o-1].click(),a[o-1].focus());break;case Gt.RIGHT:case Gt.DOWN:o===r-1?(e.stopPropagation(),e.preventDefault(),a[0].click(),a[0].focus()):(a[o+1].click(),a[o+1].focus());break;default:break}}},watch:{value:function(e){this.dispatch("ElFormItem","el.form.change",[this.value])}}},Zt=Xt,Jt=s(Zt,Yt,Kt,!1,null,null,null);Jt.options.__file="packages/radio/src/radio-group.vue";var Qt=Jt.exports;Qt.install=function(e){e.component(Qt.name,Qt)};var en=Qt,tn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("label",{staticClass:"el-radio-button",class:[e.size?"el-radio-button--"+e.size:"",{"is-active":e.value===e.label},{"is-disabled":e.isDisabled},{"is-focus":e.focus}],attrs:{role:"radio","aria-checked":e.value===e.label,"aria-disabled":e.isDisabled,tabindex:e.tabIndex},on:{keydown:function(t){if(!("button"in t)&&e._k(t.keyCode,"space",32,t.key,[" ","Spacebar"]))return null;t.stopPropagation(),t.preventDefault(),e.value=e.isDisabled?e.value:e.label}}},[n("input",{directives:[{name:"model",rawName:"v-model",value:e.value,expression:"value"}],staticClass:"el-radio-button__orig-radio",attrs:{type:"radio",name:e.name,disabled:e.isDisabled,tabindex:"-1"},domProps:{value:e.label,checked:e._q(e.value,e.label)},on:{change:[function(t){e.value=e.label},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}}),n("span",{staticClass:"el-radio-button__inner",style:e.value===e.label?e.activeStyle:null,on:{keydown:function(e){e.stopPropagation()}}},[e._t("default"),e.$slots.default?e._e():[e._v(e._s(e.label))]],2)])},nn=[];tn._withStripped=!0;var rn={name:"ElRadioButton",mixins:[D.a],inject:{elForm:{default:""},elFormItem:{default:""}},props:{label:{},disabled:Boolean,name:String},data:function(){return{focus:!1}},computed:{value:{get:function(){return this._radioGroup.value},set:function(e){this._radioGroup.$emit("input",e)}},_radioGroup:function(){var e=this.$parent;while(e){if("ElRadioGroup"===e.$options.componentName)return e;e=e.$parent}return!1},activeStyle:function(){return{backgroundColor:this._radioGroup.fill||"",borderColor:this._radioGroup.fill||"",boxShadow:this._radioGroup.fill?"-1px 0 0 0 "+this._radioGroup.fill:"",color:this._radioGroup.textColor||""}},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},size:function(){return this._radioGroup.radioGroupSize||this._elFormItemSize||(this.$ELEMENT||{}).size},isDisabled:function(){return this.disabled||this._radioGroup.disabled||(this.elForm||{}).disabled},tabIndex:function(){return this.isDisabled||this._radioGroup&&this.value!==this.label?-1:0}},methods:{handleChange:function(){var e=this;this.$nextTick((function(){e.dispatch("ElRadioGroup","handleChange",e.value)}))}}},on=rn,an=s(on,tn,nn,!1,null,null,null);an.options.__file="packages/radio/src/radio-button.vue";var sn=an.exports;sn.install=function(e){e.component(sn.name,sn)};var ln=sn,cn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("label",{staticClass:"el-checkbox",class:[e.border&&e.checkboxSize?"el-checkbox--"+e.checkboxSize:"",{"is-disabled":e.isDisabled},{"is-bordered":e.border},{"is-checked":e.isChecked}],attrs:{id:e.id}},[n("span",{staticClass:"el-checkbox__input",class:{"is-disabled":e.isDisabled,"is-checked":e.isChecked,"is-indeterminate":e.indeterminate,"is-focus":e.focus},attrs:{tabindex:!!e.indeterminate&&0,role:!!e.indeterminate&&"checkbox","aria-checked":!!e.indeterminate&&"mixed"}},[n("span",{staticClass:"el-checkbox__inner"}),e.trueLabel||e.falseLabel?n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],staticClass:"el-checkbox__original",attrs:{type:"checkbox","aria-hidden":e.indeterminate?"true":"false",name:e.name,disabled:e.isDisabled,"true-value":e.trueLabel,"false-value":e.falseLabel},domProps:{checked:Array.isArray(e.model)?e._i(e.model,null)>-1:e._q(e.model,e.trueLabel)},on:{change:[function(t){var n=e.model,i=t.target,r=i.checked?e.trueLabel:e.falseLabel;if(Array.isArray(n)){var o=null,a=e._i(n,o);i.checked?a<0&&(e.model=n.concat([o])):a>-1&&(e.model=n.slice(0,a).concat(n.slice(a+1)))}else e.model=r},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}}):n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],staticClass:"el-checkbox__original",attrs:{type:"checkbox","aria-hidden":e.indeterminate?"true":"false",disabled:e.isDisabled,name:e.name},domProps:{value:e.label,checked:Array.isArray(e.model)?e._i(e.model,e.label)>-1:e.model},on:{change:[function(t){var n=e.model,i=t.target,r=!!i.checked;if(Array.isArray(n)){var o=e.label,a=e._i(n,o);i.checked?a<0&&(e.model=n.concat([o])):a>-1&&(e.model=n.slice(0,a).concat(n.slice(a+1)))}else e.model=r},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}})]),e.$slots.default||e.label?n("span",{staticClass:"el-checkbox__label"},[e._t("default"),e.$slots.default?e._e():[e._v(e._s(e.label))]],2):e._e()])},un=[];cn._withStripped=!0;var dn={name:"ElCheckbox",mixins:[D.a],inject:{elForm:{default:""},elFormItem:{default:""}},componentName:"ElCheckbox",data:function(){return{selfModel:!1,focus:!1,isLimitExceeded:!1}},computed:{model:{get:function(){return this.isGroup?this.store:void 0!==this.value?this.value:this.selfModel},set:function(e){this.isGroup?(this.isLimitExceeded=!1,void 0!==this._checkboxGroup.min&&e.lengththis._checkboxGroup.max&&(this.isLimitExceeded=!0),!1===this.isLimitExceeded&&this.dispatch("ElCheckboxGroup","input",[e])):(this.$emit("input",e),this.selfModel=e)}},isChecked:function(){return"[object Boolean]"==={}.toString.call(this.model)?this.model:Array.isArray(this.model)?this.model.indexOf(this.label)>-1:null!==this.model&&void 0!==this.model?this.model===this.trueLabel:void 0},isGroup:function(){var e=this.$parent;while(e){if("ElCheckboxGroup"===e.$options.componentName)return this._checkboxGroup=e,!0;e=e.$parent}return!1},store:function(){return this._checkboxGroup?this._checkboxGroup.value:this.value},isLimitDisabled:function(){var e=this._checkboxGroup,t=e.max,n=e.min;return!(!t&&!n)&&this.model.length>=t&&!this.isChecked||this.model.length<=n&&this.isChecked},isDisabled:function(){return this.isGroup?this._checkboxGroup.disabled||this.disabled||(this.elForm||{}).disabled||this.isLimitDisabled:this.disabled||(this.elForm||{}).disabled},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},checkboxSize:function(){var e=this.size||this._elFormItemSize||(this.$ELEMENT||{}).size;return this.isGroup&&this._checkboxGroup.checkboxGroupSize||e}},props:{value:{},label:{},indeterminate:Boolean,disabled:Boolean,checked:Boolean,name:String,trueLabel:[String,Number],falseLabel:[String,Number],id:String,controls:String,border:Boolean,size:String},methods:{addToStore:function(){Array.isArray(this.model)&&-1===this.model.indexOf(this.label)?this.model.push(this.label):this.model=this.trueLabel||!0},handleChange:function(e){var t=this;if(!this.isLimitExceeded){var n=void 0;n=e.target.checked?void 0===this.trueLabel||this.trueLabel:void 0!==this.falseLabel&&this.falseLabel,this.$emit("change",n,e),this.$nextTick((function(){t.isGroup&&t.dispatch("ElCheckboxGroup","change",[t._checkboxGroup.value])}))}}},created:function(){this.checked&&this.addToStore()},mounted:function(){this.indeterminate&&this.$el.setAttribute("aria-controls",this.controls)},watch:{value:function(e){this.dispatch("ElFormItem","el.form.change",e)}}},hn=dn,fn=s(hn,cn,un,!1,null,null,null);fn.options.__file="packages/checkbox/src/checkbox.vue";var pn=fn.exports;pn.install=function(e){e.component(pn.name,pn)};var mn=pn,vn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("label",{staticClass:"el-checkbox-button",class:[e.size?"el-checkbox-button--"+e.size:"",{"is-disabled":e.isDisabled},{"is-checked":e.isChecked},{"is-focus":e.focus}],attrs:{role:"checkbox","aria-checked":e.isChecked,"aria-disabled":e.isDisabled}},[e.trueLabel||e.falseLabel?n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],staticClass:"el-checkbox-button__original",attrs:{type:"checkbox",name:e.name,disabled:e.isDisabled,"true-value":e.trueLabel,"false-value":e.falseLabel},domProps:{checked:Array.isArray(e.model)?e._i(e.model,null)>-1:e._q(e.model,e.trueLabel)},on:{change:[function(t){var n=e.model,i=t.target,r=i.checked?e.trueLabel:e.falseLabel;if(Array.isArray(n)){var o=null,a=e._i(n,o);i.checked?a<0&&(e.model=n.concat([o])):a>-1&&(e.model=n.slice(0,a).concat(n.slice(a+1)))}else e.model=r},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}}):n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],staticClass:"el-checkbox-button__original",attrs:{type:"checkbox",name:e.name,disabled:e.isDisabled},domProps:{value:e.label,checked:Array.isArray(e.model)?e._i(e.model,e.label)>-1:e.model},on:{change:[function(t){var n=e.model,i=t.target,r=!!i.checked;if(Array.isArray(n)){var o=e.label,a=e._i(n,o);i.checked?a<0&&(e.model=n.concat([o])):a>-1&&(e.model=n.slice(0,a).concat(n.slice(a+1)))}else e.model=r},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}}),e.$slots.default||e.label?n("span",{staticClass:"el-checkbox-button__inner",style:e.isChecked?e.activeStyle:null},[e._t("default",[e._v(e._s(e.label))])],2):e._e()])},gn=[];vn._withStripped=!0;var bn={name:"ElCheckboxButton",mixins:[D.a],inject:{elForm:{default:""},elFormItem:{default:""}},data:function(){return{selfModel:!1,focus:!1,isLimitExceeded:!1}},props:{value:{},label:{},disabled:Boolean,checked:Boolean,name:String,trueLabel:[String,Number],falseLabel:[String,Number]},computed:{model:{get:function(){return this._checkboxGroup?this.store:void 0!==this.value?this.value:this.selfModel},set:function(e){this._checkboxGroup?(this.isLimitExceeded=!1,void 0!==this._checkboxGroup.min&&e.lengththis._checkboxGroup.max&&(this.isLimitExceeded=!0),!1===this.isLimitExceeded&&this.dispatch("ElCheckboxGroup","input",[e])):void 0!==this.value?this.$emit("input",e):this.selfModel=e}},isChecked:function(){return"[object Boolean]"==={}.toString.call(this.model)?this.model:Array.isArray(this.model)?this.model.indexOf(this.label)>-1:null!==this.model&&void 0!==this.model?this.model===this.trueLabel:void 0},_checkboxGroup:function(){var e=this.$parent;while(e){if("ElCheckboxGroup"===e.$options.componentName)return e;e=e.$parent}return!1},store:function(){return this._checkboxGroup?this._checkboxGroup.value:this.value},activeStyle:function(){return{backgroundColor:this._checkboxGroup.fill||"",borderColor:this._checkboxGroup.fill||"",color:this._checkboxGroup.textColor||"","box-shadow":"-1px 0 0 0 "+this._checkboxGroup.fill}},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},size:function(){return this._checkboxGroup.checkboxGroupSize||this._elFormItemSize||(this.$ELEMENT||{}).size},isLimitDisabled:function(){var e=this._checkboxGroup,t=e.max,n=e.min;return!(!t&&!n)&&this.model.length>=t&&!this.isChecked||this.model.length<=n&&this.isChecked},isDisabled:function(){return this._checkboxGroup?this._checkboxGroup.disabled||this.disabled||(this.elForm||{}).disabled||this.isLimitDisabled:this.disabled||(this.elForm||{}).disabled}},methods:{addToStore:function(){Array.isArray(this.model)&&-1===this.model.indexOf(this.label)?this.model.push(this.label):this.model=this.trueLabel||!0},handleChange:function(e){var t=this;if(!this.isLimitExceeded){var n=void 0;n=e.target.checked?void 0===this.trueLabel||this.trueLabel:void 0!==this.falseLabel&&this.falseLabel,this.$emit("change",n,e),this.$nextTick((function(){t._checkboxGroup&&t.dispatch("ElCheckboxGroup","change",[t._checkboxGroup.value])}))}}},created:function(){this.checked&&this.addToStore()}},yn=bn,_n=s(yn,vn,gn,!1,null,null,null);_n.options.__file="packages/checkbox/src/checkbox-button.vue";var xn=_n.exports;xn.install=function(e){e.component(xn.name,xn)};var wn=xn,Cn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-checkbox-group",attrs:{role:"group","aria-label":"checkbox-group"}},[e._t("default")],2)},kn=[];Cn._withStripped=!0;var Sn={name:"ElCheckboxGroup",componentName:"ElCheckboxGroup",mixins:[D.a],inject:{elFormItem:{default:""}},props:{value:{},disabled:Boolean,min:Number,max:Number,size:String,fill:String,textColor:String},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},checkboxGroupSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size}},watch:{value:function(e){this.dispatch("ElFormItem","el.form.change",[e])}}},On=Sn,$n=s(On,Cn,kn,!1,null,null,null);$n.options.__file="packages/checkbox/src/checkbox-group.vue";var Dn=$n.exports;Dn.install=function(e){e.component(Dn.name,Dn)};var En=Dn,Tn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-switch",class:{"is-disabled":e.switchDisabled,"is-checked":e.checked},attrs:{role:"switch","aria-checked":e.checked,"aria-disabled":e.switchDisabled},on:{click:function(t){return t.preventDefault(),e.switchValue(t)}}},[n("input",{ref:"input",staticClass:"el-switch__input",attrs:{type:"checkbox",id:e.id,name:e.name,"true-value":e.activeValue,"false-value":e.inactiveValue,disabled:e.switchDisabled},on:{change:e.handleChange,keydown:function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.switchValue(t):null}}}),e.inactiveIconClass||e.inactiveText?n("span",{class:["el-switch__label","el-switch__label--left",e.checked?"":"is-active"]},[e.inactiveIconClass?n("i",{class:[e.inactiveIconClass]}):e._e(),!e.inactiveIconClass&&e.inactiveText?n("span",{attrs:{"aria-hidden":e.checked}},[e._v(e._s(e.inactiveText))]):e._e()]):e._e(),n("span",{ref:"core",staticClass:"el-switch__core",style:{width:e.coreWidth+"px"}}),e.activeIconClass||e.activeText?n("span",{class:["el-switch__label","el-switch__label--right",e.checked?"is-active":""]},[e.activeIconClass?n("i",{class:[e.activeIconClass]}):e._e(),!e.activeIconClass&&e.activeText?n("span",{attrs:{"aria-hidden":!e.checked}},[e._v(e._s(e.activeText))]):e._e()]):e._e()])},Pn=[];Tn._withStripped=!0;var Mn={name:"ElSwitch",mixins:[Z()("input"),O.a,D.a],inject:{elForm:{default:""}},props:{value:{type:[Boolean,String,Number],default:!1},disabled:{type:Boolean,default:!1},width:{type:Number,default:40},activeIconClass:{type:String,default:""},inactiveIconClass:{type:String,default:""},activeText:String,inactiveText:String,activeColor:{type:String,default:""},inactiveColor:{type:String,default:""},activeValue:{type:[Boolean,String,Number],default:!0},inactiveValue:{type:[Boolean,String,Number],default:!1},name:{type:String,default:""},validateEvent:{type:Boolean,default:!0},id:String},data:function(){return{coreWidth:this.width}},created:function(){~[this.activeValue,this.inactiveValue].indexOf(this.value)||this.$emit("input",this.inactiveValue)},computed:{checked:function(){return this.value===this.activeValue},switchDisabled:function(){return this.disabled||(this.elForm||{}).disabled}},watch:{checked:function(){this.$refs.input.checked=this.checked,(this.activeColor||this.inactiveColor)&&this.setBackgroundColor(),this.validateEvent&&this.dispatch("ElFormItem","el.form.change",[this.value])}},methods:{handleChange:function(e){var t=this,n=this.checked?this.inactiveValue:this.activeValue;this.$emit("input",n),this.$emit("change",n),this.$nextTick((function(){t.$refs.input.checked=t.checked}))},setBackgroundColor:function(){var e=this.checked?this.activeColor:this.inactiveColor;this.$refs.core.style.borderColor=e,this.$refs.core.style.backgroundColor=e},switchValue:function(){!this.switchDisabled&&this.handleChange()},getMigratingConfig:function(){return{props:{"on-color":"on-color is renamed to active-color.","off-color":"off-color is renamed to inactive-color.","on-text":"on-text is renamed to active-text.","off-text":"off-text is renamed to inactive-text.","on-value":"on-value is renamed to active-value.","off-value":"off-value is renamed to inactive-value.","on-icon-class":"on-icon-class is renamed to active-icon-class.","off-icon-class":"off-icon-class is renamed to inactive-icon-class."}}}},mounted:function(){this.coreWidth=this.width||40,(this.activeColor||this.inactiveColor)&&this.setBackgroundColor(),this.$refs.input.checked=this.checked}},In=Mn,Nn=s(In,Tn,Pn,!1,null,null,null);Nn.options.__file="packages/switch/src/component.vue";var jn=Nn.exports;jn.install=function(e){e.component(jn.name,jn)};var An=jn,Fn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleClose,expression:"handleClose"}],staticClass:"el-select",class:[e.selectSize?"el-select--"+e.selectSize:""],on:{click:function(t){return t.stopPropagation(),e.toggleMenu(t)}}},[e.multiple?n("div",{ref:"tags",staticClass:"el-select__tags",style:{"max-width":e.inputWidth-32+"px",width:"100%"}},[e.collapseTags&&e.selected.length?n("span",[n("el-tag",{attrs:{closable:!e.selectDisabled,size:e.collapseTagSize,hit:e.selected[0].hitState,type:"info","disable-transitions":""},on:{close:function(t){e.deleteTag(t,e.selected[0])}}},[n("span",{staticClass:"el-select__tags-text"},[e._v(e._s(e.selected[0].currentLabel))])]),e.selected.length>1?n("el-tag",{attrs:{closable:!1,size:e.collapseTagSize,type:"info","disable-transitions":""}},[n("span",{staticClass:"el-select__tags-text"},[e._v("+ "+e._s(e.selected.length-1))])]):e._e()],1):e._e(),e.collapseTags?e._e():n("transition-group",{on:{"after-leave":e.resetInputHeight}},e._l(e.selected,(function(t){return n("el-tag",{key:e.getValueKey(t),attrs:{closable:!e.selectDisabled,size:e.collapseTagSize,hit:t.hitState,type:"info","disable-transitions":""},on:{close:function(n){e.deleteTag(n,t)}}},[n("span",{staticClass:"el-select__tags-text"},[e._v(e._s(t.currentLabel))])])})),1),e.filterable?n("input",{directives:[{name:"model",rawName:"v-model",value:e.query,expression:"query"}],ref:"input",staticClass:"el-select__input",class:[e.selectSize?"is-"+e.selectSize:""],style:{"flex-grow":"1",width:e.inputLength/(e.inputWidth-32)+"%","max-width":e.inputWidth-42+"px"},attrs:{type:"text",disabled:e.selectDisabled,autocomplete:e.autoComplete||e.autocomplete},domProps:{value:e.query},on:{focus:e.handleFocus,blur:function(t){e.softFocus=!1},keyup:e.managePlaceholder,keydown:[e.resetInputState,function(t){if(!("button"in t)&&e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"]))return null;t.preventDefault(),e.navigateOptions("next")},function(t){if(!("button"in t)&&e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"]))return null;t.preventDefault(),e.navigateOptions("prev")},function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?(t.preventDefault(),e.selectOption(t)):null},function(t){if(!("button"in t)&&e._k(t.keyCode,"esc",27,t.key,["Esc","Escape"]))return null;t.stopPropagation(),t.preventDefault(),e.visible=!1},function(t){return"button"in t||!e._k(t.keyCode,"delete",[8,46],t.key,["Backspace","Delete","Del"])?e.deletePrevTag(t):null},function(t){if(!("button"in t)&&e._k(t.keyCode,"tab",9,t.key,"Tab"))return null;e.visible=!1}],compositionstart:e.handleComposition,compositionupdate:e.handleComposition,compositionend:e.handleComposition,input:[function(t){t.target.composing||(e.query=t.target.value)},e.debouncedQueryChange]}}):e._e()],1):e._e(),n("el-input",{ref:"reference",class:{"is-focus":e.visible},attrs:{type:"text",placeholder:e.currentPlaceholder,name:e.name,id:e.id,autocomplete:e.autoComplete||e.autocomplete,size:e.selectSize,disabled:e.selectDisabled,readonly:e.readonly,"validate-event":!1,tabindex:e.multiple&&e.filterable?"-1":null},on:{focus:e.handleFocus,blur:e.handleBlur},nativeOn:{keyup:function(t){return e.debouncedOnInputChange(t)},keydown:[function(t){if(!("button"in t)&&e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"]))return null;t.stopPropagation(),t.preventDefault(),e.navigateOptions("next")},function(t){if(!("button"in t)&&e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"]))return null;t.stopPropagation(),t.preventDefault(),e.navigateOptions("prev")},function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?(t.preventDefault(),e.selectOption(t)):null},function(t){if(!("button"in t)&&e._k(t.keyCode,"esc",27,t.key,["Esc","Escape"]))return null;t.stopPropagation(),t.preventDefault(),e.visible=!1},function(t){if(!("button"in t)&&e._k(t.keyCode,"tab",9,t.key,"Tab"))return null;e.visible=!1}],paste:function(t){return e.debouncedOnInputChange(t)},mouseenter:function(t){e.inputHovering=!0},mouseleave:function(t){e.inputHovering=!1}},model:{value:e.selectedLabel,callback:function(t){e.selectedLabel=t},expression:"selectedLabel"}},[e.$slots.prefix?n("template",{slot:"prefix"},[e._t("prefix")],2):e._e(),n("template",{slot:"suffix"},[n("i",{directives:[{name:"show",rawName:"v-show",value:!e.showClose,expression:"!showClose"}],class:["el-select__caret","el-input__icon","el-icon-"+e.iconClass]}),e.showClose?n("i",{staticClass:"el-select__caret el-input__icon el-icon-circle-close",on:{click:e.handleClearClick}}):e._e()])],2),n("transition",{attrs:{name:"el-zoom-in-top"},on:{"before-enter":e.handleMenuEnter,"after-leave":e.doDestroy}},[n("el-select-menu",{directives:[{name:"show",rawName:"v-show",value:e.visible&&!1!==e.emptyText,expression:"visible && emptyText !== false"}],ref:"popper",attrs:{"append-to-body":e.popperAppendToBody}},[n("el-scrollbar",{directives:[{name:"show",rawName:"v-show",value:e.options.length>0&&!e.loading,expression:"options.length > 0 && !loading"}],ref:"scrollbar",class:{"is-empty":!e.allowCreate&&e.query&&0===e.filteredOptionsCount},attrs:{tag:"ul","wrap-class":"el-select-dropdown__wrap","view-class":"el-select-dropdown__list"}},[e.showNewOption?n("el-option",{attrs:{value:e.query,created:""}}):e._e(),e._t("default")],2),e.emptyText&&(!e.allowCreate||e.loading||e.allowCreate&&0===e.options.length)?[e.$slots.empty?e._t("empty"):n("p",{staticClass:"el-select-dropdown__empty"},[e._v("\n "+e._s(e.emptyText)+"\n ")])]:e._e()],2)],1)],1)},Ln=[];Fn._withStripped=!0;var Vn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-select-dropdown el-popper",class:[{"is-multiple":e.$parent.multiple},e.popperClass],style:{minWidth:e.minWidth}},[e._t("default")],2)},zn=[];Vn._withStripped=!0;var Bn={name:"ElSelectDropdown",componentName:"ElSelectDropdown",mixins:[H.a],props:{placement:{default:"bottom-start"},boundariesPadding:{default:0},popperOptions:{default:function(){return{gpuAcceleration:!1}}},visibleArrow:{default:!0},appendToBody:{type:Boolean,default:!0}},data:function(){return{minWidth:""}},computed:{popperClass:function(){return this.$parent.popperClass}},watch:{"$parent.inputWidth":function(){this.minWidth=this.$parent.$el.getBoundingClientRect().width+"px"}},mounted:function(){var e=this;this.referenceElm=this.$parent.$refs.reference.$el,this.$parent.popperElm=this.popperElm=this.$el,this.$on("updatePopper",(function(){e.$parent.visible&&e.updatePopper()})),this.$on("destroyPopper",this.destroyPopper)}},Rn=Bn,Hn=s(Rn,Vn,zn,!1,null,null,null);Hn.options.__file="packages/select/src/select-dropdown.vue";var Wn=Hn.exports,qn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-select-dropdown__item",class:{selected:e.itemSelected,"is-disabled":e.disabled||e.groupDisabled||e.limitReached,hover:e.hover},on:{mouseenter:e.hoverItem,click:function(t){return t.stopPropagation(),e.selectOptionClick(t)}}},[e._t("default",[n("span",[e._v(e._s(e.currentLabel))])])],2)},Un=[];qn._withStripped=!0;var Yn="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Kn={mixins:[D.a],name:"ElOption",componentName:"ElOption",inject:["select"],props:{value:{required:!0},label:[String,Number],created:Boolean,disabled:{type:Boolean,default:!1}},data:function(){return{index:-1,groupDisabled:!1,visible:!0,hitState:!1,hover:!1}},computed:{isObject:function(){return"[object object]"===Object.prototype.toString.call(this.value).toLowerCase()},currentLabel:function(){return this.label||(this.isObject?"":this.value)},currentValue:function(){return this.value||this.label||""},itemSelected:function(){return this.select.multiple?this.contains(this.select.value,this.value):this.isEqual(this.value,this.select.value)},limitReached:function(){return!!this.select.multiple&&(!this.itemSelected&&(this.select.value||[]).length>=this.select.multipleLimit&&this.select.multipleLimit>0)}},watch:{currentLabel:function(){this.created||this.select.remote||this.dispatch("ElSelect","setSelected")},value:function(e,t){var n=this.select,i=n.remote,r=n.valueKey;if(!this.created&&!i){if(r&&"object"===("undefined"===typeof e?"undefined":Yn(e))&&"object"===("undefined"===typeof t?"undefined":Yn(t))&&e[r]===t[r])return;this.dispatch("ElSelect","setSelected")}}},methods:{isEqual:function(e,t){if(this.isObject){var n=this.select.valueKey;return Object(b["getValueByPath"])(e,n)===Object(b["getValueByPath"])(t,n)}return e===t},contains:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1];if(this.isObject){var n=this.select.valueKey;return e&&e.some((function(e){return Object(b["getValueByPath"])(e,n)===Object(b["getValueByPath"])(t,n)}))}return e&&e.indexOf(t)>-1},handleGroupDisabled:function(e){this.groupDisabled=e},hoverItem:function(){this.disabled||this.groupDisabled||(this.select.hoverIndex=this.select.options.indexOf(this))},selectOptionClick:function(){!0!==this.disabled&&!0!==this.groupDisabled&&this.dispatch("ElSelect","handleOptionClick",[this,!0])},queryChange:function(e){this.visible=new RegExp(Object(b["escapeRegexpString"])(e),"i").test(this.currentLabel)||this.created,this.visible||this.select.filteredOptionsCount--}},created:function(){this.select.options.push(this),this.select.cachedOptions.push(this),this.select.optionsCount++,this.select.filteredOptionsCount++,this.$on("queryChange",this.queryChange),this.$on("handleGroupDisabled",this.handleGroupDisabled)},beforeDestroy:function(){var e=this.select.cachedOptions.indexOf(this);e>-1&&this.select.cachedOptions.splice(e,1),this.select.onOptionDestroy(this.select.options.indexOf(this))}},Gn=Kn,Xn=s(Gn,qn,Un,!1,null,null,null);Xn.options.__file="packages/select/src/option.vue";var Zn=Xn.exports,Jn=n(28),Qn=n.n(Jn),ei=n(11),ti=n(15),ni=n.n(ti),ii=n(27),ri=n.n(ii),oi={data:function(){return{hoverOption:-1}},computed:{optionsAllDisabled:function(){return this.options.filter((function(e){return e.visible})).every((function(e){return e.disabled}))}},watch:{hoverIndex:function(e){var t=this;"number"===typeof e&&e>-1&&(this.hoverOption=this.options[e]||{}),this.options.forEach((function(e){e.hover=t.hoverOption===e}))}},methods:{navigateOptions:function(e){var t=this;if(this.visible){if(0!==this.options.length&&0!==this.filteredOptionsCount&&!this.optionsAllDisabled){"next"===e?(this.hoverIndex++,this.hoverIndex===this.options.length&&(this.hoverIndex=0)):"prev"===e&&(this.hoverIndex--,this.hoverIndex<0&&(this.hoverIndex=this.options.length-1));var n=this.options[this.hoverIndex];!0!==n.disabled&&!0!==n.groupDisabled&&n.visible||this.navigateOptions(e),this.$nextTick((function(){return t.scrollToOption(t.hoverOption)}))}}else this.visible=!0}}},ai={mixins:[D.a,g.a,Z()("reference"),oi],name:"ElSelect",componentName:"ElSelect",inject:{elForm:{default:""},elFormItem:{default:""}},provide:function(){return{select:this}},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},readonly:function(){return!this.filterable||this.multiple||!Object(b["isIE"])()&&!Object(b["isEdge"])()&&!this.visible},showClose:function(){var e=this.multiple?Array.isArray(this.value)&&this.value.length>0:void 0!==this.value&&null!==this.value&&""!==this.value,t=this.clearable&&!this.selectDisabled&&this.inputHovering&&e;return t},iconClass:function(){return this.remote&&this.filterable?"":this.visible?"arrow-up is-reverse":"arrow-up"},debounce:function(){return this.remote?300:0},emptyText:function(){return this.loading?this.loadingText||this.t("el.select.loading"):(!this.remote||""!==this.query||0!==this.options.length)&&(this.filterable&&this.query&&this.options.length>0&&0===this.filteredOptionsCount?this.noMatchText||this.t("el.select.noMatch"):0===this.options.length?this.noDataText||this.t("el.select.noData"):null)},showNewOption:function(){var e=this,t=this.options.filter((function(e){return!e.created})).some((function(t){return t.currentLabel===e.query}));return this.filterable&&this.allowCreate&&""!==this.query&&!t},selectSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},selectDisabled:function(){return this.disabled||(this.elForm||{}).disabled},collapseTagSize:function(){return["small","mini"].indexOf(this.selectSize)>-1?"mini":"small"}},components:{ElInput:m.a,ElSelectMenu:Wn,ElOption:Zn,ElTag:Qn.a,ElScrollbar:q.a},directives:{Clickoutside:V.a},props:{name:String,id:String,value:{required:!0},autocomplete:{type:String,default:"off"},autoComplete:{type:String,validator:function(e){return!0}},automaticDropdown:Boolean,size:String,disabled:Boolean,clearable:Boolean,filterable:Boolean,allowCreate:Boolean,loading:Boolean,popperClass:String,remote:Boolean,loadingText:String,noMatchText:String,noDataText:String,remoteMethod:Function,filterMethod:Function,multiple:Boolean,multipleLimit:{type:Number,default:0},placeholder:{type:String,default:function(){return Object(ti["t"])("el.select.placeholder")}},defaultFirstOption:Boolean,reserveKeyword:Boolean,valueKey:{type:String,default:"value"},collapseTags:Boolean,popperAppendToBody:{type:Boolean,default:!0}},data:function(){return{options:[],cachedOptions:[],createdLabel:null,createdSelected:!1,selected:this.multiple?[]:{},inputLength:20,inputWidth:0,initialInputHeight:0,cachedPlaceHolder:"",optionsCount:0,filteredOptionsCount:0,visible:!1,softFocus:!1,selectedLabel:"",hoverIndex:-1,query:"",previousQuery:null,inputHovering:!1,currentPlaceholder:"",menuVisibleOnFocus:!1,isOnComposition:!1,isSilentBlur:!1}},watch:{selectDisabled:function(){var e=this;this.$nextTick((function(){e.resetInputHeight()}))},placeholder:function(e){this.cachedPlaceHolder=this.currentPlaceholder=e},value:function(e,t){this.multiple&&(this.resetInputHeight(),e&&e.length>0||this.$refs.input&&""!==this.query?this.currentPlaceholder="":this.currentPlaceholder=this.cachedPlaceHolder,this.filterable&&!this.reserveKeyword&&(this.query="",this.handleQueryChange(this.query))),this.setSelected(),this.filterable&&!this.multiple&&(this.inputLength=20),Object(b["valueEquals"])(e,t)||this.dispatch("ElFormItem","el.form.change",e)},visible:function(e){var t=this;e?(this.broadcast("ElSelectDropdown","updatePopper"),this.filterable&&(this.query=this.remote?"":this.selectedLabel,this.handleQueryChange(this.query),this.multiple?this.$refs.input.focus():(this.remote||(this.broadcast("ElOption","queryChange",""),this.broadcast("ElOptionGroup","queryChange")),this.selectedLabel&&(this.currentPlaceholder=this.selectedLabel,this.selectedLabel="")))):(this.broadcast("ElSelectDropdown","destroyPopper"),this.$refs.input&&this.$refs.input.blur(),this.query="",this.previousQuery=null,this.selectedLabel="",this.inputLength=20,this.menuVisibleOnFocus=!1,this.resetHoverIndex(),this.$nextTick((function(){t.$refs.input&&""===t.$refs.input.value&&0===t.selected.length&&(t.currentPlaceholder=t.cachedPlaceHolder)})),this.multiple||(this.selected&&(this.filterable&&this.allowCreate&&this.createdSelected&&this.createdLabel?this.selectedLabel=this.createdLabel:this.selectedLabel=this.selected.currentLabel,this.filterable&&(this.query=this.selectedLabel)),this.filterable&&(this.currentPlaceholder=this.cachedPlaceHolder))),this.$emit("visible-change",e)},options:function(){var e=this;if(!this.$isServer){this.$nextTick((function(){e.broadcast("ElSelectDropdown","updatePopper")})),this.multiple&&this.resetInputHeight();var t=this.$el.querySelectorAll("input");-1===[].indexOf.call(t,document.activeElement)&&this.setSelected(),this.defaultFirstOption&&(this.filterable||this.remote)&&this.filteredOptionsCount&&this.checkDefaultFirstOption()}}},methods:{handleComposition:function(e){var t=this,n=e.target.value;if("compositionend"===e.type)this.isOnComposition=!1,this.$nextTick((function(e){return t.handleQueryChange(n)}));else{var i=n[n.length-1]||"";this.isOnComposition=!Object(Ot["isKorean"])(i)}},handleQueryChange:function(e){var t=this;this.previousQuery===e||this.isOnComposition||(null!==this.previousQuery||"function"!==typeof this.filterMethod&&"function"!==typeof this.remoteMethod?(this.previousQuery=e,this.$nextTick((function(){t.visible&&t.broadcast("ElSelectDropdown","updatePopper")})),this.hoverIndex=-1,this.multiple&&this.filterable&&this.$nextTick((function(){var e=15*t.$refs.input.value.length+20;t.inputLength=t.collapseTags?Math.min(50,e):e,t.managePlaceholder(),t.resetInputHeight()})),this.remote&&"function"===typeof this.remoteMethod?(this.hoverIndex=-1,this.remoteMethod(e)):"function"===typeof this.filterMethod?(this.filterMethod(e),this.broadcast("ElOptionGroup","queryChange")):(this.filteredOptionsCount=this.optionsCount,this.broadcast("ElOption","queryChange",e),this.broadcast("ElOptionGroup","queryChange")),this.defaultFirstOption&&(this.filterable||this.remote)&&this.filteredOptionsCount&&this.checkDefaultFirstOption()):this.previousQuery=e)},scrollToOption:function(e){var t=Array.isArray(e)&&e[0]?e[0].$el:e.$el;if(this.$refs.popper&&t){var n=this.$refs.popper.$el.querySelector(".el-select-dropdown__wrap");ri()(n,t)}this.$refs.scrollbar&&this.$refs.scrollbar.handleScroll()},handleMenuEnter:function(){var e=this;this.$nextTick((function(){return e.scrollToOption(e.selected)}))},emitChange:function(e){Object(b["valueEquals"])(this.value,e)||this.$emit("change",e)},getOption:function(e){for(var t=void 0,n="[object object]"===Object.prototype.toString.call(e).toLowerCase(),i="[object null]"===Object.prototype.toString.call(e).toLowerCase(),r="[object undefined]"===Object.prototype.toString.call(e).toLowerCase(),o=this.cachedOptions.length-1;o>=0;o--){var a=this.cachedOptions[o],s=n?Object(b["getValueByPath"])(a.value,this.valueKey)===Object(b["getValueByPath"])(e,this.valueKey):a.value===e;if(s){t=a;break}}if(t)return t;var l=n||i||r?"":e,c={value:e,currentLabel:l};return this.multiple&&(c.hitState=!1),c},setSelected:function(){var e=this;if(!this.multiple){var t=this.getOption(this.value);return t.created?(this.createdLabel=t.currentLabel,this.createdSelected=!0):this.createdSelected=!1,this.selectedLabel=t.currentLabel,this.selected=t,void(this.filterable&&(this.query=this.selectedLabel))}var n=[];Array.isArray(this.value)&&this.value.forEach((function(t){n.push(e.getOption(t))})),this.selected=n,this.$nextTick((function(){e.resetInputHeight()}))},handleFocus:function(e){this.softFocus?this.softFocus=!1:((this.automaticDropdown||this.filterable)&&(this.visible=!0,this.filterable&&(this.menuVisibleOnFocus=!0)),this.$emit("focus",e))},blur:function(){this.visible=!1,this.$refs.reference.blur()},handleBlur:function(e){var t=this;setTimeout((function(){t.isSilentBlur?t.isSilentBlur=!1:t.$emit("blur",e)}),50),this.softFocus=!1},handleClearClick:function(e){this.deleteSelected(e)},doDestroy:function(){this.$refs.popper&&this.$refs.popper.doDestroy()},handleClose:function(){this.visible=!1},toggleLastOptionHitState:function(e){if(Array.isArray(this.selected)){var t=this.selected[this.selected.length-1];if(t)return!0===e||!1===e?(t.hitState=e,e):(t.hitState=!t.hitState,t.hitState)}},deletePrevTag:function(e){if(e.target.value.length<=0&&!this.toggleLastOptionHitState()){var t=this.value.slice();t.pop(),this.$emit("input",t),this.emitChange(t)}},managePlaceholder:function(){""!==this.currentPlaceholder&&(this.currentPlaceholder=this.$refs.input.value?"":this.cachedPlaceHolder)},resetInputState:function(e){8!==e.keyCode&&this.toggleLastOptionHitState(!1),this.inputLength=15*this.$refs.input.value.length+20,this.resetInputHeight()},resetInputHeight:function(){var e=this;this.collapseTags&&!this.filterable||this.$nextTick((function(){if(e.$refs.reference){var t=e.$refs.reference.$el.childNodes,n=[].filter.call(t,(function(e){return"INPUT"===e.tagName}))[0],i=e.$refs.tags,r=e.initialInputHeight||40;n.style.height=0===e.selected.length?r+"px":Math.max(i?i.clientHeight+(i.clientHeight>r?6:0):0,r)+"px",e.visible&&!1!==e.emptyText&&e.broadcast("ElSelectDropdown","updatePopper")}}))},resetHoverIndex:function(){var e=this;setTimeout((function(){e.multiple?e.selected.length>0?e.hoverIndex=Math.min.apply(null,e.selected.map((function(t){return e.options.indexOf(t)}))):e.hoverIndex=-1:e.hoverIndex=e.options.indexOf(e.selected)}),300)},handleOptionSelect:function(e,t){var n=this;if(this.multiple){var i=(this.value||[]).slice(),r=this.getValueIndex(i,e.value);r>-1?i.splice(r,1):(this.multipleLimit<=0||i.length0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1],n="[object object]"===Object.prototype.toString.call(t).toLowerCase();if(n){var i=this.valueKey,r=-1;return e.some((function(e,n){return Object(b["getValueByPath"])(e,i)===Object(b["getValueByPath"])(t,i)&&(r=n,!0)})),r}return e.indexOf(t)},toggleMenu:function(){this.selectDisabled||(this.menuVisibleOnFocus?this.menuVisibleOnFocus=!1:this.visible=!this.visible,this.visible&&(this.$refs.input||this.$refs.reference).focus())},selectOption:function(){this.visible?this.options[this.hoverIndex]&&this.handleOptionSelect(this.options[this.hoverIndex]):this.toggleMenu()},deleteSelected:function(e){e.stopPropagation();var t=this.multiple?[]:"";this.$emit("input",t),this.emitChange(t),this.visible=!1,this.$emit("clear")},deleteTag:function(e,t){var n=this.selected.indexOf(t);if(n>-1&&!this.selectDisabled){var i=this.value.slice();i.splice(n,1),this.$emit("input",i),this.emitChange(i),this.$emit("remove-tag",t.value)}e.stopPropagation()},onInputChange:function(){this.filterable&&this.query!==this.selectedLabel&&(this.query=this.selectedLabel,this.handleQueryChange(this.query))},onOptionDestroy:function(e){e>-1&&(this.optionsCount--,this.filteredOptionsCount--,this.options.splice(e,1))},resetInputWidth:function(){this.inputWidth=this.$refs.reference.$el.getBoundingClientRect().width},handleResize:function(){this.resetInputWidth(),this.multiple&&this.resetInputHeight()},checkDefaultFirstOption:function(){this.hoverIndex=-1;for(var e=!1,t=this.options.length-1;t>=0;t--)if(this.options[t].created){e=!0,this.hoverIndex=t;break}if(!e)for(var n=0;n!==this.options.length;++n){var i=this.options[n];if(this.query){if(!i.disabled&&!i.groupDisabled&&i.visible){this.hoverIndex=n;break}}else if(i.itemSelected){this.hoverIndex=n;break}}},getValueKey:function(e){return"[object object]"!==Object.prototype.toString.call(e.value).toLowerCase()?e.value:Object(b["getValueByPath"])(e.value,this.valueKey)}},created:function(){var e=this;this.cachedPlaceHolder=this.currentPlaceholder=this.placeholder,this.multiple&&!Array.isArray(this.value)&&this.$emit("input",[]),!this.multiple&&Array.isArray(this.value)&&this.$emit("input",""),this.debouncedOnInputChange=F()(this.debounce,(function(){e.onInputChange()})),this.debouncedQueryChange=F()(this.debounce,(function(t){e.handleQueryChange(t.target.value)})),this.$on("handleOptionClick",this.handleOptionSelect),this.$on("setSelected",this.setSelected)},mounted:function(){var e=this;this.multiple&&Array.isArray(this.value)&&this.value.length>0&&(this.currentPlaceholder=""),Object(ei["addResizeListener"])(this.$el,this.handleResize);var t=this.$refs.reference;if(t&&t.$el){var n={medium:36,small:32,mini:28},i=t.$el.querySelector("input");this.initialInputHeight=i.getBoundingClientRect().height||n[this.selectSize]}this.remote&&this.multiple&&this.resetInputHeight(),this.$nextTick((function(){t&&t.$el&&(e.inputWidth=t.$el.getBoundingClientRect().width)})),this.setSelected()},beforeDestroy:function(){this.$el&&this.handleResize&&Object(ei["removeResizeListener"])(this.$el,this.handleResize)}},si=ai,li=s(si,Fn,Ln,!1,null,null,null);li.options.__file="packages/select/src/select.vue";var ci=li.exports;ci.install=function(e){e.component(ci.name,ci)};var ui=ci;Zn.install=function(e){e.component(Zn.name,Zn)};var di=Zn,hi=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("ul",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-select-group__wrap"},[n("li",{staticClass:"el-select-group__title"},[e._v(e._s(e.label))]),n("li",[n("ul",{staticClass:"el-select-group"},[e._t("default")],2)])])},fi=[];hi._withStripped=!0;var pi={mixins:[D.a],name:"ElOptionGroup",componentName:"ElOptionGroup",props:{label:String,disabled:{type:Boolean,default:!1}},data:function(){return{visible:!0}},watch:{disabled:function(e){this.broadcast("ElOption","handleGroupDisabled",e)}},methods:{queryChange:function(){this.visible=this.$children&&Array.isArray(this.$children)&&this.$children.some((function(e){return!0===e.visible}))}},created:function(){this.$on("queryChange",this.queryChange)},mounted:function(){this.disabled&&this.broadcast("ElOption","handleGroupDisabled",this.disabled)}},mi=pi,vi=s(mi,hi,fi,!1,null,null,null);vi.options.__file="packages/select/src/option-group.vue";var gi=vi.exports;gi.install=function(e){e.component(gi.name,gi)};var bi=gi,yi=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("button",{staticClass:"el-button",class:[e.type?"el-button--"+e.type:"",e.buttonSize?"el-button--"+e.buttonSize:"",{"is-disabled":e.buttonDisabled,"is-loading":e.loading,"is-plain":e.plain,"is-round":e.round,"is-circle":e.circle}],attrs:{disabled:e.buttonDisabled||e.loading,autofocus:e.autofocus,type:e.nativeType},on:{click:e.handleClick}},[e.loading?n("i",{staticClass:"el-icon-loading"}):e._e(),e.icon&&!e.loading?n("i",{class:e.icon}):e._e(),e.$slots.default?n("span",[e._t("default")],2):e._e()])},_i=[];yi._withStripped=!0;var xi={name:"ElButton",inject:{elForm:{default:""},elFormItem:{default:""}},props:{type:{type:String,default:"default"},size:String,icon:{type:String,default:""},nativeType:{type:String,default:"button"},loading:Boolean,disabled:Boolean,plain:Boolean,autofocus:Boolean,round:Boolean,circle:Boolean},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},buttonSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},buttonDisabled:function(){return this.disabled||(this.elForm||{}).disabled}},methods:{handleClick:function(e){this.$emit("click",e)}}},wi=xi,Ci=s(wi,yi,_i,!1,null,null,null);Ci.options.__file="packages/button/src/button.vue";var ki=Ci.exports;ki.install=function(e){e.component(ki.name,ki)};var Si=ki,Oi=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-button-group"},[e._t("default")],2)},$i=[];Oi._withStripped=!0;var Di={name:"ElButtonGroup"},Ei=Di,Ti=s(Ei,Oi,$i,!1,null,null,null);Ti.options.__file="packages/button/src/button-group.vue";var Pi=Ti.exports;Pi.install=function(e){e.component(Pi.name,Pi)};var Mi=Pi,Ii=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-table",class:[{"el-table--fit":e.fit,"el-table--striped":e.stripe,"el-table--border":e.border||e.isGroup,"el-table--hidden":e.isHidden,"el-table--group":e.isGroup,"el-table--fluid-height":e.maxHeight,"el-table--scrollable-x":e.layout.scrollX,"el-table--scrollable-y":e.layout.scrollY,"el-table--enable-row-hover":!e.store.states.isComplex,"el-table--enable-row-transition":0!==(e.store.states.data||[]).length&&(e.store.states.data||[]).length<100},e.tableSize?"el-table--"+e.tableSize:""],on:{mouseleave:function(t){e.handleMouseLeave(t)}}},[n("div",{ref:"hiddenColumns",staticClass:"hidden-columns"},[e._t("default")],2),e.showHeader?n("div",{directives:[{name:"mousewheel",rawName:"v-mousewheel",value:e.handleHeaderFooterMousewheel,expression:"handleHeaderFooterMousewheel"}],ref:"headerWrapper",staticClass:"el-table__header-wrapper"},[n("table-header",{ref:"tableHeader",style:{width:e.layout.bodyWidth?e.layout.bodyWidth+"px":""},attrs:{store:e.store,border:e.border,"default-sort":e.defaultSort}})],1):e._e(),n("div",{ref:"bodyWrapper",staticClass:"el-table__body-wrapper",class:[e.layout.scrollX?"is-scrolling-"+e.scrollPosition:"is-scrolling-none"],style:[e.bodyHeight]},[n("table-body",{style:{width:e.bodyWidth},attrs:{context:e.context,store:e.store,stripe:e.stripe,"row-class-name":e.rowClassName,"row-style":e.rowStyle,highlight:e.highlightCurrentRow}}),e.data&&0!==e.data.length?e._e():n("div",{ref:"emptyBlock",staticClass:"el-table__empty-block",style:e.emptyBlockStyle},[n("span",{staticClass:"el-table__empty-text"},[e._t("empty",[e._v(e._s(e.emptyText||e.t("el.table.emptyText")))])],2)]),e.$slots.append?n("div",{ref:"appendWrapper",staticClass:"el-table__append-wrapper"},[e._t("append")],2):e._e()],1),e.showSummary?n("div",{directives:[{name:"show",rawName:"v-show",value:e.data&&e.data.length>0,expression:"data && data.length > 0"},{name:"mousewheel",rawName:"v-mousewheel",value:e.handleHeaderFooterMousewheel,expression:"handleHeaderFooterMousewheel"}],ref:"footerWrapper",staticClass:"el-table__footer-wrapper"},[n("table-footer",{style:{width:e.layout.bodyWidth?e.layout.bodyWidth+"px":""},attrs:{store:e.store,border:e.border,"sum-text":e.sumText||e.t("el.table.sumText"),"summary-method":e.summaryMethod,"default-sort":e.defaultSort}})],1):e._e(),e.fixedColumns.length>0?n("div",{directives:[{name:"mousewheel",rawName:"v-mousewheel",value:e.handleFixedMousewheel,expression:"handleFixedMousewheel"}],ref:"fixedWrapper",staticClass:"el-table__fixed",style:[{width:e.layout.fixedWidth?e.layout.fixedWidth+"px":""},e.fixedHeight]},[e.showHeader?n("div",{ref:"fixedHeaderWrapper",staticClass:"el-table__fixed-header-wrapper"},[n("table-header",{ref:"fixedTableHeader",style:{width:e.bodyWidth},attrs:{fixed:"left",border:e.border,store:e.store}})],1):e._e(),n("div",{ref:"fixedBodyWrapper",staticClass:"el-table__fixed-body-wrapper",style:[{top:e.layout.headerHeight+"px"},e.fixedBodyHeight]},[n("table-body",{style:{width:e.bodyWidth},attrs:{fixed:"left",store:e.store,stripe:e.stripe,highlight:e.highlightCurrentRow,"row-class-name":e.rowClassName,"row-style":e.rowStyle}}),e.$slots.append?n("div",{staticClass:"el-table__append-gutter",style:{height:e.layout.appendHeight+"px"}}):e._e()],1),e.showSummary?n("div",{directives:[{name:"show",rawName:"v-show",value:e.data&&e.data.length>0,expression:"data && data.length > 0"}],ref:"fixedFooterWrapper",staticClass:"el-table__fixed-footer-wrapper"},[n("table-footer",{style:{width:e.bodyWidth},attrs:{fixed:"left",border:e.border,"sum-text":e.sumText||e.t("el.table.sumText"),"summary-method":e.summaryMethod,store:e.store}})],1):e._e()]):e._e(),e.rightFixedColumns.length>0?n("div",{directives:[{name:"mousewheel",rawName:"v-mousewheel",value:e.handleFixedMousewheel,expression:"handleFixedMousewheel"}],ref:"rightFixedWrapper",staticClass:"el-table__fixed-right",style:[{width:e.layout.rightFixedWidth?e.layout.rightFixedWidth+"px":"",right:e.layout.scrollY?(e.border?e.layout.gutterWidth:e.layout.gutterWidth||0)+"px":""},e.fixedHeight]},[e.showHeader?n("div",{ref:"rightFixedHeaderWrapper",staticClass:"el-table__fixed-header-wrapper"},[n("table-header",{ref:"rightFixedTableHeader",style:{width:e.bodyWidth},attrs:{fixed:"right",border:e.border,store:e.store}})],1):e._e(),n("div",{ref:"rightFixedBodyWrapper",staticClass:"el-table__fixed-body-wrapper",style:[{top:e.layout.headerHeight+"px"},e.fixedBodyHeight]},[n("table-body",{style:{width:e.bodyWidth},attrs:{fixed:"right",store:e.store,stripe:e.stripe,"row-class-name":e.rowClassName,"row-style":e.rowStyle,highlight:e.highlightCurrentRow}}),e.$slots.append?n("div",{staticClass:"el-table__append-gutter",style:{height:e.layout.appendHeight+"px"}}):e._e()],1),e.showSummary?n("div",{directives:[{name:"show",rawName:"v-show",value:e.data&&e.data.length>0,expression:"data && data.length > 0"}],ref:"rightFixedFooterWrapper",staticClass:"el-table__fixed-footer-wrapper"},[n("table-footer",{style:{width:e.bodyWidth},attrs:{fixed:"right",border:e.border,"sum-text":e.sumText||e.t("el.table.sumText"),"summary-method":e.summaryMethod,store:e.store}})],1):e._e()]):e._e(),e.rightFixedColumns.length>0?n("div",{ref:"rightFixedPatch",staticClass:"el-table__fixed-right-patch",style:{width:e.layout.scrollY?e.layout.gutterWidth+"px":"0",height:e.layout.headerHeight+"px"}}):e._e(),n("div",{directives:[{name:"show",rawName:"v-show",value:e.resizeProxyVisible,expression:"resizeProxyVisible"}],ref:"resizeProxy",staticClass:"el-table__column-resize-proxy"})])},Ni=[];Ii._withStripped=!0;var ji=n(14),Ai=n.n(ji),Fi=n(34),Li=n(38),Vi=n.n(Li),zi="undefined"!==typeof navigator&&navigator.userAgent.toLowerCase().indexOf("firefox")>-1,Bi=function(e,t){e&&e.addEventListener&&e.addEventListener(zi?"DOMMouseScroll":"mousewheel",(function(e){var n=Vi()(e);t&&t.apply(this,[e,n])}))},Ri={bind:function(e,t){Bi(e,t.value)}},Hi=n(6),Wi=n.n(Hi),qi="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ui=function(e){var t=e.target;while(t&&"HTML"!==t.tagName.toUpperCase()){if("TD"===t.tagName.toUpperCase())return t;t=t.parentNode}return null},Yi=function(e){return null!==e&&"object"===("undefined"===typeof e?"undefined":qi(e))},Ki=function(e,t,n,i,r){if(!t&&!i&&(!r||Array.isArray(r)&&!r.length))return e;n="string"===typeof n?"descending"===n?-1:1:n&&n<0?-1:1;var o=i?null:function(n,i){return r?(Array.isArray(r)||(r=[r]),r.map((function(t){return"string"===typeof t?Object(b["getValueByPath"])(n,t):t(n,i,e)}))):("$key"!==t&&Yi(n)&&"$value"in n&&(n=n.$value),[Yi(n)?Object(b["getValueByPath"])(n,t):n])},a=function(e,t){if(i)return i(e.value,t.value);for(var n=0,r=e.key.length;nt.key[n])return 1}return 0};return e.map((function(e,t){return{value:e,index:t,key:o?o(e,t):null}})).sort((function(e,t){var i=a(e,t);return i||(i=e.index-t.index),i*n})).map((function(e){return e.value}))},Gi=function(e,t){var n=null;return e.columns.forEach((function(e){e.id===t&&(n=e)})),n},Xi=function(e,t){for(var n=null,i=0;i2&&void 0!==arguments[2]?arguments[2]:"children",i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"hasChildren",r=function(e){return!(Array.isArray(e)&&e.length)};function o(e,a,s){t(e,a,s),a.forEach((function(e){if(e[i])t(e,null,s+1);else{var a=e[n];r(a)||o(e,a,s+1)}}))}e.forEach((function(e){if(e[i])t(e,null,0);else{var a=e[n];r(a)||o(e,a,0)}}))}var lr={data:function(){return{states:{defaultExpandAll:!1,expandRows:[]}}},methods:{updateExpandRows:function(){var e=this.states,t=e.data,n=void 0===t?[]:t,i=e.rowKey,r=e.defaultExpandAll,o=e.expandRows;if(r)this.states.expandRows=n.slice();else if(i){var a=Qi(o,i);this.states.expandRows=n.reduce((function(e,t){var n=Ji(t,i),r=a[n];return r&&e.push(t),e}),[])}else this.states.expandRows=[]},toggleRowExpansion:function(e,t){var n=ar(this.states.expandRows,e,t);n&&(this.table.$emit("expand-change",e,this.states.expandRows.slice()),this.scheduleLayout())},setExpandRowKeys:function(e){this.assertRowKey();var t=this.states,n=t.data,i=t.rowKey,r=Qi(n,i);this.states.expandRows=e.reduce((function(e,t){var n=r[t];return n&&e.push(n.row),e}),[])},isRowExpanded:function(e){var t=this.states,n=t.expandRows,i=void 0===n?[]:n,r=t.rowKey;if(r){var o=Qi(i,r);return!!o[Ji(e,r)]}return-1!==i.indexOf(e)}}},cr={data:function(){return{states:{_currentRowKey:null,currentRow:null}}},methods:{setCurrentRowKey:function(e){this.assertRowKey(),this.states._currentRowKey=e,this.setCurrentRowByKey(e)},restoreCurrentRowKey:function(){this.states._currentRowKey=null},setCurrentRowByKey:function(e){var t=this.states,n=t.data,i=void 0===n?[]:n,r=t.rowKey,o=null;r&&(o=Object(b["arrayFind"])(i,(function(t){return Ji(t,r)===e}))),t.currentRow=o},updateCurrentRow:function(e){var t=this.states,n=this.table,i=t.currentRow;if(e&&e!==i)return t.currentRow=e,void n.$emit("current-change",e,i);!e&&i&&(t.currentRow=null,n.$emit("current-change",null,i))},updateCurrentRowData:function(){var e=this.states,t=this.table,n=e.rowKey,i=e._currentRowKey,r=e.data||[],o=e.currentRow;if(-1===r.indexOf(o)&&o){if(n){var a=Ji(o,n);this.setCurrentRowByKey(a)}else e.currentRow=null;null===e.currentRow&&t.$emit("current-change",null,o)}else i&&(this.setCurrentRowByKey(i),this.restoreCurrentRowKey())}}},ur=Object.assign||function(e){for(var t=1;t0&&t[0]&&"selection"===t[0].type&&!t[0].fixed&&(t[0].fixed=!0,e.fixedColumns.unshift(t[0]));var n=t.filter((function(e){return!e.fixed}));e.originColumns=[].concat(e.fixedColumns).concat(n).concat(e.rightFixedColumns);var i=fr(n),r=fr(e.fixedColumns),o=fr(e.rightFixedColumns);e.leafColumnsLength=i.length,e.fixedLeafColumnsLength=r.length,e.rightFixedLeafColumnsLength=o.length,e.columns=[].concat(r).concat(i).concat(o),e.isComplex=e.fixedColumns.length>0||e.rightFixedColumns.length>0},scheduleLayout:function(e){e&&this.updateColumns(),this.table.debouncedUpdateLayout()},isSelected:function(e){var t=this.states.selection,n=void 0===t?[]:t;return n.indexOf(e)>-1},clearSelection:function(){var e=this.states;e.isAllSelected=!1;var t=e.selection;t.length&&(e.selection=[],this.table.$emit("selection-change",[]))},cleanSelection:function(){var e=this.states,t=e.data,n=e.rowKey,i=e.selection,r=void 0;if(n){r=[];var o=Qi(i,n),a=Qi(t,n);for(var s in o)o.hasOwnProperty(s)&&!a[s]&&r.push(o[s].row)}else r=i.filter((function(e){return-1===t.indexOf(e)}));if(r.length){var l=i.filter((function(e){return-1===r.indexOf(e)}));e.selection=l,this.table.$emit("selection-change",l.slice())}},toggleRowSelection:function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],i=ar(this.states.selection,e,t);if(i){var r=(this.states.selection||[]).slice();n&&this.table.$emit("select",r,e),this.table.$emit("selection-change",r)}},_toggleAllSelection:function(){var e=this.states,t=e.data,n=void 0===t?[]:t,i=e.selection,r=e.selectOnIndeterminate?!e.isAllSelected:!(e.isAllSelected||i.length);e.isAllSelected=r;var o=!1;n.forEach((function(t,n){e.selectable?e.selectable.call(null,t,n)&&ar(i,t,r)&&(o=!0):ar(i,t,r)&&(o=!0)})),o&&this.table.$emit("selection-change",i?i.slice():[]),this.table.$emit("select-all",i)},updateSelectionByRowKey:function(){var e=this.states,t=e.selection,n=e.rowKey,i=e.data,r=Qi(t,n);i.forEach((function(e){var i=Ji(e,n),o=r[i];o&&(t[o.index]=e)}))},updateAllSelected:function(){var e=this.states,t=e.selection,n=e.rowKey,i=e.selectable,r=e.data||[];if(0!==r.length){var o=void 0;n&&(o=Qi(t,n));for(var a=function(e){return o?!!o[Ji(e,n)]:-1!==t.indexOf(e)},s=!0,l=0,c=0,u=r.length;c1?n-1:0),r=1;r1&&void 0!==arguments[1]?arguments[1]:{};if(!e)throw new Error("Table is required.");var n=new mr;return n.table=e,n.toggleAllSelection=F()(10,n._toggleAllSelection),Object.keys(t).forEach((function(e){n.states[e]=t[e]})),n}function gr(e){var t={};return Object.keys(e).forEach((function(n){var i=e[n],r=void 0;"string"===typeof i?r=function(){return this.store.states[i]}:"function"===typeof i?r=function(){return i.call(this,this.store.states)}:console.error("invalid value type"),r&&(t[n]=r)})),t}var br=n(29),yr=n.n(br);function _r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var xr=function(){function e(t){for(var n in _r(this,e),this.observers=[],this.table=null,this.store=null,this.columns=null,this.fit=!0,this.showHeader=!0,this.height=null,this.scrollX=!1,this.scrollY=!1,this.bodyWidth=null,this.fixedWidth=null,this.rightFixedWidth=null,this.tableHeight=null,this.headerHeight=44,this.appendHeight=0,this.footerHeight=44,this.viewportHeight=null,this.bodyHeight=null,this.fixedBodyHeight=null,this.gutterWidth=yr()(),t)t.hasOwnProperty(n)&&(this[n]=t[n]);if(!this.table)throw new Error("table is required for Table Layout");if(!this.store)throw new Error("store is required for Table Layout")}return e.prototype.updateScrollY=function(){var e=this.height;if(null===e)return!1;var t=this.table.bodyWrapper;if(this.table.$el&&t){var n=t.querySelector(".el-table__body"),i=this.scrollY,r=n.offsetHeight>this.bodyHeight;return this.scrollY=r,i!==r}return!1},e.prototype.setHeight=function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"height";if(!Wi.a.prototype.$isServer){var i=this.table.$el;if(e=rr(e),this.height=e,!i&&(e||0===e))return Wi.a.nextTick((function(){return t.setHeight(e,n)}));"number"===typeof e?(i.style[n]=e+"px",this.updateElsHeight()):"string"===typeof e&&(i.style[n]=e,this.updateElsHeight())}},e.prototype.setMaxHeight=function(e){this.setHeight(e,"max-height")},e.prototype.getFlattenColumns=function(){var e=[],t=this.table.columns;return t.forEach((function(t){t.isColumnGroup?e.push.apply(e,t.columns):e.push(t)})),e},e.prototype.updateElsHeight=function(){var e=this;if(!this.table.$ready)return Wi.a.nextTick((function(){return e.updateElsHeight()}));var t=this.table.$refs,n=t.headerWrapper,i=t.appendWrapper,r=t.footerWrapper;if(this.appendHeight=i?i.offsetHeight:0,!this.showHeader||n){var o=n.querySelector(".el-table__header tr"),a=this.headerDisplayNone(o),s=this.headerHeight=this.showHeader?n.offsetHeight:0;if(this.showHeader&&!a&&n.offsetWidth>0&&(this.table.columns||[]).length>0&&s<2)return Wi.a.nextTick((function(){return e.updateElsHeight()}));var l=this.tableHeight=this.table.$el.clientHeight,c=this.footerHeight=r?r.offsetHeight:0;null!==this.height&&(this.bodyHeight=l-s-c+(r?1:0)),this.fixedBodyHeight=this.scrollX?this.bodyHeight-this.gutterWidth:this.bodyHeight;var u=!this.table.data||0===this.table.data.length;this.viewportHeight=this.scrollX?l-(u?0:this.gutterWidth):l,this.updateScrollY(),this.notifyObservers("scrollable")}},e.prototype.headerDisplayNone=function(e){var t=e;while("DIV"!==t.tagName){if("none"===getComputedStyle(t).display)return!0;t=t.parentElement}return!1},e.prototype.updateColumnsWidth=function(){if(!Wi.a.prototype.$isServer){var e=this.fit,t=this.table.$el.clientWidth,n=0,i=this.getFlattenColumns(),r=i.filter((function(e){return"number"!==typeof e.width}));if(i.forEach((function(e){"number"===typeof e.width&&e.realWidth&&(e.realWidth=null)})),r.length>0&&e){i.forEach((function(e){n+=e.width||e.minWidth||80}));var o=this.scrollY?this.gutterWidth:0;if(n<=t-o){this.scrollX=!1;var a=t-o-n;if(1===r.length)r[0].realWidth=(r[0].minWidth||80)+a;else{var s=r.reduce((function(e,t){return e+(t.minWidth||80)}),0),l=a/s,c=0;r.forEach((function(e,t){if(0!==t){var n=Math.floor((e.minWidth||80)*l);c+=n,e.realWidth=(e.minWidth||80)+n}})),r[0].realWidth=(r[0].minWidth||80)+a-c}}else this.scrollX=!0,r.forEach((function(e){e.realWidth=e.minWidth}));this.bodyWidth=Math.max(n,t),this.table.resizeState.width=this.bodyWidth}else i.forEach((function(e){e.width||e.minWidth?e.realWidth=e.width||e.minWidth:e.realWidth=80,n+=e.realWidth})),this.scrollX=n>t,this.bodyWidth=n;var u=this.store.states.fixedColumns;if(u.length>0){var d=0;u.forEach((function(e){d+=e.realWidth||e.width})),this.fixedWidth=d}var h=this.store.states.rightFixedColumns;if(h.length>0){var f=0;h.forEach((function(e){f+=e.realWidth||e.width})),this.rightFixedWidth=f}this.notifyObservers("columns")}},e.prototype.addObserver=function(e){this.observers.push(e)},e.prototype.removeObserver=function(e){var t=this.observers.indexOf(e);-1!==t&&this.observers.splice(t,1)},e.prototype.notifyObservers=function(e){var t=this,n=this.observers;n.forEach((function(n){switch(e){case"columns":n.onColumnsChange(t);break;case"scrollable":n.onScrollableChange(t);break;default:throw new Error("Table Layout don't have event "+e+".")}}))},e}(),wr=xr,Cr={created:function(){this.tableLayout.addObserver(this)},destroyed:function(){this.tableLayout.removeObserver(this)},computed:{tableLayout:function(){var e=this.layout;if(!e&&this.table&&(e=this.table.layout),!e)throw new Error("Can not find table layout.");return e}},mounted:function(){this.onColumnsChange(this.tableLayout),this.onScrollableChange(this.tableLayout)},updated:function(){this.__updated__||(this.onColumnsChange(this.tableLayout),this.onScrollableChange(this.tableLayout),this.__updated__=!0)},methods:{onColumnsChange:function(){var e=this.$el.querySelectorAll("colgroup > col");if(e.length){var t=this.tableLayout.getFlattenColumns(),n={};t.forEach((function(e){n[e.id]=e}));for(var i=0,r=e.length;i col[name=gutter]"),n=0,i=t.length;n=this.leftFixedLeafCount:"right"===this.fixed?e=this.columnsCount-this.rightFixedLeafCount},getSpan:function(e,t,n,i){var r=1,o=1,a=this.table.spanMethod;if("function"===typeof a){var s=a({row:e,column:t,rowIndex:n,columnIndex:i});Array.isArray(s)?(r=s[0],o=s[1]):"object"===("undefined"===typeof s?"undefined":kr(s))&&(r=s.rowspan,o=s.colspan)}return{rowspan:r,colspan:o}},getRowStyle:function(e,t){var n=this.table.rowStyle;return"function"===typeof n?n.call(null,{row:e,rowIndex:t}):n||null},getRowClass:function(e,t){var n=["el-table__row"];this.table.highlightCurrentRow&&e===this.store.states.currentRow&&n.push("current-row"),this.stripe&&t%2===1&&n.push("el-table__row--striped");var i=this.table.rowClassName;return"string"===typeof i?n.push(i):"function"===typeof i&&n.push(i.call(null,{row:e,rowIndex:t})),this.store.states.expandRows.indexOf(e)>-1&&n.push("expanded"),n},getCellStyle:function(e,t,n,i){var r=this.table.cellStyle;return"function"===typeof r?r.call(null,{rowIndex:e,columnIndex:t,row:n,column:i}):r},getCellClass:function(e,t,n,i){var r=[i.id,i.align,i.className];this.isColumnHidden(t)&&r.push("is-hidden");var o=this.table.cellClassName;return"string"===typeof o?r.push(o):"function"===typeof o&&r.push(o.call(null,{rowIndex:e,columnIndex:t,row:n,column:i})),r.join(" ")},getColspanRealWidth:function(e,t,n){if(t<1)return e[n].realWidth;var i=e.map((function(e){var t=e.realWidth;return t})).slice(n,n+t);return i.reduce((function(e,t){return e+t}),-1)},handleCellMouseEnter:function(e,t){var n=this.table,i=Ui(e);if(i){var r=Zi(n,i),o=n.hoverState={cell:i,column:r,row:t};n.$emit("cell-mouse-enter",o.row,o.column,o.cell,e)}var a=e.target.querySelector(".cell");if(Object(Le["hasClass"])(a,"el-tooltip")&&a.childNodes.length){var s=document.createRange();s.setStart(a,0),s.setEnd(a,a.childNodes.length);var l=s.getBoundingClientRect().width,c=(parseInt(Object(Le["getStyle"])(a,"paddingLeft"),10)||0)+(parseInt(Object(Le["getStyle"])(a,"paddingRight"),10)||0);if((l+c>a.offsetWidth||a.scrollWidth>a.offsetWidth)&&this.$refs.tooltip){var u=this.$refs.tooltip;this.tooltipContent=i.innerText||i.textContent,u.referenceElm=i,u.$refs.popper&&(u.$refs.popper.style.display="none"),u.doDestroy(),u.setExpectedState(!0),this.activateTooltip(u)}}},handleCellMouseLeave:function(e){var t=this.$refs.tooltip;t&&(t.setExpectedState(!1),t.handleClosePopper());var n=Ui(e);if(n){var i=this.table.hoverState||{};this.table.$emit("cell-mouse-leave",i.row,i.column,i.cell,e)}},handleMouseEnter:F()(30,(function(e){this.store.commit("setHoverRow",e)})),handleMouseLeave:F()(30,(function(){this.store.commit("setHoverRow",null)})),handleContextMenu:function(e,t){this.handleEvent(e,t,"contextmenu")},handleDoubleClick:function(e,t){this.handleEvent(e,t,"dblclick")},handleClick:function(e,t){this.store.commit("setCurrentRow",t),this.handleEvent(e,t,"click")},handleEvent:function(e,t,n){var i=this.table,r=Ui(e),o=void 0;r&&(o=Zi(i,r),o&&i.$emit("cell-"+n,t,o,r,e)),i.$emit("row-"+n,t,o,e)},rowRender:function(e,t,n){var i=this,r=this.$createElement,o=this.treeIndent,a=this.columns,s=this.firstDefaultColumnIndex,l=a.map((function(e,t){return i.isColumnHidden(t)})),c=this.getRowClass(e,t),u=!0;return n&&(c.push("el-table__row--level-"+n.level),u=n.display),r("tr",{directives:[{name:"show",value:u}],style:this.getRowStyle(e,t),class:c,key:this.getKeyOfRow(e,t),on:{dblclick:function(t){return i.handleDoubleClick(t,e)},click:function(t){return i.handleClick(t,e)},contextmenu:function(t){return i.handleContextMenu(t,e)},mouseenter:function(e){return i.handleMouseEnter(t)},mouseleave:this.handleMouseLeave}},[a.map((function(c,u){var d=i.getSpan(e,c,t,u),h=d.rowspan,f=d.colspan;if(!h||!f)return null;var p=Sr({},c);p.realWidth=i.getColspanRealWidth(a,f,u);var m={store:i.store,_self:i.context||i.table.$vnode.context,column:p,row:e,$index:t};return u===s&&n&&(m.treeNode={indent:n.level*o,level:n.level},"boolean"===typeof n.expanded&&(m.treeNode.expanded=n.expanded,"loading"in n&&(m.treeNode.loading=n.loading),"noLazyChildren"in n&&(m.treeNode.noLazyChildren=n.noLazyChildren))),r("td",{style:i.getCellStyle(t,u,e,c),class:i.getCellClass(t,u,e,c),attrs:{rowspan:h,colspan:f},on:{mouseenter:function(t){return i.handleCellMouseEnter(t,e)},mouseleave:i.handleCellMouseLeave}},[c.renderCell.call(i._renderProxy,i.$createElement,m,l[u])])}))])},wrappedRowRender:function(e,t){var n=this,i=this.$createElement,r=this.store,o=r.isRowExpanded,a=r.assertRowKey,s=r.states,l=s.treeData,c=s.lazyTreeNodeMap,u=s.childrenColumnName,d=s.rowKey;if(this.hasExpandColumn&&o(e)){var h=this.table.renderExpanded,f=this.rowRender(e,t);return h?[[f,i("tr",{key:"expanded-row__"+f.key},[i("td",{attrs:{colspan:this.columnsCount},class:"el-table__expanded-cell"},[h(this.$createElement,{row:e,$index:t,store:this.store})])])]]:(console.error("[Element Error]renderExpanded is required."),f)}if(Object.keys(l).length){a();var p=Ji(e,d),m=l[p],v=null;m&&(v={expanded:m.expanded,level:m.level,display:!0},"boolean"===typeof m.lazy&&("boolean"===typeof m.loaded&&m.loaded&&(v.noLazyChildren=!(m.children&&m.children.length)),v.loading=m.loading));var g=[this.rowRender(e,t,v)];if(m){var b=0,y=function e(i,r){i&&i.length&&r&&i.forEach((function(i){var o={display:r.display&&r.expanded,level:r.level+1},a=Ji(i,d);if(void 0===a||null===a)throw new Error("for nested data item, row-key is required.");if(m=Sr({},l[a]),m&&(o.expanded=m.expanded,m.level=m.level||o.level,m.display=!(!m.expanded||!o.display),"boolean"===typeof m.lazy&&("boolean"===typeof m.loaded&&m.loaded&&(o.noLazyChildren=!(m.children&&m.children.length)),o.loading=m.loading)),b++,g.push(n.rowRender(i,t+b,o)),m){var s=c[a]||i[u];e(s,m)}}))};m.display=!0;var _=c[p]||e[u];y(_,m)}return g}return this.rowRender(e,t)}}},$r=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"}},[e.multiple?n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleOutsideClick,expression:"handleOutsideClick"},{name:"show",rawName:"v-show",value:e.showPopper,expression:"showPopper"}],staticClass:"el-table-filter"},[n("div",{staticClass:"el-table-filter__content"},[n("el-scrollbar",{attrs:{"wrap-class":"el-table-filter__wrap"}},[n("el-checkbox-group",{staticClass:"el-table-filter__checkbox-group",model:{value:e.filteredValue,callback:function(t){e.filteredValue=t},expression:"filteredValue"}},e._l(e.filters,(function(t){return n("el-checkbox",{key:t.value,attrs:{label:t.value}},[e._v(e._s(t.text))])})),1)],1)],1),n("div",{staticClass:"el-table-filter__bottom"},[n("button",{class:{"is-disabled":0===e.filteredValue.length},attrs:{disabled:0===e.filteredValue.length},on:{click:e.handleConfirm}},[e._v(e._s(e.t("el.table.confirmFilter")))]),n("button",{on:{click:e.handleReset}},[e._v(e._s(e.t("el.table.resetFilter")))])])]):n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleOutsideClick,expression:"handleOutsideClick"},{name:"show",rawName:"v-show",value:e.showPopper,expression:"showPopper"}],staticClass:"el-table-filter"},[n("ul",{staticClass:"el-table-filter__list"},[n("li",{staticClass:"el-table-filter__list-item",class:{"is-active":void 0===e.filterValue||null===e.filterValue},on:{click:function(t){e.handleSelect(null)}}},[e._v(e._s(e.t("el.table.clearFilter")))]),e._l(e.filters,(function(t){return n("li",{key:t.value,staticClass:"el-table-filter__list-item",class:{"is-active":e.isActive(t)},attrs:{label:t.value},on:{click:function(n){e.handleSelect(t.value)}}},[e._v(e._s(t.text))])}))],2)])])},Dr=[];$r._withStripped=!0;var Er=[];!Wi.a.prototype.$isServer&&document.addEventListener("click",(function(e){Er.forEach((function(t){var n=e.target;t&&t.$el&&(n===t.$el||t.$el.contains(n)||t.handleOutsideClick&&t.handleOutsideClick(e))}))}));var Tr={open:function(e){e&&Er.push(e)},close:function(e){var t=Er.indexOf(e);-1!==t&&Er.splice(e,1)}},Pr=n(30),Mr=n.n(Pr),Ir={name:"ElTableFilterPanel",mixins:[H.a,g.a],directives:{Clickoutside:V.a},components:{ElCheckbox:Ai.a,ElCheckboxGroup:Mr.a,ElScrollbar:q.a},props:{placement:{type:String,default:"bottom-end"}},methods:{isActive:function(e){return e.value===this.filterValue},handleOutsideClick:function(){var e=this;setTimeout((function(){e.showPopper=!1}),16)},handleConfirm:function(){this.confirmFilter(this.filteredValue),this.handleOutsideClick()},handleReset:function(){this.filteredValue=[],this.confirmFilter(this.filteredValue),this.handleOutsideClick()},handleSelect:function(e){this.filterValue=e,"undefined"!==typeof e&&null!==e?this.confirmFilter(this.filteredValue):this.confirmFilter([]),this.handleOutsideClick()},confirmFilter:function(e){this.table.store.commit("filterChange",{column:this.column,values:e}),this.table.store.updateAllSelected()}},data:function(){return{table:null,cell:null,column:null}},computed:{filters:function(){return this.column&&this.column.filters},filterValue:{get:function(){return(this.column.filteredValue||[])[0]},set:function(e){this.filteredValue&&("undefined"!==typeof e&&null!==e?this.filteredValue.splice(0,1,e):this.filteredValue.splice(0,1))}},filteredValue:{get:function(){return this.column&&this.column.filteredValue||[]},set:function(e){this.column&&(this.column.filteredValue=e)}},multiple:function(){return!this.column||this.column.filterMultiple}},mounted:function(){var e=this;this.popperElm=this.$el,this.referenceElm=this.cell,this.table.bodyWrapper.addEventListener("scroll",(function(){e.updatePopper()})),this.$watch("showPopper",(function(t){e.column&&(e.column.filterOpened=t),t?Tr.open(e):Tr.close(e)}))},watch:{showPopper:function(e){!0===e&&parseInt(this.popperJS._popper.style.zIndex,10)1;return r&&(this.$parent.isGroup=!0),e("table",{class:"el-table__header",attrs:{cellspacing:"0",cellpadding:"0",border:"0"}},[e("colgroup",[this.columns.map((function(t){return e("col",{attrs:{name:t.id},key:t.id})})),this.hasGutter?e("col",{attrs:{name:"gutter"}}):""]),e("thead",{class:[{"is-group":r,"has-gutter":this.hasGutter}]},[this._l(i,(function(n,i){return e("tr",{style:t.getHeaderRowStyle(i),class:t.getHeaderRowClass(i)},[n.map((function(r,o){return e("th",{attrs:{colspan:r.colSpan,rowspan:r.rowSpan},on:{mousemove:function(e){return t.handleMouseMove(e,r)},mouseout:t.handleMouseOut,mousedown:function(e){return t.handleMouseDown(e,r)},click:function(e){return t.handleHeaderClick(e,r)},contextmenu:function(e){return t.handleHeaderContextMenu(e,r)}},style:t.getHeaderCellStyle(i,o,n,r),class:t.getHeaderCellClass(i,o,n,r),key:r.id},[e("div",{class:["cell",r.filteredValue&&r.filteredValue.length>0?"highlight":"",r.labelClassName]},[r.renderHeader?r.renderHeader.call(t._renderProxy,e,{column:r,$index:o,store:t.store,_self:t.$parent.$vnode.context}):r.label,r.sortable?e("span",{class:"caret-wrapper",on:{click:function(e){return t.handleSortClick(e,r)}}},[e("i",{class:"sort-caret ascending",on:{click:function(e){return t.handleSortClick(e,r,"ascending")}}}),e("i",{class:"sort-caret descending",on:{click:function(e){return t.handleSortClick(e,r,"descending")}}})]):"",r.filterable?e("span",{class:"el-table__column-filter-trigger",on:{click:function(e){return t.handleFilterClick(e,r)}}},[e("i",{class:["el-icon-arrow-down",r.filterOpened?"el-icon-arrow-up":""]})]):""])])})),t.hasGutter?e("th",{class:"gutter"}):""])}))])])},props:{fixed:String,store:{required:!0},border:Boolean,defaultSort:{type:Object,default:function(){return{prop:"",order:""}}}},components:{ElCheckbox:Ai.a},computed:Fr({table:function(){return this.$parent},hasGutter:function(){return!this.fixed&&this.tableLayout.gutterWidth}},gr({columns:"columns",isAllSelected:"isAllSelected",leftFixedLeafCount:"fixedLeafColumnsLength",rightFixedLeafCount:"rightFixedLeafColumnsLength",columnsCount:function(e){return e.columns.length},leftFixedCount:function(e){return e.fixedColumns.length},rightFixedCount:function(e){return e.rightFixedColumns.length}})),created:function(){this.filterPanels={}},mounted:function(){var e=this;this.$nextTick((function(){var t=e.defaultSort,n=t.prop,i=t.order,r=!0;e.store.commit("sort",{prop:n,order:i,init:r})}))},beforeDestroy:function(){var e=this.filterPanels;for(var t in e)e.hasOwnProperty(t)&&e[t]&&e[t].$destroy(!0)},methods:{isCellHidden:function(e,t){for(var n=0,i=0;i=this.leftFixedLeafCount:"right"===this.fixed?n=this.columnsCount-this.rightFixedLeafCount},getHeaderRowStyle:function(e){var t=this.table.headerRowStyle;return"function"===typeof t?t.call(null,{rowIndex:e}):t},getHeaderRowClass:function(e){var t=[],n=this.table.headerRowClassName;return"string"===typeof n?t.push(n):"function"===typeof n&&t.push(n.call(null,{rowIndex:e})),t.join(" ")},getHeaderCellStyle:function(e,t,n,i){var r=this.table.headerCellStyle;return"function"===typeof r?r.call(null,{rowIndex:e,columnIndex:t,row:n,column:i}):r},getHeaderCellClass:function(e,t,n,i){var r=[i.id,i.order,i.headerAlign,i.className,i.labelClassName];0===e&&this.isCellHidden(t,n)&&r.push("is-hidden"),i.children||r.push("is-leaf"),i.sortable&&r.push("is-sortable");var o=this.table.headerCellClassName;return"string"===typeof o?r.push(o):"function"===typeof o&&r.push(o.call(null,{rowIndex:e,columnIndex:t,row:n,column:i})),r.join(" ")},toggleAllSelection:function(e){e.stopPropagation(),this.store.commit("toggleAllSelection")},handleFilterClick:function(e,t){e.stopPropagation();var n=e.target,i="TH"===n.tagName?n:n.parentNode;if(!Object(Le["hasClass"])(i,"noclick")){i=i.querySelector(".el-table__column-filter-trigger")||i;var r=this.$parent,o=this.filterPanels[t.id];o&&t.filterOpened?o.showPopper=!1:(o||(o=new Wi.a(Ar),this.filterPanels[t.id]=o,t.filterPlacement&&(o.placement=t.filterPlacement),o.table=r,o.cell=i,o.column=t,!this.$isServer&&o.$mount(document.createElement("div"))),setTimeout((function(){o.showPopper=!0}),16))}},handleHeaderClick:function(e,t){!t.filters&&t.sortable?this.handleSortClick(e,t):t.filterable&&!t.sortable&&this.handleFilterClick(e,t),this.$parent.$emit("header-click",t,e)},handleHeaderContextMenu:function(e,t){this.$parent.$emit("header-contextmenu",t,e)},handleMouseDown:function(e,t){var n=this;if(!this.$isServer&&!(t.children&&t.children.length>0)&&this.draggingColumn&&this.border){this.dragging=!0,this.$parent.resizeProxyVisible=!0;var i=this.$parent,r=i.$el,o=r.getBoundingClientRect().left,a=this.$el.querySelector("th."+t.id),s=a.getBoundingClientRect(),l=s.left-o+30;Object(Le["addClass"])(a,"noclick"),this.dragState={startMouseLeft:e.clientX,startLeft:s.right-o,startColumnLeft:s.left-o,tableLeft:o};var c=i.$refs.resizeProxy;c.style.left=this.dragState.startLeft+"px",document.onselectstart=function(){return!1},document.ondragstart=function(){return!1};var u=function(e){var t=e.clientX-n.dragState.startMouseLeft,i=n.dragState.startLeft+t;c.style.left=Math.max(l,i)+"px"},d=function r(){if(n.dragging){var o=n.dragState,s=o.startColumnLeft,l=o.startLeft,d=parseInt(c.style.left,10),h=d-s;t.width=t.realWidth=h,i.$emit("header-dragend",t.width,l-s,t,e),n.store.scheduleLayout(),document.body.style.cursor="",n.dragging=!1,n.draggingColumn=null,n.dragState={},i.resizeProxyVisible=!1}document.removeEventListener("mousemove",u),document.removeEventListener("mouseup",r),document.onselectstart=null,document.ondragstart=null,setTimeout((function(){Object(Le["removeClass"])(a,"noclick")}),0)};document.addEventListener("mousemove",u),document.addEventListener("mouseup",d)}},handleMouseMove:function(e,t){if(!(t.children&&t.children.length>0)){var n=e.target;while(n&&"TH"!==n.tagName)n=n.parentNode;if(t&&t.resizable&&!this.dragging&&this.border){var i=n.getBoundingClientRect(),r=document.body.style;i.width>12&&i.right-e.pageX<8?(r.cursor="col-resize",Object(Le["hasClass"])(n,"is-sortable")&&(n.style.cursor="col-resize"),this.draggingColumn=t):this.dragging||(r.cursor="",Object(Le["hasClass"])(n,"is-sortable")&&(n.style.cursor="pointer"),this.draggingColumn=null)}}},handleMouseOut:function(){this.$isServer||(document.body.style.cursor="")},toggleOrder:function(e){var t=e.order,n=e.sortOrders;if(""===t)return n[0];var i=n.indexOf(t||null);return n[i>n.length-2?0:i+1]},handleSortClick:function(e,t,n){e.stopPropagation();var i=t.order===n?null:n||this.toggleOrder(t),r=e.target;while(r&&"TH"!==r.tagName)r=r.parentNode;if(r&&"TH"===r.tagName&&Object(Le["hasClass"])(r,"noclick"))Object(Le["removeClass"])(r,"noclick");else if(t.sortable){var o=this.store.states,a=o.sortProp,s=void 0,l=o.sortingColumn;(l!==t||l===t&&null===l.order)&&(l&&(l.order=null),o.sortingColumn=t,a=t.property),s=t.order=i||null,o.sortProp=a,o.sortOrder=s,this.store.commit("changeSortCondition")}}},data:function(){return{draggingColumn:null,dragging:!1,dragState:{}}}},Br=Object.assign||function(e){for(var t=1;t=this.leftFixedLeafCount;if("right"===this.fixed){for(var i=0,r=0;r=this.columnsCount-this.rightFixedCount)},getRowClasses:function(e,t){var n=[e.id,e.align,e.labelClassName];return e.className&&n.push(e.className),this.isCellHidden(t,this.columns,e)&&n.push("is-hidden"),e.children||n.push("is-leaf"),n}}},Hr=Object.assign||function(e){for(var t=1;t0){var i=n.scrollTop;t.pixelY<0&&0!==i&&e.preventDefault(),t.pixelY>0&&n.scrollHeight-n.clientHeight>i&&e.preventDefault(),n.scrollTop+=Math.ceil(t.pixelY/5)}else n.scrollLeft+=Math.ceil(t.pixelX/5)},handleHeaderFooterMousewheel:function(e,t){var n=t.pixelX,i=t.pixelY;Math.abs(n)>=Math.abs(i)&&(this.bodyWrapper.scrollLeft+=t.pixelX/5)},syncPostion:Object(Fi["throttle"])(20,(function(){var e=this.bodyWrapper,t=e.scrollLeft,n=e.scrollTop,i=e.offsetWidth,r=e.scrollWidth,o=this.$refs,a=o.headerWrapper,s=o.footerWrapper,l=o.fixedBodyWrapper,c=o.rightFixedBodyWrapper;a&&(a.scrollLeft=t),s&&(s.scrollLeft=t),l&&(l.scrollTop=n),c&&(c.scrollTop=n);var u=r-i-1;this.scrollPosition=t>=u?"right":0===t?"left":"middle"})),bindEvents:function(){this.bodyWrapper.addEventListener("scroll",this.syncPostion,{passive:!0}),this.fit&&Object(ei["addResizeListener"])(this.$el,this.resizeListener)},unbindEvents:function(){this.bodyWrapper.removeEventListener("scroll",this.syncPostion,{passive:!0}),this.fit&&Object(ei["removeResizeListener"])(this.$el,this.resizeListener)},resizeListener:function(){if(this.$ready){var e=!1,t=this.$el,n=this.resizeState,i=n.width,r=n.height,o=t.offsetWidth;i!==o&&(e=!0);var a=t.offsetHeight;(this.height||this.shouldUpdateHeight)&&r!==a&&(e=!0),e&&(this.resizeState.width=o,this.resizeState.height=a,this.doLayout())}},doLayout:function(){this.shouldUpdateHeight&&this.layout.updateElsHeight(),this.layout.updateColumnsWidth()},sort:function(e,t){this.store.commit("sort",{prop:e,order:t})},toggleAllSelection:function(){this.store.commit("toggleAllSelection")}},computed:Hr({tableSize:function(){return this.size||(this.$ELEMENT||{}).size},bodyWrapper:function(){return this.$refs.bodyWrapper},shouldUpdateHeight:function(){return this.height||this.maxHeight||this.fixedColumns.length>0||this.rightFixedColumns.length>0},bodyWidth:function(){var e=this.layout,t=e.bodyWidth,n=e.scrollY,i=e.gutterWidth;return t?t-(n?i:0)+"px":""},bodyHeight:function(){var e=this.layout,t=e.headerHeight,n=void 0===t?0:t,i=e.bodyHeight,r=e.footerHeight,o=void 0===r?0:r;if(this.height)return{height:i?i+"px":""};if(this.maxHeight){var a=rr(this.maxHeight);if("number"===typeof a)return{"max-height":a-o-(this.showHeader?n:0)+"px"}}return{}},fixedBodyHeight:function(){if(this.height)return{height:this.layout.fixedBodyHeight?this.layout.fixedBodyHeight+"px":""};if(this.maxHeight){var e=rr(this.maxHeight);if("number"===typeof e)return e=this.layout.scrollX?e-this.layout.gutterWidth:e,this.showHeader&&(e-=this.layout.headerHeight),e-=this.layout.footerHeight,{"max-height":e+"px"}}return{}},fixedHeight:function(){return this.maxHeight?this.showSummary?{bottom:0}:{bottom:this.layout.scrollX&&this.data.length?this.layout.gutterWidth+"px":""}:this.showSummary?{height:this.layout.tableHeight?this.layout.tableHeight+"px":""}:{height:this.layout.viewportHeight?this.layout.viewportHeight+"px":""}},emptyBlockStyle:function(){if(this.data&&this.data.length)return null;var e="100%";return this.layout.appendHeight&&(e="calc(100% - "+this.layout.appendHeight+"px)"),{width:this.bodyWidth,height:e}}},gr({selection:"selection",columns:"columns",tableData:"data",fixedColumns:"fixedColumns",rightFixedColumns:"rightFixedColumns"})),watch:{height:{immediate:!0,handler:function(e){this.layout.setHeight(e)}},maxHeight:{immediate:!0,handler:function(e){this.layout.setMaxHeight(e)}},currentRowKey:{immediate:!0,handler:function(e){this.rowKey&&this.store.setCurrentRowKey(e)}},data:{immediate:!0,handler:function(e){this.store.commit("setData",e)}},expandRowKeys:{immediate:!0,handler:function(e){e&&this.store.setExpandRowKeysAdapter(e)}}},created:function(){var e=this;this.tableId="el-table_"+Wr++,this.debouncedUpdateLayout=Object(Fi["debounce"])(50,(function(){return e.doLayout()}))},mounted:function(){var e=this;this.bindEvents(),this.store.updateColumns(),this.doLayout(),this.resizeState={width:this.$el.offsetWidth,height:this.$el.offsetHeight},this.store.states.columns.forEach((function(t){t.filteredValue&&t.filteredValue.length&&e.store.commit("filterChange",{column:t,values:t.filteredValue,silent:!0})})),this.$ready=!0},destroyed:function(){this.unbindEvents()},data:function(){var e=this.treeProps,t=e.hasChildren,n=void 0===t?"hasChildren":t,i=e.children,r=void 0===i?"children":i;this.store=vr(this,{rowKey:this.rowKey,defaultExpandAll:this.defaultExpandAll,selectOnIndeterminate:this.selectOnIndeterminate,indent:this.indent,lazy:this.lazy,lazyColumnIdentifier:n,childrenColumnName:r});var o=new wr({store:this.store,table:this,fit:this.fit,showHeader:this.showHeader});return{layout:o,isHidden:!1,renderExpanded:null,resizeProxyVisible:!1,resizeState:{width:null,height:null},isGroup:!1,scrollPosition:"left"}}},Ur=qr,Yr=s(Ur,Ii,Ni,!1,null,null,null);Yr.options.__file="packages/table/src/table.vue";var Kr=Yr.exports;Kr.install=function(e){e.component(Kr.name,Kr)};var Gr=Kr,Xr={default:{order:""},selection:{width:48,minWidth:48,realWidth:48,order:"",className:"el-table-column--selection"},expand:{width:48,minWidth:48,realWidth:48,order:""},index:{width:48,minWidth:48,realWidth:48,order:""}},Zr={selection:{renderHeader:function(e,t){var n=t.store;return e("el-checkbox",{attrs:{disabled:n.states.data&&0===n.states.data.length,indeterminate:n.states.selection.length>0&&!this.isAllSelected,value:this.isAllSelected},nativeOn:{click:this.toggleAllSelection}})},renderCell:function(e,t){var n=t.row,i=t.column,r=t.store,o=t.$index;return e("el-checkbox",{nativeOn:{click:function(e){return e.stopPropagation()}},attrs:{value:r.isSelected(n),disabled:!!i.selectable&&!i.selectable.call(null,n,o)},on:{input:function(){r.commit("rowSelectedChanged",n)}}})},sortable:!1,resizable:!1},index:{renderHeader:function(e,t){var n=t.column;return n.label||"#"},renderCell:function(e,t){var n=t.$index,i=t.column,r=n+1,o=i.index;return"number"===typeof o?r=n+o:"function"===typeof o&&(r=o(n)),e("div",[r])},sortable:!1},expand:{renderHeader:function(e,t){var n=t.column;return n.label||""},renderCell:function(e,t){var n=t.row,i=t.store,r=["el-table__expand-icon"];i.states.expandRows.indexOf(n)>-1&&r.push("el-table__expand-icon--expanded");var o=function(e){e.stopPropagation(),i.toggleRowExpansion(n)};return e("div",{class:r,on:{click:o}},[e("i",{class:"el-icon el-icon-arrow-right"})])},sortable:!1,resizable:!1,className:"el-table__expand-column"}};function Jr(e,t){var n=t.row,i=t.column,r=t.$index,o=i.property,a=o&&Object(b["getPropByPath"])(n,o).v;return i&&i.formatter?i.formatter(n,i,a,r):a}function Qr(e,t){var n=t.row,i=t.treeNode,r=t.store;if(!i)return null;var o=[],a=function(e){e.stopPropagation(),r.loadOrToggle(n)};if(i.indent&&o.push(e("span",{class:"el-table__indent",style:{"padding-left":i.indent+"px"}})),"boolean"!==typeof i.expanded||i.noLazyChildren)o.push(e("span",{class:"el-table__placeholder"}));else{var s=["el-table__expand-icon",i.expanded?"el-table__expand-icon--expanded":""],l=["el-icon-arrow-right"];i.loading&&(l=["el-icon-loading"]),o.push(e("div",{class:s,on:{click:a}},[e("i",{class:l})]))}return o}var eo=Object.assign||function(e){for(var t=1;t-1}))}}},data:function(){return{isSubColumn:!1,columns:[]}},computed:{owner:function(){var e=this.$parent;while(e&&!e.tableId)e=e.$parent;return e},columnOrTableParent:function(){var e=this.$parent;while(e&&!e.tableId&&!e.columnId)e=e.$parent;return e},realWidth:function(){return nr(this.width)},realMinWidth:function(){return ir(this.minWidth)},realAlign:function(){return this.align?"is-"+this.align:null},realHeaderAlign:function(){return this.headerAlign?"is-"+this.headerAlign:this.realAlign}},methods:{getPropsData:function(){for(var e=this,t=arguments.length,n=Array(t),i=0;i3&&void 0!==arguments[3]?arguments[3]:"-";if(!e)return null;var r=(mo[n]||mo["default"]).parser,o=t||lo[n];return r(e,o,i)},bo=function(e,t,n){if(!e)return null;var i=(mo[n]||mo["default"]).formatter,r=t||lo[n];return i(e,r)},yo=function(e,t){var n=function(e,t){var n=e instanceof Date,i=t instanceof Date;return n&&i?e.getTime()===t.getTime():!n&&!i&&e===t},i=e instanceof Array,r=t instanceof Array;return i&&r?e.length===t.length&&e.every((function(e,i){return n(e,t[i])})):!i&&!r&&n(e,t)},_o=function(e){return"string"===typeof e||e instanceof String},xo=function(e){return null===e||void 0===e||_o(e)||Array.isArray(e)&&2===e.length&&e.every(_o)},wo={mixins:[D.a,so],inject:{elForm:{default:""},elFormItem:{default:""}},props:{size:String,format:String,valueFormat:String,readonly:Boolean,placeholder:String,startPlaceholder:String,endPlaceholder:String,prefixIcon:String,clearIcon:{type:String,default:"el-icon-circle-close"},name:{default:"",validator:xo},disabled:Boolean,clearable:{type:Boolean,default:!0},id:{default:"",validator:xo},popperClass:String,editable:{type:Boolean,default:!0},align:{type:String,default:"left"},value:{},defaultValue:{},defaultTime:{},rangeSeparator:{default:"-"},pickerOptions:{},unlinkPanels:Boolean,validateEvent:{type:Boolean,default:!0}},components:{ElInput:m.a},directives:{Clickoutside:V.a},data:function(){return{pickerVisible:!1,showClose:!1,userInput:null,valueOnOpen:null,unwatchPickerOptions:null}},watch:{pickerVisible:function(e){this.readonly||this.pickerDisabled||(e?(this.showPicker(),this.valueOnOpen=Array.isArray(this.value)?[].concat(this.value):this.value):(this.hidePicker(),this.emitChange(this.value),this.userInput=null,this.validateEvent&&this.dispatch("ElFormItem","el.form.blur"),this.$emit("blur",this),this.blur()))},parsedValue:{immediate:!0,handler:function(e){this.picker&&(this.picker.value=e)}},defaultValue:function(e){this.picker&&(this.picker.defaultValue=e)},value:function(e,t){yo(e,t)||this.pickerVisible||!this.validateEvent||this.dispatch("ElFormItem","el.form.change",e)}},computed:{ranged:function(){return this.type.indexOf("range")>-1},reference:function(){var e=this.$refs.reference;return e.$el||e},refInput:function(){return this.reference?[].slice.call(this.reference.querySelectorAll("input")):[]},valueIsEmpty:function(){var e=this.value;if(Array.isArray(e)){for(var t=0,n=e.length;t0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];e.userInput=null,e.pickerVisible=e.picker.visible=n,e.emitInput(t),e.picker.resetView&&e.picker.resetView()})),this.picker.$on("select-range",(function(t,n,i){0!==e.refInput.length&&(i&&"min"!==i?"max"===i&&(e.refInput[1].setSelectionRange(t,n),e.refInput[1].focus()):(e.refInput[0].setSelectionRange(t,n),e.refInput[0].focus()))}))},unmountPicker:function(){this.picker&&(this.picker.$destroy(),this.picker.$off(),"function"===typeof this.unwatchPickerOptions&&this.unwatchPickerOptions(),this.picker.$el.parentNode.removeChild(this.picker.$el))},emitChange:function(e){yo(e,this.valueOnOpen)||(this.$emit("change",e),this.valueOnOpen=e,this.validateEvent&&this.dispatch("ElFormItem","el.form.change",e))},emitInput:function(e){var t=this.formatToValue(e);yo(this.value,t)||this.$emit("input",t)},isValidValue:function(e){return this.picker||this.mountPicker(),!this.picker.isValidValue||e&&this.picker.isValidValue(e)}}},Co=wo,ko=s(Co,ro,oo,!1,null,null,null);ko.options.__file="packages/date-picker/src/picker.vue";var So=ko.exports,Oo=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-enter":e.handleEnter,"after-leave":e.handleLeave}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-picker-panel el-date-picker el-popper",class:[{"has-sidebar":e.$slots.sidebar||e.shortcuts,"has-time":e.showTime},e.popperClass]},[n("div",{staticClass:"el-picker-panel__body-wrapper"},[e._t("sidebar"),e.shortcuts?n("div",{staticClass:"el-picker-panel__sidebar"},e._l(e.shortcuts,(function(t,i){return n("button",{key:i,staticClass:"el-picker-panel__shortcut",attrs:{type:"button"},on:{click:function(n){e.handleShortcutClick(t)}}},[e._v(e._s(t.text))])})),0):e._e(),n("div",{staticClass:"el-picker-panel__body"},[e.showTime?n("div",{staticClass:"el-date-picker__time-header"},[n("span",{staticClass:"el-date-picker__editor-wrap"},[n("el-input",{attrs:{placeholder:e.t("el.datepicker.selectDate"),value:e.visibleDate,size:"small"},on:{input:function(t){return e.userInputDate=t},change:e.handleVisibleDateChange}})],1),n("span",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleTimePickClose,expression:"handleTimePickClose"}],staticClass:"el-date-picker__editor-wrap"},[n("el-input",{ref:"input",attrs:{placeholder:e.t("el.datepicker.selectTime"),value:e.visibleTime,size:"small"},on:{focus:function(t){e.timePickerVisible=!0},input:function(t){return e.userInputTime=t},change:e.handleVisibleTimeChange}}),n("time-picker",{ref:"timepicker",attrs:{"time-arrow-control":e.arrowControl,visible:e.timePickerVisible},on:{pick:e.handleTimePick,mounted:e.proxyTimePickerDataProperties}})],1)]):e._e(),n("div",{directives:[{name:"show",rawName:"v-show",value:"time"!==e.currentView,expression:"currentView !== 'time'"}],staticClass:"el-date-picker__header",class:{"el-date-picker__header--bordered":"year"===e.currentView||"month"===e.currentView}},[n("button",{staticClass:"el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-d-arrow-left",attrs:{type:"button","aria-label":e.t("el.datepicker.prevYear")},on:{click:e.prevYear}}),n("button",{directives:[{name:"show",rawName:"v-show",value:"date"===e.currentView,expression:"currentView === 'date'"}],staticClass:"el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-arrow-left",attrs:{type:"button","aria-label":e.t("el.datepicker.prevMonth")},on:{click:e.prevMonth}}),n("span",{staticClass:"el-date-picker__header-label",attrs:{role:"button"},on:{click:e.showYearPicker}},[e._v(e._s(e.yearLabel))]),n("span",{directives:[{name:"show",rawName:"v-show",value:"date"===e.currentView,expression:"currentView === 'date'"}],staticClass:"el-date-picker__header-label",class:{active:"month"===e.currentView},attrs:{role:"button"},on:{click:e.showMonthPicker}},[e._v(e._s(e.t("el.datepicker.month"+(e.month+1))))]),n("button",{staticClass:"el-picker-panel__icon-btn el-date-picker__next-btn el-icon-d-arrow-right",attrs:{type:"button","aria-label":e.t("el.datepicker.nextYear")},on:{click:e.nextYear}}),n("button",{directives:[{name:"show",rawName:"v-show",value:"date"===e.currentView,expression:"currentView === 'date'"}],staticClass:"el-picker-panel__icon-btn el-date-picker__next-btn el-icon-arrow-right",attrs:{type:"button","aria-label":e.t("el.datepicker.nextMonth")},on:{click:e.nextMonth}})]),n("div",{staticClass:"el-picker-panel__content"},[n("date-table",{directives:[{name:"show",rawName:"v-show",value:"date"===e.currentView,expression:"currentView === 'date'"}],attrs:{"selection-mode":e.selectionMode,"first-day-of-week":e.firstDayOfWeek,value:e.value,"default-value":e.defaultValue?new Date(e.defaultValue):null,date:e.date,"cell-class-name":e.cellClassName,"disabled-date":e.disabledDate},on:{pick:e.handleDatePick}}),n("year-table",{directives:[{name:"show",rawName:"v-show",value:"year"===e.currentView,expression:"currentView === 'year'"}],attrs:{value:e.value,"default-value":e.defaultValue?new Date(e.defaultValue):null,date:e.date,"disabled-date":e.disabledDate},on:{pick:e.handleYearPick}}),n("month-table",{directives:[{name:"show",rawName:"v-show",value:"month"===e.currentView,expression:"currentView === 'month'"}],attrs:{value:e.value,"default-value":e.defaultValue?new Date(e.defaultValue):null,date:e.date,"disabled-date":e.disabledDate},on:{pick:e.handleMonthPick}})],1)])],2),n("div",{directives:[{name:"show",rawName:"v-show",value:e.footerVisible&&"date"===e.currentView,expression:"footerVisible && currentView === 'date'"}],staticClass:"el-picker-panel__footer"},[n("el-button",{directives:[{name:"show",rawName:"v-show",value:"dates"!==e.selectionMode,expression:"selectionMode !== 'dates'"}],staticClass:"el-picker-panel__link-btn",attrs:{size:"mini",type:"text"},on:{click:e.changeToNow}},[e._v("\n "+e._s(e.t("el.datepicker.now"))+"\n ")]),n("el-button",{staticClass:"el-picker-panel__link-btn",attrs:{plain:"",size:"mini"},on:{click:e.confirm}},[e._v("\n "+e._s(e.t("el.datepicker.confirm"))+"\n ")])],1)])])},$o=[];Oo._withStripped=!0;var Do=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":function(t){e.$emit("dodestroy")}}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-time-panel el-popper",class:e.popperClass},[n("div",{staticClass:"el-time-panel__content",class:{"has-seconds":e.showSeconds}},[n("time-spinner",{ref:"spinner",attrs:{"arrow-control":e.useArrow,"show-seconds":e.showSeconds,"am-pm-mode":e.amPmMode,date:e.date},on:{change:e.handleChange,"select-range":e.setSelectionRange}})],1),n("div",{staticClass:"el-time-panel__footer"},[n("button",{staticClass:"el-time-panel__btn cancel",attrs:{type:"button"},on:{click:e.handleCancel}},[e._v(e._s(e.t("el.datepicker.cancel")))]),n("button",{staticClass:"el-time-panel__btn",class:{confirm:!e.disabled},attrs:{type:"button"},on:{click:function(t){e.handleConfirm()}}},[e._v(e._s(e.t("el.datepicker.confirm")))])])])])},Eo=[];Do._withStripped=!0;var To=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-time-spinner",class:{"has-seconds":e.showSeconds}},[e.arrowControl?e._e():[n("el-scrollbar",{ref:"hours",staticClass:"el-time-spinner__wrapper",attrs:{"wrap-style":"max-height: inherit;","view-class":"el-time-spinner__list",noresize:"",tag:"ul"},nativeOn:{mouseenter:function(t){e.emitSelectRange("hours")},mousemove:function(t){e.adjustCurrentSpinner("hours")}}},e._l(e.hoursList,(function(t,i){return n("li",{key:i,staticClass:"el-time-spinner__item",class:{active:i===e.hours,disabled:t},on:{click:function(n){e.handleClick("hours",{value:i,disabled:t})}}},[e._v(e._s(("0"+(e.amPmMode?i%12||12:i)).slice(-2))+e._s(e.amPm(i)))])})),0),n("el-scrollbar",{ref:"minutes",staticClass:"el-time-spinner__wrapper",attrs:{"wrap-style":"max-height: inherit;","view-class":"el-time-spinner__list",noresize:"",tag:"ul"},nativeOn:{mouseenter:function(t){e.emitSelectRange("minutes")},mousemove:function(t){e.adjustCurrentSpinner("minutes")}}},e._l(e.minutesList,(function(t,i){return n("li",{key:i,staticClass:"el-time-spinner__item",class:{active:i===e.minutes,disabled:!t},on:{click:function(t){e.handleClick("minutes",{value:i,disabled:!1})}}},[e._v(e._s(("0"+i).slice(-2)))])})),0),n("el-scrollbar",{directives:[{name:"show",rawName:"v-show",value:e.showSeconds,expression:"showSeconds"}],ref:"seconds",staticClass:"el-time-spinner__wrapper",attrs:{"wrap-style":"max-height: inherit;","view-class":"el-time-spinner__list",noresize:"",tag:"ul"},nativeOn:{mouseenter:function(t){e.emitSelectRange("seconds")},mousemove:function(t){e.adjustCurrentSpinner("seconds")}}},e._l(60,(function(t,i){return n("li",{key:i,staticClass:"el-time-spinner__item",class:{active:i===e.seconds},on:{click:function(t){e.handleClick("seconds",{value:i,disabled:!1})}}},[e._v(e._s(("0"+i).slice(-2)))])})),0)],e.arrowControl?[n("div",{staticClass:"el-time-spinner__wrapper is-arrow",on:{mouseenter:function(t){e.emitSelectRange("hours")}}},[n("i",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.decrease,expression:"decrease"}],staticClass:"el-time-spinner__arrow el-icon-arrow-up"}),n("i",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.increase,expression:"increase"}],staticClass:"el-time-spinner__arrow el-icon-arrow-down"}),n("ul",{ref:"hours",staticClass:"el-time-spinner__list"},e._l(e.arrowHourList,(function(t,i){return n("li",{key:i,staticClass:"el-time-spinner__item",class:{active:t===e.hours,disabled:e.hoursList[t]}},[e._v(e._s(void 0===t?"":("0"+(e.amPmMode?t%12||12:t)).slice(-2)+e.amPm(t)))])})),0)]),n("div",{staticClass:"el-time-spinner__wrapper is-arrow",on:{mouseenter:function(t){e.emitSelectRange("minutes")}}},[n("i",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.decrease,expression:"decrease"}],staticClass:"el-time-spinner__arrow el-icon-arrow-up"}),n("i",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.increase,expression:"increase"}],staticClass:"el-time-spinner__arrow el-icon-arrow-down"}),n("ul",{ref:"minutes",staticClass:"el-time-spinner__list"},e._l(e.arrowMinuteList,(function(t,i){return n("li",{key:i,staticClass:"el-time-spinner__item",class:{active:t===e.minutes}},[e._v("\n "+e._s(void 0===t?"":("0"+t).slice(-2))+"\n ")])})),0)]),e.showSeconds?n("div",{staticClass:"el-time-spinner__wrapper is-arrow",on:{mouseenter:function(t){e.emitSelectRange("seconds")}}},[n("i",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.decrease,expression:"decrease"}],staticClass:"el-time-spinner__arrow el-icon-arrow-up"}),n("i",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.increase,expression:"increase"}],staticClass:"el-time-spinner__arrow el-icon-arrow-down"}),n("ul",{ref:"seconds",staticClass:"el-time-spinner__list"},e._l(e.arrowSecondList,(function(t,i){return n("li",{key:i,staticClass:"el-time-spinner__item",class:{active:t===e.seconds}},[e._v("\n "+e._s(void 0===t?"":("0"+t).slice(-2))+"\n ")])})),0)]):e._e()]:e._e()],2)},Po=[];To._withStripped=!0;var Mo={components:{ElScrollbar:q.a},directives:{repeatClick:Nt},props:{date:{},defaultValue:{},showSeconds:{type:Boolean,default:!0},arrowControl:Boolean,amPmMode:{type:String,default:""}},computed:{hours:function(){return this.date.getHours()},minutes:function(){return this.date.getMinutes()},seconds:function(){return this.date.getSeconds()},hoursList:function(){return Object(ao["getRangeHours"])(this.selectableRange)},minutesList:function(){return Object(ao["getRangeMinutes"])(this.selectableRange,this.hours)},arrowHourList:function(){var e=this.hours;return[e>0?e-1:void 0,e,e<23?e+1:void 0]},arrowMinuteList:function(){var e=this.minutes;return[e>0?e-1:void 0,e,e<59?e+1:void 0]},arrowSecondList:function(){var e=this.seconds;return[e>0?e-1:void 0,e,e<59?e+1:void 0]}},data:function(){return{selectableRange:[],currentScrollbar:null}},mounted:function(){var e=this;this.$nextTick((function(){!e.arrowControl&&e.bindScrollEvent()}))},methods:{increase:function(){this.scrollDown(1)},decrease:function(){this.scrollDown(-1)},modifyDateField:function(e,t){switch(e){case"hours":this.$emit("change",Object(ao["modifyTime"])(this.date,t,this.minutes,this.seconds));break;case"minutes":this.$emit("change",Object(ao["modifyTime"])(this.date,this.hours,t,this.seconds));break;case"seconds":this.$emit("change",Object(ao["modifyTime"])(this.date,this.hours,this.minutes,t));break}},handleClick:function(e,t){var n=t.value,i=t.disabled;i||(this.modifyDateField(e,n),this.emitSelectRange(e),this.adjustSpinner(e,n))},emitSelectRange:function(e){"hours"===e?this.$emit("select-range",0,2):"minutes"===e?this.$emit("select-range",3,5):"seconds"===e&&this.$emit("select-range",6,8),this.currentScrollbar=e},bindScrollEvent:function(){var e=this,t=function(t){e.$refs[t].wrap.onscroll=function(n){e.handleScroll(t,n)}};t("hours"),t("minutes"),t("seconds")},handleScroll:function(e){var t=Math.min(Math.round((this.$refs[e].wrap.scrollTop-(.5*this.scrollBarHeight(e)-10)/this.typeItemHeight(e)+3)/this.typeItemHeight(e)),"hours"===e?23:59);this.modifyDateField(e,t)},adjustSpinners:function(){this.adjustSpinner("hours",this.hours),this.adjustSpinner("minutes",this.minutes),this.adjustSpinner("seconds",this.seconds)},adjustCurrentSpinner:function(e){this.adjustSpinner(e,this[e])},adjustSpinner:function(e,t){if(!this.arrowControl){var n=this.$refs[e].wrap;n&&(n.scrollTop=Math.max(0,t*this.typeItemHeight(e)))}},scrollDown:function(e){this.currentScrollbar||this.emitSelectRange("hours");var t=this.currentScrollbar,n=this.hoursList,i=this[t];if("hours"===this.currentScrollbar){var r=Math.abs(e);e=e>0?1:-1;var o=n.length;while(o--&&r)i=(i+e+n.length)%n.length,n[i]||r--;if(n[i])return}else i=(i+e+60)%60;this.modifyDateField(t,i),this.adjustSpinner(t,i)},amPm:function(e){var t="a"===this.amPmMode.toLowerCase();if(!t)return"";var n="A"===this.amPmMode,i=e<12?" am":" pm";return n&&(i=i.toUpperCase()),i},typeItemHeight:function(e){return this.$refs[e].$el.querySelector("li").offsetHeight},scrollBarHeight:function(e){return this.$refs[e].$el.offsetHeight}}},Io=Mo,No=s(Io,To,Po,!1,null,null,null);No.options.__file="packages/date-picker/src/basic/time-spinner.vue";var jo=No.exports,Ao={mixins:[g.a],components:{TimeSpinner:jo},props:{visible:Boolean,timeArrowControl:Boolean},watch:{visible:function(e){var t=this;e?(this.oldValue=this.value,this.$nextTick((function(){return t.$refs.spinner.emitSelectRange("hours")}))):this.needInitAdjust=!0},value:function(e){var t=this,n=void 0;e instanceof Date?n=Object(ao["limitTimeRange"])(e,this.selectableRange,this.format):e||(n=this.defaultValue?new Date(this.defaultValue):new Date),this.date=n,this.visible&&this.needInitAdjust&&(this.$nextTick((function(e){return t.adjustSpinners()})),this.needInitAdjust=!1)},selectableRange:function(e){this.$refs.spinner.selectableRange=e},defaultValue:function(e){Object(ao["isDate"])(this.value)||(this.date=e?new Date(e):new Date)}},data:function(){return{popperClass:"",format:"HH:mm:ss",value:"",defaultValue:null,date:new Date,oldValue:new Date,selectableRange:[],selectionRange:[0,2],disabled:!1,arrowControl:!1,needInitAdjust:!0}},computed:{showSeconds:function(){return-1!==(this.format||"").indexOf("ss")},useArrow:function(){return this.arrowControl||this.timeArrowControl||!1},amPmMode:function(){return-1!==(this.format||"").indexOf("A")?"A":-1!==(this.format||"").indexOf("a")?"a":""}},methods:{handleCancel:function(){this.$emit("pick",this.oldValue,!1)},handleChange:function(e){this.visible&&(this.date=Object(ao["clearMilliseconds"])(e),this.isValidValue(this.date)&&this.$emit("pick",this.date,!0))},setSelectionRange:function(e,t){this.$emit("select-range",e,t),this.selectionRange=[e,t]},handleConfirm:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=arguments[1];if(!t){var n=Object(ao["clearMilliseconds"])(Object(ao["limitTimeRange"])(this.date,this.selectableRange,this.format));this.$emit("pick",n,e,t)}},handleKeydown:function(e){var t=e.keyCode,n={38:-1,40:1,37:-1,39:1};if(37===t||39===t){var i=n[t];return this.changeSelectionRange(i),void e.preventDefault()}if(38===t||40===t){var r=n[t];return this.$refs.spinner.scrollDown(r),void e.preventDefault()}},isValidValue:function(e){return Object(ao["timeWithinRange"])(e,this.selectableRange,this.format)},adjustSpinners:function(){return this.$refs.spinner.adjustSpinners()},changeSelectionRange:function(e){var t=[0,3].concat(this.showSeconds?[6]:[]),n=["hours","minutes"].concat(this.showSeconds?["seconds"]:[]),i=t.indexOf(this.selectionRange[0]),r=(i+e+t.length)%t.length;this.$refs.spinner.emitSelectRange(n[r])}},mounted:function(){var e=this;this.$nextTick((function(){return e.handleConfirm(!0,!0)})),this.$emit("mounted")}},Fo=Ao,Lo=s(Fo,Do,Eo,!1,null,null,null);Lo.options.__file="packages/date-picker/src/panel/time.vue";var Vo=Lo.exports,zo=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("table",{staticClass:"el-year-table",on:{click:e.handleYearTableClick}},[n("tbody",[n("tr",[n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+0)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+1)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+1))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+2)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+2))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+3)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+3))])])]),n("tr",[n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+4)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+4))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+5)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+5))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+6)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+6))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+7)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+7))])])]),n("tr",[n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+8)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+8))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+9)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+9))])]),n("td"),n("td")])])])},Bo=[];zo._withStripped=!0;var Ro=function(e){var t=Object(ao["getDayCountOfYear"])(e),n=new Date(e,0,1);return Object(ao["range"])(t).map((function(e){return Object(ao["nextDate"])(n,e)}))},Ho={props:{disabledDate:{},value:{},defaultValue:{validator:function(e){return null===e||e instanceof Date&&Object(ao["isDate"])(e)}},date:{}},computed:{startYear:function(){return 10*Math.floor(this.date.getFullYear()/10)}},methods:{getCellStyle:function(e){var t={},n=new Date;return t.disabled="function"===typeof this.disabledDate&&Ro(e).every(this.disabledDate),t.current=Object(b["arrayFindIndex"])(Object(b["coerceTruthyValueToArray"])(this.value),(function(t){return t.getFullYear()===e}))>=0,t.today=n.getFullYear()===e,t.default=this.defaultValue&&this.defaultValue.getFullYear()===e,t},handleYearTableClick:function(e){var t=e.target;if("A"===t.tagName){if(Object(Le["hasClass"])(t.parentNode,"disabled"))return;var n=t.textContent||t.innerText;this.$emit("pick",Number(n))}}}},Wo=Ho,qo=s(Wo,zo,Bo,!1,null,null,null);qo.options.__file="packages/date-picker/src/basic/year-table.vue";var Uo=qo.exports,Yo=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("table",{staticClass:"el-month-table",on:{click:e.handleMonthTableClick,mousemove:e.handleMouseMove}},[n("tbody",e._l(e.rows,(function(t,i){return n("tr",{key:i},e._l(t,(function(t,i){return n("td",{key:i,class:e.getCellStyle(t)},[n("div",[n("a",{staticClass:"cell"},[e._v(e._s(e.t("el.datepicker.months."+e.months[t.text])))])])])})),0)})),0)])},Ko=[];Yo._withStripped=!0;var Go=function(e,t){var n=Object(ao["getDayCountOfMonth"])(e,t),i=new Date(e,t,1);return Object(ao["range"])(n).map((function(e){return Object(ao["nextDate"])(i,e)}))},Xo=function(e){return new Date(e.getFullYear(),e.getMonth())},Zo=function(e){return"number"===typeof e||"string"===typeof e?Xo(new Date(e)).getTime():e instanceof Date?Xo(e).getTime():NaN},Jo={props:{disabledDate:{},value:{},selectionMode:{default:"month"},minDate:{},maxDate:{},defaultValue:{validator:function(e){return null===e||Object(ao["isDate"])(e)||Array.isArray(e)&&e.every(ao["isDate"])}},date:{},rangeState:{default:function(){return{endDate:null,selecting:!1}}}},mixins:[g.a],watch:{"rangeState.endDate":function(e){this.markRange(this.minDate,e)},minDate:function(e,t){Zo(e)!==Zo(t)&&this.markRange(this.minDate,this.maxDate)},maxDate:function(e,t){Zo(e)!==Zo(t)&&this.markRange(this.minDate,this.maxDate)}},data:function(){return{months:["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"],tableRows:[[],[],[]],lastRow:null,lastColumn:null}},methods:{cellMatchesDate:function(e,t){var n=new Date(t);return this.date.getFullYear()===n.getFullYear()&&Number(e.text)===n.getMonth()},getCellStyle:function(e){var t=this,n={},i=this.date.getFullYear(),r=new Date,o=e.text,a=this.defaultValue?Array.isArray(this.defaultValue)?this.defaultValue:[this.defaultValue]:[];return n.disabled="function"===typeof this.disabledDate&&Go(i,o).every(this.disabledDate),n.current=Object(b["arrayFindIndex"])(Object(b["coerceTruthyValueToArray"])(this.value),(function(e){return e.getFullYear()===i&&e.getMonth()===o}))>=0,n.today=r.getFullYear()===i&&r.getMonth()===o,n.default=a.some((function(n){return t.cellMatchesDate(e,n)})),e.inRange&&(n["in-range"]=!0,e.start&&(n["start-date"]=!0),e.end&&(n["end-date"]=!0)),n},getMonthOfCell:function(e){var t=this.date.getFullYear();return new Date(t,e,1)},markRange:function(e,t){e=Zo(e),t=Zo(t)||e;var n=[Math.min(e,t),Math.max(e,t)];e=n[0],t=n[1];for(var i=this.rows,r=0,o=i.length;r=e&&d<=t,c.start=e&&d===e,c.end=t&&d===t}},handleMouseMove:function(e){if(this.rangeState.selecting){var t=e.target;if("A"===t.tagName&&(t=t.parentNode.parentNode),"DIV"===t.tagName&&(t=t.parentNode),"TD"===t.tagName){var n=t.parentNode.rowIndex,i=t.cellIndex;this.rows[n][i].disabled||n===this.lastRow&&i===this.lastColumn||(this.lastRow=n,this.lastColumn=i,this.$emit("changerange",{minDate:this.minDate,maxDate:this.maxDate,rangeState:{selecting:!0,endDate:this.getMonthOfCell(4*n+i)}}))}}},handleMonthTableClick:function(e){var t=e.target;if("A"===t.tagName&&(t=t.parentNode.parentNode),"DIV"===t.tagName&&(t=t.parentNode),"TD"===t.tagName&&!Object(Le["hasClass"])(t,"disabled")){var n=t.cellIndex,i=t.parentNode.rowIndex,r=4*i+n,o=this.getMonthOfCell(r);"range"===this.selectionMode?this.rangeState.selecting?(o>=this.minDate?this.$emit("pick",{minDate:this.minDate,maxDate:o}):this.$emit("pick",{minDate:o,maxDate:this.minDate}),this.rangeState.selecting=!1):(this.$emit("pick",{minDate:o,maxDate:null}),this.rangeState.selecting=!0):this.$emit("pick",r)}}},computed:{rows:function(){for(var e=this,t=this.tableRows,n=this.disabledDate,i=[],r=Zo(new Date),o=0;o<3;o++)for(var a=t[o],s=function(t){var s=a[t];s||(s={row:o,column:t,type:"normal",inRange:!1,start:!1,end:!1}),s.type="normal";var l=4*o+t,c=new Date(e.date.getFullYear(),l).getTime();s.inRange=c>=Zo(e.minDate)&&c<=Zo(e.maxDate),s.start=e.minDate&&c===Zo(e.minDate),s.end=e.maxDate&&c===Zo(e.maxDate);var u=c===r;u&&(s.type="today"),s.text=l;var d=new Date(c);s.disabled="function"===typeof n&&n(d),s.selected=Object(b["arrayFind"])(i,(function(e){return e.getTime()===d.getTime()})),e.$set(a,t,s)},l=0;l<4;l++)s(l);return t}}},Qo=Jo,ea=s(Qo,Yo,Ko,!1,null,null,null);ea.options.__file="packages/date-picker/src/basic/month-table.vue";var ta=ea.exports,na=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("table",{staticClass:"el-date-table",class:{"is-week-mode":"week"===e.selectionMode},attrs:{cellspacing:"0",cellpadding:"0"},on:{click:e.handleClick,mousemove:e.handleMouseMove}},[n("tbody",[n("tr",[e.showWeekNumber?n("th",[e._v(e._s(e.t("el.datepicker.week")))]):e._e(),e._l(e.WEEKS,(function(t,i){return n("th",{key:i},[e._v(e._s(e.t("el.datepicker.weeks."+t)))])}))],2),e._l(e.rows,(function(t,i){return n("tr",{key:i,staticClass:"el-date-table__row",class:{current:e.isWeekActive(t[1])}},e._l(t,(function(t,i){return n("td",{key:i,class:e.getCellClasses(t)},[n("div",[n("span",[e._v("\n "+e._s(t.text)+"\n ")])])])})),0)}))],2)])},ia=[];na._withStripped=!0;var ra=["sun","mon","tue","wed","thu","fri","sat"],oa=function(e){return"number"===typeof e||"string"===typeof e?Object(ao["clearTime"])(new Date(e)).getTime():e instanceof Date?Object(ao["clearTime"])(e).getTime():NaN},aa=function(e,t){var n="function"===typeof t?Object(b["arrayFindIndex"])(e,t):e.indexOf(t);return n>=0?[].concat(e.slice(0,n),e.slice(n+1)):e},sa={mixins:[g.a],props:{firstDayOfWeek:{default:7,type:Number,validator:function(e){return e>=1&&e<=7}},value:{},defaultValue:{validator:function(e){return null===e||Object(ao["isDate"])(e)||Array.isArray(e)&&e.every(ao["isDate"])}},date:{},selectionMode:{default:"day"},showWeekNumber:{type:Boolean,default:!1},disabledDate:{},cellClassName:{},minDate:{},maxDate:{},rangeState:{default:function(){return{endDate:null,selecting:!1}}}},computed:{offsetDay:function(){var e=this.firstDayOfWeek;return e>3?7-e:-e},WEEKS:function(){var e=this.firstDayOfWeek;return ra.concat(ra).slice(e,e+7)},year:function(){return this.date.getFullYear()},month:function(){return this.date.getMonth()},startDate:function(){return Object(ao["getStartDateOfMonth"])(this.year,this.month)},rows:function(){var e=this,t=new Date(this.year,this.month,1),n=Object(ao["getFirstDayOfMonth"])(t),i=Object(ao["getDayCountOfMonth"])(t.getFullYear(),t.getMonth()),r=Object(ao["getDayCountOfMonth"])(t.getFullYear(),0===t.getMonth()?11:t.getMonth()-1);n=0===n?7:n;for(var o=this.offsetDay,a=this.tableRows,s=1,l=this.startDate,c=this.disabledDate,u=this.cellClassName,d="dates"===this.selectionMode?Object(b["coerceTruthyValueToArray"])(this.value):[],h=oa(new Date),f=0;f<6;f++){var p=a[f];this.showWeekNumber&&(p[0]||(p[0]={type:"week",text:Object(ao["getWeekNumber"])(Object(ao["nextDate"])(l,7*f+1))}));for(var m=function(t){var a=p[e.showWeekNumber?t+1:t];a||(a={row:f,column:t,type:"normal",inRange:!1,start:!1,end:!1}),a.type="normal";var m=7*f+t,v=Object(ao["nextDate"])(l,m-o).getTime();a.inRange=v>=oa(e.minDate)&&v<=oa(e.maxDate),a.start=e.minDate&&v===oa(e.minDate),a.end=e.maxDate&&v===oa(e.maxDate);var g=v===h;if(g&&(a.type="today"),f>=0&&f<=1){var y=n+o<0?7+n+o:n+o;t+7*f>=y?a.text=s++:(a.text=r-(y-t%7)+1+7*f,a.type="prev-month")}else s<=i?a.text=s++:(a.text=s++-i,a.type="next-month");var _=new Date(v);a.disabled="function"===typeof c&&c(_),a.selected=Object(b["arrayFind"])(d,(function(e){return e.getTime()===_.getTime()})),a.customClass="function"===typeof u&&u(_),e.$set(p,e.showWeekNumber?t+1:t,a)},v=0;v<7;v++)m(v);if("week"===this.selectionMode){var g=this.showWeekNumber?1:0,y=this.showWeekNumber?7:6,_=this.isWeekActive(p[g+1]);p[g].inRange=_,p[g].start=_,p[y].inRange=_,p[y].end=_}}return a}},watch:{"rangeState.endDate":function(e){this.markRange(this.minDate,e)},minDate:function(e,t){oa(e)!==oa(t)&&this.markRange(this.minDate,this.maxDate)},maxDate:function(e,t){oa(e)!==oa(t)&&this.markRange(this.minDate,this.maxDate)}},data:function(){return{tableRows:[[],[],[],[],[],[]],lastRow:null,lastColumn:null}},methods:{cellMatchesDate:function(e,t){var n=new Date(t);return this.year===n.getFullYear()&&this.month===n.getMonth()&&Number(e.text)===n.getDate()},getCellClasses:function(e){var t=this,n=this.selectionMode,i=this.defaultValue?Array.isArray(this.defaultValue)?this.defaultValue:[this.defaultValue]:[],r=[];return"normal"!==e.type&&"today"!==e.type||e.disabled?r.push(e.type):(r.push("available"),"today"===e.type&&r.push("today")),"normal"===e.type&&i.some((function(n){return t.cellMatchesDate(e,n)}))&&r.push("default"),"day"!==n||"normal"!==e.type&&"today"!==e.type||!this.cellMatchesDate(e,this.value)||r.push("current"),!e.inRange||"normal"!==e.type&&"today"!==e.type&&"week"!==this.selectionMode||(r.push("in-range"),e.start&&r.push("start-date"),e.end&&r.push("end-date")),e.disabled&&r.push("disabled"),e.selected&&r.push("selected"),e.customClass&&r.push(e.customClass),r.join(" ")},getDateOfCell:function(e,t){var n=7*e+(t-(this.showWeekNumber?1:0))-this.offsetDay;return Object(ao["nextDate"])(this.startDate,n)},isWeekActive:function(e){if("week"!==this.selectionMode)return!1;var t=new Date(this.year,this.month,1),n=t.getFullYear(),i=t.getMonth();if("prev-month"===e.type&&(t.setMonth(0===i?11:i-1),t.setFullYear(0===i?n-1:n)),"next-month"===e.type&&(t.setMonth(11===i?0:i+1),t.setFullYear(11===i?n+1:n)),t.setDate(parseInt(e.text,10)),Object(ao["isDate"])(this.value)){var r=(this.value.getDay()-this.firstDayOfWeek+7)%7-1,o=Object(ao["prevDate"])(this.value,r);return o.getTime()===t.getTime()}return!1},markRange:function(e,t){e=oa(e),t=oa(t)||e;var n=[Math.min(e,t),Math.max(e,t)];e=n[0],t=n[1];for(var i=this.startDate,r=this.rows,o=0,a=r.length;o=e&&h<=t,u.start=e&&h===e,u.end=t&&h===t}},handleMouseMove:function(e){if(this.rangeState.selecting){var t=e.target;if("SPAN"===t.tagName&&(t=t.parentNode.parentNode),"DIV"===t.tagName&&(t=t.parentNode),"TD"===t.tagName){var n=t.parentNode.rowIndex-1,i=t.cellIndex;this.rows[n][i].disabled||n===this.lastRow&&i===this.lastColumn||(this.lastRow=n,this.lastColumn=i,this.$emit("changerange",{minDate:this.minDate,maxDate:this.maxDate,rangeState:{selecting:!0,endDate:this.getDateOfCell(n,i)}}))}}},handleClick:function(e){var t=e.target;if("SPAN"===t.tagName&&(t=t.parentNode.parentNode),"DIV"===t.tagName&&(t=t.parentNode),"TD"===t.tagName){var n=t.parentNode.rowIndex-1,i="week"===this.selectionMode?1:t.cellIndex,r=this.rows[n][i];if(!r.disabled&&"week"!==r.type){var o=this.getDateOfCell(n,i);if("range"===this.selectionMode)this.rangeState.selecting?(o>=this.minDate?this.$emit("pick",{minDate:this.minDate,maxDate:o}):this.$emit("pick",{minDate:o,maxDate:this.minDate}),this.rangeState.selecting=!1):(this.$emit("pick",{minDate:o,maxDate:null}),this.rangeState.selecting=!0);else if("day"===this.selectionMode)this.$emit("pick",o);else if("week"===this.selectionMode){var a=Object(ao["getWeekNumber"])(o),s=o.getFullYear()+"w"+a;this.$emit("pick",{year:o.getFullYear(),week:a,value:s,date:o})}else if("dates"===this.selectionMode){var l=this.value||[],c=r.selected?aa(l,(function(e){return e.getTime()===o.getTime()})):[].concat(l,[o]);this.$emit("pick",c)}}}}}},la=sa,ca=s(la,na,ia,!1,null,null,null);ca.options.__file="packages/date-picker/src/basic/date-table.vue";var ua=ca.exports,da={mixins:[g.a],directives:{Clickoutside:V.a},watch:{showTime:function(e){var t=this;e&&this.$nextTick((function(e){var n=t.$refs.input.$el;n&&(t.pickerWidth=n.getBoundingClientRect().width+10)}))},value:function(e){"dates"===this.selectionMode&&this.value||(Object(ao["isDate"])(e)?this.date=new Date(e):this.date=this.getDefaultValue())},defaultValue:function(e){Object(ao["isDate"])(this.value)||(this.date=e?new Date(e):new Date)},timePickerVisible:function(e){var t=this;e&&this.$nextTick((function(){return t.$refs.timepicker.adjustSpinners()}))},selectionMode:function(e){"month"===e?"year"===this.currentView&&"month"===this.currentView||(this.currentView="month"):"dates"===e&&(this.currentView="date")}},methods:{proxyTimePickerDataProperties:function(){var e=this,t=function(t){e.$refs.timepicker.format=t},n=function(t){e.$refs.timepicker.value=t},i=function(t){e.$refs.timepicker.date=t},r=function(t){e.$refs.timepicker.selectableRange=t};this.$watch("value",n),this.$watch("date",i),this.$watch("selectableRange",r),t(this.timeFormat),n(this.value),i(this.date),r(this.selectableRange)},handleClear:function(){this.date=this.getDefaultValue(),this.$emit("pick",null)},emit:function(e){for(var t=this,n=arguments.length,i=Array(n>1?n-1:0),r=1;r0)||Object(ao["timeWithinRange"])(e,this.selectableRange,this.format||"HH:mm:ss")}},components:{TimePicker:Vo,YearTable:Uo,MonthTable:ta,DateTable:ua,ElInput:m.a,ElButton:ae.a},data:function(){return{popperClass:"",date:new Date,value:"",defaultValue:null,defaultTime:null,showTime:!1,selectionMode:"day",shortcuts:"",visible:!1,currentView:"date",disabledDate:"",cellClassName:"",selectableRange:[],firstDayOfWeek:7,showWeekNumber:!1,timePickerVisible:!1,format:"",arrowControl:!1,userInputDate:null,userInputTime:null}},computed:{year:function(){return this.date.getFullYear()},month:function(){return this.date.getMonth()},week:function(){return Object(ao["getWeekNumber"])(this.date)},monthDate:function(){return this.date.getDate()},footerVisible:function(){return this.showTime||"dates"===this.selectionMode},visibleTime:function(){return null!==this.userInputTime?this.userInputTime:Object(ao["formatDate"])(this.value||this.defaultValue,this.timeFormat)},visibleDate:function(){return null!==this.userInputDate?this.userInputDate:Object(ao["formatDate"])(this.value||this.defaultValue,this.dateFormat)},yearLabel:function(){var e=this.t("el.datepicker.year");if("year"===this.currentView){var t=10*Math.floor(this.year/10);return e?t+" "+e+" - "+(t+9)+" "+e:t+" - "+(t+9)}return this.year+" "+e},timeFormat:function(){return this.format?Object(ao["extractTimeFormat"])(this.format):"HH:mm:ss"},dateFormat:function(){return this.format?Object(ao["extractDateFormat"])(this.format):"yyyy-MM-dd"}}},ha=da,fa=s(ha,Oo,$o,!1,null,null,null);fa.options.__file="packages/date-picker/src/panel/date.vue";var pa=fa.exports,ma=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":function(t){e.$emit("dodestroy")}}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-picker-panel el-date-range-picker el-popper",class:[{"has-sidebar":e.$slots.sidebar||e.shortcuts,"has-time":e.showTime},e.popperClass]},[n("div",{staticClass:"el-picker-panel__body-wrapper"},[e._t("sidebar"),e.shortcuts?n("div",{staticClass:"el-picker-panel__sidebar"},e._l(e.shortcuts,(function(t,i){return n("button",{key:i,staticClass:"el-picker-panel__shortcut",attrs:{type:"button"},on:{click:function(n){e.handleShortcutClick(t)}}},[e._v(e._s(t.text))])})),0):e._e(),n("div",{staticClass:"el-picker-panel__body"},[e.showTime?n("div",{staticClass:"el-date-range-picker__time-header"},[n("span",{staticClass:"el-date-range-picker__editors-wrap"},[n("span",{staticClass:"el-date-range-picker__time-picker-wrap"},[n("el-input",{ref:"minInput",staticClass:"el-date-range-picker__editor",attrs:{size:"small",disabled:e.rangeState.selecting,placeholder:e.t("el.datepicker.startDate"),value:e.minVisibleDate},on:{input:function(t){return e.handleDateInput(t,"min")},change:function(t){return e.handleDateChange(t,"min")}}})],1),n("span",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleMinTimeClose,expression:"handleMinTimeClose"}],staticClass:"el-date-range-picker__time-picker-wrap"},[n("el-input",{staticClass:"el-date-range-picker__editor",attrs:{size:"small",disabled:e.rangeState.selecting,placeholder:e.t("el.datepicker.startTime"),value:e.minVisibleTime},on:{focus:function(t){e.minTimePickerVisible=!0},input:function(t){return e.handleTimeInput(t,"min")},change:function(t){return e.handleTimeChange(t,"min")}}}),n("time-picker",{ref:"minTimePicker",attrs:{"time-arrow-control":e.arrowControl,visible:e.minTimePickerVisible},on:{pick:e.handleMinTimePick,mounted:function(t){e.$refs.minTimePicker.format=e.timeFormat}}})],1)]),n("span",{staticClass:"el-icon-arrow-right"}),n("span",{staticClass:"el-date-range-picker__editors-wrap is-right"},[n("span",{staticClass:"el-date-range-picker__time-picker-wrap"},[n("el-input",{staticClass:"el-date-range-picker__editor",attrs:{size:"small",disabled:e.rangeState.selecting,placeholder:e.t("el.datepicker.endDate"),value:e.maxVisibleDate,readonly:!e.minDate},on:{input:function(t){return e.handleDateInput(t,"max")},change:function(t){return e.handleDateChange(t,"max")}}})],1),n("span",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleMaxTimeClose,expression:"handleMaxTimeClose"}],staticClass:"el-date-range-picker__time-picker-wrap"},[n("el-input",{staticClass:"el-date-range-picker__editor",attrs:{size:"small",disabled:e.rangeState.selecting,placeholder:e.t("el.datepicker.endTime"),value:e.maxVisibleTime,readonly:!e.minDate},on:{focus:function(t){e.minDate&&(e.maxTimePickerVisible=!0)},input:function(t){return e.handleTimeInput(t,"max")},change:function(t){return e.handleTimeChange(t,"max")}}}),n("time-picker",{ref:"maxTimePicker",attrs:{"time-arrow-control":e.arrowControl,visible:e.maxTimePickerVisible},on:{pick:e.handleMaxTimePick,mounted:function(t){e.$refs.maxTimePicker.format=e.timeFormat}}})],1)])]):e._e(),n("div",{staticClass:"el-picker-panel__content el-date-range-picker__content is-left"},[n("div",{staticClass:"el-date-range-picker__header"},[n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-left",attrs:{type:"button"},on:{click:e.leftPrevYear}}),n("button",{staticClass:"el-picker-panel__icon-btn el-icon-arrow-left",attrs:{type:"button"},on:{click:e.leftPrevMonth}}),e.unlinkPanels?n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-right",class:{"is-disabled":!e.enableYearArrow},attrs:{type:"button",disabled:!e.enableYearArrow},on:{click:e.leftNextYear}}):e._e(),e.unlinkPanels?n("button",{staticClass:"el-picker-panel__icon-btn el-icon-arrow-right",class:{"is-disabled":!e.enableMonthArrow},attrs:{type:"button",disabled:!e.enableMonthArrow},on:{click:e.leftNextMonth}}):e._e(),n("div",[e._v(e._s(e.leftLabel))])]),n("date-table",{attrs:{"selection-mode":"range",date:e.leftDate,"default-value":e.defaultValue,"min-date":e.minDate,"max-date":e.maxDate,"range-state":e.rangeState,"disabled-date":e.disabledDate,"cell-class-name":e.cellClassName,"first-day-of-week":e.firstDayOfWeek},on:{changerange:e.handleChangeRange,pick:e.handleRangePick}})],1),n("div",{staticClass:"el-picker-panel__content el-date-range-picker__content is-right"},[n("div",{staticClass:"el-date-range-picker__header"},[e.unlinkPanels?n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-left",class:{"is-disabled":!e.enableYearArrow},attrs:{type:"button",disabled:!e.enableYearArrow},on:{click:e.rightPrevYear}}):e._e(),e.unlinkPanels?n("button",{staticClass:"el-picker-panel__icon-btn el-icon-arrow-left",class:{"is-disabled":!e.enableMonthArrow},attrs:{type:"button",disabled:!e.enableMonthArrow},on:{click:e.rightPrevMonth}}):e._e(),n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-right",attrs:{type:"button"},on:{click:e.rightNextYear}}),n("button",{staticClass:"el-picker-panel__icon-btn el-icon-arrow-right",attrs:{type:"button"},on:{click:e.rightNextMonth}}),n("div",[e._v(e._s(e.rightLabel))])]),n("date-table",{attrs:{"selection-mode":"range",date:e.rightDate,"default-value":e.defaultValue,"min-date":e.minDate,"max-date":e.maxDate,"range-state":e.rangeState,"disabled-date":e.disabledDate,"cell-class-name":e.cellClassName,"first-day-of-week":e.firstDayOfWeek},on:{changerange:e.handleChangeRange,pick:e.handleRangePick}})],1)])],2),e.showTime?n("div",{staticClass:"el-picker-panel__footer"},[n("el-button",{staticClass:"el-picker-panel__link-btn",attrs:{size:"mini",type:"text"},on:{click:e.handleClear}},[e._v("\n "+e._s(e.t("el.datepicker.clear"))+"\n ")]),n("el-button",{staticClass:"el-picker-panel__link-btn",attrs:{plain:"",size:"mini",disabled:e.btnDisabled},on:{click:function(t){e.handleConfirm(!1)}}},[e._v("\n "+e._s(e.t("el.datepicker.confirm"))+"\n ")])],1):e._e()])])},va=[];ma._withStripped=!0;var ga=function(e){return Array.isArray(e)?[new Date(e[0]),new Date(e[1])]:e?[new Date(e),Object(ao["nextDate"])(new Date(e),1)]:[new Date,Object(ao["nextDate"])(new Date,1)]},ba={mixins:[g.a],directives:{Clickoutside:V.a},computed:{btnDisabled:function(){return!(this.minDate&&this.maxDate&&!this.selecting&&this.isValidValue([this.minDate,this.maxDate]))},leftLabel:function(){return this.leftDate.getFullYear()+" "+this.t("el.datepicker.year")+" "+this.t("el.datepicker.month"+(this.leftDate.getMonth()+1))},rightLabel:function(){return this.rightDate.getFullYear()+" "+this.t("el.datepicker.year")+" "+this.t("el.datepicker.month"+(this.rightDate.getMonth()+1))},leftYear:function(){return this.leftDate.getFullYear()},leftMonth:function(){return this.leftDate.getMonth()},leftMonthDate:function(){return this.leftDate.getDate()},rightYear:function(){return this.rightDate.getFullYear()},rightMonth:function(){return this.rightDate.getMonth()},rightMonthDate:function(){return this.rightDate.getDate()},minVisibleDate:function(){return null!==this.dateUserInput.min?this.dateUserInput.min:this.minDate?Object(ao["formatDate"])(this.minDate,this.dateFormat):""},maxVisibleDate:function(){return null!==this.dateUserInput.max?this.dateUserInput.max:this.maxDate||this.minDate?Object(ao["formatDate"])(this.maxDate||this.minDate,this.dateFormat):""},minVisibleTime:function(){return null!==this.timeUserInput.min?this.timeUserInput.min:this.minDate?Object(ao["formatDate"])(this.minDate,this.timeFormat):""},maxVisibleTime:function(){return null!==this.timeUserInput.max?this.timeUserInput.max:this.maxDate||this.minDate?Object(ao["formatDate"])(this.maxDate||this.minDate,this.timeFormat):""},timeFormat:function(){return this.format?Object(ao["extractTimeFormat"])(this.format):"HH:mm:ss"},dateFormat:function(){return this.format?Object(ao["extractDateFormat"])(this.format):"yyyy-MM-dd"},enableMonthArrow:function(){var e=(this.leftMonth+1)%12,t=this.leftMonth+1>=12?1:0;return this.unlinkPanels&&new Date(this.leftYear+t,e)=12}},data:function(){return{popperClass:"",value:[],defaultValue:null,defaultTime:null,minDate:"",maxDate:"",leftDate:new Date,rightDate:Object(ao["nextMonth"])(new Date),rangeState:{endDate:null,selecting:!1,row:null,column:null},showTime:!1,shortcuts:"",visible:"",disabledDate:"",cellClassName:"",firstDayOfWeek:7,minTimePickerVisible:!1,maxTimePickerVisible:!1,format:"",arrowControl:!1,unlinkPanels:!1,dateUserInput:{min:null,max:null},timeUserInput:{min:null,max:null}}},watch:{minDate:function(e){var t=this;this.dateUserInput.min=null,this.timeUserInput.min=null,this.$nextTick((function(){if(t.$refs.maxTimePicker&&t.maxDate&&t.maxDatethis.maxDate&&(this.maxDate=this.minDate)):(this.maxDate=Object(ao["modifyDate"])(this.maxDate,n.getFullYear(),n.getMonth(),n.getDate()),this.maxDatethis.maxDate&&(this.maxDate=this.minDate),this.$refs.minTimePicker.value=this.minDate,this.minTimePickerVisible=!1):(this.maxDate=Object(ao["modifyTime"])(this.maxDate,n.getHours(),n.getMinutes(),n.getSeconds()),this.maxDate1&&void 0!==arguments[1])||arguments[1],i=this.defaultTime||[],r=Object(ao["modifyWithTimeString"])(e.minDate,i[0]),o=Object(ao["modifyWithTimeString"])(e.maxDate,i[1]);this.maxDate===o&&this.minDate===r||(this.onPick&&this.onPick(e),this.maxDate=o,this.minDate=r,setTimeout((function(){t.maxDate=o,t.minDate=r}),10),n&&!this.showTime&&this.handleConfirm())},handleShortcutClick:function(e){e.onClick&&e.onClick(this)},handleMinTimePick:function(e,t,n){this.minDate=this.minDate||new Date,e&&(this.minDate=Object(ao["modifyTime"])(this.minDate,e.getHours(),e.getMinutes(),e.getSeconds())),n||(this.minTimePickerVisible=t),(!this.maxDate||this.maxDate&&this.maxDate.getTime()this.maxDate.getTime()&&(this.minDate=new Date(this.maxDate))},handleMaxTimeClose:function(){this.maxTimePickerVisible=!1},leftPrevYear:function(){this.leftDate=Object(ao["prevYear"])(this.leftDate),this.unlinkPanels||(this.rightDate=Object(ao["nextMonth"])(this.leftDate))},leftPrevMonth:function(){this.leftDate=Object(ao["prevMonth"])(this.leftDate),this.unlinkPanels||(this.rightDate=Object(ao["nextMonth"])(this.leftDate))},rightNextYear:function(){this.unlinkPanels?this.rightDate=Object(ao["nextYear"])(this.rightDate):(this.leftDate=Object(ao["nextYear"])(this.leftDate),this.rightDate=Object(ao["nextMonth"])(this.leftDate))},rightNextMonth:function(){this.unlinkPanels?this.rightDate=Object(ao["nextMonth"])(this.rightDate):(this.leftDate=Object(ao["nextMonth"])(this.leftDate),this.rightDate=Object(ao["nextMonth"])(this.leftDate))},leftNextYear:function(){this.leftDate=Object(ao["nextYear"])(this.leftDate)},leftNextMonth:function(){this.leftDate=Object(ao["nextMonth"])(this.leftDate)},rightPrevYear:function(){this.rightDate=Object(ao["prevYear"])(this.rightDate)},rightPrevMonth:function(){this.rightDate=Object(ao["prevMonth"])(this.rightDate)},handleConfirm:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.isValidValue([this.minDate,this.maxDate])&&this.$emit("pick",[this.minDate,this.maxDate],e)},isValidValue:function(e){return Array.isArray(e)&&e&&e[0]&&e[1]&&Object(ao["isDate"])(e[0])&&Object(ao["isDate"])(e[1])&&e[0].getTime()<=e[1].getTime()&&("function"!==typeof this.disabledDate||!this.disabledDate(e[0])&&!this.disabledDate(e[1]))},resetView:function(){this.minDate=this.value&&Object(ao["isDate"])(this.value[0])?new Date(this.value[0]):null,this.maxDate=this.value&&Object(ao["isDate"])(this.value[0])?new Date(this.value[1]):null}},components:{TimePicker:Vo,DateTable:ua,ElInput:m.a,ElButton:ae.a}},ya=ba,_a=s(ya,ma,va,!1,null,null,null);_a.options.__file="packages/date-picker/src/panel/date-range.vue";var xa=_a.exports,wa=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":function(t){e.$emit("dodestroy")}}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-picker-panel el-date-range-picker el-popper",class:[{"has-sidebar":e.$slots.sidebar||e.shortcuts},e.popperClass]},[n("div",{staticClass:"el-picker-panel__body-wrapper"},[e._t("sidebar"),e.shortcuts?n("div",{staticClass:"el-picker-panel__sidebar"},e._l(e.shortcuts,(function(t,i){return n("button",{key:i,staticClass:"el-picker-panel__shortcut",attrs:{type:"button"},on:{click:function(n){e.handleShortcutClick(t)}}},[e._v(e._s(t.text))])})),0):e._e(),n("div",{staticClass:"el-picker-panel__body"},[n("div",{staticClass:"el-picker-panel__content el-date-range-picker__content is-left"},[n("div",{staticClass:"el-date-range-picker__header"},[n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-left",attrs:{type:"button"},on:{click:e.leftPrevYear}}),e.unlinkPanels?n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-right",class:{"is-disabled":!e.enableYearArrow},attrs:{type:"button",disabled:!e.enableYearArrow},on:{click:e.leftNextYear}}):e._e(),n("div",[e._v(e._s(e.leftLabel))])]),n("month-table",{attrs:{"selection-mode":"range",date:e.leftDate,"default-value":e.defaultValue,"min-date":e.minDate,"max-date":e.maxDate,"range-state":e.rangeState,"disabled-date":e.disabledDate},on:{changerange:e.handleChangeRange,pick:e.handleRangePick}})],1),n("div",{staticClass:"el-picker-panel__content el-date-range-picker__content is-right"},[n("div",{staticClass:"el-date-range-picker__header"},[e.unlinkPanels?n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-left",class:{"is-disabled":!e.enableYearArrow},attrs:{type:"button",disabled:!e.enableYearArrow},on:{click:e.rightPrevYear}}):e._e(),n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-right",attrs:{type:"button"},on:{click:e.rightNextYear}}),n("div",[e._v(e._s(e.rightLabel))])]),n("month-table",{attrs:{"selection-mode":"range",date:e.rightDate,"default-value":e.defaultValue,"min-date":e.minDate,"max-date":e.maxDate,"range-state":e.rangeState,"disabled-date":e.disabledDate},on:{changerange:e.handleChangeRange,pick:e.handleRangePick}})],1)])],2)])])},Ca=[];wa._withStripped=!0;var ka=function(e){return Array.isArray(e)?[new Date(e[0]),new Date(e[1])]:e?[new Date(e),Object(ao["nextMonth"])(new Date(e))]:[new Date,Object(ao["nextMonth"])(new Date)]},Sa={mixins:[g.a],directives:{Clickoutside:V.a},computed:{btnDisabled:function(){return!(this.minDate&&this.maxDate&&!this.selecting&&this.isValidValue([this.minDate,this.maxDate]))},leftLabel:function(){return this.leftDate.getFullYear()+" "+this.t("el.datepicker.year")},rightLabel:function(){return this.rightDate.getFullYear()+" "+this.t("el.datepicker.year")},leftYear:function(){return this.leftDate.getFullYear()},rightYear:function(){return this.rightDate.getFullYear()===this.leftDate.getFullYear()?this.leftDate.getFullYear()+1:this.rightDate.getFullYear()},enableYearArrow:function(){return this.unlinkPanels&&this.rightYear>this.leftYear+1}},data:function(){return{popperClass:"",value:[],defaultValue:null,defaultTime:null,minDate:"",maxDate:"",leftDate:new Date,rightDate:Object(ao["nextYear"])(new Date),rangeState:{endDate:null,selecting:!1,row:null,column:null},shortcuts:"",visible:"",disabledDate:"",format:"",arrowControl:!1,unlinkPanels:!1}},watch:{value:function(e){if(e){if(Array.isArray(e))if(this.minDate=Object(ao["isDate"])(e[0])?new Date(e[0]):null,this.maxDate=Object(ao["isDate"])(e[1])?new Date(e[1]):null,this.minDate)if(this.leftDate=this.minDate,this.unlinkPanels&&this.maxDate){var t=this.minDate.getFullYear(),n=this.maxDate.getFullYear();this.rightDate=t===n?Object(ao["nextYear"])(this.maxDate):this.maxDate}else this.rightDate=Object(ao["nextYear"])(this.leftDate);else this.leftDate=ka(this.defaultValue)[0],this.rightDate=Object(ao["nextYear"])(this.leftDate)}else this.minDate=null,this.maxDate=null},defaultValue:function(e){if(!Array.isArray(this.value)){var t=ka(e),n=t[0],i=t[1];this.leftDate=n,this.rightDate=e&&e[1]&&n.getFullYear()!==i.getFullYear()&&this.unlinkPanels?i:Object(ao["nextYear"])(this.leftDate)}}},methods:{handleClear:function(){this.minDate=null,this.maxDate=null,this.leftDate=ka(this.defaultValue)[0],this.rightDate=Object(ao["nextYear"])(this.leftDate),this.$emit("pick",null)},handleChangeRange:function(e){this.minDate=e.minDate,this.maxDate=e.maxDate,this.rangeState=e.rangeState},handleRangePick:function(e){var t=this,n=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=this.defaultTime||[],r=Object(ao["modifyWithTimeString"])(e.minDate,i[0]),o=Object(ao["modifyWithTimeString"])(e.maxDate,i[1]);this.maxDate===o&&this.minDate===r||(this.onPick&&this.onPick(e),this.maxDate=o,this.minDate=r,setTimeout((function(){t.maxDate=o,t.minDate=r}),10),n&&this.handleConfirm())},handleShortcutClick:function(e){e.onClick&&e.onClick(this)},leftPrevYear:function(){this.leftDate=Object(ao["prevYear"])(this.leftDate),this.unlinkPanels||(this.rightDate=Object(ao["prevYear"])(this.rightDate))},rightNextYear:function(){this.unlinkPanels||(this.leftDate=Object(ao["nextYear"])(this.leftDate)),this.rightDate=Object(ao["nextYear"])(this.rightDate)},leftNextYear:function(){this.leftDate=Object(ao["nextYear"])(this.leftDate)},rightPrevYear:function(){this.rightDate=Object(ao["prevYear"])(this.rightDate)},handleConfirm:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.isValidValue([this.minDate,this.maxDate])&&this.$emit("pick",[this.minDate,this.maxDate],e)},isValidValue:function(e){return Array.isArray(e)&&e&&e[0]&&e[1]&&Object(ao["isDate"])(e[0])&&Object(ao["isDate"])(e[1])&&e[0].getTime()<=e[1].getTime()&&("function"!==typeof this.disabledDate||!this.disabledDate(e[0])&&!this.disabledDate(e[1]))},resetView:function(){this.minDate=this.value&&Object(ao["isDate"])(this.value[0])?new Date(this.value[0]):null,this.maxDate=this.value&&Object(ao["isDate"])(this.value[0])?new Date(this.value[1]):null}},components:{MonthTable:ta,ElInput:m.a,ElButton:ae.a}},Oa=Sa,$a=s(Oa,wa,Ca,!1,null,null,null);$a.options.__file="packages/date-picker/src/panel/month-range.vue";var Da=$a.exports,Ea=function(e){return"daterange"===e||"datetimerange"===e?xa:"monthrange"===e?Da:pa},Ta={mixins:[So],name:"ElDatePicker",props:{type:{type:String,default:"date"},timeArrowControl:Boolean},watch:{type:function(e){this.picker?(this.unmountPicker(),this.panel=Ea(e),this.mountPicker()):this.panel=Ea(e)}},created:function(){this.panel=Ea(this.type)},install:function(e){e.component(Ta.name,Ta)}},Pa=Ta,Ma=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"before-enter":e.handleMenuEnter,"after-leave":function(t){e.$emit("dodestroy")}}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],ref:"popper",staticClass:"el-picker-panel time-select el-popper",class:e.popperClass,style:{width:e.width+"px"}},[n("el-scrollbar",{attrs:{noresize:"","wrap-class":"el-picker-panel__content"}},e._l(e.items,(function(t){return n("div",{key:t.value,staticClass:"time-select-item",class:{selected:e.value===t.value,disabled:t.disabled,default:t.value===e.defaultValue},attrs:{disabled:t.disabled},on:{click:function(n){e.handleClick(t)}}},[e._v(e._s(t.value))])})),0)],1)])},Ia=[];Ma._withStripped=!0;var Na=function(e){var t=(e||"").split(":");if(t.length>=2){var n=parseInt(t[0],10),i=parseInt(t[1],10);return{hours:n,minutes:i}}return null},ja=function(e,t){var n=Na(e),i=Na(t),r=n.minutes+60*n.hours,o=i.minutes+60*i.hours;return r===o?0:r>o?1:-1},Aa=function(e){return(e.hours<10?"0"+e.hours:e.hours)+":"+(e.minutes<10?"0"+e.minutes:e.minutes)},Fa=function(e,t){var n=Na(e),i=Na(t),r={hours:n.hours,minutes:n.minutes};return r.minutes+=i.minutes,r.hours+=i.hours,r.hours+=Math.floor(r.minutes/60),r.minutes=r.minutes%60,Aa(r)},La={components:{ElScrollbar:q.a},watch:{value:function(e){var t=this;e&&this.$nextTick((function(){return t.scrollToOption()}))}},methods:{handleClick:function(e){e.disabled||this.$emit("pick",e.value)},handleClear:function(){this.$emit("pick",null)},scrollToOption:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:".selected",t=this.$refs.popper.querySelector(".el-picker-panel__content");ri()(t,t.querySelector(e))},handleMenuEnter:function(){var e=this,t=-1!==this.items.map((function(e){return e.value})).indexOf(this.value),n=-1!==this.items.map((function(e){return e.value})).indexOf(this.defaultValue),i=(t?".selected":n&&".default")||".time-select-item:not(.disabled)";this.$nextTick((function(){return e.scrollToOption(i)}))},scrollDown:function(e){var t=this.items,n=t.length,i=t.length,r=t.map((function(e){return e.value})).indexOf(this.value);while(i--)if(r=(r+e+n)%n,!t[r].disabled)return void this.$emit("pick",t[r].value,!0)},isValidValue:function(e){return-1!==this.items.filter((function(e){return!e.disabled})).map((function(e){return e.value})).indexOf(e)},handleKeydown:function(e){var t=e.keyCode;if(38===t||40===t){var n={40:1,38:-1},i=n[t.toString()];return this.scrollDown(i),void e.stopPropagation()}}},data:function(){return{popperClass:"",start:"09:00",end:"18:00",step:"00:30",value:"",defaultValue:"",visible:!1,minTime:"",maxTime:"",width:0}},computed:{items:function(){var e=this.start,t=this.end,n=this.step,i=[];if(e&&t&&n){var r=e;while(ja(r,t)<=0)i.push({value:r,disabled:ja(r,this.minTime||"-1:-1")<=0||ja(r,this.maxTime||"100:100")>=0}),r=Fa(r,n)}return i}}},Va=La,za=s(Va,Ma,Ia,!1,null,null,null);za.options.__file="packages/date-picker/src/panel/time-select.vue";var Ba=za.exports,Ra={mixins:[So],name:"ElTimeSelect",componentName:"ElTimeSelect",props:{type:{type:String,default:"time-select"}},beforeCreate:function(){this.panel=Ba},install:function(e){e.component(Ra.name,Ra)}},Ha=Ra,Wa=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":function(t){e.$emit("dodestroy")}}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-time-range-picker el-picker-panel el-popper",class:e.popperClass},[n("div",{staticClass:"el-time-range-picker__content"},[n("div",{staticClass:"el-time-range-picker__cell"},[n("div",{staticClass:"el-time-range-picker__header"},[e._v(e._s(e.t("el.datepicker.startTime")))]),n("div",{staticClass:"el-time-range-picker__body el-time-panel__content",class:{"has-seconds":e.showSeconds,"is-arrow":e.arrowControl}},[n("time-spinner",{ref:"minSpinner",attrs:{"show-seconds":e.showSeconds,"am-pm-mode":e.amPmMode,"arrow-control":e.arrowControl,date:e.minDate},on:{change:e.handleMinChange,"select-range":e.setMinSelectionRange}})],1)]),n("div",{staticClass:"el-time-range-picker__cell"},[n("div",{staticClass:"el-time-range-picker__header"},[e._v(e._s(e.t("el.datepicker.endTime")))]),n("div",{staticClass:"el-time-range-picker__body el-time-panel__content",class:{"has-seconds":e.showSeconds,"is-arrow":e.arrowControl}},[n("time-spinner",{ref:"maxSpinner",attrs:{"show-seconds":e.showSeconds,"am-pm-mode":e.amPmMode,"arrow-control":e.arrowControl,date:e.maxDate},on:{change:e.handleMaxChange,"select-range":e.setMaxSelectionRange}})],1)])]),n("div",{staticClass:"el-time-panel__footer"},[n("button",{staticClass:"el-time-panel__btn cancel",attrs:{type:"button"},on:{click:function(t){e.handleCancel()}}},[e._v(e._s(e.t("el.datepicker.cancel")))]),n("button",{staticClass:"el-time-panel__btn confirm",attrs:{type:"button",disabled:e.btnDisabled},on:{click:function(t){e.handleConfirm()}}},[e._v(e._s(e.t("el.datepicker.confirm")))])])])])},qa=[];Wa._withStripped=!0;var Ua=Object(ao["parseDate"])("00:00:00","HH:mm:ss"),Ya=Object(ao["parseDate"])("23:59:59","HH:mm:ss"),Ka=function(e){return Object(ao["modifyDate"])(Ua,e.getFullYear(),e.getMonth(),e.getDate())},Ga=function(e){return Object(ao["modifyDate"])(Ya,e.getFullYear(),e.getMonth(),e.getDate())},Xa=function(e,t){return new Date(Math.min(e.getTime()+t,Ga(e).getTime()))},Za={mixins:[g.a],components:{TimeSpinner:jo},computed:{showSeconds:function(){return-1!==(this.format||"").indexOf("ss")},offset:function(){return this.showSeconds?11:8},spinner:function(){return this.selectionRange[0]this.maxDate.getTime()},amPmMode:function(){return-1!==(this.format||"").indexOf("A")?"A":-1!==(this.format||"").indexOf("a")?"a":""}},data:function(){return{popperClass:"",minDate:new Date,maxDate:new Date,value:[],oldValue:[new Date,new Date],defaultValue:null,format:"HH:mm:ss",visible:!1,selectionRange:[0,2],arrowControl:!1}},watch:{value:function(e){Array.isArray(e)?(this.minDate=new Date(e[0]),this.maxDate=new Date(e[1])):Array.isArray(this.defaultValue)?(this.minDate=new Date(this.defaultValue[0]),this.maxDate=new Date(this.defaultValue[1])):this.defaultValue?(this.minDate=new Date(this.defaultValue),this.maxDate=Xa(new Date(this.defaultValue),36e5)):(this.minDate=new Date,this.maxDate=Xa(new Date,36e5))},visible:function(e){var t=this;e&&(this.oldValue=this.value,this.$nextTick((function(){return t.$refs.minSpinner.emitSelectRange("hours")})))}},methods:{handleClear:function(){this.$emit("pick",null)},handleCancel:function(){this.$emit("pick",this.oldValue)},handleMinChange:function(e){this.minDate=Object(ao["clearMilliseconds"])(e),this.handleChange()},handleMaxChange:function(e){this.maxDate=Object(ao["clearMilliseconds"])(e),this.handleChange()},handleChange:function(){this.isValidValue([this.minDate,this.maxDate])&&(this.$refs.minSpinner.selectableRange=[[Ka(this.minDate),this.maxDate]],this.$refs.maxSpinner.selectableRange=[[this.minDate,Ga(this.maxDate)]],this.$emit("pick",[this.minDate,this.maxDate],!0))},setMinSelectionRange:function(e,t){this.$emit("select-range",e,t,"min"),this.selectionRange=[e,t]},setMaxSelectionRange:function(e,t){this.$emit("select-range",e,t,"max"),this.selectionRange=[e+this.offset,t+this.offset]},handleConfirm:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.$refs.minSpinner.selectableRange,n=this.$refs.maxSpinner.selectableRange;this.minDate=Object(ao["limitTimeRange"])(this.minDate,t,this.format),this.maxDate=Object(ao["limitTimeRange"])(this.maxDate,n,this.format),this.$emit("pick",[this.minDate,this.maxDate],e)},adjustSpinners:function(){this.$refs.minSpinner.adjustSpinners(),this.$refs.maxSpinner.adjustSpinners()},changeSelectionRange:function(e){var t=this.showSeconds?[0,3,6,11,14,17]:[0,3,8,11],n=["hours","minutes"].concat(this.showSeconds?["seconds"]:[]),i=t.indexOf(this.selectionRange[0]),r=(i+e+t.length)%t.length,o=t.length/2;r-1}},openDelay:{type:Number,default:0},closeDelay:{type:Number,default:200},title:String,disabled:Boolean,content:String,reference:{},popperClass:String,width:{},visibleArrow:{default:!0},arrowOffset:{type:Number,default:0},transition:{type:String,default:"fade-in-linear"},tabindex:{type:Number,default:0}},computed:{tooltipId:function(){return"el-popover-"+Object(b["generateId"])()}},watch:{showPopper:function(e){this.disabled||(e?this.$emit("show"):this.$emit("hide"))}},mounted:function(){var e=this,t=this.referenceElm=this.reference||this.$refs.reference,n=this.popper||this.$refs.popper;!t&&this.$slots.reference&&this.$slots.reference[0]&&(t=this.referenceElm=this.$slots.reference[0].elm),t&&(Object(Le["addClass"])(t,"el-popover__reference"),t.setAttribute("aria-describedby",this.tooltipId),t.setAttribute("tabindex",this.tabindex),n.setAttribute("tabindex",0),"click"!==this.trigger&&(Object(Le["on"])(t,"focusin",(function(){e.handleFocus();var n=t.__vue__;n&&"function"===typeof n.focus&&n.focus()})),Object(Le["on"])(n,"focusin",this.handleFocus),Object(Le["on"])(t,"focusout",this.handleBlur),Object(Le["on"])(n,"focusout",this.handleBlur)),Object(Le["on"])(t,"keydown",this.handleKeydown),Object(Le["on"])(t,"click",this.handleClick)),"click"===this.trigger?(Object(Le["on"])(t,"click",this.doToggle),Object(Le["on"])(document,"click",this.handleDocumentClick)):"hover"===this.trigger?(Object(Le["on"])(t,"mouseenter",this.handleMouseEnter),Object(Le["on"])(n,"mouseenter",this.handleMouseEnter),Object(Le["on"])(t,"mouseleave",this.handleMouseLeave),Object(Le["on"])(n,"mouseleave",this.handleMouseLeave)):"focus"===this.trigger&&(this.tabindex<0&&console.warn("[Element Warn][Popover]a negative taindex means that the element cannot be focused by tab key"),t.querySelector("input, textarea")?(Object(Le["on"])(t,"focusin",this.doShow),Object(Le["on"])(t,"focusout",this.doClose)):(Object(Le["on"])(t,"mousedown",this.doShow),Object(Le["on"])(t,"mouseup",this.doClose)))},beforeDestroy:function(){this.cleanup()},deactivated:function(){this.cleanup()},methods:{doToggle:function(){this.showPopper=!this.showPopper},doShow:function(){this.showPopper=!0},doClose:function(){this.showPopper=!1},handleFocus:function(){Object(Le["addClass"])(this.referenceElm,"focusing"),"click"!==this.trigger&&"focus"!==this.trigger||(this.showPopper=!0)},handleClick:function(){Object(Le["removeClass"])(this.referenceElm,"focusing")},handleBlur:function(){Object(Le["removeClass"])(this.referenceElm,"focusing"),"click"!==this.trigger&&"focus"!==this.trigger||(this.showPopper=!1)},handleMouseEnter:function(){var e=this;clearTimeout(this._timer),this.openDelay?this._timer=setTimeout((function(){e.showPopper=!0}),this.openDelay):this.showPopper=!0},handleKeydown:function(e){27===e.keyCode&&"manual"!==this.trigger&&this.doClose()},handleMouseLeave:function(){var e=this;clearTimeout(this._timer),this.closeDelay?this._timer=setTimeout((function(){e.showPopper=!1}),this.closeDelay):this.showPopper=!1},handleDocumentClick:function(e){var t=this.reference||this.$refs.reference,n=this.popper||this.$refs.popper;!t&&this.$slots.reference&&this.$slots.reference[0]&&(t=this.referenceElm=this.$slots.reference[0].elm),this.$el&&t&&!this.$el.contains(e.target)&&!t.contains(e.target)&&n&&!n.contains(e.target)&&(this.showPopper=!1)},handleAfterEnter:function(){this.$emit("after-enter")},handleAfterLeave:function(){this.$emit("after-leave"),this.doDestroy()},cleanup:function(){(this.openDelay||this.closeDelay)&&clearTimeout(this._timer)}},destroyed:function(){var e=this.reference;Object(Le["off"])(e,"click",this.doToggle),Object(Le["off"])(e,"mouseup",this.doClose),Object(Le["off"])(e,"mousedown",this.doShow),Object(Le["off"])(e,"focusin",this.doShow),Object(Le["off"])(e,"focusout",this.doClose),Object(Le["off"])(e,"mousedown",this.doShow),Object(Le["off"])(e,"mouseup",this.doClose),Object(Le["off"])(e,"mouseleave",this.handleMouseLeave),Object(Le["off"])(e,"mouseenter",this.handleMouseEnter),Object(Le["off"])(document,"click",this.handleDocumentClick)}},as=os,ss=s(as,is,rs,!1,null,null,null);ss.options.__file="packages/popover/src/main.vue";var ls=ss.exports,cs=function(e,t,n){var i=t.expression?t.value:t.arg,r=n.context.$refs[i];r&&(Array.isArray(r)?r[0].$refs.reference=e:r.$refs.reference=e)},us={bind:function(e,t,n){cs(e,t,n)},inserted:function(e,t,n){cs(e,t,n)}};Wi.a.directive("popover",us),ls.install=function(e){e.directive("popover",us),e.component(ls.name,ls)},ls.directive=us;var ds=ls,hs={name:"ElTooltip",mixins:[H.a],props:{openDelay:{type:Number,default:0},disabled:Boolean,manual:Boolean,effect:{type:String,default:"dark"},arrowOffset:{type:Number,default:0},popperClass:String,content:String,visibleArrow:{default:!0},transition:{type:String,default:"el-fade-in-linear"},popperOptions:{default:function(){return{boundariesPadding:10,gpuAcceleration:!1}}},enterable:{type:Boolean,default:!0},hideAfter:{type:Number,default:0},tabindex:{type:Number,default:0}},data:function(){return{tooltipId:"el-tooltip-"+Object(b["generateId"])(),timeoutPending:null,focusing:!1}},beforeCreate:function(){var e=this;this.$isServer||(this.popperVM=new Wi.a({data:{node:""},render:function(e){return this.node}}).$mount(),this.debounceClose=F()(200,(function(){return e.handleClosePopper()})))},render:function(e){var t=this;this.popperVM&&(this.popperVM.node=e("transition",{attrs:{name:this.transition},on:{afterLeave:this.doDestroy}},[e("div",{on:{mouseleave:function(){t.setExpectedState(!1),t.debounceClose()},mouseenter:function(){t.setExpectedState(!0)}},ref:"popper",attrs:{role:"tooltip",id:this.tooltipId,"aria-hidden":this.disabled||!this.showPopper?"true":"false"},directives:[{name:"show",value:!this.disabled&&this.showPopper}],class:["el-tooltip__popper","is-"+this.effect,this.popperClass]},[this.$slots.content||this.content])]));var n=this.getFirstElement();if(!n)return null;var i=n.data=n.data||{};return i.staticClass=this.addTooltipClass(i.staticClass),n},mounted:function(){var e=this;this.referenceElm=this.$el,1===this.$el.nodeType&&(this.$el.setAttribute("aria-describedby",this.tooltipId),this.$el.setAttribute("tabindex",this.tabindex),Object(Le["on"])(this.referenceElm,"mouseenter",this.show),Object(Le["on"])(this.referenceElm,"mouseleave",this.hide),Object(Le["on"])(this.referenceElm,"focus",(function(){if(e.$slots.default&&e.$slots.default.length){var t=e.$slots.default[0].componentInstance;t&&t.focus?t.focus():e.handleFocus()}else e.handleFocus()})),Object(Le["on"])(this.referenceElm,"blur",this.handleBlur),Object(Le["on"])(this.referenceElm,"click",this.removeFocusing)),this.value&&this.popperVM&&this.popperVM.$nextTick((function(){e.value&&e.updatePopper()}))},watch:{focusing:function(e){e?Object(Le["addClass"])(this.referenceElm,"focusing"):Object(Le["removeClass"])(this.referenceElm,"focusing")}},methods:{show:function(){this.setExpectedState(!0),this.handleShowPopper()},hide:function(){this.setExpectedState(!1),this.debounceClose()},handleFocus:function(){this.focusing=!0,this.show()},handleBlur:function(){this.focusing=!1,this.hide()},removeFocusing:function(){this.focusing=!1},addTooltipClass:function(e){return e?"el-tooltip "+e.replace("el-tooltip",""):"el-tooltip"},handleShowPopper:function(){var e=this;this.expectedState&&!this.manual&&(clearTimeout(this.timeout),this.timeout=setTimeout((function(){e.showPopper=!0}),this.openDelay),this.hideAfter>0&&(this.timeoutPending=setTimeout((function(){e.showPopper=!1}),this.hideAfter)))},handleClosePopper:function(){this.enterable&&this.expectedState||this.manual||(clearTimeout(this.timeout),this.timeoutPending&&clearTimeout(this.timeoutPending),this.showPopper=!1,this.disabled&&this.doDestroy())},setExpectedState:function(e){!1===e&&clearTimeout(this.timeoutPending),this.expectedState=e},getFirstElement:function(){var e=this.$slots.default;if(!Array.isArray(e))return null;for(var t=null,n=0;n0){Ds=Ts.shift();var t=Ds.options;for(var n in t)t.hasOwnProperty(n)&&(Es[n]=t[n]);void 0===t.callback&&(Es.callback=Ps);var i=Es.callback;Es.callback=function(t,n){i(t,n),e()},Object(ks["isVNode"])(Es.message)?(Es.$slots.default=[Es.message],Es.message=null):delete Es.$slots.default,["modal","showClose","closeOnClickModal","closeOnPressEscape","closeOnHashChange"].forEach((function(e){void 0===Es[e]&&(Es[e]=!0)})),document.body.appendChild(Es.$el),Wi.a.nextTick((function(){Es.visible=!0}))}},Ns=function e(t,n){if(!Wi.a.prototype.$isServer){if("string"===typeof t||Object(ks["isVNode"])(t)?(t={message:t},"string"===typeof arguments[1]&&(t.title=arguments[1])):t.callback&&!n&&(n=t.callback),"undefined"!==typeof Promise)return new Promise((function(i,r){Ts.push({options:St()({},Os,e.defaults,t),callback:n,resolve:i,reject:r}),Is()}));Ts.push({options:St()({},Os,e.defaults,t),callback:n}),Is()}};Ns.setDefaults=function(e){Ns.defaults=e},Ns.alert=function(e,t,n){return"object"===("undefined"===typeof t?"undefined":Ss(t))?(n=t,t=""):void 0===t&&(t=""),Ns(St()({title:t,message:e,$type:"alert",closeOnPressEscape:!1,closeOnClickModal:!1},n))},Ns.confirm=function(e,t,n){return"object"===("undefined"===typeof t?"undefined":Ss(t))?(n=t,t=""):void 0===t&&(t=""),Ns(St()({title:t,message:e,$type:"confirm",showCancelButton:!0},n))},Ns.prompt=function(e,t,n){return"object"===("undefined"===typeof t?"undefined":Ss(t))?(n=t,t=""):void 0===t&&(t=""),Ns(St()({title:t,message:e,showCancelButton:!0,showInput:!0,$type:"prompt"},n))},Ns.close=function(){Es.doClose(),Es.visible=!1,Ts=[],Ds=null};var js=Ns,As=js,Fs=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-breadcrumb",attrs:{"aria-label":"Breadcrumb",role:"navigation"}},[e._t("default")],2)},Ls=[];Fs._withStripped=!0;var Vs={name:"ElBreadcrumb",props:{separator:{type:String,default:"/"},separatorClass:{type:String,default:""}},provide:function(){return{elBreadcrumb:this}},mounted:function(){var e=this.$el.querySelectorAll(".el-breadcrumb__item");e.length&&e[e.length-1].setAttribute("aria-current","page")}},zs=Vs,Bs=s(zs,Fs,Ls,!1,null,null,null);Bs.options.__file="packages/breadcrumb/src/breadcrumb.vue";var Rs=Bs.exports;Rs.install=function(e){e.component(Rs.name,Rs)};var Hs=Rs,Ws=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("span",{staticClass:"el-breadcrumb__item"},[n("span",{ref:"link",class:["el-breadcrumb__inner",e.to?"is-link":""],attrs:{role:"link"}},[e._t("default")],2),e.separatorClass?n("i",{staticClass:"el-breadcrumb__separator",class:e.separatorClass}):n("span",{staticClass:"el-breadcrumb__separator",attrs:{role:"presentation"}},[e._v(e._s(e.separator))])])},qs=[];Ws._withStripped=!0;var Us={name:"ElBreadcrumbItem",props:{to:{},replace:Boolean},data:function(){return{separator:"",separatorClass:""}},inject:["elBreadcrumb"],mounted:function(){var e=this;this.separator=this.elBreadcrumb.separator,this.separatorClass=this.elBreadcrumb.separatorClass;var t=this.$refs.link;t.setAttribute("role","link"),t.addEventListener("click",(function(t){var n=e.to,i=e.$router;n&&i&&(e.replace?i.replace(n):i.push(n))}))}},Ys=Us,Ks=s(Ys,Ws,qs,!1,null,null,null);Ks.options.__file="packages/breadcrumb/src/breadcrumb-item.vue";var Gs=Ks.exports;Gs.install=function(e){e.component(Gs.name,Gs)};var Xs=Gs,Zs=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("form",{staticClass:"el-form",class:[e.labelPosition?"el-form--label-"+e.labelPosition:"",{"el-form--inline":e.inline}]},[e._t("default")],2)},Js=[];Zs._withStripped=!0;var Qs={name:"ElForm",componentName:"ElForm",provide:function(){return{elForm:this}},props:{model:Object,rules:Object,labelPosition:String,labelWidth:String,labelSuffix:{type:String,default:""},inline:Boolean,inlineMessage:Boolean,statusIcon:Boolean,showMessage:{type:Boolean,default:!0},size:String,disabled:Boolean,validateOnRuleChange:{type:Boolean,default:!0},hideRequiredAsterisk:{type:Boolean,default:!1}},watch:{rules:function(){this.fields.forEach((function(e){e.removeValidateEvents(),e.addValidateEvents()})),this.validateOnRuleChange&&this.validate((function(){}))}},computed:{autoLabelWidth:function(){if(!this.potentialLabelWidthArr.length)return 0;var e=Math.max.apply(Math,this.potentialLabelWidthArr);return e?e+"px":""}},data:function(){return{fields:[],potentialLabelWidthArr:[]}},created:function(){var e=this;this.$on("el.form.addField",(function(t){t&&e.fields.push(t)})),this.$on("el.form.removeField",(function(t){t.prop&&e.fields.splice(e.fields.indexOf(t),1)}))},methods:{resetFields:function(){this.model?this.fields.forEach((function(e){e.resetField()})):console.warn("[Element Warn][Form]model is required for resetFields to work.")},clearValidate:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=e.length?"string"===typeof e?this.fields.filter((function(t){return e===t.prop})):this.fields.filter((function(t){return e.indexOf(t.prop)>-1})):this.fields;t.forEach((function(e){e.clearValidate()}))},validate:function(e){var t=this;if(this.model){var n=void 0;"function"!==typeof e&&window.Promise&&(n=new window.Promise((function(t,n){e=function(e){e?t(e):n(e)}})));var i=!0,r=0;0===this.fields.length&&e&&e(!0);var o={};return this.fields.forEach((function(n){n.validate("",(function(n,a){n&&(i=!1),o=St()({},o,a),"function"===typeof e&&++r===t.fields.length&&e(i,o)}))})),n||void 0}console.warn("[Element Warn][Form]model is required for validate to work!")},validateField:function(e,t){e=[].concat(e);var n=this.fields.filter((function(t){return-1!==e.indexOf(t.prop)}));n.length?n.forEach((function(e){e.validate("",t)})):console.warn("[Element Warn]please pass correct props!")},getLabelWidthIndex:function(e){var t=this.potentialLabelWidthArr.indexOf(e);if(-1===t)throw new Error("[ElementForm]unpected width ",e);return t},registerLabelWidth:function(e,t){if(e&&t){var n=this.getLabelWidthIndex(t);this.potentialLabelWidthArr.splice(n,1,e)}else e&&this.potentialLabelWidthArr.push(e)},deregisterLabelWidth:function(e){var t=this.getLabelWidthIndex(e);this.potentialLabelWidthArr.splice(t,1)}}},el=Qs,tl=s(el,Zs,Js,!1,null,null,null);tl.options.__file="packages/form/src/form.vue";var nl=tl.exports;nl.install=function(e){e.component(nl.name,nl)};var il=nl,rl=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-form-item",class:[{"el-form-item--feedback":e.elForm&&e.elForm.statusIcon,"is-error":"error"===e.validateState,"is-validating":"validating"===e.validateState,"is-success":"success"===e.validateState,"is-required":e.isRequired||e.required,"is-no-asterisk":e.elForm&&e.elForm.hideRequiredAsterisk},e.sizeClass?"el-form-item--"+e.sizeClass:""]},[n("label-wrap",{attrs:{"is-auto-width":e.labelStyle&&"auto"===e.labelStyle.width,"update-all":"auto"===e.form.labelWidth}},[e.label||e.$slots.label?n("label",{staticClass:"el-form-item__label",style:e.labelStyle,attrs:{for:e.labelFor}},[e._t("label",[e._v(e._s(e.label+e.form.labelSuffix))])],2):e._e()]),n("div",{staticClass:"el-form-item__content",style:e.contentStyle},[e._t("default"),n("transition",{attrs:{name:"el-zoom-in-top"}},["error"===e.validateState&&e.showMessage&&e.form.showMessage?e._t("error",[n("div",{staticClass:"el-form-item__error",class:{"el-form-item__error--inline":"boolean"===typeof e.inlineMessage?e.inlineMessage:e.elForm&&e.elForm.inlineMessage||!1}},[e._v("\n "+e._s(e.validateMessage)+"\n ")])],{error:e.validateMessage}):e._e()],2)],2)],1)},ol=[];rl._withStripped=!0;var al,sl,ll=n(40),cl=n.n(ll),ul={props:{isAutoWidth:Boolean,updateAll:Boolean},inject:["elForm","elFormItem"],render:function(){var e=arguments[0],t=this.$slots.default;if(!t)return null;if(this.isAutoWidth){var n=this.elForm.autoLabelWidth,i={};if(n&&"auto"!==n){var r=parseInt(n,10)-this.computedWidth;r&&(i.marginLeft=r+"px")}return e("div",{class:"el-form-item__label-wrap",style:i},[t])}return t[0]},methods:{getLabelWidth:function(){if(this.$el&&this.$el.firstElementChild){var e=window.getComputedStyle(this.$el.firstElementChild).width;return Math.ceil(parseFloat(e))}return 0},updateLabelWidth:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"update";this.$slots.default&&this.isAutoWidth&&this.$el.firstElementChild&&("update"===e?this.computedWidth=this.getLabelWidth():"remove"===e&&this.elForm.deregisterLabelWidth(this.computedWidth))}},watch:{computedWidth:function(e,t){this.updateAll&&(this.elForm.registerLabelWidth(e,t),this.elFormItem.updateComputedLabelWidth(e))}},data:function(){return{computedWidth:0}},mounted:function(){this.updateLabelWidth("update")},updated:function(){this.updateLabelWidth("update")},beforeDestroy:function(){this.updateLabelWidth("remove")}},dl=ul,hl=s(dl,al,sl,!1,null,null,null);hl.options.__file="packages/form/src/label-wrap.vue";var fl=hl.exports,pl={name:"ElFormItem",componentName:"ElFormItem",mixins:[D.a],provide:function(){return{elFormItem:this}},inject:["elForm"],props:{label:String,labelWidth:String,prop:String,required:{type:Boolean,default:void 0},rules:[Object,Array],error:String,validateStatus:String,for:String,inlineMessage:{type:[String,Boolean],default:""},showMessage:{type:Boolean,default:!0},size:String},components:{LabelWrap:fl},watch:{error:{immediate:!0,handler:function(e){this.validateMessage=e,this.validateState=e?"error":""}},validateStatus:function(e){this.validateState=e}},computed:{labelFor:function(){return this.for||this.prop},labelStyle:function(){var e={};if("top"===this.form.labelPosition)return e;var t=this.labelWidth||this.form.labelWidth;return t&&(e.width=t),e},contentStyle:function(){var e={},t=this.label;if("top"===this.form.labelPosition||this.form.inline)return e;if(!t&&!this.labelWidth&&this.isNested)return e;var n=this.labelWidth||this.form.labelWidth;return"auto"===n?"auto"===this.labelWidth?e.marginLeft=this.computedLabelWidth:"auto"===this.form.labelWidth&&(e.marginLeft=this.elForm.autoLabelWidth):e.marginLeft=n,e},form:function(){var e=this.$parent,t=e.$options.componentName;while("ElForm"!==t)"ElFormItem"===t&&(this.isNested=!0),e=e.$parent,t=e.$options.componentName;return e},fieldValue:function(){var e=this.form.model;if(e&&this.prop){var t=this.prop;return-1!==t.indexOf(":")&&(t=t.replace(/:/,".")),Object(b["getPropByPath"])(e,t,!0).v}},isRequired:function(){var e=this.getRules(),t=!1;return e&&e.length&&e.every((function(e){return!e.required||(t=!0,!1)})),t},_formSize:function(){return this.elForm.size},elFormItemSize:function(){return this.size||this._formSize},sizeClass:function(){return this.elFormItemSize||(this.$ELEMENT||{}).size}},data:function(){return{validateState:"",validateMessage:"",validateDisabled:!1,validator:{},isNested:!1,computedLabelWidth:""}},methods:{validate:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:b["noop"];this.validateDisabled=!1;var i=this.getFilteredRule(e);if((!i||0===i.length)&&void 0===this.required)return n(),!0;this.validateState="validating";var r={};i&&i.length>0&&i.forEach((function(e){delete e.trigger})),r[this.prop]=i;var o=new cl.a(r),a={};a[this.prop]=this.fieldValue,o.validate(a,{firstFields:!0},(function(e,i){t.validateState=e?"error":"success",t.validateMessage=e?e[0].message:"",n(t.validateMessage,i),t.elForm&&t.elForm.$emit("validate",t.prop,!e,t.validateMessage||null)}))},clearValidate:function(){this.validateState="",this.validateMessage="",this.validateDisabled=!1},resetField:function(){var e=this;this.validateState="",this.validateMessage="";var t=this.form.model,n=this.fieldValue,i=this.prop;-1!==i.indexOf(":")&&(i=i.replace(/:/,"."));var r=Object(b["getPropByPath"])(t,i,!0);this.validateDisabled=!0,Array.isArray(n)?r.o[r.k]=[].concat(this.initialValue):r.o[r.k]=this.initialValue,this.$nextTick((function(){e.validateDisabled=!1})),this.broadcast("ElTimeSelect","fieldReset",this.initialValue)},getRules:function(){var e=this.form.rules,t=this.rules,n=void 0!==this.required?{required:!!this.required}:[],i=Object(b["getPropByPath"])(e,this.prop||"");return e=e?i.o[this.prop||""]||i.v:[],[].concat(t||e||[]).concat(n)},getFilteredRule:function(e){var t=this.getRules();return t.filter((function(t){return!t.trigger||""===e||(Array.isArray(t.trigger)?t.trigger.indexOf(e)>-1:t.trigger===e)})).map((function(e){return St()({},e)}))},onFieldBlur:function(){this.validate("blur")},onFieldChange:function(){this.validateDisabled?this.validateDisabled=!1:this.validate("change")},updateComputedLabelWidth:function(e){this.computedLabelWidth=e?e+"px":""},addValidateEvents:function(){var e=this.getRules();(e.length||void 0!==this.required)&&(this.$on("el.form.blur",this.onFieldBlur),this.$on("el.form.change",this.onFieldChange))},removeValidateEvents:function(){this.$off()}},mounted:function(){if(this.prop){this.dispatch("ElForm","el.form.addField",[this]);var e=this.fieldValue;Array.isArray(e)&&(e=[].concat(e)),Object.defineProperty(this,"initialValue",{value:e}),this.addValidateEvents()}},beforeDestroy:function(){this.dispatch("ElForm","el.form.removeField",[this])}},ml=pl,vl=s(ml,rl,ol,!1,null,null,null);vl.options.__file="packages/form/src/form-item.vue";var gl=vl.exports;gl.install=function(e){e.component(gl.name,gl)};var bl=gl,yl=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-tabs__active-bar",class:"is-"+e.rootTabs.tabPosition,style:e.barStyle})},_l=[];yl._withStripped=!0;var xl={name:"TabBar",props:{tabs:Array},inject:["rootTabs"],computed:{barStyle:{get:function(){var e=this,t={},n=0,i=0,r=-1!==["top","bottom"].indexOf(this.rootTabs.tabPosition)?"width":"height",o="width"===r?"x":"y",a=function(e){return e.toLowerCase().replace(/( |^)[a-z]/g,(function(e){return e.toUpperCase()}))};this.tabs.every((function(t,o){var s=Object(b["arrayFind"])(e.$parent.$refs.tabs||[],(function(e){return e.id.replace("tab-","")===t.paneName}));if(!s)return!1;if(t.active){i=s["client"+a(r)];var l=window.getComputedStyle(s);return"width"===r&&e.tabs.length>1&&(i-=parseFloat(l.paddingLeft)+parseFloat(l.paddingRight)),"width"===r&&(n+=parseFloat(l.paddingLeft)),!1}return n+=s["client"+a(r)],!0}));var s="translate"+a(o)+"("+n+"px)";return t[r]=i+"px",t.transform=s,t.msTransform=s,t.webkitTransform=s,t}}}},wl=xl,Cl=s(wl,yl,_l,!1,null,null,null);Cl.options.__file="packages/tabs/src/tab-bar.vue";var kl=Cl.exports;function Sl(){}var Ol,$l,Dl=function(e){return e.toLowerCase().replace(/( |^)[a-z]/g,(function(e){return e.toUpperCase()}))},El={name:"TabNav",components:{TabBar:kl},inject:["rootTabs"],props:{panes:Array,currentName:String,editable:Boolean,onTabClick:{type:Function,default:Sl},onTabRemove:{type:Function,default:Sl},type:String,stretch:Boolean},data:function(){return{scrollable:!1,navOffset:0,isFocus:!1,focusable:!0}},computed:{navStyle:function(){var e=-1!==["top","bottom"].indexOf(this.rootTabs.tabPosition)?"X":"Y";return{transform:"translate"+e+"(-"+this.navOffset+"px)"}},sizeName:function(){return-1!==["top","bottom"].indexOf(this.rootTabs.tabPosition)?"width":"height"}},methods:{scrollPrev:function(){var e=this.$refs.navScroll["offset"+Dl(this.sizeName)],t=this.navOffset;if(t){var n=t>e?t-e:0;this.navOffset=n}},scrollNext:function(){var e=this.$refs.nav["offset"+Dl(this.sizeName)],t=this.$refs.navScroll["offset"+Dl(this.sizeName)],n=this.navOffset;if(!(e-n<=t)){var i=e-n>2*t?n+t:e-t;this.navOffset=i}},scrollToActiveTab:function(){if(this.scrollable){var e=this.$refs.nav,t=this.$el.querySelector(".is-active");if(t){var n=this.$refs.navScroll,i=-1!==["top","bottom"].indexOf(this.rootTabs.tabPosition),r=t.getBoundingClientRect(),o=n.getBoundingClientRect(),a=i?e.offsetWidth-o.width:e.offsetHeight-o.height,s=this.navOffset,l=s;i?(r.lefto.right&&(l=s+r.right-o.right)):(r.topo.bottom&&(l=s+(r.bottom-o.bottom))),l=Math.max(l,0),this.navOffset=Math.min(l,a)}}},update:function(){if(this.$refs.nav){var e=this.sizeName,t=this.$refs.nav["offset"+Dl(e)],n=this.$refs.navScroll["offset"+Dl(e)],i=this.navOffset;if(n0&&(this.navOffset=0)}},changeTab:function(e){var t=e.keyCode,n=void 0,i=void 0,r=void 0;-1!==[37,38,39,40].indexOf(t)&&(r=e.currentTarget.querySelectorAll("[role=tab]"),i=Array.prototype.indexOf.call(r,e.target),n=37===t||38===t?0===i?r.length-1:i-1:i0&&void 0!==arguments[0]&&arguments[0];if(this.$slots.default){var n=this.$slots.default.filter((function(e){return e.tag&&e.componentOptions&&"ElTabPane"===e.componentOptions.Ctor.options.name})),i=n.map((function(e){var t=e.componentInstance;return t})),r=!(i.length===this.panes.length&&i.every((function(t,n){return t===e.panes[n]})));(t||r)&&(this.panes=i)}else 0!==this.panes.length&&(this.panes=[])},handleTabClick:function(e,t,n){e.disabled||(this.setCurrentName(t),this.$emit("tab-click",e,n))},handleTabRemove:function(e,t){e.disabled||(t.stopPropagation(),this.$emit("edit",e.name,"remove"),this.$emit("tab-remove",e.name))},handleTabAdd:function(){this.$emit("edit",null,"add"),this.$emit("tab-add")},setCurrentName:function(e){var t=this,n=function(){t.currentName=e,t.$emit("input",e)};if(this.currentName!==e&&this.beforeLeave){var i=this.beforeLeave(e,this.currentName);i&&i.then?i.then((function(){n(),t.$refs.nav&&t.$refs.nav.removeFocus()}),(function(){})):!1!==i&&n()}else n()}},render:function(e){var t,n=this.type,i=this.handleTabClick,r=this.handleTabRemove,o=this.handleTabAdd,a=this.currentName,s=this.panes,l=this.editable,c=this.addable,u=this.tabPosition,d=this.stretch,h=l||c?e("span",{class:"el-tabs__new-tab",on:{click:o,keydown:function(e){13===e.keyCode&&o()}},attrs:{tabindex:"0"}},[e("i",{class:"el-icon-plus"})]):null,f={props:{currentName:a,onTabClick:i,onTabRemove:r,editable:l,type:n,panes:s,stretch:d},ref:"nav"},p=e("div",{class:["el-tabs__header","is-"+u]},[h,e("tab-nav",f)]),m=e("div",{class:"el-tabs__content"},[this.$slots.default]);return e("div",{class:(t={"el-tabs":!0,"el-tabs--card":"card"===n},t["el-tabs--"+u]=!0,t["el-tabs--border-card"]="border-card"===n,t)},["bottom"!==u?[p,m]:[m,p]])},created:function(){this.currentName||this.setCurrentName("0"),this.$on("tab-nav-update",this.calcPaneInstances.bind(null,!0))},mounted:function(){this.calcPaneInstances()},updated:function(){this.calcPaneInstances()}},Al=jl,Fl=s(Al,Ml,Il,!1,null,null,null);Fl.options.__file="packages/tabs/src/tabs.vue";var Ll=Fl.exports;Ll.install=function(e){e.component(Ll.name,Ll)};var Vl=Ll,zl=function(){var e=this,t=e.$createElement,n=e._self._c||t;return!e.lazy||e.loaded||e.active?n("div",{directives:[{name:"show",rawName:"v-show",value:e.active,expression:"active"}],staticClass:"el-tab-pane",attrs:{role:"tabpanel","aria-hidden":!e.active,id:"pane-"+e.paneName,"aria-labelledby":"tab-"+e.paneName}},[e._t("default")],2):e._e()},Bl=[];zl._withStripped=!0;var Rl={name:"ElTabPane",componentName:"ElTabPane",props:{label:String,labelContent:Function,name:String,closable:Boolean,disabled:Boolean,lazy:Boolean},data:function(){return{index:null,loaded:!1}},computed:{isClosable:function(){return this.closable||this.$parent.closable},active:function(){var e=this.$parent.currentName===(this.name||this.index);return e&&(this.loaded=!0),e},paneName:function(){return this.name||this.index}},updated:function(){this.$parent.$emit("tab-nav-update")}},Hl=Rl,Wl=s(Hl,zl,Bl,!1,null,null,null);Wl.options.__file="packages/tabs/src/tab-pane.vue";var ql=Wl.exports;ql.install=function(e){e.component(ql.name,ql)};var Ul,Yl,Kl=ql,Gl={name:"ElTag",props:{text:String,closable:Boolean,type:String,hit:Boolean,disableTransitions:Boolean,color:String,size:String,effect:{type:String,default:"light",validator:function(e){return-1!==["dark","light","plain"].indexOf(e)}}},methods:{handleClose:function(e){e.stopPropagation(),this.$emit("close",e)},handleClick:function(e){this.$emit("click",e)}},computed:{tagSize:function(){return this.size||(this.$ELEMENT||{}).size}},render:function(e){var t=this.type,n=this.tagSize,i=this.hit,r=this.effect,o=["el-tag",t?"el-tag--"+t:"",n?"el-tag--"+n:"",r?"el-tag--"+r:"",i&&"is-hit"],a=e("span",{class:o,style:{backgroundColor:this.color},on:{click:this.handleClick}},[this.$slots.default,this.closable&&e("i",{class:"el-tag__close el-icon-close",on:{click:this.handleClose}})]);return this.disableTransitions?a:e("transition",{attrs:{name:"el-zoom-in-center"}},[a])}},Xl=Gl,Zl=s(Xl,Ul,Yl,!1,null,null,null);Zl.options.__file="packages/tag/src/tag.vue";var Jl=Zl.exports;Jl.install=function(e){e.component(Jl.name,Jl)};var Ql=Jl,ec=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-tree",class:{"el-tree--highlight-current":e.highlightCurrent,"is-dragging":!!e.dragState.draggingNode,"is-drop-not-allow":!e.dragState.allowDrop,"is-drop-inner":"inner"===e.dragState.dropType},attrs:{role:"tree"}},[e._l(e.root.childNodes,(function(t){return n("el-tree-node",{key:e.getNodeKey(t),attrs:{node:t,props:e.props,"render-after-expand":e.renderAfterExpand,"show-checkbox":e.showCheckbox,"render-content":e.renderContent},on:{"node-expand":e.handleNodeExpand}})})),e.isEmpty?n("div",{staticClass:"el-tree__empty-block"},[n("span",{staticClass:"el-tree__empty-text"},[e._v(e._s(e.emptyText))])]):e._e(),n("div",{directives:[{name:"show",rawName:"v-show",value:e.dragState.showDropIndicator,expression:"dragState.showDropIndicator"}],ref:"dropIndicator",staticClass:"el-tree__drop-indicator"})],2)},tc=[];ec._withStripped=!0;var nc="$treeNodeId",ic=function(e,t){t&&!t[nc]&&Object.defineProperty(t,nc,{value:e.id,enumerable:!1,configurable:!1,writable:!1})},rc=function(e,t){return e?t[e]:t[nc]},oc=function(e,t){var n=e;while(n&&"BODY"!==n.tagName){if(n.__vue__&&n.__vue__.$options.name===t)return n.__vue__;n=n.parentNode}return null},ac=function(){function e(e,t){for(var n=0;n0&&i.lazy&&i.defaultExpandAll&&this.expand(),Array.isArray(this.data)||ic(this,this.data),this.data){var a=i.defaultExpandedKeys,s=i.key;s&&a&&-1!==a.indexOf(this.key)&&this.expand(null,i.autoExpandParent),s&&void 0!==i.currentNodeKey&&this.key===i.currentNodeKey&&(i.currentNode=this,i.currentNode.isCurrent=!0),i.lazy&&i._initDefaultCheckedNode(this),this.updateLeafState()}}return e.prototype.setData=function(e){Array.isArray(e)||ic(this,e),this.data=e,this.childNodes=[];var t=void 0;t=0===this.level&&this.data instanceof Array?this.data:uc(this,"children")||[];for(var n=0,i=t.length;n1&&void 0!==arguments[1])||arguments[1],n=function n(i){for(var r=i.childNodes||[],o=!1,a=0,s=r.length;a-1&&t.splice(n,1);var i=this.childNodes.indexOf(e);i>-1&&(this.store&&this.store.deregisterNode(e),e.parent=null,this.childNodes.splice(i,1)),this.updateLeafState()},e.prototype.removeChildByData=function(e){for(var t=null,n=0;n0)i.expanded=!0,i=i.parent}n.expanded=!0,e&&e()};this.shouldLoadData()?this.loadData((function(e){e instanceof Array&&(n.checked?n.setChecked(!0,!0):n.store.checkStrictly||cc(n),i())})):i()},e.prototype.doCreateChildren=function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e.forEach((function(e){t.insertChild(St()({data:e},n),void 0,!0)}))},e.prototype.collapse=function(){this.expanded=!1},e.prototype.shouldLoadData=function(){return!0===this.store.lazy&&this.store.load&&!this.loaded},e.prototype.updateLeafState=function(){if(!0!==this.store.lazy||!0===this.loaded||"undefined"===typeof this.isLeafByUser){var e=this.childNodes;!this.store.lazy||!0===this.store.lazy&&!0===this.loaded?this.isLeaf=!e||0===e.length:this.isLeaf=!1}else this.isLeaf=this.isLeafByUser},e.prototype.setChecked=function(e,t,n,i){var r=this;if(this.indeterminate="half"===e,this.checked=!0===e,!this.store.checkStrictly){if(!this.shouldLoadData()||this.store.checkDescendants){var o=lc(this.childNodes),a=o.all,s=o.allWithoutDisable;this.isLeaf||a||!s||(this.checked=!1,e=!1);var l=function(){if(t){for(var n=r.childNodes,o=0,a=n.length;o0&&void 0!==arguments[0]&&arguments[0];if(0===this.level)return this.data;var t=this.data;if(!t)return null;var n=this.store.props,i="children";return n&&(i=n.children||"children"),void 0===t[i]&&(t[i]=null),e&&!t[i]&&(t[i]=[]),t[i]},e.prototype.updateChildren=function(){var e=this,t=this.getChildren()||[],n=this.childNodes.map((function(e){return e.data})),i={},r=[];t.forEach((function(e,t){var o=e[nc],a=!!o&&Object(b["arrayFindIndex"])(n,(function(e){return e[nc]===o}))>=0;a?i[o]={index:t,data:e}:r.push({index:t,data:e})})),this.store.lazy||n.forEach((function(t){i[t[nc]]||e.removeChildByData(t)})),r.forEach((function(t){var n=t.index,i=t.data;e.insertChild({data:i},n)})),this.updateLeafState()},e.prototype.loadData=function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!0!==this.store.lazy||!this.store.load||this.loaded||this.loading&&!Object.keys(n).length)e&&e.call(this);else{this.loading=!0;var i=function(i){t.loaded=!0,t.loading=!1,t.childNodes=[],t.doCreateChildren(i,n),t.updateLeafState(),e&&e.call(t,i)};this.store.load(this,i)}},ac(e,[{key:"label",get:function(){return uc(this,"label")}},{key:"key",get:function(){var e=this.store.key;return this.data?this.data[e]:null}},{key:"disabled",get:function(){return uc(this,"disabled")}},{key:"nextSibling",get:function(){var e=this.parent;if(e){var t=e.childNodes.indexOf(this);if(t>-1)return e.childNodes[t+1]}return null}},{key:"previousSibling",get:function(){var e=this.parent;if(e){var t=e.childNodes.indexOf(this);if(t>-1)return t>0?e.childNodes[t-1]:null}return null}}]),e}(),fc=hc,pc="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function mc(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var vc=function(){function e(t){var n=this;for(var i in mc(this,e),this.currentNode=null,this.currentNodeKey=null,t)t.hasOwnProperty(i)&&(this[i]=t[i]);if(this.nodesMap={},this.root=new fc({data:this.data,store:this}),this.lazy&&this.load){var r=this.load;r(this.root,(function(e){n.root.doCreateChildren(e),n._initDefaultCheckedNodes()}))}else this._initDefaultCheckedNodes()}return e.prototype.filter=function(e){var t=this.filterNodeMethod,n=this.lazy,i=function i(r){var o=r.root?r.root.childNodes:r.childNodes;if(o.forEach((function(n){n.visible=t.call(n,e,n.data,n),i(n)})),!r.visible&&o.length){var a=!0;a=!o.some((function(e){return e.visible})),r.root?r.root.visible=!1===a:r.visible=!1===a}e&&(!r.visible||r.isLeaf||n||r.expand())};i(this)},e.prototype.setData=function(e){var t=e!==this.root.data;t?(this.root.setData(e),this._initDefaultCheckedNodes()):this.root.updateChildren()},e.prototype.getNode=function(e){if(e instanceof fc)return e;var t="object"!==("undefined"===typeof e?"undefined":pc(e))?e:rc(this.key,e);return this.nodesMap[t]||null},e.prototype.insertBefore=function(e,t){var n=this.getNode(t);n.parent.insertBefore({data:e},n)},e.prototype.insertAfter=function(e,t){var n=this.getNode(t);n.parent.insertAfter({data:e},n)},e.prototype.remove=function(e){var t=this.getNode(e);t&&t.parent&&(t===this.currentNode&&(this.currentNode=null),t.parent.removeChild(t))},e.prototype.append=function(e,t){var n=t?this.getNode(t):this.root;n&&n.insertChild({data:e})},e.prototype._initDefaultCheckedNodes=function(){var e=this,t=this.defaultCheckedKeys||[],n=this.nodesMap;t.forEach((function(t){var i=n[t];i&&i.setChecked(!0,!e.checkStrictly)}))},e.prototype._initDefaultCheckedNode=function(e){var t=this.defaultCheckedKeys||[];-1!==t.indexOf(e.key)&&e.setChecked(!0,!this.checkStrictly)},e.prototype.setDefaultCheckedKey=function(e){e!==this.defaultCheckedKeys&&(this.defaultCheckedKeys=e,this._initDefaultCheckedNodes())},e.prototype.registerNode=function(e){var t=this.key;if(t&&e&&e.data){var n=e.key;void 0!==n&&(this.nodesMap[e.key]=e)}},e.prototype.deregisterNode=function(e){var t=this,n=this.key;n&&e&&e.data&&(e.childNodes.forEach((function(e){t.deregisterNode(e)})),delete this.nodesMap[e.key])},e.prototype.getCheckedNodes=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=[],i=function i(r){var o=r.root?r.root.childNodes:r.childNodes;o.forEach((function(r){(r.checked||t&&r.indeterminate)&&(!e||e&&r.isLeaf)&&n.push(r.data),i(r)}))};return i(this),n},e.prototype.getCheckedKeys=function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return this.getCheckedNodes(t).map((function(t){return(t||{})[e.key]}))},e.prototype.getHalfCheckedNodes=function(){var e=[],t=function t(n){var i=n.root?n.root.childNodes:n.childNodes;i.forEach((function(n){n.indeterminate&&e.push(n.data),t(n)}))};return t(this),e},e.prototype.getHalfCheckedKeys=function(){var e=this;return this.getHalfCheckedNodes().map((function(t){return(t||{})[e.key]}))},e.prototype._getAllNodes=function(){var e=[],t=this.nodesMap;for(var n in t)t.hasOwnProperty(n)&&e.push(t[n]);return e},e.prototype.updateChildren=function(e,t){var n=this.nodesMap[e];if(n){for(var i=n.childNodes,r=i.length-1;r>=0;r--){var o=i[r];this.remove(o.data)}for(var a=0,s=t.length;a1&&void 0!==arguments[1]&&arguments[1],n=arguments[2],i=this._getAllNodes().sort((function(e,t){return t.level-e.level})),r=Object.create(null),o=Object.keys(n);i.forEach((function(e){return e.setChecked(!1,!1)}));for(var a=0,s=i.length;a-1;if(u){var d=l.parent;while(d&&d.level>0)r[d.data[e]]=!0,d=d.parent;l.isLeaf||this.checkStrictly?l.setChecked(!0,!1):(l.setChecked(!0,!0),t&&function(){l.setChecked(!1,!1);var e=function e(t){var n=t.childNodes;n.forEach((function(t){t.isLeaf||t.setChecked(!1,!1),e(t)}))};e(l)}())}else l.checked&&!r[c]&&l.setChecked(!1,!1)}},e.prototype.setCheckedNodes=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=this.key,i={};e.forEach((function(e){i[(e||{})[n]]=!0})),this._setCheckedKeys(n,t,i)},e.prototype.setCheckedKeys=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];this.defaultCheckedKeys=e;var n=this.key,i={};e.forEach((function(e){i[e]=!0})),this._setCheckedKeys(n,t,i)},e.prototype.setDefaultExpandedKeys=function(e){var t=this;e=e||[],this.defaultExpandedKeys=e,e.forEach((function(e){var n=t.getNode(e);n&&n.expand(null,t.autoExpandParent)}))},e.prototype.setChecked=function(e,t,n){var i=this.getNode(e);i&&i.setChecked(!!t,n)},e.prototype.getCurrentNode=function(){return this.currentNode},e.prototype.setCurrentNode=function(e){var t=this.currentNode;t&&(t.isCurrent=!1),this.currentNode=e,this.currentNode.isCurrent=!0},e.prototype.setUserCurrentNode=function(e){var t=e[this.key],n=this.nodesMap[t];this.setCurrentNode(n)},e.prototype.setCurrentNodeKey=function(e){if(null===e||void 0===e)return this.currentNode&&(this.currentNode.isCurrent=!1),void(this.currentNode=null);var t=this.getNode(e);t&&this.setCurrentNode(t)},e}(),gc=vc,bc=function(){var e=this,t=this,n=t.$createElement,i=t._self._c||n;return i("div",{directives:[{name:"show",rawName:"v-show",value:t.node.visible,expression:"node.visible"}],ref:"node",staticClass:"el-tree-node",class:{"is-expanded":t.expanded,"is-current":t.node.isCurrent,"is-hidden":!t.node.visible,"is-focusable":!t.node.disabled,"is-checked":!t.node.disabled&&t.node.checked},attrs:{role:"treeitem",tabindex:"-1","aria-expanded":t.expanded,"aria-disabled":t.node.disabled,"aria-checked":t.node.checked,draggable:t.tree.draggable},on:{click:function(e){return e.stopPropagation(),t.handleClick(e)},contextmenu:function(t){return e.handleContextMenu(t)},dragstart:function(e){return e.stopPropagation(),t.handleDragStart(e)},dragover:function(e){return e.stopPropagation(),t.handleDragOver(e)},dragend:function(e){return e.stopPropagation(),t.handleDragEnd(e)},drop:function(e){return e.stopPropagation(),t.handleDrop(e)}}},[i("div",{staticClass:"el-tree-node__content",style:{"padding-left":(t.node.level-1)*t.tree.indent+"px"}},[i("span",{class:[{"is-leaf":t.node.isLeaf,expanded:!t.node.isLeaf&&t.expanded},"el-tree-node__expand-icon",t.tree.iconClass?t.tree.iconClass:"el-icon-caret-right"],on:{click:function(e){return e.stopPropagation(),t.handleExpandIconClick(e)}}}),t.showCheckbox?i("el-checkbox",{attrs:{indeterminate:t.node.indeterminate,disabled:!!t.node.disabled},on:{change:t.handleCheckChange},nativeOn:{click:function(e){e.stopPropagation()}},model:{value:t.node.checked,callback:function(e){t.$set(t.node,"checked",e)},expression:"node.checked"}}):t._e(),t.node.loading?i("span",{staticClass:"el-tree-node__loading-icon el-icon-loading"}):t._e(),i("node-content",{attrs:{node:t.node}})],1),i("el-collapse-transition",[!t.renderAfterExpand||t.childNodeRendered?i("div",{directives:[{name:"show",rawName:"v-show",value:t.expanded,expression:"expanded"}],staticClass:"el-tree-node__children",attrs:{role:"group","aria-expanded":t.expanded}},t._l(t.node.childNodes,(function(e){return i("el-tree-node",{key:t.getNodeKey(e),attrs:{"render-content":t.renderContent,"render-after-expand":t.renderAfterExpand,"show-checkbox":t.showCheckbox,node:e},on:{"node-expand":t.handleChildNodeExpand}})})),1):t._e()])],1)},yc=[];bc._withStripped=!0;var _c={name:"ElTreeNode",componentName:"ElTreeNode",mixins:[D.a],props:{node:{default:function(){return{}}},props:{},renderContent:Function,renderAfterExpand:{type:Boolean,default:!0},showCheckbox:{type:Boolean,default:!1}},components:{ElCollapseTransition:Ye.a,ElCheckbox:Ai.a,NodeContent:{props:{node:{required:!0}},render:function(e){var t=this.$parent,n=t.tree,i=this.node,r=i.data,o=i.store;return t.renderContent?t.renderContent.call(t._renderProxy,e,{_self:n.$vnode.context,node:i,data:r,store:o}):n.$scopedSlots.default?n.$scopedSlots.default({node:i,data:r}):e("span",{class:"el-tree-node__label"},[i.label])}}},data:function(){return{tree:null,expanded:!1,childNodeRendered:!1,oldChecked:null,oldIndeterminate:null}},watch:{"node.indeterminate":function(e){this.handleSelectChange(this.node.checked,e)},"node.checked":function(e){this.handleSelectChange(e,this.node.indeterminate)},"node.expanded":function(e){var t=this;this.$nextTick((function(){return t.expanded=e})),e&&(this.childNodeRendered=!0)}},methods:{getNodeKey:function(e){return rc(this.tree.nodeKey,e.data)},handleSelectChange:function(e,t){this.oldChecked!==e&&this.oldIndeterminate!==t&&this.tree.$emit("check-change",this.node.data,e,t),this.oldChecked=e,this.indeterminate=t},handleClick:function(){var e=this.tree.store;e.setCurrentNode(this.node),this.tree.$emit("current-change",e.currentNode?e.currentNode.data:null,e.currentNode),this.tree.currentNode=this,this.tree.expandOnClickNode&&this.handleExpandIconClick(),this.tree.checkOnClickNode&&!this.node.disabled&&this.handleCheckChange(null,{target:{checked:!this.node.checked}}),this.tree.$emit("node-click",this.node.data,this.node,this)},handleContextMenu:function(e){this.tree._events["node-contextmenu"]&&this.tree._events["node-contextmenu"].length>0&&(e.stopPropagation(),e.preventDefault()),this.tree.$emit("node-contextmenu",e,this.node.data,this.node,this)},handleExpandIconClick:function(){this.node.isLeaf||(this.expanded?(this.tree.$emit("node-collapse",this.node.data,this.node,this),this.node.collapse()):(this.node.expand(),this.$emit("node-expand",this.node.data,this.node,this)))},handleCheckChange:function(e,t){var n=this;this.node.setChecked(t.target.checked,!this.tree.checkStrictly),this.$nextTick((function(){var e=n.tree.store;n.tree.$emit("check",n.node.data,{checkedNodes:e.getCheckedNodes(),checkedKeys:e.getCheckedKeys(),halfCheckedNodes:e.getHalfCheckedNodes(),halfCheckedKeys:e.getHalfCheckedKeys()})}))},handleChildNodeExpand:function(e,t,n){this.broadcast("ElTreeNode","tree-node-expand",t),this.tree.$emit("node-expand",e,t,n)},handleDragStart:function(e){this.tree.draggable&&this.tree.$emit("tree-node-drag-start",e,this)},handleDragOver:function(e){this.tree.draggable&&(this.tree.$emit("tree-node-drag-over",e,this),e.preventDefault())},handleDrop:function(e){e.preventDefault()},handleDragEnd:function(e){this.tree.draggable&&this.tree.$emit("tree-node-drag-end",e,this)}},created:function(){var e=this,t=this.$parent;t.isTree?this.tree=t:this.tree=t.tree;var n=this.tree;n||console.warn("Can not find node's tree.");var i=n.props||{},r=i["children"]||"children";this.$watch("node.data."+r,(function(){e.node.updateChildren()})),this.node.expanded&&(this.expanded=!0,this.childNodeRendered=!0),this.tree.accordion&&this.$on("tree-node-expand",(function(t){e.node!==t&&e.node.collapse()}))}},xc=_c,wc=s(xc,bc,yc,!1,null,null,null);wc.options.__file="packages/tree/src/tree-node.vue";var Cc=wc.exports,kc={name:"ElTree",mixins:[D.a],components:{ElTreeNode:Cc},data:function(){return{store:null,root:null,currentNode:null,treeItems:null,checkboxItems:[],dragState:{showDropIndicator:!1,draggingNode:null,dropNode:null,allowDrop:!0}}},props:{data:{type:Array},emptyText:{type:String,default:function(){return Object(ti["t"])("el.tree.emptyText")}},renderAfterExpand:{type:Boolean,default:!0},nodeKey:String,checkStrictly:Boolean,defaultExpandAll:Boolean,expandOnClickNode:{type:Boolean,default:!0},checkOnClickNode:Boolean,checkDescendants:{type:Boolean,default:!1},autoExpandParent:{type:Boolean,default:!0},defaultCheckedKeys:Array,defaultExpandedKeys:Array,currentNodeKey:[String,Number],renderContent:Function,showCheckbox:{type:Boolean,default:!1},draggable:{type:Boolean,default:!1},allowDrag:Function,allowDrop:Function,props:{default:function(){return{children:"children",label:"label",disabled:"disabled"}}},lazy:{type:Boolean,default:!1},highlightCurrent:Boolean,load:Function,filterNodeMethod:Function,accordion:Boolean,indent:{type:Number,default:18},iconClass:String},computed:{children:{set:function(e){this.data=e},get:function(){return this.data}},treeItemArray:function(){return Array.prototype.slice.call(this.treeItems)},isEmpty:function(){var e=this.root.childNodes;return!e||0===e.length||e.every((function(e){var t=e.visible;return!t}))}},watch:{defaultCheckedKeys:function(e){this.store.setDefaultCheckedKey(e)},defaultExpandedKeys:function(e){this.store.defaultExpandedKeys=e,this.store.setDefaultExpandedKeys(e)},data:function(e){this.store.setData(e)},checkboxItems:function(e){Array.prototype.forEach.call(e,(function(e){e.setAttribute("tabindex",-1)}))},checkStrictly:function(e){this.store.checkStrictly=e}},methods:{filter:function(e){if(!this.filterNodeMethod)throw new Error("[Tree] filterNodeMethod is required when filter");this.store.filter(e)},getNodeKey:function(e){return rc(this.nodeKey,e.data)},getNodePath:function(e){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in getNodePath");var t=this.store.getNode(e);if(!t)return[];var n=[t.data],i=t.parent;while(i&&i!==this.root)n.push(i.data),i=i.parent;return n.reverse()},getCheckedNodes:function(e,t){return this.store.getCheckedNodes(e,t)},getCheckedKeys:function(e){return this.store.getCheckedKeys(e)},getCurrentNode:function(){var e=this.store.getCurrentNode();return e?e.data:null},getCurrentKey:function(){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in getCurrentKey");var e=this.getCurrentNode();return e?e[this.nodeKey]:null},setCheckedNodes:function(e,t){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in setCheckedNodes");this.store.setCheckedNodes(e,t)},setCheckedKeys:function(e,t){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in setCheckedKeys");this.store.setCheckedKeys(e,t)},setChecked:function(e,t,n){this.store.setChecked(e,t,n)},getHalfCheckedNodes:function(){return this.store.getHalfCheckedNodes()},getHalfCheckedKeys:function(){return this.store.getHalfCheckedKeys()},setCurrentNode:function(e){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in setCurrentNode");this.store.setUserCurrentNode(e)},setCurrentKey:function(e){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in setCurrentKey");this.store.setCurrentNodeKey(e)},getNode:function(e){return this.store.getNode(e)},remove:function(e){this.store.remove(e)},append:function(e,t){this.store.append(e,t)},insertBefore:function(e,t){this.store.insertBefore(e,t)},insertAfter:function(e,t){this.store.insertAfter(e,t)},handleNodeExpand:function(e,t,n){this.broadcast("ElTreeNode","tree-node-expand",t),this.$emit("node-expand",e,t,n)},updateKeyChildren:function(e,t){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in updateKeyChild");this.store.updateChildren(e,t)},initTabIndex:function(){this.treeItems=this.$el.querySelectorAll(".is-focusable[role=treeitem]"),this.checkboxItems=this.$el.querySelectorAll("input[type=checkbox]");var e=this.$el.querySelectorAll(".is-checked[role=treeitem]");e.length?e[0].setAttribute("tabindex",0):this.treeItems[0]&&this.treeItems[0].setAttribute("tabindex",0)},handleKeydown:function(e){var t=e.target;if(-1!==t.className.indexOf("el-tree-node")){var n=e.keyCode;this.treeItems=this.$el.querySelectorAll(".is-focusable[role=treeitem]");var i=this.treeItemArray.indexOf(t),r=void 0;[38,40].indexOf(n)>-1&&(e.preventDefault(),r=38===n?0!==i?i-1:0:i-1&&(e.preventDefault(),t.click());var o=t.querySelector('[type="checkbox"]');[13,32].indexOf(n)>-1&&o&&(e.preventDefault(),o.click())}}},created:function(){var e=this;this.isTree=!0,this.store=new gc({key:this.nodeKey,data:this.data,lazy:this.lazy,props:this.props,load:this.load,currentNodeKey:this.currentNodeKey,checkStrictly:this.checkStrictly,checkDescendants:this.checkDescendants,defaultCheckedKeys:this.defaultCheckedKeys,defaultExpandedKeys:this.defaultExpandedKeys,autoExpandParent:this.autoExpandParent,defaultExpandAll:this.defaultExpandAll,filterNodeMethod:this.filterNodeMethod}),this.root=this.store.root;var t=this.dragState;this.$on("tree-node-drag-start",(function(n,i){if("function"===typeof e.allowDrag&&!e.allowDrag(i.node))return n.preventDefault(),!1;n.dataTransfer.effectAllowed="move";try{n.dataTransfer.setData("text/plain","")}catch(r){}t.draggingNode=i,e.$emit("node-drag-start",i.node,n)})),this.$on("tree-node-drag-over",(function(n,i){var r=oc(n.target,"ElTreeNode"),o=t.dropNode;o&&o!==r&&Object(Le["removeClass"])(o.$el,"is-drop-inner");var a=t.draggingNode;if(a&&r){var s=!0,l=!0,c=!0,u=!0;"function"===typeof e.allowDrop&&(s=e.allowDrop(a.node,r.node,"prev"),u=l=e.allowDrop(a.node,r.node,"inner"),c=e.allowDrop(a.node,r.node,"next")),n.dataTransfer.dropEffect=l?"move":"none",(s||l||c)&&o!==r&&(o&&e.$emit("node-drag-leave",a.node,o.node,n),e.$emit("node-drag-enter",a.node,r.node,n)),(s||l||c)&&(t.dropNode=r),r.node.nextSibling===a.node&&(c=!1),r.node.previousSibling===a.node&&(s=!1),r.node.contains(a.node,!1)&&(l=!1),(a.node===r.node||a.node.contains(r.node))&&(s=!1,l=!1,c=!1);var d=r.$el.getBoundingClientRect(),h=e.$el.getBoundingClientRect(),f=void 0,p=s?l?.25:c?.45:1:-1,m=c?l?.75:s?.55:0:1,v=-9999,g=n.clientY-d.top;f=gd.height*m?"after":l?"inner":"none";var b=r.$el.querySelector(".el-tree-node__expand-icon").getBoundingClientRect(),y=e.$refs.dropIndicator;"before"===f?v=b.top-h.top:"after"===f&&(v=b.bottom-h.top),y.style.top=v+"px",y.style.left=b.right-h.left+"px","inner"===f?Object(Le["addClass"])(r.$el,"is-drop-inner"):Object(Le["removeClass"])(r.$el,"is-drop-inner"),t.showDropIndicator="before"===f||"after"===f,t.allowDrop=t.showDropIndicator||u,t.dropType=f,e.$emit("node-drag-over",a.node,r.node,n)}})),this.$on("tree-node-drag-end",(function(n){var i=t.draggingNode,r=t.dropType,o=t.dropNode;if(n.preventDefault(),n.dataTransfer.dropEffect="move",i&&o){var a={data:i.node.data};"none"!==r&&i.node.remove(),"before"===r?o.node.parent.insertBefore(a,o.node):"after"===r?o.node.parent.insertAfter(a,o.node):"inner"===r&&o.node.insertChild(a),"none"!==r&&e.store.registerNode(a),Object(Le["removeClass"])(o.$el,"is-drop-inner"),e.$emit("node-drag-end",i.node,o.node,r,n),"none"!==r&&e.$emit("node-drop",i.node,o.node,r,n)}i&&!o&&e.$emit("node-drag-end",i.node,null,r,n),t.showDropIndicator=!1,t.draggingNode=null,t.dropNode=null,t.allowDrop=!0}))},mounted:function(){this.initTabIndex(),this.$el.addEventListener("keydown",this.handleKeydown)},updated:function(){this.treeItems=this.$el.querySelectorAll("[role=treeitem]"),this.checkboxItems=this.$el.querySelectorAll("input[type=checkbox]")}},Sc=kc,Oc=s(Sc,ec,tc,!1,null,null,null);Oc.options.__file="packages/tree/src/tree.vue";var $c=Oc.exports;$c.install=function(e){e.component($c.name,$c)};var Dc=$c,Ec=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-alert-fade"}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-alert",class:[e.typeClass,e.center?"is-center":"","is-"+e.effect],attrs:{role:"alert"}},[e.showIcon?n("i",{staticClass:"el-alert__icon",class:[e.iconClass,e.isBigIcon]}):e._e(),n("div",{staticClass:"el-alert__content"},[e.title||e.$slots.title?n("span",{staticClass:"el-alert__title",class:[e.isBoldTitle]},[e._t("title",[e._v(e._s(e.title))])],2):e._e(),e.$slots.default&&!e.description?n("p",{staticClass:"el-alert__description"},[e._t("default")],2):e._e(),e.description&&!e.$slots.default?n("p",{staticClass:"el-alert__description"},[e._v(e._s(e.description))]):e._e(),n("i",{directives:[{name:"show",rawName:"v-show",value:e.closable,expression:"closable"}],staticClass:"el-alert__closebtn",class:{"is-customed":""!==e.closeText,"el-icon-close":""===e.closeText},on:{click:function(t){e.close()}}},[e._v(e._s(e.closeText))])])])])},Tc=[];Ec._withStripped=!0;var Pc={success:"el-icon-success",warning:"el-icon-warning",error:"el-icon-error"},Mc={name:"ElAlert",props:{title:{type:String,default:""},description:{type:String,default:""},type:{type:String,default:"info"},closable:{type:Boolean,default:!0},closeText:{type:String,default:""},showIcon:Boolean,center:Boolean,effect:{type:String,default:"light",validator:function(e){return-1!==["light","dark"].indexOf(e)}}},data:function(){return{visible:!0}},methods:{close:function(){this.visible=!1,this.$emit("close")}},computed:{typeClass:function(){return"el-alert--"+this.type},iconClass:function(){return Pc[this.type]||"el-icon-info"},isBigIcon:function(){return this.description||this.$slots.default?"is-big":""},isBoldTitle:function(){return this.description||this.$slots.default?"is-bold":""}}},Ic=Mc,Nc=s(Ic,Ec,Tc,!1,null,null,null);Nc.options.__file="packages/alert/src/main.vue";var jc=Nc.exports;jc.install=function(e){e.component(jc.name,jc)};var Ac=jc,Fc=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-notification-fade"}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],class:["el-notification",e.customClass,e.horizontalClass],style:e.positionStyle,attrs:{role:"alert"},on:{mouseenter:function(t){e.clearTimer()},mouseleave:function(t){e.startTimer()},click:e.click}},[e.type||e.iconClass?n("i",{staticClass:"el-notification__icon",class:[e.typeClass,e.iconClass]}):e._e(),n("div",{staticClass:"el-notification__group",class:{"is-with-icon":e.typeClass||e.iconClass}},[n("h2",{staticClass:"el-notification__title",domProps:{textContent:e._s(e.title)}}),n("div",{directives:[{name:"show",rawName:"v-show",value:e.message,expression:"message"}],staticClass:"el-notification__content"},[e._t("default",[e.dangerouslyUseHTMLString?n("p",{domProps:{innerHTML:e._s(e.message)}}):n("p",[e._v(e._s(e.message))])])],2),e.showClose?n("div",{staticClass:"el-notification__closeBtn el-icon-close",on:{click:function(t){return t.stopPropagation(),e.close(t)}}}):e._e()])])])},Lc=[];Fc._withStripped=!0;var Vc={success:"success",info:"info",warning:"warning",error:"error"},zc={data:function(){return{visible:!1,title:"",message:"",duration:4500,type:"",showClose:!0,customClass:"",iconClass:"",onClose:null,onClick:null,closed:!1,verticalOffset:0,timer:null,dangerouslyUseHTMLString:!1,position:"top-right"}},computed:{typeClass:function(){return this.type&&Vc[this.type]?"el-icon-"+Vc[this.type]:""},horizontalClass:function(){return this.position.indexOf("right")>-1?"right":"left"},verticalProperty:function(){return/^top-/.test(this.position)?"top":"bottom"},positionStyle:function(){var e;return e={},e[this.verticalProperty]=this.verticalOffset+"px",e}},watch:{closed:function(e){e&&(this.visible=!1,this.$el.addEventListener("transitionend",this.destroyElement))}},methods:{destroyElement:function(){this.$el.removeEventListener("transitionend",this.destroyElement),this.$destroy(!0),this.$el.parentNode.removeChild(this.$el)},click:function(){"function"===typeof this.onClick&&this.onClick()},close:function(){this.closed=!0,"function"===typeof this.onClose&&this.onClose()},clearTimer:function(){clearTimeout(this.timer)},startTimer:function(){var e=this;this.duration>0&&(this.timer=setTimeout((function(){e.closed||e.close()}),this.duration))},keydown:function(e){46===e.keyCode||8===e.keyCode?this.clearTimer():27===e.keyCode?this.closed||this.close():this.startTimer()}},mounted:function(){var e=this;this.duration>0&&(this.timer=setTimeout((function(){e.closed||e.close()}),this.duration)),document.addEventListener("keydown",this.keydown)},beforeDestroy:function(){document.removeEventListener("keydown",this.keydown)}},Bc=zc,Rc=s(Bc,Fc,Lc,!1,null,null,null);Rc.options.__file="packages/notification/src/main.vue";var Hc=Rc.exports,Wc=Wi.a.extend(Hc),qc=void 0,Uc=[],Yc=1,Kc=function e(t){if(!Wi.a.prototype.$isServer){t=St()({},t);var n=t.onClose,i="notification_"+Yc++,r=t.position||"top-right";t.onClose=function(){e.close(i,n)},qc=new Wc({data:t}),Object(ks["isVNode"])(t.message)&&(qc.$slots.default=[t.message],t.message="REPLACED_BY_VNODE"),qc.id=i,qc.$mount(),document.body.appendChild(qc.$el),qc.visible=!0,qc.dom=qc.$el,qc.dom.style.zIndex=C["PopupManager"].nextZIndex();var o=t.offset||0;return Uc.filter((function(e){return e.position===r})).forEach((function(e){o+=e.$el.offsetHeight+16})),o+=16,qc.verticalOffset=o,Uc.push(qc),qc}};["success","warning","info","error"].forEach((function(e){Kc[e]=function(t){return("string"===typeof t||Object(ks["isVNode"])(t))&&(t={message:t}),t.type=e,Kc(t)}})),Kc.close=function(e,t){var n=-1,i=Uc.length,r=Uc.filter((function(t,i){return t.id===e&&(n=i,!0)}))[0];if(r&&("function"===typeof t&&t(r),Uc.splice(n,1),!(i<=1)))for(var o=r.position,a=r.dom.offsetHeight,s=n;s=0;e--)Uc[e].close()};var Gc=Kc,Xc=Gc,Zc=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-slider",class:{"is-vertical":e.vertical,"el-slider--with-input":e.showInput},attrs:{role:"slider","aria-valuemin":e.min,"aria-valuemax":e.max,"aria-orientation":e.vertical?"vertical":"horizontal","aria-disabled":e.sliderDisabled}},[e.showInput&&!e.range?n("el-input-number",{ref:"input",staticClass:"el-slider__input",attrs:{step:e.step,disabled:e.sliderDisabled,controls:e.showInputControls,min:e.min,max:e.max,debounce:e.debounce,size:e.inputSize},on:{change:e.emitChange},model:{value:e.firstValue,callback:function(t){e.firstValue=t},expression:"firstValue"}}):e._e(),n("div",{ref:"slider",staticClass:"el-slider__runway",class:{"show-input":e.showInput,disabled:e.sliderDisabled},style:e.runwayStyle,on:{click:e.onSliderClick}},[n("div",{staticClass:"el-slider__bar",style:e.barStyle}),n("slider-button",{ref:"button1",attrs:{vertical:e.vertical,"tooltip-class":e.tooltipClass},model:{value:e.firstValue,callback:function(t){e.firstValue=t},expression:"firstValue"}}),e.range?n("slider-button",{ref:"button2",attrs:{vertical:e.vertical,"tooltip-class":e.tooltipClass},model:{value:e.secondValue,callback:function(t){e.secondValue=t},expression:"secondValue"}}):e._e(),e._l(e.stops,(function(t,i){return e.showStops?n("div",{key:i,staticClass:"el-slider__stop",style:e.getStopStyle(t)}):e._e()})),e.markList.length>0?[n("div",e._l(e.markList,(function(t,i){return n("div",{key:i,staticClass:"el-slider__stop el-slider__marks-stop",style:e.getStopStyle(t.position)})})),0),n("div",{staticClass:"el-slider__marks"},e._l(e.markList,(function(t,i){return n("slider-marker",{key:i,style:e.getStopStyle(t.position),attrs:{mark:t.mark}})})),1)]:e._e()],2)],1)},Jc=[];Zc._withStripped=!0;var Qc=n(41),eu=n.n(Qc),tu=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{ref:"button",staticClass:"el-slider__button-wrapper",class:{hover:e.hovering,dragging:e.dragging},style:e.wrapperStyle,attrs:{tabindex:"0"},on:{mouseenter:e.handleMouseEnter,mouseleave:e.handleMouseLeave,mousedown:e.onButtonDown,touchstart:e.onButtonDown,focus:e.handleMouseEnter,blur:e.handleMouseLeave,keydown:[function(t){return"button"in t||!e._k(t.keyCode,"left",37,t.key,["Left","ArrowLeft"])?"button"in t&&0!==t.button?null:e.onLeftKeyDown(t):null},function(t){return"button"in t||!e._k(t.keyCode,"right",39,t.key,["Right","ArrowRight"])?"button"in t&&2!==t.button?null:e.onRightKeyDown(t):null},function(t){return"button"in t||!e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"])?(t.preventDefault(),e.onLeftKeyDown(t)):null},function(t){return"button"in t||!e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"])?(t.preventDefault(),e.onRightKeyDown(t)):null}]}},[n("el-tooltip",{ref:"tooltip",attrs:{placement:"top","popper-class":e.tooltipClass,disabled:!e.showTooltip}},[n("span",{attrs:{slot:"content"},slot:"content"},[e._v(e._s(e.formatValue))]),n("div",{staticClass:"el-slider__button",class:{hover:e.hovering,dragging:e.dragging}})])],1)},nu=[];tu._withStripped=!0;var iu={name:"ElSliderButton",components:{ElTooltip:rt.a},props:{value:{type:Number,default:0},vertical:{type:Boolean,default:!1},tooltipClass:String},data:function(){return{hovering:!1,dragging:!1,isClick:!1,startX:0,currentX:0,startY:0,currentY:0,startPosition:0,newPosition:null,oldValue:this.value}},computed:{disabled:function(){return this.$parent.sliderDisabled},max:function(){return this.$parent.max},min:function(){return this.$parent.min},step:function(){return this.$parent.step},showTooltip:function(){return this.$parent.showTooltip},precision:function(){return this.$parent.precision},currentPosition:function(){return(this.value-this.min)/(this.max-this.min)*100+"%"},enableFormat:function(){return this.$parent.formatTooltip instanceof Function},formatValue:function(){return this.enableFormat&&this.$parent.formatTooltip(this.value)||this.value},wrapperStyle:function(){return this.vertical?{bottom:this.currentPosition}:{left:this.currentPosition}}},watch:{dragging:function(e){this.$parent.dragging=e}},methods:{displayTooltip:function(){this.$refs.tooltip&&(this.$refs.tooltip.showPopper=!0)},hideTooltip:function(){this.$refs.tooltip&&(this.$refs.tooltip.showPopper=!1)},handleMouseEnter:function(){this.hovering=!0,this.displayTooltip()},handleMouseLeave:function(){this.hovering=!1,this.hideTooltip()},onButtonDown:function(e){this.disabled||(e.preventDefault(),this.onDragStart(e),window.addEventListener("mousemove",this.onDragging),window.addEventListener("touchmove",this.onDragging),window.addEventListener("mouseup",this.onDragEnd),window.addEventListener("touchend",this.onDragEnd),window.addEventListener("contextmenu",this.onDragEnd))},onLeftKeyDown:function(){this.disabled||(this.newPosition=parseFloat(this.currentPosition)-this.step/(this.max-this.min)*100,this.setPosition(this.newPosition),this.$parent.emitChange())},onRightKeyDown:function(){this.disabled||(this.newPosition=parseFloat(this.currentPosition)+this.step/(this.max-this.min)*100,this.setPosition(this.newPosition),this.$parent.emitChange())},onDragStart:function(e){this.dragging=!0,this.isClick=!0,"touchstart"===e.type&&(e.clientY=e.touches[0].clientY,e.clientX=e.touches[0].clientX),this.vertical?this.startY=e.clientY:this.startX=e.clientX,this.startPosition=parseFloat(this.currentPosition),this.newPosition=this.startPosition},onDragging:function(e){if(this.dragging){this.isClick=!1,this.displayTooltip(),this.$parent.resetSize();var t=0;"touchmove"===e.type&&(e.clientY=e.touches[0].clientY,e.clientX=e.touches[0].clientX),this.vertical?(this.currentY=e.clientY,t=(this.startY-this.currentY)/this.$parent.sliderSize*100):(this.currentX=e.clientX,t=(this.currentX-this.startX)/this.$parent.sliderSize*100),this.newPosition=this.startPosition+t,this.setPosition(this.newPosition)}},onDragEnd:function(){var e=this;this.dragging&&(setTimeout((function(){e.dragging=!1,e.hideTooltip(),e.isClick||(e.setPosition(e.newPosition),e.$parent.emitChange())}),0),window.removeEventListener("mousemove",this.onDragging),window.removeEventListener("touchmove",this.onDragging),window.removeEventListener("mouseup",this.onDragEnd),window.removeEventListener("touchend",this.onDragEnd),window.removeEventListener("contextmenu",this.onDragEnd))},setPosition:function(e){var t=this;if(null!==e&&!isNaN(e)){e<0?e=0:e>100&&(e=100);var n=100/((this.max-this.min)/this.step),i=Math.round(e/n),r=i*n*(this.max-this.min)*.01+this.min;r=parseFloat(r.toFixed(this.precision)),this.$emit("input",r),this.$nextTick((function(){t.displayTooltip(),t.$refs.tooltip&&t.$refs.tooltip.updatePopper()})),this.dragging||this.value===this.oldValue||(this.oldValue=this.value)}}}},ru=iu,ou=s(ru,tu,nu,!1,null,null,null);ou.options.__file="packages/slider/src/button.vue";var au=ou.exports,su={name:"ElMarker",props:{mark:{type:[String,Object]}},render:function(){var e=arguments[0],t="string"===typeof this.mark?this.mark:this.mark.label;return e("div",{class:"el-slider__marks-text",style:this.mark.style||{}},[t])}},lu={name:"ElSlider",mixins:[D.a],inject:{elForm:{default:""}},props:{min:{type:Number,default:0},max:{type:Number,default:100},step:{type:Number,default:1},value:{type:[Number,Array],default:0},showInput:{type:Boolean,default:!1},showInputControls:{type:Boolean,default:!0},inputSize:{type:String,default:"small"},showStops:{type:Boolean,default:!1},showTooltip:{type:Boolean,default:!0},formatTooltip:Function,disabled:{type:Boolean,default:!1},range:{type:Boolean,default:!1},vertical:{type:Boolean,default:!1},height:{type:String},debounce:{type:Number,default:300},label:{type:String},tooltipClass:String,marks:Object},components:{ElInputNumber:eu.a,SliderButton:au,SliderMarker:su},data:function(){return{firstValue:null,secondValue:null,oldValue:null,dragging:!1,sliderSize:1}},watch:{value:function(e,t){this.dragging||Array.isArray(e)&&Array.isArray(t)&&e.every((function(e,n){return e===t[n]}))||this.setValues()},dragging:function(e){e||this.setValues()},firstValue:function(e){this.range?this.$emit("input",[this.minValue,this.maxValue]):this.$emit("input",e)},secondValue:function(){this.range&&this.$emit("input",[this.minValue,this.maxValue])},min:function(){this.setValues()},max:function(){this.setValues()}},methods:{valueChanged:function(){var e=this;return this.range?![this.minValue,this.maxValue].every((function(t,n){return t===e.oldValue[n]})):this.value!==this.oldValue},setValues:function(){if(this.min>this.max)console.error("[Element Error][Slider]min should not be greater than max.");else{var e=this.value;this.range&&Array.isArray(e)?e[1]this.max?this.$emit("input",[this.max,this.max]):e[0]this.max?this.$emit("input",[e[0],this.max]):(this.firstValue=e[0],this.secondValue=e[1],this.valueChanged()&&(this.dispatch("ElFormItem","el.form.change",[this.minValue,this.maxValue]),this.oldValue=e.slice())):this.range||"number"!==typeof e||isNaN(e)||(ethis.max?this.$emit("input",this.max):(this.firstValue=e,this.valueChanged()&&(this.dispatch("ElFormItem","el.form.change",e),this.oldValue=e)))}},setPosition:function(e){var t=this.min+e*(this.max-this.min)/100;if(this.range){var n=void 0;n=Math.abs(this.minValue-t)this.secondValue?"button1":"button2",this.$refs[n].setPosition(e)}else this.$refs.button1.setPosition(e)},onSliderClick:function(e){if(!this.sliderDisabled&&!this.dragging){if(this.resetSize(),this.vertical){var t=this.$refs.slider.getBoundingClientRect().bottom;this.setPosition((t-e.clientY)/this.sliderSize*100)}else{var n=this.$refs.slider.getBoundingClientRect().left;this.setPosition((e.clientX-n)/this.sliderSize*100)}this.emitChange()}},resetSize:function(){this.$refs.slider&&(this.sliderSize=this.$refs.slider["client"+(this.vertical?"Height":"Width")])},emitChange:function(){var e=this;this.$nextTick((function(){e.$emit("change",e.range?[e.minValue,e.maxValue]:e.value)}))},getStopStyle:function(e){return this.vertical?{bottom:e+"%"}:{left:e+"%"}}},computed:{stops:function(){var e=this;if(!this.showStops||this.min>this.max)return[];if(0===this.step)return[];for(var t=(this.max-this.min)/this.step,n=100*this.step/(this.max-this.min),i=[],r=1;r100*(e.maxValue-e.min)/(e.max-e.min)})):i.filter((function(t){return t>100*(e.firstValue-e.min)/(e.max-e.min)}))},markList:function(){var e=this;if(!this.marks)return[];var t=Object.keys(this.marks);return t.map(parseFloat).sort((function(e,t){return e-t})).filter((function(t){return t<=e.max&&t>=e.min})).map((function(t){return{point:t,position:100*(t-e.min)/(e.max-e.min),mark:e.marks[t]}}))},minValue:function(){return Math.min(this.firstValue,this.secondValue)},maxValue:function(){return Math.max(this.firstValue,this.secondValue)},barSize:function(){return this.range?100*(this.maxValue-this.minValue)/(this.max-this.min)+"%":100*(this.firstValue-this.min)/(this.max-this.min)+"%"},barStart:function(){return this.range?100*(this.minValue-this.min)/(this.max-this.min)+"%":"0%"},precision:function(){var e=[this.min,this.max,this.step].map((function(e){var t=(""+e).split(".")[1];return t?t.length:0}));return Math.max.apply(null,e)},runwayStyle:function(){return this.vertical?{height:this.height}:{}},barStyle:function(){return this.vertical?{height:this.barSize,bottom:this.barStart}:{width:this.barSize,left:this.barStart}},sliderDisabled:function(){return this.disabled||(this.elForm||{}).disabled}},mounted:function(){var e=void 0;this.range?(Array.isArray(this.value)?(this.firstValue=Math.max(this.min,this.value[0]),this.secondValue=Math.min(this.max,this.value[1])):(this.firstValue=this.min,this.secondValue=this.max),this.oldValue=[this.firstValue,this.secondValue],e=this.firstValue+"-"+this.secondValue):("number"!==typeof this.value||isNaN(this.value)?this.firstValue=this.min:this.firstValue=Math.min(this.max,Math.max(this.min,this.value)),this.oldValue=this.firstValue,e=this.firstValue),this.$el.setAttribute("aria-valuetext",e),this.$el.setAttribute("aria-label",this.label?this.label:"slider between "+this.min+" and "+this.max),this.resetSize(),window.addEventListener("resize",this.resetSize)},beforeDestroy:function(){window.removeEventListener("resize",this.resetSize)}},cu=lu,uu=s(cu,Zc,Jc,!1,null,null,null);uu.options.__file="packages/slider/src/main.vue";var du=uu.exports;du.install=function(e){e.component(du.name,du)};var hu=du,fu=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-loading-fade"},on:{"after-leave":e.handleAfterLeave}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-loading-mask",class:[e.customClass,{"is-fullscreen":e.fullscreen}],style:{backgroundColor:e.background||""}},[n("div",{staticClass:"el-loading-spinner"},[e.spinner?n("i",{class:e.spinner}):n("svg",{staticClass:"circular",attrs:{viewBox:"25 25 50 50"}},[n("circle",{staticClass:"path",attrs:{cx:"50",cy:"50",r:"20",fill:"none"}})]),e.text?n("p",{staticClass:"el-loading-text"},[e._v(e._s(e.text))]):e._e()])])])},pu=[];fu._withStripped=!0;var mu={data:function(){return{text:null,spinner:null,background:null,fullscreen:!0,visible:!1,customClass:""}},methods:{handleAfterLeave:function(){this.$emit("after-leave")},setText:function(e){this.text=e}}},vu=mu,gu=s(vu,fu,pu,!1,null,null,null);gu.options.__file="packages/loading/src/loading.vue";var bu=gu.exports,yu=n(31),_u=n.n(yu),xu=Wi.a.extend(bu),wu={install:function(e){if(!e.prototype.$isServer){var t=function(t,i){i.value?e.nextTick((function(){i.modifiers.fullscreen?(t.originalPosition=Object(Le["getStyle"])(document.body,"position"),t.originalOverflow=Object(Le["getStyle"])(document.body,"overflow"),t.maskStyle.zIndex=C["PopupManager"].nextZIndex(),Object(Le["addClass"])(t.mask,"is-fullscreen"),n(document.body,t,i)):(Object(Le["removeClass"])(t.mask,"is-fullscreen"),i.modifiers.body?(t.originalPosition=Object(Le["getStyle"])(document.body,"position"),["top","left"].forEach((function(e){var n="top"===e?"scrollTop":"scrollLeft";t.maskStyle[e]=t.getBoundingClientRect()[e]+document.body[n]+document.documentElement[n]-parseInt(Object(Le["getStyle"])(document.body,"margin-"+e),10)+"px"})),["height","width"].forEach((function(e){t.maskStyle[e]=t.getBoundingClientRect()[e]+"px"})),n(document.body,t,i)):(t.originalPosition=Object(Le["getStyle"])(t,"position"),n(t,t,i)))})):(_u()(t.instance,(function(e){if(t.instance.hiding){t.domVisible=!1;var n=i.modifiers.fullscreen||i.modifiers.body?document.body:t;Object(Le["removeClass"])(n,"el-loading-parent--relative"),Object(Le["removeClass"])(n,"el-loading-parent--hidden"),t.instance.hiding=!1}}),300,!0),t.instance.visible=!1,t.instance.hiding=!0)},n=function(t,n,i){n.domVisible||"none"===Object(Le["getStyle"])(n,"display")||"hidden"===Object(Le["getStyle"])(n,"visibility")?n.domVisible&&!0===n.instance.hiding&&(n.instance.visible=!0,n.instance.hiding=!1):(Object.keys(n.maskStyle).forEach((function(e){n.mask.style[e]=n.maskStyle[e]})),"absolute"!==n.originalPosition&&"fixed"!==n.originalPosition&&Object(Le["addClass"])(t,"el-loading-parent--relative"),i.modifiers.fullscreen&&i.modifiers.lock&&Object(Le["addClass"])(t,"el-loading-parent--hidden"),n.domVisible=!0,t.appendChild(n.mask),e.nextTick((function(){n.instance.hiding?n.instance.$emit("after-leave"):n.instance.visible=!0})),n.domInserted=!0)};e.directive("loading",{bind:function(e,n,i){var r=e.getAttribute("element-loading-text"),o=e.getAttribute("element-loading-spinner"),a=e.getAttribute("element-loading-background"),s=e.getAttribute("element-loading-custom-class"),l=i.context,c=new xu({el:document.createElement("div"),data:{text:l&&l[r]||r,spinner:l&&l[o]||o,background:l&&l[a]||a,customClass:l&&l[s]||s,fullscreen:!!n.modifiers.fullscreen}});e.instance=c,e.mask=c.$el,e.maskStyle={},n.value&&t(e,n)},update:function(e,n){e.instance.setText(e.getAttribute("element-loading-text")),n.oldValue!==n.value&&t(e,n)},unbind:function(e,n){e.domInserted&&(e.mask&&e.mask.parentNode&&e.mask.parentNode.removeChild(e.mask),t(e,{value:!1,modifiers:n.modifiers})),e.instance&&e.instance.$destroy()}})}}},Cu=wu,ku=Wi.a.extend(bu),Su={text:null,fullscreen:!0,body:!1,lock:!1,customClass:""},Ou=void 0;ku.prototype.originalPosition="",ku.prototype.originalOverflow="",ku.prototype.close=function(){var e=this;this.fullscreen&&(Ou=void 0),_u()(this,(function(t){var n=e.fullscreen||e.body?document.body:e.target;Object(Le["removeClass"])(n,"el-loading-parent--relative"),Object(Le["removeClass"])(n,"el-loading-parent--hidden"),e.$el&&e.$el.parentNode&&e.$el.parentNode.removeChild(e.$el),e.$destroy()}),300),this.visible=!1};var $u=function(e,t,n){var i={};e.fullscreen?(n.originalPosition=Object(Le["getStyle"])(document.body,"position"),n.originalOverflow=Object(Le["getStyle"])(document.body,"overflow"),i.zIndex=C["PopupManager"].nextZIndex()):e.body?(n.originalPosition=Object(Le["getStyle"])(document.body,"position"),["top","left"].forEach((function(t){var n="top"===t?"scrollTop":"scrollLeft";i[t]=e.target.getBoundingClientRect()[t]+document.body[n]+document.documentElement[n]+"px"})),["height","width"].forEach((function(t){i[t]=e.target.getBoundingClientRect()[t]+"px"}))):n.originalPosition=Object(Le["getStyle"])(t,"position"),Object.keys(i).forEach((function(e){n.$el.style[e]=i[e]}))},Du=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!Wi.a.prototype.$isServer){if(e=St()({},Su,e),"string"===typeof e.target&&(e.target=document.querySelector(e.target)),e.target=e.target||document.body,e.target!==document.body?e.fullscreen=!1:e.body=!0,e.fullscreen&&Ou)return Ou;var t=e.body?document.body:e.target,n=new ku({el:document.createElement("div"),data:e});return $u(e,t,n),"absolute"!==n.originalPosition&&"fixed"!==n.originalPosition&&Object(Le["addClass"])(t,"el-loading-parent--relative"),e.fullscreen&&e.lock&&Object(Le["addClass"])(t,"el-loading-parent--hidden"),t.appendChild(n.$el),Wi.a.nextTick((function(){n.visible=!0})),e.fullscreen&&(Ou=n),n}},Eu=Du,Tu={install:function(e){e.use(Cu),e.prototype.$loading=Eu},directive:Cu,service:Eu},Pu=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("i",{class:"el-icon-"+e.name})},Mu=[];Pu._withStripped=!0;var Iu={name:"ElIcon",props:{name:String}},Nu=Iu,ju=s(Nu,Pu,Mu,!1,null,null,null);ju.options.__file="packages/icon/src/icon.vue";var Au=ju.exports;Au.install=function(e){e.component(Au.name,Au)};var Fu=Au,Lu={name:"ElRow",componentName:"ElRow",props:{tag:{type:String,default:"div"},gutter:Number,type:String,justify:{type:String,default:"start"},align:{type:String,default:"top"}},computed:{style:function(){var e={};return this.gutter&&(e.marginLeft="-"+this.gutter/2+"px",e.marginRight=e.marginLeft),e}},render:function(e){return e(this.tag,{class:["el-row","start"!==this.justify?"is-justify-"+this.justify:"","top"!==this.align?"is-align-"+this.align:"",{"el-row--flex":"flex"===this.type}],style:this.style},this.$slots.default)},install:function(e){e.component(Lu.name,Lu)}},Vu=Lu,zu="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Bu={name:"ElCol",props:{span:{type:Number,default:24},tag:{type:String,default:"div"},offset:Number,pull:Number,push:Number,xs:[Number,Object],sm:[Number,Object],md:[Number,Object],lg:[Number,Object],xl:[Number,Object]},computed:{gutter:function(){var e=this.$parent;while(e&&"ElRow"!==e.$options.componentName)e=e.$parent;return e?e.gutter:0}},render:function(e){var t=this,n=[],i={};return this.gutter&&(i.paddingLeft=this.gutter/2+"px",i.paddingRight=i.paddingLeft),["span","offset","pull","push"].forEach((function(e){(t[e]||0===t[e])&&n.push("span"!==e?"el-col-"+e+"-"+t[e]:"el-col-"+t[e])})),["xs","sm","md","lg","xl"].forEach((function(e){if("number"===typeof t[e])n.push("el-col-"+e+"-"+t[e]);else if("object"===zu(t[e])){var i=t[e];Object.keys(i).forEach((function(t){n.push("span"!==t?"el-col-"+e+"-"+t+"-"+i[t]:"el-col-"+e+"-"+i[t])}))}})),e(this.tag,{class:["el-col",n],style:i},this.$slots.default)},install:function(e){e.component(Bu.name,Bu)}},Ru=Bu,Hu=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition-group",{class:["el-upload-list","el-upload-list--"+e.listType,{"is-disabled":e.disabled}],attrs:{tag:"ul",name:"el-list"}},e._l(e.files,(function(t){return n("li",{key:t.uid,class:["el-upload-list__item","is-"+t.status,e.focusing?"focusing":""],attrs:{tabindex:"0"},on:{keydown:function(n){if(!("button"in n)&&e._k(n.keyCode,"delete",[8,46],n.key,["Backspace","Delete","Del"]))return null;!e.disabled&&e.$emit("remove",t)},focus:function(t){e.focusing=!0},blur:function(t){e.focusing=!1},click:function(t){e.focusing=!1}}},[e._t("default",["uploading"!==t.status&&["picture-card","picture"].indexOf(e.listType)>-1?n("img",{staticClass:"el-upload-list__item-thumbnail",attrs:{src:t.url,alt:""}}):e._e(),n("a",{staticClass:"el-upload-list__item-name",on:{click:function(n){e.handleClick(t)}}},[n("i",{staticClass:"el-icon-document"}),e._v(e._s(t.name)+"\n ")]),n("label",{staticClass:"el-upload-list__item-status-label"},[n("i",{class:{"el-icon-upload-success":!0,"el-icon-circle-check":"text"===e.listType,"el-icon-check":["picture-card","picture"].indexOf(e.listType)>-1}})]),e.disabled?e._e():n("i",{staticClass:"el-icon-close",on:{click:function(n){e.$emit("remove",t)}}}),e.disabled?e._e():n("i",{staticClass:"el-icon-close-tip"},[e._v(e._s(e.t("el.upload.deleteTip")))]),"uploading"===t.status?n("el-progress",{attrs:{type:"picture-card"===e.listType?"circle":"line","stroke-width":"picture-card"===e.listType?6:2,percentage:e.parsePercentage(t.percentage)}}):e._e(),"picture-card"===e.listType?n("span",{staticClass:"el-upload-list__item-actions"},[e.handlePreview&&"picture-card"===e.listType?n("span",{staticClass:"el-upload-list__item-preview",on:{click:function(n){e.handlePreview(t)}}},[n("i",{staticClass:"el-icon-zoom-in"})]):e._e(),e.disabled?e._e():n("span",{staticClass:"el-upload-list__item-delete",on:{click:function(n){e.$emit("remove",t)}}},[n("i",{staticClass:"el-icon-delete"})])]):e._e()],{file:t})],2)})),0)},Wu=[];Hu._withStripped=!0;var qu=n(32),Uu=n.n(qu),Yu={name:"ElUploadList",mixins:[g.a],data:function(){return{focusing:!1}},components:{ElProgress:Uu.a},props:{files:{type:Array,default:function(){return[]}},disabled:{type:Boolean,default:!1},handlePreview:Function,listType:String},methods:{parsePercentage:function(e){return parseInt(e,10)},handleClick:function(e){this.handlePreview&&this.handlePreview(e)}}},Ku=Yu,Gu=s(Ku,Hu,Wu,!1,null,null,null);Gu.options.__file="packages/upload/src/upload-list.vue";var Xu=Gu.exports,Zu=n(24),Ju=n.n(Zu);function Qu(e,t,n){var i=void 0;i=n.response?""+(n.response.error||n.response):n.responseText?""+n.responseText:"fail to post "+e+" "+n.status;var r=new Error(i);return r.status=n.status,r.method="post",r.url=e,r}function ed(e){var t=e.responseText||e.response;if(!t)return t;try{return JSON.parse(t)}catch(n){return t}}function td(e){if("undefined"!==typeof XMLHttpRequest){var t=new XMLHttpRequest,n=e.action;t.upload&&(t.upload.onprogress=function(t){t.total>0&&(t.percent=t.loaded/t.total*100),e.onProgress(t)});var i=new FormData;e.data&&Object.keys(e.data).forEach((function(t){i.append(t,e.data[t])})),i.append(e.filename,e.file,e.file.name),t.onerror=function(t){e.onError(t)},t.onload=function(){if(t.status<200||t.status>=300)return e.onError(Qu(n,e,t));e.onSuccess(ed(t))},t.open("post",n,!0),e.withCredentials&&"withCredentials"in t&&(t.withCredentials=!0);var r=e.headers||{};for(var o in r)r.hasOwnProperty(o)&&null!==r[o]&&t.setRequestHeader(o,r[o]);return t.send(i),t}}var nd=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-upload-dragger",class:{"is-dragover":e.dragover},on:{drop:function(t){return t.preventDefault(),e.onDrop(t)},dragover:function(t){return t.preventDefault(),e.onDragover(t)},dragleave:function(t){t.preventDefault(),e.dragover=!1}}},[e._t("default")],2)},id=[];nd._withStripped=!0;var rd={name:"ElUploadDrag",props:{disabled:Boolean},inject:{uploader:{default:""}},data:function(){return{dragover:!1}},methods:{onDragover:function(){this.disabled||(this.dragover=!0)},onDrop:function(e){if(!this.disabled&&this.uploader){var t=this.uploader.accept;this.dragover=!1,t?this.$emit("file",[].slice.call(e.dataTransfer.files).filter((function(e){var n=e.type,i=e.name,r=i.indexOf(".")>-1?"."+i.split(".").pop():"",o=n.replace(/\/.*$/,"");return t.split(",").map((function(e){return e.trim()})).filter((function(e){return e})).some((function(e){return/\..+$/.test(e)?r===e:/\/\*$/.test(e)?o===e.replace(/\/\*$/,""):!!/^[^\/]+\/[^\/]+$/.test(e)&&n===e}))}))):this.$emit("file",e.dataTransfer.files)}}}},od=rd,ad=s(od,nd,id,!1,null,null,null);ad.options.__file="packages/upload/src/upload-dragger.vue";var sd,ld,cd=ad.exports,ud={inject:["uploader"],components:{UploadDragger:cd},props:{type:String,action:{type:String,required:!0},name:{type:String,default:"file"},data:Object,headers:Object,withCredentials:Boolean,multiple:Boolean,accept:String,onStart:Function,onProgress:Function,onSuccess:Function,onError:Function,beforeUpload:Function,drag:Boolean,onPreview:{type:Function,default:function(){}},onRemove:{type:Function,default:function(){}},fileList:Array,autoUpload:Boolean,listType:String,httpRequest:{type:Function,default:td},disabled:Boolean,limit:Number,onExceed:Function},data:function(){return{mouseover:!1,reqs:{}}},methods:{isImage:function(e){return-1!==e.indexOf("image")},handleChange:function(e){var t=e.target.files;t&&this.uploadFiles(t)},uploadFiles:function(e){var t=this;if(this.limit&&this.fileList.length+e.length>this.limit)this.onExceed&&this.onExceed(e,this.fileList);else{var n=Array.prototype.slice.call(e);this.multiple||(n=n.slice(0,1)),0!==n.length&&n.forEach((function(e){t.onStart(e),t.autoUpload&&t.upload(e)}))}},upload:function(e){var t=this;if(this.$refs.input.value=null,!this.beforeUpload)return this.post(e);var n=this.beforeUpload(e);n&&n.then?n.then((function(n){var i=Object.prototype.toString.call(n);if("[object File]"===i||"[object Blob]"===i){for(var r in"[object Blob]"===i&&(n=new File([n],e.name,{type:e.type})),e)e.hasOwnProperty(r)&&(n[r]=e[r]);t.post(n)}else t.post(e)}),(function(){t.onRemove(null,e)})):!1!==n?this.post(e):this.onRemove(null,e)},abort:function(e){var t=this.reqs;if(e){var n=e;e.uid&&(n=e.uid),t[n]&&t[n].abort()}else Object.keys(t).forEach((function(e){t[e]&&t[e].abort(),delete t[e]}))},post:function(e){var t=this,n=e.uid,i={headers:this.headers,withCredentials:this.withCredentials,file:e,data:this.data,filename:this.name,action:this.action,onProgress:function(n){t.onProgress(n,e)},onSuccess:function(i){t.onSuccess(i,e),delete t.reqs[n]},onError:function(i){t.onError(i,e),delete t.reqs[n]}},r=this.httpRequest(i);this.reqs[n]=r,r&&r.then&&r.then(i.onSuccess,i.onError)},handleClick:function(){this.disabled||(this.$refs.input.value=null,this.$refs.input.click())},handleKeydown:function(e){e.target===e.currentTarget&&(13!==e.keyCode&&32!==e.keyCode||this.handleClick())}},render:function(e){var t=this.handleClick,n=this.drag,i=this.name,r=this.handleChange,o=this.multiple,a=this.accept,s=this.listType,l=this.uploadFiles,c=this.disabled,u=this.handleKeydown,d={class:{"el-upload":!0},on:{click:t,keydown:u}};return d.class["el-upload--"+s]=!0,e("div",Ju()([d,{attrs:{tabindex:"0"}}]),[n?e("upload-dragger",{attrs:{disabled:c},on:{file:l}},[this.$slots.default]):this.$slots.default,e("input",{class:"el-upload__input",attrs:{type:"file",name:i,multiple:o,accept:a},ref:"input",on:{change:r}})])}},dd=ud,hd=s(dd,sd,ld,!1,null,null,null);hd.options.__file="packages/upload/src/upload.vue";var fd=hd.exports;function pd(){}var md,vd,gd={name:"ElUpload",mixins:[O.a],components:{ElProgress:Uu.a,UploadList:Xu,Upload:fd},provide:function(){return{uploader:this}},inject:{elForm:{default:""}},props:{action:{type:String,required:!0},headers:{type:Object,default:function(){return{}}},data:Object,multiple:Boolean,name:{type:String,default:"file"},drag:Boolean,dragger:Boolean,withCredentials:Boolean,showFileList:{type:Boolean,default:!0},accept:String,type:{type:String,default:"select"},beforeUpload:Function,beforeRemove:Function,onRemove:{type:Function,default:pd},onChange:{type:Function,default:pd},onPreview:{type:Function},onSuccess:{type:Function,default:pd},onProgress:{type:Function,default:pd},onError:{type:Function,default:pd},fileList:{type:Array,default:function(){return[]}},autoUpload:{type:Boolean,default:!0},listType:{type:String,default:"text"},httpRequest:Function,disabled:Boolean,limit:Number,onExceed:{type:Function,default:pd}},data:function(){return{uploadFiles:[],dragOver:!1,draging:!1,tempIndex:1}},computed:{uploadDisabled:function(){return this.disabled||(this.elForm||{}).disabled}},watch:{listType:function(e){"picture-card"!==e&&"picture"!==e||(this.uploadFiles=this.uploadFiles.map((function(e){if(!e.url&&e.raw)try{e.url=URL.createObjectURL(e.raw)}catch(t){console.error("[Element Error][Upload]",t)}return e})))},fileList:{immediate:!0,handler:function(e){var t=this;this.uploadFiles=e.map((function(e){return e.uid=e.uid||Date.now()+t.tempIndex++,e.status=e.status||"success",e}))}}},methods:{handleStart:function(e){e.uid=Date.now()+this.tempIndex++;var t={status:"ready",name:e.name,size:e.size,percentage:0,uid:e.uid,raw:e};if("picture-card"===this.listType||"picture"===this.listType)try{t.url=URL.createObjectURL(e)}catch(n){return void console.error("[Element Error][Upload]",n)}this.uploadFiles.push(t),this.onChange(t,this.uploadFiles)},handleProgress:function(e,t){var n=this.getFile(t);this.onProgress(e,n,this.uploadFiles),n.status="uploading",n.percentage=e.percent||0},handleSuccess:function(e,t){var n=this.getFile(t);n&&(n.status="success",n.response=e,this.onSuccess(e,n,this.uploadFiles),this.onChange(n,this.uploadFiles))},handleError:function(e,t){var n=this.getFile(t),i=this.uploadFiles;n.status="fail",i.splice(i.indexOf(n),1),this.onError(e,n,this.uploadFiles),this.onChange(n,this.uploadFiles)},handleRemove:function(e,t){var n=this;t&&(e=this.getFile(t));var i=function(){n.abort(e);var t=n.uploadFiles;t.splice(t.indexOf(e),1),n.onRemove(e,t)};if(this.beforeRemove){if("function"===typeof this.beforeRemove){var r=this.beforeRemove(e,this.uploadFiles);r&&r.then?r.then((function(){i()}),pd):!1!==r&&i()}}else i()},getFile:function(e){var t=this.uploadFiles,n=void 0;return t.every((function(t){return n=e.uid===t.uid?t:null,!n})),n},abort:function(e){this.$refs["upload-inner"].abort(e)},clearFiles:function(){this.uploadFiles=[]},submit:function(){var e=this;this.uploadFiles.filter((function(e){return"ready"===e.status})).forEach((function(t){e.$refs["upload-inner"].upload(t.raw)}))},getMigratingConfig:function(){return{props:{"default-file-list":"default-file-list is renamed to file-list.","show-upload-list":"show-upload-list is renamed to show-file-list.","thumbnail-mode":"thumbnail-mode has been deprecated, you can implement the same effect according to this case: http://element.eleme.io/#/zh-CN/component/upload#yong-hu-tou-xiang-shang-chuan"}}}},beforeDestroy:function(){this.uploadFiles.forEach((function(e){e.url&&0===e.url.indexOf("blob:")&&URL.revokeObjectURL(e.url)}))},render:function(e){var t=this,n=void 0;this.showFileList&&(n=e(Xu,{attrs:{disabled:this.uploadDisabled,listType:this.listType,files:this.uploadFiles,handlePreview:this.onPreview},on:{remove:this.handleRemove}},[function(e){if(t.$scopedSlots.file)return t.$scopedSlots.file({file:e.file})}]));var i={props:{type:this.type,drag:this.drag,action:this.action,multiple:this.multiple,"before-upload":this.beforeUpload,"with-credentials":this.withCredentials,headers:this.headers,name:this.name,data:this.data,accept:this.accept,fileList:this.uploadFiles,autoUpload:this.autoUpload,listType:this.listType,disabled:this.uploadDisabled,limit:this.limit,"on-exceed":this.onExceed,"on-start":this.handleStart,"on-progress":this.handleProgress,"on-success":this.handleSuccess,"on-error":this.handleError,"on-preview":this.onPreview,"on-remove":this.handleRemove,"http-request":this.httpRequest},ref:"upload-inner"},r=this.$slots.trigger||this.$slots.default,o=e("upload",i,[r]);return e("div",["picture-card"===this.listType?n:"",this.$slots.trigger?[o,this.$slots.default]:o,this.$slots.tip,"picture-card"!==this.listType?n:""])}},bd=gd,yd=s(bd,md,vd,!1,null,null,null);yd.options.__file="packages/upload/src/index.vue";var _d=yd.exports;_d.install=function(e){e.component(_d.name,_d)};var xd=_d,wd=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-progress",class:["el-progress--"+e.type,e.status?"is-"+e.status:"",{"el-progress--without-text":!e.showText,"el-progress--text-inside":e.textInside}],attrs:{role:"progressbar","aria-valuenow":e.percentage,"aria-valuemin":"0","aria-valuemax":"100"}},["line"===e.type?n("div",{staticClass:"el-progress-bar"},[n("div",{staticClass:"el-progress-bar__outer",style:{height:e.strokeWidth+"px"}},[n("div",{staticClass:"el-progress-bar__inner",style:e.barStyle},[e.showText&&e.textInside?n("div",{staticClass:"el-progress-bar__innerText"},[e._v(e._s(e.content))]):e._e()])])]):n("div",{staticClass:"el-progress-circle",style:{height:e.width+"px",width:e.width+"px"}},[n("svg",{attrs:{viewBox:"0 0 100 100"}},[n("path",{staticClass:"el-progress-circle__track",style:e.trailPathStyle,attrs:{d:e.trackPath,stroke:"#e5e9f2","stroke-width":e.relativeStrokeWidth,fill:"none"}}),n("path",{staticClass:"el-progress-circle__path",style:e.circlePathStyle,attrs:{d:e.trackPath,stroke:e.stroke,fill:"none","stroke-linecap":"round","stroke-width":e.percentage?e.relativeStrokeWidth:0}})])]),e.showText&&!e.textInside?n("div",{staticClass:"el-progress__text",style:{fontSize:e.progressTextSize+"px"}},[e.status?n("i",{class:e.iconClass}):[e._v(e._s(e.content))]],2):e._e()])},Cd=[];wd._withStripped=!0;var kd={name:"ElProgress",props:{type:{type:String,default:"line",validator:function(e){return["line","circle","dashboard"].indexOf(e)>-1}},percentage:{type:Number,default:0,required:!0,validator:function(e){return e>=0&&e<=100}},status:{type:String,validator:function(e){return["success","exception","warning"].indexOf(e)>-1}},strokeWidth:{type:Number,default:6},textInside:{type:Boolean,default:!1},width:{type:Number,default:126},showText:{type:Boolean,default:!0},color:{type:[String,Array,Function],default:""},format:Function},computed:{barStyle:function(){var e={};return e.width=this.percentage+"%",e.backgroundColor=this.getCurrentColor(this.percentage),e},relativeStrokeWidth:function(){return(this.strokeWidth/this.width*100).toFixed(1)},radius:function(){return"circle"===this.type||"dashboard"===this.type?parseInt(50-parseFloat(this.relativeStrokeWidth)/2,10):0},trackPath:function(){var e=this.radius,t="dashboard"===this.type;return"\n M 50 50\n m 0 "+(t?"":"-")+e+"\n a "+e+" "+e+" 0 1 1 0 "+(t?"-":"")+2*e+"\n a "+e+" "+e+" 0 1 1 0 "+(t?"":"-")+2*e+"\n "},perimeter:function(){return 2*Math.PI*this.radius},rate:function(){return"dashboard"===this.type?.75:1},strokeDashoffset:function(){var e=-1*this.perimeter*(1-this.rate)/2;return e+"px"},trailPathStyle:function(){return{strokeDasharray:this.perimeter*this.rate+"px, "+this.perimeter+"px",strokeDashoffset:this.strokeDashoffset}},circlePathStyle:function(){return{strokeDasharray:this.perimeter*this.rate*(this.percentage/100)+"px, "+this.perimeter+"px",strokeDashoffset:this.strokeDashoffset,transition:"stroke-dasharray 0.6s ease 0s, stroke 0.6s ease"}},stroke:function(){var e=void 0;if(this.color)e=this.getCurrentColor(this.percentage);else switch(this.status){case"success":e="#13ce66";break;case"exception":e="#ff4949";break;case"warning":e="#e6a23c";break;default:e="#20a0ff"}return e},iconClass:function(){return"warning"===this.status?"el-icon-warning":"line"===this.type?"success"===this.status?"el-icon-circle-check":"el-icon-circle-close":"success"===this.status?"el-icon-check":"el-icon-close"},progressTextSize:function(){return"line"===this.type?12+.4*this.strokeWidth:.111111*this.width+2},content:function(){return"function"===typeof this.format?this.format(this.percentage)||"":this.percentage+"%"}},methods:{getCurrentColor:function(e){return"function"===typeof this.color?this.color(e):"string"===typeof this.color?this.color:this.getLevelColor(e)},getLevelColor:function(e){for(var t=this.getColorArray().sort((function(e,t){return e.percentage-t.percentage})),n=0;ne)return t[n].color;return t[t.length-1].color},getColorArray:function(){var e=this.color,t=100/e.length;return e.map((function(e,n){return"string"===typeof e?{color:e,progress:(n+1)*t}:e}))}}},Sd=kd,Od=s(Sd,wd,Cd,!1,null,null,null);Od.options.__file="packages/progress/src/progress.vue";var $d=Od.exports;$d.install=function(e){e.component($d.name,$d)};var Dd=$d,Ed=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("span",{staticClass:"el-spinner"},[n("svg",{staticClass:"el-spinner-inner",style:{width:e.radius/2+"px",height:e.radius/2+"px"},attrs:{viewBox:"0 0 50 50"}},[n("circle",{staticClass:"path",attrs:{cx:"25",cy:"25",r:"20",fill:"none",stroke:e.strokeColor,"stroke-width":e.strokeWidth}})])])},Td=[];Ed._withStripped=!0;var Pd={name:"ElSpinner",props:{type:String,radius:{type:Number,default:100},strokeWidth:{type:Number,default:5},strokeColor:{type:String,default:"#efefef"}}},Md=Pd,Id=s(Md,Ed,Td,!1,null,null,null);Id.options.__file="packages/spinner/src/spinner.vue";var Nd=Id.exports;Nd.install=function(e){e.component(Nd.name,Nd)};var jd=Nd,Ad=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-message-fade"},on:{"after-leave":e.handleAfterLeave}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],class:["el-message",e.type&&!e.iconClass?"el-message--"+e.type:"",e.center?"is-center":"",e.showClose?"is-closable":"",e.customClass],style:e.positionStyle,attrs:{role:"alert"},on:{mouseenter:e.clearTimer,mouseleave:e.startTimer}},[e.iconClass?n("i",{class:e.iconClass}):n("i",{class:e.typeClass}),e._t("default",[e.dangerouslyUseHTMLString?n("p",{staticClass:"el-message__content",domProps:{innerHTML:e._s(e.message)}}):n("p",{staticClass:"el-message__content"},[e._v(e._s(e.message))])]),e.showClose?n("i",{staticClass:"el-message__closeBtn el-icon-close",on:{click:e.close}}):e._e()],2)])},Fd=[];Ad._withStripped=!0;var Ld={success:"success",info:"info",warning:"warning",error:"error"},Vd={data:function(){return{visible:!1,message:"",duration:3e3,type:"info",iconClass:"",customClass:"",onClose:null,showClose:!1,closed:!1,verticalOffset:20,timer:null,dangerouslyUseHTMLString:!1,center:!1}},computed:{typeClass:function(){return this.type&&!this.iconClass?"el-message__icon el-icon-"+Ld[this.type]:""},positionStyle:function(){return{top:this.verticalOffset+"px"}}},watch:{closed:function(e){e&&(this.visible=!1)}},methods:{handleAfterLeave:function(){this.$destroy(!0),this.$el.parentNode.removeChild(this.$el)},close:function(){this.closed=!0,"function"===typeof this.onClose&&this.onClose(this)},clearTimer:function(){clearTimeout(this.timer)},startTimer:function(){var e=this;this.duration>0&&(this.timer=setTimeout((function(){e.closed||e.close()}),this.duration))},keydown:function(e){27===e.keyCode&&(this.closed||this.close())}},mounted:function(){this.startTimer(),document.addEventListener("keydown",this.keydown)},beforeDestroy:function(){document.removeEventListener("keydown",this.keydown)}},zd=Vd,Bd=s(zd,Ad,Fd,!1,null,null,null);Bd.options.__file="packages/message/src/main.vue";var Rd=Bd.exports,Hd=Wi.a.extend(Rd),Wd=void 0,qd=[],Ud=1,Yd=function e(t){if(!Wi.a.prototype.$isServer){t=t||{},"string"===typeof t&&(t={message:t});var n=t.onClose,i="message_"+Ud++;t.onClose=function(){e.close(i,n)},Wd=new Hd({data:t}),Wd.id=i,Object(ks["isVNode"])(Wd.message)&&(Wd.$slots.default=[Wd.message],Wd.message=null),Wd.$mount(),document.body.appendChild(Wd.$el);var r=t.offset||20;return qd.forEach((function(e){r+=e.$el.offsetHeight+16})),Wd.verticalOffset=r,Wd.visible=!0,Wd.$el.style.zIndex=C["PopupManager"].nextZIndex(),qd.push(Wd),Wd}};["success","warning","info","error"].forEach((function(e){Yd[e]=function(t){return"string"===typeof t&&(t={message:t}),t.type=e,Yd(t)}})),Yd.close=function(e,t){for(var n=qd.length,i=-1,r=0;rqd.length-1))for(var o=qd[i].$el.offsetHeight,a=i;a=0;e--)qd[e].close()};var Kd=Yd,Gd=Kd,Xd=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-badge"},[e._t("default"),n("transition",{attrs:{name:"el-zoom-in-center"}},[n("sup",{directives:[{name:"show",rawName:"v-show",value:!e.hidden&&(e.content||0===e.content||e.isDot),expression:"!hidden && (content || content === 0 || isDot)"}],staticClass:"el-badge__content",class:["el-badge__content--"+e.type,{"is-fixed":e.$slots.default,"is-dot":e.isDot}],domProps:{textContent:e._s(e.content)}})])],2)},Zd=[];Xd._withStripped=!0;var Jd={name:"ElBadge",props:{value:[String,Number],max:Number,isDot:Boolean,hidden:Boolean,type:{type:String,validator:function(e){return["primary","success","warning","info","danger"].indexOf(e)>-1}}},computed:{content:function(){if(!this.isDot){var e=this.value,t=this.max;return"number"===typeof e&&"number"===typeof t&&t0&&e-1this.value,n=this.allowHalf&&this.pointerAtLeftHalf&&e-.5<=this.currentValue&&e>this.currentValue;return t||n},getIconStyle:function(e){var t=this.rateDisabled?this.disabledVoidColor:this.voidColor;return{color:e<=this.currentValue?this.activeColor:t}},selectValue:function(e){this.rateDisabled||(this.allowHalf&&this.pointerAtLeftHalf?(this.$emit("input",this.currentValue),this.$emit("change",this.currentValue)):(this.$emit("input",e),this.$emit("change",e)))},handleKey:function(e){if(!this.rateDisabled){var t=this.currentValue,n=e.keyCode;38===n||39===n?(this.allowHalf?t+=.5:t+=1,e.stopPropagation(),e.preventDefault()):37!==n&&40!==n||(this.allowHalf?t-=.5:t-=1,e.stopPropagation(),e.preventDefault()),t=t<0?0:t,t=t>this.max?this.max:t,this.$emit("input",t),this.$emit("change",t)}},setCurrentValue:function(e,t){if(!this.rateDisabled){if(this.allowHalf){var n=t.target;Object(Le["hasClass"])(n,"el-rate__item")&&(n=n.querySelector(".el-rate__icon")),Object(Le["hasClass"])(n,"el-rate__decimal")&&(n=n.parentNode),this.pointerAtLeftHalf=2*t.offsetX<=n.clientWidth,this.currentValue=this.pointerAtLeftHalf?e-.5:e}else this.currentValue=e;this.hoverIndex=e}},resetCurrentValue:function(){this.rateDisabled||(this.allowHalf&&(this.pointerAtLeftHalf=this.value!==Math.floor(this.value)),this.currentValue=this.value,this.hoverIndex=-1)}},created:function(){this.value||this.$emit("input",0)}},ph=fh,mh=s(ph,uh,dh,!1,null,null,null);mh.options.__file="packages/rate/src/main.vue";var vh=mh.exports;vh.install=function(e){e.component(vh.name,vh)};var gh=vh,bh=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-steps",class:[!e.simple&&"el-steps--"+e.direction,e.simple&&"el-steps--simple"]},[e._t("default")],2)},yh=[];bh._withStripped=!0;var _h={name:"ElSteps",mixins:[O.a],props:{space:[Number,String],active:Number,direction:{type:String,default:"horizontal"},alignCenter:Boolean,simple:Boolean,finishStatus:{type:String,default:"finish"},processStatus:{type:String,default:"process"}},data:function(){return{steps:[],stepOffset:0}},methods:{getMigratingConfig:function(){return{props:{center:"center is removed."}}}},watch:{active:function(e,t){this.$emit("change",e,t)},steps:function(e){e.forEach((function(e,t){e.index=t}))}}},xh=_h,wh=s(xh,bh,yh,!1,null,null,null);wh.options.__file="packages/steps/src/steps.vue";var Ch=wh.exports;Ch.install=function(e){e.component(Ch.name,Ch)};var kh=Ch,Sh=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-step",class:[!e.isSimple&&"is-"+e.$parent.direction,e.isSimple&&"is-simple",e.isLast&&!e.space&&!e.isCenter&&"is-flex",e.isCenter&&!e.isVertical&&!e.isSimple&&"is-center"],style:e.style},[n("div",{staticClass:"el-step__head",class:"is-"+e.currentStatus},[n("div",{staticClass:"el-step__line",style:e.isLast?"":{marginRight:e.$parent.stepOffset+"px"}},[n("i",{staticClass:"el-step__line-inner",style:e.lineStyle})]),n("div",{staticClass:"el-step__icon",class:"is-"+(e.icon?"icon":"text")},["success"!==e.currentStatus&&"error"!==e.currentStatus?e._t("icon",[e.icon?n("i",{staticClass:"el-step__icon-inner",class:[e.icon]}):e._e(),e.icon||e.isSimple?e._e():n("div",{staticClass:"el-step__icon-inner"},[e._v(e._s(e.index+1))])]):n("i",{staticClass:"el-step__icon-inner is-status",class:["el-icon-"+("success"===e.currentStatus?"check":"close")]})],2)]),n("div",{staticClass:"el-step__main"},[n("div",{ref:"title",staticClass:"el-step__title",class:["is-"+e.currentStatus]},[e._t("title",[e._v(e._s(e.title))])],2),e.isSimple?n("div",{staticClass:"el-step__arrow"}):n("div",{staticClass:"el-step__description",class:["is-"+e.currentStatus]},[e._t("description",[e._v(e._s(e.description))])],2)])])},Oh=[];Sh._withStripped=!0;var $h={name:"ElStep",props:{title:String,icon:String,description:String,status:String},data:function(){return{index:-1,lineStyle:{},internalStatus:""}},beforeCreate:function(){this.$parent.steps.push(this)},beforeDestroy:function(){var e=this.$parent.steps,t=e.indexOf(this);t>=0&&e.splice(t,1)},computed:{currentStatus:function(){return this.status||this.internalStatus},prevStatus:function(){var e=this.$parent.steps[this.index-1];return e?e.currentStatus:"wait"},isCenter:function(){return this.$parent.alignCenter},isVertical:function(){return"vertical"===this.$parent.direction},isSimple:function(){return this.$parent.simple},isLast:function(){var e=this.$parent;return e.steps[e.steps.length-1]===this},stepsCount:function(){return this.$parent.steps.length},space:function(){var e=this.isSimple,t=this.$parent.space;return e?"":t},style:function(){var e={},t=this.$parent,n=t.steps.length,i="number"===typeof this.space?this.space+"px":this.space?this.space:100/(n-(this.isCenter?0:1))+"%";return e.flexBasis=i,this.isVertical?e:(this.isLast?e.maxWidth=100/this.stepsCount+"%":e.marginRight=-this.$parent.stepOffset+"px",e)}},methods:{updateStatus:function(e){var t=this.$parent.$children[this.index-1];e>this.index?this.internalStatus=this.$parent.finishStatus:e===this.index&&"error"!==this.prevStatus?this.internalStatus=this.$parent.processStatus:this.internalStatus="wait",t&&t.calcProgress(this.internalStatus)},calcProgress:function(e){var t=100,n={};n.transitionDelay=150*this.index+"ms",e===this.$parent.processStatus?(this.currentStatus,t=0):"wait"===e&&(t=0,n.transitionDelay=-150*this.index+"ms"),n.borderWidth=t&&!this.isSimple?"1px":0,"vertical"===this.$parent.direction?n.height=t+"%":n.width=t+"%",this.lineStyle=n}},mounted:function(){var e=this,t=this.$watch("index",(function(n){e.$watch("$parent.active",e.updateStatus,{immediate:!0}),e.$watch("$parent.processStatus",(function(){var t=e.$parent.active;e.updateStatus(t)}),{immediate:!0}),t()}))}},Dh=$h,Eh=s(Dh,Sh,Oh,!1,null,null,null);Eh.options.__file="packages/steps/src/step.vue";var Th=Eh.exports;Th.install=function(e){e.component(Th.name,Th)};var Ph=Th,Mh=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:e.carouselClasses,on:{mouseenter:function(t){return t.stopPropagation(),e.handleMouseEnter(t)},mouseleave:function(t){return t.stopPropagation(),e.handleMouseLeave(t)}}},[n("div",{staticClass:"el-carousel__container",style:{height:e.height}},[e.arrowDisplay?n("transition",{attrs:{name:"carousel-arrow-left"}},[n("button",{directives:[{name:"show",rawName:"v-show",value:("always"===e.arrow||e.hover)&&(e.loop||e.activeIndex>0),expression:"(arrow === 'always' || hover) && (loop || activeIndex > 0)"}],staticClass:"el-carousel__arrow el-carousel__arrow--left",attrs:{type:"button"},on:{mouseenter:function(t){e.handleButtonEnter("left")},mouseleave:e.handleButtonLeave,click:function(t){t.stopPropagation(),e.throttledArrowClick(e.activeIndex-1)}}},[n("i",{staticClass:"el-icon-arrow-left"})])]):e._e(),e.arrowDisplay?n("transition",{attrs:{name:"carousel-arrow-right"}},[n("button",{directives:[{name:"show",rawName:"v-show",value:("always"===e.arrow||e.hover)&&(e.loop||e.activeIndex0}))},carouselClasses:function(){var e=["el-carousel","el-carousel--"+this.direction];return"card"===this.type&&e.push("el-carousel--card"),e},indicatorsClasses:function(){var e=["el-carousel__indicators","el-carousel__indicators--"+this.direction];return this.hasLabel&&e.push("el-carousel__indicators--labels"),"outside"!==this.indicatorPosition&&"card"!==this.type||e.push("el-carousel__indicators--outside"),e}},watch:{items:function(e){e.length>0&&this.setActiveItem(this.initialIndex)},activeIndex:function(e,t){this.resetItemPosition(t),t>-1&&this.$emit("change",e,t)},autoplay:function(e){e?this.startTimer():this.pauseTimer()},loop:function(){this.setActiveItem(this.activeIndex)}},methods:{handleMouseEnter:function(){this.hover=!0,this.pauseTimer()},handleMouseLeave:function(){this.hover=!1,this.startTimer()},itemInStage:function(e,t){var n=this.items.length;return t===n-1&&e.inStage&&this.items[0].active||e.inStage&&this.items[t+1]&&this.items[t+1].active?"left":!!(0===t&&e.inStage&&this.items[n-1].active||e.inStage&&this.items[t-1]&&this.items[t-1].active)&&"right"},handleButtonEnter:function(e){var t=this;"vertical"!==this.direction&&this.items.forEach((function(n,i){e===t.itemInStage(n,i)&&(n.hover=!0)}))},handleButtonLeave:function(){"vertical"!==this.direction&&this.items.forEach((function(e){e.hover=!1}))},updateItems:function(){this.items=this.$children.filter((function(e){return"ElCarouselItem"===e.$options.name}))},resetItemPosition:function(e){var t=this;this.items.forEach((function(n,i){n.translateItem(i,t.activeIndex,e)}))},playSlides:function(){this.activeIndex0&&(e=this.items.indexOf(t[0]))}if(e=Number(e),isNaN(e)||e!==Math.floor(e))console.warn("[Element Warn][Carousel]index must be an integer.");else{var n=this.items.length,i=this.activeIndex;this.activeIndex=e<0?this.loop?n-1:0:e>=n?this.loop?0:n-1:e,i===this.activeIndex&&this.resetItemPosition(i)}},prev:function(){this.setActiveItem(this.activeIndex-1)},next:function(){this.setActiveItem(this.activeIndex+1)},handleIndicatorClick:function(e){this.activeIndex=e},handleIndicatorHover:function(e){"hover"===this.trigger&&e!==this.activeIndex&&(this.activeIndex=e)}},created:function(){var e=this;this.throttledArrowClick=jh()(300,!0,(function(t){e.setActiveItem(t)})),this.throttledIndicatorHover=jh()(300,(function(t){e.handleIndicatorHover(t)}))},mounted:function(){var e=this;this.updateItems(),this.$nextTick((function(){Object(ei["addResizeListener"])(e.$el,e.resetItemPosition),e.initialIndex=0&&(e.activeIndex=e.initialIndex),e.startTimer()}))},beforeDestroy:function(){this.$el&&Object(ei["removeResizeListener"])(this.$el,this.resetItemPosition),this.pauseTimer()}},Fh=Ah,Lh=s(Fh,Mh,Ih,!1,null,null,null);Lh.options.__file="packages/carousel/src/main.vue";var Vh=Lh.exports;Vh.install=function(e){e.component(Vh.name,Vh)};var zh=Vh,Bh={vertical:{offset:"offsetHeight",scroll:"scrollTop",scrollSize:"scrollHeight",size:"height",key:"vertical",axis:"Y",client:"clientY",direction:"top"},horizontal:{offset:"offsetWidth",scroll:"scrollLeft",scrollSize:"scrollWidth",size:"width",key:"horizontal",axis:"X",client:"clientX",direction:"left"}};function Rh(e){var t=e.move,n=e.size,i=e.bar,r={},o="translate"+i.axis+"("+t+"%)";return r[i.size]=n,r.transform=o,r.msTransform=o,r.webkitTransform=o,r}var Hh={name:"Bar",props:{vertical:Boolean,size:String,move:Number},computed:{bar:function(){return Bh[this.vertical?"vertical":"horizontal"]},wrap:function(){return this.$parent.wrap}},render:function(e){var t=this.size,n=this.move,i=this.bar;return e("div",{class:["el-scrollbar__bar","is-"+i.key],on:{mousedown:this.clickTrackHandler}},[e("div",{ref:"thumb",class:"el-scrollbar__thumb",on:{mousedown:this.clickThumbHandler},style:Rh({size:t,move:n,bar:i})})])},methods:{clickThumbHandler:function(e){e.ctrlKey||2===e.button||(this.startDrag(e),this[this.bar.axis]=e.currentTarget[this.bar.offset]-(e[this.bar.client]-e.currentTarget.getBoundingClientRect()[this.bar.direction]))},clickTrackHandler:function(e){var t=Math.abs(e.target.getBoundingClientRect()[this.bar.direction]-e[this.bar.client]),n=this.$refs.thumb[this.bar.offset]/2,i=100*(t-n)/this.$el[this.bar.offset];this.wrap[this.bar.scroll]=i*this.wrap[this.bar.scrollSize]/100},startDrag:function(e){e.stopImmediatePropagation(),this.cursorDown=!0,Object(Le["on"])(document,"mousemove",this.mouseMoveDocumentHandler),Object(Le["on"])(document,"mouseup",this.mouseUpDocumentHandler),document.onselectstart=function(){return!1}},mouseMoveDocumentHandler:function(e){if(!1!==this.cursorDown){var t=this[this.bar.axis];if(t){var n=-1*(this.$el.getBoundingClientRect()[this.bar.direction]-e[this.bar.client]),i=this.$refs.thumb[this.bar.offset]-t,r=100*(n-i)/this.$el[this.bar.offset];this.wrap[this.bar.scroll]=r*this.wrap[this.bar.scrollSize]/100}}},mouseUpDocumentHandler:function(e){this.cursorDown=!1,this[this.bar.axis]=0,Object(Le["off"])(document,"mousemove",this.mouseMoveDocumentHandler),document.onselectstart=null}},destroyed:function(){Object(Le["off"])(document,"mouseup",this.mouseUpDocumentHandler)}},Wh={name:"ElScrollbar",components:{Bar:Hh},props:{native:Boolean,wrapStyle:{},wrapClass:{},viewClass:{},viewStyle:{},noresize:Boolean,tag:{type:String,default:"div"}},data:function(){return{sizeWidth:"0",sizeHeight:"0",moveX:0,moveY:0}},computed:{wrap:function(){return this.$refs.wrap}},render:function(e){var t=yr()(),n=this.wrapStyle;if(t){var i="-"+t+"px",r="margin-bottom: "+i+"; margin-right: "+i+";";Array.isArray(this.wrapStyle)?(n=Object(b["toObject"])(this.wrapStyle),n.marginRight=n.marginBottom=i):"string"===typeof this.wrapStyle?n+=r:n=r}var o=e(this.tag,{class:["el-scrollbar__view",this.viewClass],style:this.viewStyle,ref:"resize"},this.$slots.default),a=e("div",{ref:"wrap",style:n,on:{scroll:this.handleScroll},class:[this.wrapClass,"el-scrollbar__wrap",t?"":"el-scrollbar__wrap--hidden-default"]},[[o]]),s=void 0;return s=this.native?[e("div",{ref:"wrap",class:[this.wrapClass,"el-scrollbar__wrap"],style:n},[[o]])]:[a,e(Hh,{attrs:{move:this.moveX,size:this.sizeWidth}}),e(Hh,{attrs:{vertical:!0,move:this.moveY,size:this.sizeHeight}})],e("div",{class:"el-scrollbar"},s)},methods:{handleScroll:function(){var e=this.wrap;this.moveY=100*e.scrollTop/e.clientHeight,this.moveX=100*e.scrollLeft/e.clientWidth},update:function(){var e=void 0,t=void 0,n=this.wrap;n&&(e=100*n.clientHeight/n.scrollHeight,t=100*n.clientWidth/n.scrollWidth,this.sizeHeight=e<100?e+"%":"",this.sizeWidth=t<100?t+"%":"")}},mounted:function(){this.native||(this.$nextTick(this.update),!this.noresize&&Object(ei["addResizeListener"])(this.$refs.resize,this.update))},beforeDestroy:function(){this.native||!this.noresize&&Object(ei["removeResizeListener"])(this.$refs.resize,this.update)},install:function(e){e.component(Wh.name,Wh)}},qh=Wh,Uh=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"show",rawName:"v-show",value:e.ready,expression:"ready"}],staticClass:"el-carousel__item",class:{"is-active":e.active,"el-carousel__item--card":"card"===e.$parent.type,"is-in-stage":e.inStage,"is-hover":e.hover,"is-animating":e.animating},style:e.itemStyle,on:{click:e.handleItemClick}},["card"===e.$parent.type?n("div",{directives:[{name:"show",rawName:"v-show",value:!e.active,expression:"!active"}],staticClass:"el-carousel__mask"}):e._e(),e._t("default")],2)},Yh=[];Uh._withStripped=!0;var Kh=.83,Gh={name:"ElCarouselItem",props:{name:String,label:{type:[String,Number],default:""}},data:function(){return{hover:!1,translate:0,scale:1,active:!1,ready:!1,inStage:!1,animating:!1}},methods:{processIndex:function(e,t,n){return 0===t&&e===n-1?-1:t===n-1&&0===e?n:e=n/2?n+1:e>t+1&&e-t>=n/2?-2:e},calcCardTranslate:function(e,t){var n=this.$parent.$el.offsetWidth;return this.inStage?n*((2-Kh)*(e-t)+1)/4:e2&&this.$parent.loop&&(e=this.processIndex(e,t,o)),"card"===i)"vertical"===r&&console.warn("[Element Warn][Carousel]vertical directionis not supported in card mode"),this.inStage=Math.round(Math.abs(e-t))<=1,this.active=e===t,this.translate=this.calcCardTranslate(e,t),this.scale=this.active?1:Kh;else{this.active=e===t;var a="vertical"===r;this.translate=this.calcTranslate(e,t,a)}this.ready=!0},handleItemClick:function(){var e=this.$parent;if(e&&"card"===e.type){var t=e.items.indexOf(this);e.setActiveItem(t)}}},computed:{parentDirection:function(){return this.$parent.direction},itemStyle:function(){var e="vertical"===this.parentDirection?"translateY":"translateX",t=e+"("+this.translate+"px) scale("+this.scale+")",n={transform:t};return Object(b["autoprefixer"])(n)}},created:function(){this.$parent&&this.$parent.updateItems()},destroyed:function(){this.$parent&&this.$parent.updateItems()}},Xh=Gh,Zh=s(Xh,Uh,Yh,!1,null,null,null);Zh.options.__file="packages/carousel/src/item.vue";var Jh=Zh.exports;Jh.install=function(e){e.component(Jh.name,Jh)};var Qh=Jh,ef=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-collapse",attrs:{role:"tablist","aria-multiselectable":"true"}},[e._t("default")],2)},tf=[];ef._withStripped=!0;var nf={name:"ElCollapse",componentName:"ElCollapse",props:{accordion:Boolean,value:{type:[Array,String,Number],default:function(){return[]}}},data:function(){return{activeNames:[].concat(this.value)}},provide:function(){return{collapse:this}},watch:{value:function(e){this.activeNames=[].concat(e)}},methods:{setActiveNames:function(e){e=[].concat(e);var t=this.accordion?e[0]:e;this.activeNames=e,this.$emit("input",t),this.$emit("change",t)},handleItemClick:function(e){if(this.accordion)this.setActiveNames(!this.activeNames[0]&&0!==this.activeNames[0]||this.activeNames[0]!==e.name?e.name:"");else{var t=this.activeNames.slice(0),n=t.indexOf(e.name);n>-1?t.splice(n,1):t.push(e.name),this.setActiveNames(t)}}},created:function(){this.$on("item-click",this.handleItemClick)}},rf=nf,of=s(rf,ef,tf,!1,null,null,null);of.options.__file="packages/collapse/src/collapse.vue";var af=of.exports;af.install=function(e){e.component(af.name,af)};var sf=af,lf=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-collapse-item",class:{"is-active":e.isActive,"is-disabled":e.disabled}},[n("div",{attrs:{role:"tab","aria-expanded":e.isActive,"aria-controls":"el-collapse-content-"+e.id,"aria-describedby":"el-collapse-content-"+e.id}},[n("div",{staticClass:"el-collapse-item__header",class:{focusing:e.focusing,"is-active":e.isActive},attrs:{role:"button",id:"el-collapse-head-"+e.id,tabindex:e.disabled?void 0:0},on:{click:e.handleHeaderClick,keyup:function(t){return"button"in t||!e._k(t.keyCode,"space",32,t.key,[" ","Spacebar"])||!e._k(t.keyCode,"enter",13,t.key,"Enter")?(t.stopPropagation(),e.handleEnterClick(t)):null},focus:e.handleFocus,blur:function(t){e.focusing=!1}}},[e._t("title",[e._v(e._s(e.title))]),n("i",{staticClass:"el-collapse-item__arrow el-icon-arrow-right",class:{"is-active":e.isActive}})],2)]),n("el-collapse-transition",[n("div",{directives:[{name:"show",rawName:"v-show",value:e.isActive,expression:"isActive"}],staticClass:"el-collapse-item__wrap",attrs:{role:"tabpanel","aria-hidden":!e.isActive,"aria-labelledby":"el-collapse-head-"+e.id,id:"el-collapse-content-"+e.id}},[n("div",{staticClass:"el-collapse-item__content"},[e._t("default")],2)])])],1)},cf=[];lf._withStripped=!0;var uf={name:"ElCollapseItem",componentName:"ElCollapseItem",mixins:[D.a],components:{ElCollapseTransition:Ye.a},data:function(){return{contentWrapStyle:{height:"auto",display:"block"},contentHeight:0,focusing:!1,isClick:!1,id:Object(b["generateId"])()}},inject:["collapse"],props:{title:String,name:{type:[String,Number],default:function(){return this._uid}},disabled:Boolean},computed:{isActive:function(){return this.collapse.activeNames.indexOf(this.name)>-1}},methods:{handleFocus:function(){var e=this;setTimeout((function(){e.isClick?e.isClick=!1:e.focusing=!0}),50)},handleHeaderClick:function(){this.disabled||(this.dispatch("ElCollapse","item-click",this),this.focusing=!1,this.isClick=!0)},handleEnterClick:function(){this.dispatch("ElCollapse","item-click",this)}}},df=uf,hf=s(df,lf,cf,!1,null,null,null);hf.options.__file="packages/collapse/src/collapse-item.vue";var ff=hf.exports;ff.install=function(e){e.component(ff.name,ff)};var pf=ff,mf=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:function(){return e.toggleDropDownVisible(!1)},expression:"() => toggleDropDownVisible(false)"}],ref:"reference",class:["el-cascader",e.realSize&&"el-cascader--"+e.realSize,{"is-disabled":e.isDisabled}],on:{mouseenter:function(t){e.inputHover=!0},mouseleave:function(t){e.inputHover=!1},click:function(){return e.toggleDropDownVisible(!e.readonly||void 0)},keydown:e.handleKeyDown}},[n("el-input",{ref:"input",class:{"is-focus":e.dropDownVisible},attrs:{size:e.realSize,placeholder:e.placeholder,readonly:e.readonly,disabled:e.isDisabled,"validate-event":!1},on:{focus:e.handleFocus,blur:e.handleBlur,input:e.handleInput},model:{value:e.multiple?e.presentText:e.inputValue,callback:function(t){e.multiple?e.presentText:e.inputValue=t},expression:"multiple ? presentText : inputValue"}},[n("template",{slot:"suffix"},[e.clearBtnVisible?n("i",{key:"clear",staticClass:"el-input__icon el-icon-circle-close",on:{click:function(t){return t.stopPropagation(),e.handleClear(t)}}}):n("i",{key:"arrow-down",class:["el-input__icon","el-icon-arrow-down",e.dropDownVisible&&"is-reverse"],on:{click:function(t){t.stopPropagation(),e.toggleDropDownVisible()}}})])],2),e.multiple?n("div",{staticClass:"el-cascader__tags"},[e._l(e.presentTags,(function(t,i){return n("el-tag",{key:t.key,attrs:{type:"info",size:e.tagSize,hit:t.hitState,closable:t.closable,"disable-transitions":""},on:{close:function(t){e.deleteTag(i)}}},[n("span",[e._v(e._s(t.text))])])})),e.filterable&&!e.isDisabled?n("input",{directives:[{name:"model",rawName:"v-model.trim",value:e.inputValue,expression:"inputValue",modifiers:{trim:!0}}],staticClass:"el-cascader__search-input",attrs:{type:"text",placeholder:e.presentTags.length?"":e.placeholder},domProps:{value:e.inputValue},on:{input:[function(t){t.target.composing||(e.inputValue=t.target.value.trim())},function(t){return e.handleInput(e.inputValue,t)}],click:function(t){t.stopPropagation(),e.toggleDropDownVisible(!0)},keydown:function(t){return"button"in t||!e._k(t.keyCode,"delete",[8,46],t.key,["Backspace","Delete","Del"])?e.handleDelete(t):null},blur:function(t){e.$forceUpdate()}}}):e._e()],2):e._e(),n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":e.handleDropdownLeave}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.dropDownVisible,expression:"dropDownVisible"}],ref:"popper",class:["el-popper","el-cascader__dropdown",e.popperClass]},[n("el-cascader-panel",{directives:[{name:"show",rawName:"v-show",value:!e.filtering,expression:"!filtering"}],ref:"panel",attrs:{options:e.options,props:e.config,border:!1,"render-label":e.$scopedSlots.default},on:{"expand-change":e.handleExpandChange,close:function(t){e.toggleDropDownVisible(!1)}},model:{value:e.checkedValue,callback:function(t){e.checkedValue=t},expression:"checkedValue"}}),e.filterable?n("el-scrollbar",{directives:[{name:"show",rawName:"v-show",value:e.filtering,expression:"filtering"}],ref:"suggestionPanel",staticClass:"el-cascader__suggestion-panel",attrs:{tag:"ul","view-class":"el-cascader__suggestion-list"},nativeOn:{keydown:function(t){return e.handleSuggestionKeyDown(t)}}},[e.suggestions.length?e._l(e.suggestions,(function(t,i){return n("li",{key:t.uid,class:["el-cascader__suggestion-item",t.checked&&"is-checked"],attrs:{tabindex:-1},on:{click:function(t){e.handleSuggestionClick(i)}}},[n("span",[e._v(e._s(t.text))]),t.checked?n("i",{staticClass:"el-icon-check"}):e._e()])})):e._t("empty",[n("li",{staticClass:"el-cascader__empty-text"},[e._v(e._s(e.t("el.cascader.noMatch")))])])],2):e._e()],1)])],1)},vf=[];mf._withStripped=!0;var gf=n(42),bf=n.n(gf),yf=n(33),_f=n.n(yf),xf=_f.a.keys,wf={expandTrigger:{newProp:"expandTrigger",type:String},changeOnSelect:{newProp:"checkStrictly",type:Boolean},hoverThreshold:{newProp:"hoverThreshold",type:Number}},Cf={props:{placement:{type:String,default:"bottom-start"},appendToBody:H.a.props.appendToBody,visibleArrow:{type:Boolean,default:!0},arrowOffset:H.a.props.arrowOffset,offset:H.a.props.offset,boundariesPadding:H.a.props.boundariesPadding,popperOptions:H.a.props.popperOptions},methods:H.a.methods,data:H.a.data,beforeDestroy:H.a.beforeDestroy},kf={medium:36,small:32,mini:28},Sf={name:"ElCascader",directives:{Clickoutside:V.a},mixins:[Cf,D.a,g.a,O.a],inject:{elForm:{default:""},elFormItem:{default:""}},components:{ElInput:m.a,ElTag:Qn.a,ElScrollbar:q.a,ElCascaderPanel:bf.a},props:{value:{},options:Array,props:Object,size:String,placeholder:{type:String,default:function(){return Object(ti["t"])("el.cascader.placeholder")}},disabled:Boolean,clearable:Boolean,filterable:Boolean,filterMethod:Function,separator:{type:String,default:" / "},showAllLevels:{type:Boolean,default:!0},collapseTags:Boolean,debounce:{type:Number,default:300},beforeFilter:{type:Function,default:function(){return function(){}}},popperClass:String},data:function(){return{dropDownVisible:!1,checkedValue:this.value||null,inputHover:!1,inputValue:null,presentText:null,presentTags:[],checkedNodes:[],filtering:!1,suggestions:[],inputInitialHeight:0,pressDeleteCount:0}},computed:{realSize:function(){var e=(this.elFormItem||{}).elFormItemSize;return this.size||e||(this.$ELEMENT||{}).size},tagSize:function(){return["small","mini"].indexOf(this.realSize)>-1?"mini":"small"},isDisabled:function(){return this.disabled||(this.elForm||{}).disabled},config:function(){var e=this.props||{},t=this.$attrs;return Object.keys(wf).forEach((function(n){var i=wf[n],r=i.newProp,o=i.type,a=t[n]||t[Object(b["kebabCase"])(n)];Object(Ot["isDef"])(n)&&!Object(Ot["isDef"])(e[r])&&(o===Boolean&&""===a&&(a=!0),e[r]=a)})),e},multiple:function(){return this.config.multiple},leafOnly:function(){return!this.config.checkStrictly},readonly:function(){return!this.filterable||this.multiple},clearBtnVisible:function(){return!(!this.clearable||this.isDisabled||this.filtering||!this.inputHover)&&(this.multiple?!!this.checkedNodes.filter((function(e){return!e.isDisabled})).length:!!this.presentText)},panel:function(){return this.$refs.panel}},watch:{disabled:function(){this.computePresentContent()},value:function(e){Object(b["isEqual"])(e,this.checkedValue)||(this.checkedValue=e,this.computePresentContent())},checkedValue:function(e){var t=this.value,n=this.dropDownVisible,i=this.config,r=i.checkStrictly,o=i.multiple;Object(b["isEqual"])(e,t)&&!Object(hh["isUndefined"])(t)||(this.computePresentContent(),o||r||!n||this.toggleDropDownVisible(!1),this.$emit("input",e),this.$emit("change",e),this.dispatch("ElFormItem","el.form.change",[e]))},options:{handler:function(){this.$nextTick(this.computePresentContent)},deep:!0},presentText:function(e){this.inputValue=e},presentTags:function(e,t){this.multiple&&(e.length||t.length)&&this.$nextTick(this.updateStyle)},filtering:function(e){this.$nextTick(this.updatePopper)}},mounted:function(){var e=this,t=this.$refs.input;t&&t.$el&&(this.inputInitialHeight=t.$el.offsetHeight||kf[this.realSize]||40),Object(b["isEmpty"])(this.value)||this.computePresentContent(),this.filterHandler=F()(this.debounce,(function(){var t=e.inputValue;if(t){var n=e.beforeFilter(t);n&&n.then?n.then(e.getSuggestions):!1!==n?e.getSuggestions():e.filtering=!1}else e.filtering=!1})),Object(ei["addResizeListener"])(this.$el,this.updateStyle)},beforeDestroy:function(){Object(ei["removeResizeListener"])(this.$el,this.updateStyle)},methods:{getMigratingConfig:function(){return{props:{"expand-trigger":"expand-trigger is removed, use `props.expandTrigger` instead.","change-on-select":"change-on-select is removed, use `props.checkStrictly` instead.","hover-threshold":"hover-threshold is removed, use `props.hoverThreshold` instead"},events:{"active-item-change":"active-item-change is renamed to expand-change"}}},toggleDropDownVisible:function(e){var t=this;if(!this.isDisabled){var n=this.dropDownVisible,i=this.$refs.input;e=Object(Ot["isDef"])(e)?e:!n,e!==n&&(this.dropDownVisible=e,e&&this.$nextTick((function(){t.updatePopper(),t.panel.scrollIntoView()})),i.$refs.input.setAttribute("aria-expanded",e),this.$emit("visible-change",e))}},handleDropdownLeave:function(){this.filtering=!1,this.inputValue=this.presentText},handleKeyDown:function(e){switch(e.keyCode){case xf.enter:this.toggleDropDownVisible();break;case xf.down:this.toggleDropDownVisible(!0),this.focusFirstNode(),e.preventDefault();break;case xf.esc:case xf.tab:this.toggleDropDownVisible(!1);break}},handleFocus:function(e){this.$emit("focus",e)},handleBlur:function(e){this.$emit("blur",e)},handleInput:function(e,t){!this.dropDownVisible&&this.toggleDropDownVisible(!0),t&&t.isComposing||(e?this.filterHandler():this.filtering=!1)},handleClear:function(){this.presentText="",this.panel.clearCheckedNodes()},handleExpandChange:function(e){this.$nextTick(this.updatePopper.bind(this)),this.$emit("expand-change",e),this.$emit("active-item-change",e)},focusFirstNode:function(){var e=this;this.$nextTick((function(){var t=e.filtering,n=e.$refs,i=n.popper,r=n.suggestionPanel,o=null;if(t&&r)o=r.$el.querySelector(".el-cascader__suggestion-item");else{var a=i.querySelector(".el-cascader-menu");o=a.querySelector('.el-cascader-node[tabindex="-1"]')}o&&(o.focus(),!t&&o.click())}))},computePresentContent:function(){var e=this;this.$nextTick((function(){e.config.multiple?(e.computePresentTags(),e.presentText=e.presentTags.length?" ":null):e.computePresentText()}))},computePresentText:function(){var e=this.checkedValue,t=this.config;if(!Object(b["isEmpty"])(e)){var n=this.panel.getNodeByValue(e);if(n&&(t.checkStrictly||n.isLeaf))return void(this.presentText=n.getText(this.showAllLevels,this.separator))}this.presentText=null},computePresentTags:function(){var e=this.isDisabled,t=this.leafOnly,n=this.showAllLevels,i=this.separator,r=this.collapseTags,o=this.getCheckedNodes(t),a=[],s=function(t){return{node:t,key:t.uid,text:t.getText(n,i),hitState:!1,closable:!e&&!t.isDisabled}};if(o.length){var l=o[0],c=o.slice(1),u=c.length;a.push(s(l)),u&&(r?a.push({key:-1,text:"+ "+u,closable:!1}):c.forEach((function(e){return a.push(s(e))})))}this.checkedNodes=o,this.presentTags=a},getSuggestions:function(){var e=this,t=this.filterMethod;Object(hh["isFunction"])(t)||(t=function(e,t){return e.text.includes(t)});var n=this.panel.getFlattedNodes(this.leafOnly).filter((function(n){return!n.isDisabled&&(n.text=n.getText(e.showAllLevels,e.separator)||"",t(n,e.inputValue))}));this.multiple?this.presentTags.forEach((function(e){e.hitState=!1})):n.forEach((function(t){t.checked=Object(b["isEqual"])(e.checkedValue,t.getValueByOption())})),this.filtering=!0,this.suggestions=n,this.$nextTick(this.updatePopper)},handleSuggestionKeyDown:function(e){var t=e.keyCode,n=e.target;switch(t){case xf.enter:n.click();break;case xf.up:var i=n.previousElementSibling;i&&i.focus();break;case xf.down:var r=n.nextElementSibling;r&&r.focus();break;case xf.esc:case xf.tab:this.toggleDropDownVisible(!1);break}},handleDelete:function(){var e=this.inputValue,t=this.pressDeleteCount,n=this.presentTags,i=n.length-1,r=n[i];this.pressDeleteCount=e?0:t+1,r&&this.pressDeleteCount&&(r.hitState?this.deleteTag(i):r.hitState=!0)},handleSuggestionClick:function(e){var t=this.multiple,n=this.suggestions[e];if(t){var i=n.checked;n.doCheck(!i),this.panel.calculateMultiCheckedValue()}else this.checkedValue=n.getValueByOption(),this.toggleDropDownVisible(!1)},deleteTag:function(e){var t=this.checkedValue,n=t[e];this.checkedValue=t.filter((function(t,n){return n!==e})),this.$emit("remove-tag",n)},updateStyle:function(){var e=this.$el,t=this.inputInitialHeight;if(!this.$isServer&&e){var n=this.$refs.suggestionPanel,i=e.querySelector(".el-input__inner");if(i){var r=e.querySelector(".el-cascader__tags"),o=null;if(n&&(o=n.$el)){var a=o.querySelector(".el-cascader__suggestion-list");a.style.minWidth=i.offsetWidth+"px"}if(r){var s=r.offsetHeight,l=Math.max(s+6,t)+"px";i.style.height=l,this.updatePopper()}}}},getCheckedNodes:function(e){return this.panel.getCheckedNodes(e)}}},Of=Sf,$f=s(Of,mf,vf,!1,null,null,null);$f.options.__file="packages/cascader/src/cascader.vue";var Df=$f.exports;Df.install=function(e){e.component(Df.name,Df)};var Ef=Df,Tf=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.hide,expression:"hide"}],class:["el-color-picker",e.colorDisabled?"is-disabled":"",e.colorSize?"el-color-picker--"+e.colorSize:""]},[e.colorDisabled?n("div",{staticClass:"el-color-picker__mask"}):e._e(),n("div",{staticClass:"el-color-picker__trigger",on:{click:e.handleTrigger}},[n("span",{staticClass:"el-color-picker__color",class:{"is-alpha":e.showAlpha}},[n("span",{staticClass:"el-color-picker__color-inner",style:{backgroundColor:e.displayedColor}}),e.value||e.showPanelColor?e._e():n("span",{staticClass:"el-color-picker__empty el-icon-close"})]),n("span",{directives:[{name:"show",rawName:"v-show",value:e.value||e.showPanelColor,expression:"value || showPanelColor"}],staticClass:"el-color-picker__icon el-icon-arrow-down"})]),n("picker-dropdown",{ref:"dropdown",class:["el-color-picker__panel",e.popperClass||""],attrs:{color:e.color,"show-alpha":e.showAlpha,predefine:e.predefine},on:{pick:e.confirmValue,clear:e.clearValue},model:{value:e.showPicker,callback:function(t){e.showPicker=t},expression:"showPicker"}})],1)},Pf=[];Tf._withStripped=!0;var Mf="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function If(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var Nf=function(e,t,n){return[e,t*n/((e=(2-t)*n)<1?e:2-e)||0,e/2]},jf=function(e){return"string"===typeof e&&-1!==e.indexOf(".")&&1===parseFloat(e)},Af=function(e){return"string"===typeof e&&-1!==e.indexOf("%")},Ff=function(e,t){jf(e)&&(e="100%");var n=Af(e);return e=Math.min(t,Math.max(0,parseFloat(e))),n&&(e=parseInt(e*t,10)/100),Math.abs(e-t)<1e-6?1:e%t/parseFloat(t)},Lf={10:"A",11:"B",12:"C",13:"D",14:"E",15:"F"},Vf=function(e){var t=e.r,n=e.g,i=e.b,r=function(e){e=Math.min(Math.round(e),255);var t=Math.floor(e/16),n=e%16;return""+(Lf[t]||t)+(Lf[n]||n)};return isNaN(t)||isNaN(n)||isNaN(i)?"":"#"+r(t)+r(n)+r(i)},zf={A:10,B:11,C:12,D:13,E:14,F:15},Bf=function(e){return 2===e.length?16*(zf[e[0].toUpperCase()]||+e[0])+(zf[e[1].toUpperCase()]||+e[1]):zf[e[1].toUpperCase()]||+e[1]},Rf=function(e,t,n){t/=100,n/=100;var i=t,r=Math.max(n,.01),o=void 0,a=void 0;return n*=2,t*=n<=1?n:2-n,i*=r<=1?r:2-r,a=(n+t)/2,o=0===n?2*i/(r+i):2*t/(n+t),{h:e,s:100*o,v:100*a}},Hf=function(e,t,n){e=Ff(e,255),t=Ff(t,255),n=Ff(n,255);var i=Math.max(e,t,n),r=Math.min(e,t,n),o=void 0,a=void 0,s=i,l=i-r;if(a=0===i?0:l/i,i===r)o=0;else{switch(i){case e:o=(t-n)/l+(t2?parseFloat(e):parseInt(e,10)}));if(4===i.length?this._alpha=Math.floor(100*parseFloat(i[3])):3===i.length&&(this._alpha=100),i.length>=3){var r=Rf(i[0],i[1],i[2]),o=r.h,a=r.s,s=r.v;n(o,a,s)}}else if(-1!==e.indexOf("hsv")){var l=e.replace(/hsva|hsv|\(|\)/gm,"").split(/\s|,/g).filter((function(e){return""!==e})).map((function(e,t){return t>2?parseFloat(e):parseInt(e,10)}));4===l.length?this._alpha=Math.floor(100*parseFloat(l[3])):3===l.length&&(this._alpha=100),l.length>=3&&n(l[0],l[1],l[2])}else if(-1!==e.indexOf("rgb")){var c=e.replace(/rgba|rgb|\(|\)/gm,"").split(/\s|,/g).filter((function(e){return""!==e})).map((function(e,t){return t>2?parseFloat(e):parseInt(e,10)}));if(4===c.length?this._alpha=Math.floor(100*parseFloat(c[3])):3===c.length&&(this._alpha=100),c.length>=3){var u=Hf(c[0],c[1],c[2]),d=u.h,h=u.s,f=u.v;n(d,h,f)}}else if(-1!==e.indexOf("#")){var p=e.replace("#","").trim();if(!/^(?:[0-9a-fA-F]{3}){1,2}$/.test(p))return;var m=void 0,v=void 0,g=void 0;3===p.length?(m=Bf(p[0]+p[0]),v=Bf(p[1]+p[1]),g=Bf(p[2]+p[2])):6!==p.length&&8!==p.length||(m=Bf(p.substring(0,2)),v=Bf(p.substring(2,4)),g=Bf(p.substring(4,6))),8===p.length?this._alpha=Math.floor(Bf(p.substring(6))/255*100):3!==p.length&&6!==p.length||(this._alpha=100);var b=Hf(m,v,g),y=b.h,_=b.s,x=b.v;n(y,_,x)}},e.prototype.compare=function(e){return Math.abs(e._hue-this._hue)<2&&Math.abs(e._saturation-this._saturation)<1&&Math.abs(e._value-this._value)<1&&Math.abs(e._alpha-this._alpha)<1},e.prototype.doOnChange=function(){var e=this._hue,t=this._saturation,n=this._value,i=this._alpha,r=this.format;if(this.enableAlpha)switch(r){case"hsl":var o=Nf(e,t/100,n/100);this.value="hsla("+e+", "+Math.round(100*o[1])+"%, "+Math.round(100*o[2])+"%, "+i/100+")";break;case"hsv":this.value="hsva("+e+", "+Math.round(t)+"%, "+Math.round(n)+"%, "+i/100+")";break;default:var a=Wf(e,t,n),s=a.r,l=a.g,c=a.b;this.value="rgba("+s+", "+l+", "+c+", "+i/100+")"}else switch(r){case"hsl":var u=Nf(e,t/100,n/100);this.value="hsl("+e+", "+Math.round(100*u[1])+"%, "+Math.round(100*u[2])+"%)";break;case"hsv":this.value="hsv("+e+", "+Math.round(t)+"%, "+Math.round(n)+"%)";break;case"rgb":var d=Wf(e,t,n),h=d.r,f=d.g,p=d.b;this.value="rgb("+h+", "+f+", "+p+")";break;default:this.value=Vf(Wf(e,t,n))}},e}(),Uf=qf,Yf=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":e.doDestroy}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.showPopper,expression:"showPopper"}],staticClass:"el-color-dropdown"},[n("div",{staticClass:"el-color-dropdown__main-wrapper"},[n("hue-slider",{ref:"hue",staticStyle:{float:"right"},attrs:{color:e.color,vertical:""}}),n("sv-panel",{ref:"sl",attrs:{color:e.color}})],1),e.showAlpha?n("alpha-slider",{ref:"alpha",attrs:{color:e.color}}):e._e(),e.predefine?n("predefine",{attrs:{color:e.color,colors:e.predefine}}):e._e(),n("div",{staticClass:"el-color-dropdown__btns"},[n("span",{staticClass:"el-color-dropdown__value"},[n("el-input",{attrs:{"validate-event":!1,size:"mini"},on:{blur:e.handleConfirm},nativeOn:{keyup:function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.handleConfirm(t):null}},model:{value:e.customInput,callback:function(t){e.customInput=t},expression:"customInput"}})],1),n("el-button",{staticClass:"el-color-dropdown__link-btn",attrs:{size:"mini",type:"text"},on:{click:function(t){e.$emit("clear")}}},[e._v("\n "+e._s(e.t("el.colorpicker.clear"))+"\n ")]),n("el-button",{staticClass:"el-color-dropdown__btn",attrs:{plain:"",size:"mini"},on:{click:e.confirmValue}},[e._v("\n "+e._s(e.t("el.colorpicker.confirm"))+"\n ")])],1)],1)])},Kf=[];Yf._withStripped=!0;var Gf=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-color-svpanel",style:{backgroundColor:e.background}},[n("div",{staticClass:"el-color-svpanel__white"}),n("div",{staticClass:"el-color-svpanel__black"}),n("div",{staticClass:"el-color-svpanel__cursor",style:{top:e.cursorTop+"px",left:e.cursorLeft+"px"}},[n("div")])])},Xf=[];Gf._withStripped=!0;var Zf=!1,Jf=function(e,t){if(!Wi.a.prototype.$isServer){var n=function(e){t.drag&&t.drag(e)},i=function e(i){document.removeEventListener("mousemove",n),document.removeEventListener("mouseup",e),document.onselectstart=null,document.ondragstart=null,Zf=!1,t.end&&t.end(i)};e.addEventListener("mousedown",(function(e){Zf||(document.onselectstart=function(){return!1},document.ondragstart=function(){return!1},document.addEventListener("mousemove",n),document.addEventListener("mouseup",i),Zf=!0,t.start&&t.start(e))}))}},Qf={name:"el-sl-panel",props:{color:{required:!0}},computed:{colorValue:function(){var e=this.color.get("hue"),t=this.color.get("value");return{hue:e,value:t}}},watch:{colorValue:function(){this.update()}},methods:{update:function(){var e=this.color.get("saturation"),t=this.color.get("value"),n=this.$el,i=n.clientWidth,r=n.clientHeight;this.cursorLeft=e*i/100,this.cursorTop=(100-t)*r/100,this.background="hsl("+this.color.get("hue")+", 100%, 50%)"},handleDrag:function(e){var t=this.$el,n=t.getBoundingClientRect(),i=e.clientX-n.left,r=e.clientY-n.top;i=Math.max(0,i),i=Math.min(i,n.width),r=Math.max(0,r),r=Math.min(r,n.height),this.cursorLeft=i,this.cursorTop=r,this.color.set({saturation:i/n.width*100,value:100-r/n.height*100})}},mounted:function(){var e=this;Jf(this.$el,{drag:function(t){e.handleDrag(t)},end:function(t){e.handleDrag(t)}}),this.update()},data:function(){return{cursorTop:0,cursorLeft:0,background:"hsl(0, 100%, 50%)"}}},ep=Qf,tp=s(ep,Gf,Xf,!1,null,null,null);tp.options.__file="packages/color-picker/src/components/sv-panel.vue";var np=tp.exports,ip=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-color-hue-slider",class:{"is-vertical":e.vertical}},[n("div",{ref:"bar",staticClass:"el-color-hue-slider__bar",on:{click:e.handleClick}}),n("div",{ref:"thumb",staticClass:"el-color-hue-slider__thumb",style:{left:e.thumbLeft+"px",top:e.thumbTop+"px"}})])},rp=[];ip._withStripped=!0;var op={name:"el-color-hue-slider",props:{color:{required:!0},vertical:Boolean},data:function(){return{thumbLeft:0,thumbTop:0}},computed:{hueValue:function(){var e=this.color.get("hue");return e}},watch:{hueValue:function(){this.update()}},methods:{handleClick:function(e){var t=this.$refs.thumb,n=e.target;n!==t&&this.handleDrag(e)},handleDrag:function(e){var t=this.$el.getBoundingClientRect(),n=this.$refs.thumb,i=void 0;if(this.vertical){var r=e.clientY-t.top;r=Math.min(r,t.height-n.offsetHeight/2),r=Math.max(n.offsetHeight/2,r),i=Math.round((r-n.offsetHeight/2)/(t.height-n.offsetHeight)*360)}else{var o=e.clientX-t.left;o=Math.min(o,t.width-n.offsetWidth/2),o=Math.max(n.offsetWidth/2,o),i=Math.round((o-n.offsetWidth/2)/(t.width-n.offsetWidth)*360)}this.color.set("hue",i)},getThumbLeft:function(){if(this.vertical)return 0;var e=this.$el,t=this.color.get("hue");if(!e)return 0;var n=this.$refs.thumb;return Math.round(t*(e.offsetWidth-n.offsetWidth/2)/360)},getThumbTop:function(){if(!this.vertical)return 0;var e=this.$el,t=this.color.get("hue");if(!e)return 0;var n=this.$refs.thumb;return Math.round(t*(e.offsetHeight-n.offsetHeight/2)/360)},update:function(){this.thumbLeft=this.getThumbLeft(),this.thumbTop=this.getThumbTop()}},mounted:function(){var e=this,t=this.$refs,n=t.bar,i=t.thumb,r={drag:function(t){e.handleDrag(t)},end:function(t){e.handleDrag(t)}};Jf(n,r),Jf(i,r),this.update()}},ap=op,sp=s(ap,ip,rp,!1,null,null,null);sp.options.__file="packages/color-picker/src/components/hue-slider.vue";var lp=sp.exports,cp=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-color-alpha-slider",class:{"is-vertical":e.vertical}},[n("div",{ref:"bar",staticClass:"el-color-alpha-slider__bar",style:{background:e.background},on:{click:e.handleClick}}),n("div",{ref:"thumb",staticClass:"el-color-alpha-slider__thumb",style:{left:e.thumbLeft+"px",top:e.thumbTop+"px"}})])},up=[];cp._withStripped=!0;var dp={name:"el-color-alpha-slider",props:{color:{required:!0},vertical:Boolean},watch:{"color._alpha":function(){this.update()},"color.value":function(){this.update()}},methods:{handleClick:function(e){var t=this.$refs.thumb,n=e.target;n!==t&&this.handleDrag(e)},handleDrag:function(e){var t=this.$el.getBoundingClientRect(),n=this.$refs.thumb;if(this.vertical){var i=e.clientY-t.top;i=Math.max(n.offsetHeight/2,i),i=Math.min(i,t.height-n.offsetHeight/2),this.color.set("alpha",Math.round((i-n.offsetHeight/2)/(t.height-n.offsetHeight)*100))}else{var r=e.clientX-t.left;r=Math.max(n.offsetWidth/2,r),r=Math.min(r,t.width-n.offsetWidth/2),this.color.set("alpha",Math.round((r-n.offsetWidth/2)/(t.width-n.offsetWidth)*100))}},getThumbLeft:function(){if(this.vertical)return 0;var e=this.$el,t=this.color._alpha;if(!e)return 0;var n=this.$refs.thumb;return Math.round(t*(e.offsetWidth-n.offsetWidth/2)/100)},getThumbTop:function(){if(!this.vertical)return 0;var e=this.$el,t=this.color._alpha;if(!e)return 0;var n=this.$refs.thumb;return Math.round(t*(e.offsetHeight-n.offsetHeight/2)/100)},getBackground:function(){if(this.color&&this.color.value){var e=this.color.toRgb(),t=e.r,n=e.g,i=e.b;return"linear-gradient(to right, rgba("+t+", "+n+", "+i+", 0) 0%, rgba("+t+", "+n+", "+i+", 1) 100%)"}return null},update:function(){this.thumbLeft=this.getThumbLeft(),this.thumbTop=this.getThumbTop(),this.background=this.getBackground()}},data:function(){return{thumbLeft:0,thumbTop:0,background:null}},mounted:function(){var e=this,t=this.$refs,n=t.bar,i=t.thumb,r={drag:function(t){e.handleDrag(t)},end:function(t){e.handleDrag(t)}};Jf(n,r),Jf(i,r),this.update()}},hp=dp,fp=s(hp,cp,up,!1,null,null,null);fp.options.__file="packages/color-picker/src/components/alpha-slider.vue";var pp=fp.exports,mp=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-color-predefine"},[n("div",{staticClass:"el-color-predefine__colors"},e._l(e.rgbaColors,(function(t,i){return n("div",{key:e.colors[i],staticClass:"el-color-predefine__color-selector",class:{selected:t.selected,"is-alpha":t._alpha<100},on:{click:function(t){e.handleSelect(i)}}},[n("div",{style:{"background-color":t.value}})])})),0)])},vp=[];mp._withStripped=!0;var gp={props:{colors:{type:Array,required:!0},color:{required:!0}},data:function(){return{rgbaColors:this.parseColors(this.colors,this.color)}},methods:{handleSelect:function(e){this.color.fromString(this.colors[e])},parseColors:function(e,t){return e.map((function(e){var n=new Uf;return n.enableAlpha=!0,n.format="rgba",n.fromString(e),n.selected=n.value===t.value,n}))}},watch:{"$parent.currentColor":function(e){var t=new Uf;t.fromString(e),this.rgbaColors.forEach((function(e){e.selected=t.compare(e)}))},colors:function(e){this.rgbaColors=this.parseColors(e,this.color)},color:function(e){this.rgbaColors=this.parseColors(this.colors,e)}}},bp=gp,yp=s(bp,mp,vp,!1,null,null,null);yp.options.__file="packages/color-picker/src/components/predefine.vue";var _p=yp.exports,xp={name:"el-color-picker-dropdown",mixins:[H.a,g.a],components:{SvPanel:np,HueSlider:lp,AlphaSlider:pp,ElInput:m.a,ElButton:ae.a,Predefine:_p},props:{color:{required:!0},showAlpha:Boolean,predefine:Array},data:function(){return{customInput:""}},computed:{currentColor:function(){var e=this.$parent;return e.value||e.showPanelColor?e.color.value:""}},methods:{confirmValue:function(){this.$emit("pick")},handleConfirm:function(){this.color.fromString(this.customInput)}},mounted:function(){this.$parent.popperElm=this.popperElm=this.$el,this.referenceElm=this.$parent.$el},watch:{showPopper:function(e){var t=this;!0===e&&this.$nextTick((function(){var e=t.$refs,n=e.sl,i=e.hue,r=e.alpha;n&&n.update(),i&&i.update(),r&&r.update()}))},currentColor:{immediate:!0,handler:function(e){this.customInput=e}}}},wp=xp,Cp=s(wp,Yf,Kf,!1,null,null,null);Cp.options.__file="packages/color-picker/src/components/picker-dropdown.vue";var kp=Cp.exports,Sp={name:"ElColorPicker",mixins:[D.a],props:{value:String,showAlpha:Boolean,colorFormat:String,disabled:Boolean,size:String,popperClass:String,predefine:Array},inject:{elForm:{default:""},elFormItem:{default:""}},directives:{Clickoutside:V.a},computed:{displayedColor:function(){return this.value||this.showPanelColor?this.displayedRgb(this.color,this.showAlpha):"transparent"},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},colorSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},colorDisabled:function(){return this.disabled||(this.elForm||{}).disabled}},watch:{value:function(e){e?e&&e!==this.color.value&&this.color.fromString(e):this.showPanelColor=!1},color:{deep:!0,handler:function(){this.showPanelColor=!0}},displayedColor:function(e){if(this.showPicker){var t=new Uf({enableAlpha:this.showAlpha,format:this.colorFormat});t.fromString(this.value);var n=this.displayedRgb(t,this.showAlpha);e!==n&&this.$emit("active-change",e)}}},methods:{handleTrigger:function(){this.colorDisabled||(this.showPicker=!this.showPicker)},confirmValue:function(){var e=this.color.value;this.$emit("input",e),this.$emit("change",e),this.dispatch("ElFormItem","el.form.change",e),this.showPicker=!1},clearValue:function(){this.$emit("input",null),this.$emit("change",null),null!==this.value&&this.dispatch("ElFormItem","el.form.change",null),this.showPanelColor=!1,this.showPicker=!1,this.resetColor()},hide:function(){this.showPicker=!1,this.resetColor()},resetColor:function(){var e=this;this.$nextTick((function(t){e.value?e.color.fromString(e.value):e.showPanelColor=!1}))},displayedRgb:function(e,t){if(!(e instanceof Uf))throw Error("color should be instance of Color Class");var n=e.toRgb(),i=n.r,r=n.g,o=n.b;return t?"rgba("+i+", "+r+", "+o+", "+e.get("alpha")/100+")":"rgb("+i+", "+r+", "+o+")"}},mounted:function(){var e=this.value;e&&this.color.fromString(e),this.popperElm=this.$refs.dropdown.$el},data:function(){var e=new Uf({enableAlpha:this.showAlpha,format:this.colorFormat});return{color:e,showPicker:!1,showPanelColor:!1}},components:{PickerDropdown:kp}},Op=Sp,$p=s(Op,Tf,Pf,!1,null,null,null);$p.options.__file="packages/color-picker/src/main.vue";var Dp=$p.exports;Dp.install=function(e){e.component(Dp.name,Dp)};var Ep=Dp,Tp=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-transfer"},[n("transfer-panel",e._b({ref:"leftPanel",attrs:{data:e.sourceData,title:e.titles[0]||e.t("el.transfer.titles.0"),"default-checked":e.leftDefaultChecked,placeholder:e.filterPlaceholder||e.t("el.transfer.filterPlaceholder")},on:{"checked-change":e.onSourceCheckedChange}},"transfer-panel",e.$props,!1),[e._t("left-footer")],2),n("div",{staticClass:"el-transfer__buttons"},[n("el-button",{class:["el-transfer__button",e.hasButtonTexts?"is-with-texts":""],attrs:{type:"primary",disabled:0===e.rightChecked.length},nativeOn:{click:function(t){return e.addToLeft(t)}}},[n("i",{staticClass:"el-icon-arrow-left"}),void 0!==e.buttonTexts[0]?n("span",[e._v(e._s(e.buttonTexts[0]))]):e._e()]),n("el-button",{class:["el-transfer__button",e.hasButtonTexts?"is-with-texts":""],attrs:{type:"primary",disabled:0===e.leftChecked.length},nativeOn:{click:function(t){return e.addToRight(t)}}},[void 0!==e.buttonTexts[1]?n("span",[e._v(e._s(e.buttonTexts[1]))]):e._e(),n("i",{staticClass:"el-icon-arrow-right"})])],1),n("transfer-panel",e._b({ref:"rightPanel",attrs:{data:e.targetData,title:e.titles[1]||e.t("el.transfer.titles.1"),"default-checked":e.rightDefaultChecked,placeholder:e.filterPlaceholder||e.t("el.transfer.filterPlaceholder")},on:{"checked-change":e.onTargetCheckedChange}},"transfer-panel",e.$props,!1),[e._t("right-footer")],2)],1)},Pp=[];Tp._withStripped=!0;var Mp=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-transfer-panel"},[n("p",{staticClass:"el-transfer-panel__header"},[n("el-checkbox",{attrs:{indeterminate:e.isIndeterminate},on:{change:e.handleAllCheckedChange},model:{value:e.allChecked,callback:function(t){e.allChecked=t},expression:"allChecked"}},[e._v("\n "+e._s(e.title)+"\n "),n("span",[e._v(e._s(e.checkedSummary))])])],1),n("div",{class:["el-transfer-panel__body",e.hasFooter?"is-with-footer":""]},[e.filterable?n("el-input",{staticClass:"el-transfer-panel__filter",attrs:{size:"small",placeholder:e.placeholder},nativeOn:{mouseenter:function(t){e.inputHover=!0},mouseleave:function(t){e.inputHover=!1}},model:{value:e.query,callback:function(t){e.query=t},expression:"query"}},[n("i",{class:["el-input__icon","el-icon-"+e.inputIcon],attrs:{slot:"prefix"},on:{click:e.clearQuery},slot:"prefix"})]):e._e(),n("el-checkbox-group",{directives:[{name:"show",rawName:"v-show",value:!e.hasNoMatch&&e.data.length>0,expression:"!hasNoMatch && data.length > 0"}],staticClass:"el-transfer-panel__list",class:{"is-filterable":e.filterable},model:{value:e.checked,callback:function(t){e.checked=t},expression:"checked"}},e._l(e.filteredData,(function(t){return n("el-checkbox",{key:t[e.keyProp],staticClass:"el-transfer-panel__item",attrs:{label:t[e.keyProp],disabled:t[e.disabledProp]}},[n("option-content",{attrs:{option:t}})],1)})),1),n("p",{directives:[{name:"show",rawName:"v-show",value:e.hasNoMatch,expression:"hasNoMatch"}],staticClass:"el-transfer-panel__empty"},[e._v(e._s(e.t("el.transfer.noMatch")))]),n("p",{directives:[{name:"show",rawName:"v-show",value:0===e.data.length&&!e.hasNoMatch,expression:"data.length === 0 && !hasNoMatch"}],staticClass:"el-transfer-panel__empty"},[e._v(e._s(e.t("el.transfer.noData")))])],1),e.hasFooter?n("p",{staticClass:"el-transfer-panel__footer"},[e._t("default")],2):e._e()])},Ip=[];Mp._withStripped=!0;var Np={mixins:[g.a],name:"ElTransferPanel",componentName:"ElTransferPanel",components:{ElCheckboxGroup:Mr.a,ElCheckbox:Ai.a,ElInput:m.a,OptionContent:{props:{option:Object},render:function(e){var t=function e(t){return"ElTransferPanel"===t.$options.componentName?t:t.$parent?e(t.$parent):t},n=t(this),i=n.$parent||n;return n.renderContent?n.renderContent(e,this.option):i.$scopedSlots.default?i.$scopedSlots.default({option:this.option}):e("span",[this.option[n.labelProp]||this.option[n.keyProp]])}}},props:{data:{type:Array,default:function(){return[]}},renderContent:Function,placeholder:String,title:String,filterable:Boolean,format:Object,filterMethod:Function,defaultChecked:Array,props:Object},data:function(){return{checked:[],allChecked:!1,query:"",inputHover:!1,checkChangeByUser:!0}},watch:{checked:function(e,t){if(this.updateAllChecked(),this.checkChangeByUser){var n=e.concat(t).filter((function(n){return-1===e.indexOf(n)||-1===t.indexOf(n)}));this.$emit("checked-change",e,n)}else this.$emit("checked-change",e),this.checkChangeByUser=!0},data:function(){var e=this,t=[],n=this.filteredData.map((function(t){return t[e.keyProp]}));this.checked.forEach((function(e){n.indexOf(e)>-1&&t.push(e)})),this.checkChangeByUser=!1,this.checked=t},checkableData:function(){this.updateAllChecked()},defaultChecked:{immediate:!0,handler:function(e,t){var n=this;if(!t||e.length!==t.length||!e.every((function(e){return t.indexOf(e)>-1}))){var i=[],r=this.checkableData.map((function(e){return e[n.keyProp]}));e.forEach((function(e){r.indexOf(e)>-1&&i.push(e)})),this.checkChangeByUser=!1,this.checked=i}}}},computed:{filteredData:function(){var e=this;return this.data.filter((function(t){if("function"===typeof e.filterMethod)return e.filterMethod(e.query,t);var n=t[e.labelProp]||t[e.keyProp].toString();return n.toLowerCase().indexOf(e.query.toLowerCase())>-1}))},checkableData:function(){var e=this;return this.filteredData.filter((function(t){return!t[e.disabledProp]}))},checkedSummary:function(){var e=this.checked.length,t=this.data.length,n=this.format,i=n.noChecked,r=n.hasChecked;return i&&r?e>0?r.replace(/\${checked}/g,e).replace(/\${total}/g,t):i.replace(/\${total}/g,t):e+"/"+t},isIndeterminate:function(){var e=this.checked.length;return e>0&&e0&&0===this.filteredData.length},inputIcon:function(){return this.query.length>0&&this.inputHover?"circle-close":"search"},labelProp:function(){return this.props.label||"label"},keyProp:function(){return this.props.key||"key"},disabledProp:function(){return this.props.disabled||"disabled"},hasFooter:function(){return!!this.$slots.default}},methods:{updateAllChecked:function(){var e=this,t=this.checkableData.map((function(t){return t[e.keyProp]}));this.allChecked=t.length>0&&t.every((function(t){return e.checked.indexOf(t)>-1}))},handleAllCheckedChange:function(e){var t=this;this.checked=e?this.checkableData.map((function(e){return e[t.keyProp]})):[]},clearQuery:function(){"circle-close"===this.inputIcon&&(this.query="")}}},jp=Np,Ap=s(jp,Mp,Ip,!1,null,null,null);Ap.options.__file="packages/transfer/src/transfer-panel.vue";var Fp=Ap.exports,Lp={name:"ElTransfer",mixins:[D.a,g.a,O.a],components:{TransferPanel:Fp,ElButton:ae.a},props:{data:{type:Array,default:function(){return[]}},titles:{type:Array,default:function(){return[]}},buttonTexts:{type:Array,default:function(){return[]}},filterPlaceholder:{type:String,default:""},filterMethod:Function,leftDefaultChecked:{type:Array,default:function(){return[]}},rightDefaultChecked:{type:Array,default:function(){return[]}},renderContent:Function,value:{type:Array,default:function(){return[]}},format:{type:Object,default:function(){return{}}},filterable:Boolean,props:{type:Object,default:function(){return{label:"label",key:"key",disabled:"disabled"}}},targetOrder:{type:String,default:"original"}},data:function(){return{leftChecked:[],rightChecked:[]}},computed:{dataObj:function(){var e=this.props.key;return this.data.reduce((function(t,n){return(t[n[e]]=n)&&t}),{})},sourceData:function(){var e=this;return this.data.filter((function(t){return-1===e.value.indexOf(t[e.props.key])}))},targetData:function(){var e=this;return"original"===this.targetOrder?this.data.filter((function(t){return e.value.indexOf(t[e.props.key])>-1})):this.value.reduce((function(t,n){var i=e.dataObj[n];return i&&t.push(i),t}),[])},hasButtonTexts:function(){return 2===this.buttonTexts.length}},watch:{value:function(e){this.dispatch("ElFormItem","el.form.change",e)}},methods:{getMigratingConfig:function(){return{props:{"footer-format":"footer-format is renamed to format."}}},onSourceCheckedChange:function(e,t){this.leftChecked=e,void 0!==t&&this.$emit("left-check-change",e,t)},onTargetCheckedChange:function(e,t){this.rightChecked=e,void 0!==t&&this.$emit("right-check-change",e,t)},addToLeft:function(){var e=this.value.slice();this.rightChecked.forEach((function(t){var n=e.indexOf(t);n>-1&&e.splice(n,1)})),this.$emit("input",e),this.$emit("change",e,"left",this.rightChecked)},addToRight:function(){var e=this,t=this.value.slice(),n=[],i=this.props.key;this.data.forEach((function(t){var r=t[i];e.leftChecked.indexOf(r)>-1&&-1===e.value.indexOf(r)&&n.push(r)})),t="unshift"===this.targetOrder?n.concat(t):t.concat(n),this.$emit("input",t),this.$emit("change",t,"right",this.leftChecked)},clearQuery:function(e){"left"===e?this.$refs.leftPanel.query="":"right"===e&&(this.$refs.rightPanel.query="")}}},Vp=Lp,zp=s(Vp,Tp,Pp,!1,null,null,null);zp.options.__file="packages/transfer/src/main.vue";var Bp=zp.exports;Bp.install=function(e){e.component(Bp.name,Bp)};var Rp=Bp,Hp=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("section",{staticClass:"el-container",class:{"is-vertical":e.isVertical}},[e._t("default")],2)},Wp=[];Hp._withStripped=!0;var qp={name:"ElContainer",componentName:"ElContainer",props:{direction:String},computed:{isVertical:function(){return"vertical"===this.direction||"horizontal"!==this.direction&&(!(!this.$slots||!this.$slots.default)&&this.$slots.default.some((function(e){var t=e.componentOptions&&e.componentOptions.tag;return"el-header"===t||"el-footer"===t})))}}},Up=qp,Yp=s(Up,Hp,Wp,!1,null,null,null);Yp.options.__file="packages/container/src/main.vue";var Kp=Yp.exports;Kp.install=function(e){e.component(Kp.name,Kp)};var Gp=Kp,Xp=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("header",{staticClass:"el-header",style:{height:e.height}},[e._t("default")],2)},Zp=[];Xp._withStripped=!0;var Jp={name:"ElHeader",componentName:"ElHeader",props:{height:{type:String,default:"60px"}}},Qp=Jp,em=s(Qp,Xp,Zp,!1,null,null,null);em.options.__file="packages/header/src/main.vue";var tm=em.exports;tm.install=function(e){e.component(tm.name,tm)};var nm=tm,im=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("aside",{staticClass:"el-aside",style:{width:e.width}},[e._t("default")],2)},rm=[];im._withStripped=!0;var om={name:"ElAside",componentName:"ElAside",props:{width:{type:String,default:"300px"}}},am=om,sm=s(am,im,rm,!1,null,null,null);sm.options.__file="packages/aside/src/main.vue";var lm=sm.exports;lm.install=function(e){e.component(lm.name,lm)};var cm=lm,um=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("main",{staticClass:"el-main"},[e._t("default")],2)},dm=[];um._withStripped=!0;var hm={name:"ElMain",componentName:"ElMain"},fm=hm,pm=s(fm,um,dm,!1,null,null,null);pm.options.__file="packages/main/src/main.vue";var mm=pm.exports;mm.install=function(e){e.component(mm.name,mm)};var vm=mm,gm=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("footer",{staticClass:"el-footer",style:{height:e.height}},[e._t("default")],2)},bm=[];gm._withStripped=!0;var ym={name:"ElFooter",componentName:"ElFooter",props:{height:{type:String,default:"60px"}}},_m=ym,xm=s(_m,gm,bm,!1,null,null,null);xm.options.__file="packages/footer/src/main.vue";var wm=xm.exports;wm.install=function(e){e.component(wm.name,wm)};var Cm,km,Sm=wm,Om={name:"ElTimeline",props:{reverse:{type:Boolean,default:!1}},provide:function(){return{timeline:this}},render:function(){var e=arguments[0],t=this.reverse,n={"el-timeline":!0,"is-reverse":t},i=this.$slots.default||[];return t&&(i=i.reverse()),e("ul",{class:n},[i])}},$m=Om,Dm=s($m,Cm,km,!1,null,null,null);Dm.options.__file="packages/timeline/src/main.vue";var Em=Dm.exports;Em.install=function(e){e.component(Em.name,Em)};var Tm=Em,Pm=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{staticClass:"el-timeline-item"},[n("div",{staticClass:"el-timeline-item__tail"}),e.$slots.dot?e._e():n("div",{staticClass:"el-timeline-item__node",class:["el-timeline-item__node--"+(e.size||""),"el-timeline-item__node--"+(e.type||"")],style:{backgroundColor:e.color}},[e.icon?n("i",{staticClass:"el-timeline-item__icon",class:e.icon}):e._e()]),e.$slots.dot?n("div",{staticClass:"el-timeline-item__dot"},[e._t("dot")],2):e._e(),n("div",{staticClass:"el-timeline-item__wrapper"},[e.hideTimestamp||"top"!==e.placement?e._e():n("div",{staticClass:"el-timeline-item__timestamp is-top"},[e._v("\n "+e._s(e.timestamp)+"\n ")]),n("div",{staticClass:"el-timeline-item__content"},[e._t("default")],2),e.hideTimestamp||"bottom"!==e.placement?e._e():n("div",{staticClass:"el-timeline-item__timestamp is-bottom"},[e._v("\n "+e._s(e.timestamp)+"\n ")])])])},Mm=[];Pm._withStripped=!0;var Im={name:"ElTimelineItem",inject:["timeline"],props:{timestamp:String,hideTimestamp:{type:Boolean,default:!1},placement:{type:String,default:"bottom"},type:String,color:String,size:{type:String,default:"normal"},icon:String}},Nm=Im,jm=s(Nm,Pm,Mm,!1,null,null,null);jm.options.__file="packages/timeline/src/item.vue";var Am=jm.exports;Am.install=function(e){e.component(Am.name,Am)};var Fm=Am,Lm=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("a",e._b({class:["el-link",e.type?"el-link--"+e.type:"",e.disabled&&"is-disabled",e.underline&&!e.disabled&&"is-underline"],attrs:{href:e.disabled?null:e.href},on:{click:e.handleClick}},"a",e.$attrs,!1),[e.icon?n("i",{class:e.icon}):e._e(),e.$slots.default?n("span",{staticClass:"el-link--inner"},[e._t("default")],2):e._e(),e.$slots.icon?[e.$slots.icon?e._t("icon"):e._e()]:e._e()],2)},Vm=[];Lm._withStripped=!0;var zm={name:"ElLink",props:{type:{type:String,default:"default"},underline:{type:Boolean,default:!0},disabled:Boolean,href:String,icon:String},methods:{handleClick:function(e){this.disabled||this.href||this.$emit("click",e)}}},Bm=zm,Rm=s(Bm,Lm,Vm,!1,null,null,null);Rm.options.__file="packages/link/src/main.vue";var Hm=Rm.exports;Hm.install=function(e){e.component(Hm.name,Hm)};var Wm=Hm,qm=function(e,t){var n=t._c;return n("div",t._g(t._b({class:[t.data.staticClass,"el-divider","el-divider--"+t.props.direction]},"div",t.data.attrs,!1),t.listeners),[t.slots().default&&"vertical"!==t.props.direction?n("div",{class:["el-divider__text","is-"+t.props.contentPosition]},[t._t("default")],2):t._e()])},Um=[];qm._withStripped=!0;var Ym={name:"ElDivider",props:{direction:{type:String,default:"horizontal",validator:function(e){return-1!==["horizontal","vertical"].indexOf(e)}},contentPosition:{type:String,default:"center",validator:function(e){return-1!==["left","center","right"].indexOf(e)}}}},Km=Ym,Gm=s(Km,qm,Um,!0,null,null,null);Gm.options.__file="packages/divider/src/main.vue";var Xm=Gm.exports;Xm.install=function(e){e.component(Xm.name,Xm)};var Zm=Xm,Jm=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-image"},[e.loading?e._t("placeholder",[n("div",{staticClass:"el-image__placeholder"})]):e.error?e._t("error",[n("div",{staticClass:"el-image__error"},[e._v(e._s(e.t("el.image.error")))])]):n("img",e._g(e._b({staticClass:"el-image__inner",class:{"el-image__inner--center":e.alignCenter,"el-image__preview":e.preview},style:e.imageStyle,attrs:{src:e.src},on:{click:e.clickHandler}},"img",e.$attrs,!1),e.$listeners)),e.preview&&e.showViewer?n("image-viewer",{attrs:{"z-index":e.zIndex,"on-close":e.closeViewer,"url-list":e.previewSrcList}}):e._e()],2)},Qm=[];Jm._withStripped=!0;var ev=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"viewer-fade"}},[n("div",{staticClass:"el-image-viewer__wrapper",style:{"z-index":e.zIndex}},[n("div",{staticClass:"el-image-viewer__mask"}),n("span",{staticClass:"el-image-viewer__btn el-image-viewer__close",on:{click:e.hide}},[n("i",{staticClass:"el-icon-circle-close"})]),e.isSingle?e._e():[n("span",{staticClass:"el-image-viewer__btn el-image-viewer__prev",class:{"is-disabled":!e.infinite&&e.isFirst},on:{click:e.prev}},[n("i",{staticClass:"el-icon-arrow-left"})]),n("span",{staticClass:"el-image-viewer__btn el-image-viewer__next",class:{"is-disabled":!e.infinite&&e.isLast},on:{click:e.next}},[n("i",{staticClass:"el-icon-arrow-right"})])],n("div",{staticClass:"el-image-viewer__btn el-image-viewer__actions"},[n("div",{staticClass:"el-image-viewer__actions__inner"},[n("i",{staticClass:"el-icon-zoom-out",on:{click:function(t){e.handleActions("zoomOut")}}}),n("i",{staticClass:"el-icon-zoom-in",on:{click:function(t){e.handleActions("zoomIn")}}}),n("i",{staticClass:"el-image-viewer__actions__divider"}),n("i",{class:e.mode.icon,on:{click:e.toggleMode}}),n("i",{staticClass:"el-image-viewer__actions__divider"}),n("i",{staticClass:"el-icon-refresh-left",on:{click:function(t){e.handleActions("anticlocelise")}}}),n("i",{staticClass:"el-icon-refresh-right",on:{click:function(t){e.handleActions("clocelise")}}})])]),n("div",{staticClass:"el-image-viewer__canvas"},e._l(e.urlList,(function(t,i){return i===e.index?n("img",{key:t,ref:"img",refInFor:!0,staticClass:"el-image-viewer__img",style:e.imgStyle,attrs:{src:e.currentImg},on:{load:e.handleImgLoad,error:e.handleImgError,mousedown:e.handleMouseDown}}):e._e()})),0)],2)])},tv=[];ev._withStripped=!0;var nv=Object.assign||function(e){for(var t=1;t0?e.handleActions("zoomIn",{zoomRate:.015,enableTransition:!1}):e.handleActions("zoomOut",{zoomRate:.015,enableTransition:!1})})),Object(Le["on"])(document,"keydown",this._keyDownHandler),Object(Le["on"])(document,rv,this._mouseWheelHandler)},deviceSupportUninstall:function(){Object(Le["off"])(document,"keydown",this._keyDownHandler),Object(Le["off"])(document,rv,this._mouseWheelHandler),this._keyDownHandler=null,this._mouseWheelHandler=null},handleImgLoad:function(e){this.loading=!1},handleImgError:function(e){this.loading=!1,e.target.alt="加载失败"},handleMouseDown:function(e){var t=this;if(!this.loading&&0===e.button){var n=this.transform,i=n.offsetX,r=n.offsetY,o=e.pageX,a=e.pageY;this._dragHandler=Object(b["rafThrottle"])((function(e){t.transform.offsetX=i+e.pageX-o,t.transform.offsetY=r+e.pageY-a})),Object(Le["on"])(document,"mousemove",this._dragHandler),Object(Le["on"])(document,"mouseup",(function(e){Object(Le["off"])(document,"mousemove",t._dragHandler)})),e.preventDefault()}},reset:function(){this.transform={scale:1,deg:0,offsetX:0,offsetY:0,enableTransition:!1}},toggleMode:function(){if(!this.loading){var e=Object.keys(iv),t=Object.values(iv),n=t.indexOf(this.mode),i=(n+1)%e.length;this.mode=iv[e[i]],this.reset()}},prev:function(){if(!this.isFirst||this.infinite){var e=this.urlList.length;this.index=(this.index-1+e)%e}},next:function(){if(!this.isLast||this.infinite){var e=this.urlList.length;this.index=(this.index+1)%e}},handleActions:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!this.loading){var n=nv({zoomRate:.2,rotateDeg:90,enableTransition:!0},t),i=n.zoomRate,r=n.rotateDeg,o=n.enableTransition,a=this.transform;switch(e){case"zoomOut":a.scale>.2&&(a.scale=parseFloat((a.scale-i).toFixed(3)));break;case"zoomIn":a.scale=parseFloat((a.scale+i).toFixed(3));break;case"clocelise":a.deg+=r;break;case"anticlocelise":a.deg-=r;break}a.enableTransition=o}}},mounted:function(){this.deviceSupportInstall()}},av=ov,sv=s(av,ev,tv,!1,null,null,null);sv.options.__file="packages/image/src/image-viewer.vue";var lv=sv.exports,cv=function(){return void 0!==document.documentElement.style.objectFit},uv={NONE:"none",CONTAIN:"contain",COVER:"cover",FILL:"fill",SCALE_DOWN:"scale-down"},dv={name:"ElImage",mixins:[g.a],inheritAttrs:!1,components:{ImageViewer:lv},props:{src:String,fit:String,lazy:Boolean,scrollContainer:{},previewSrcList:{type:Array,default:function(){return[]}},zIndex:{type:Number,default:2e3}},data:function(){return{loading:!0,error:!1,show:!this.lazy,imageWidth:0,imageHeight:0,showViewer:!1}},computed:{imageStyle:function(){var e=this.fit;return!this.$isServer&&e?cv()?{"object-fit":e}:this.getImageStyle(e):{}},alignCenter:function(){return!this.$isServer&&!cv()&&this.fit!==uv.FILL},preview:function(){var e=this.previewSrcList;return Array.isArray(e)&&e.length>0}},watch:{src:function(e){this.show&&this.loadImage()},show:function(e){e&&this.loadImage()}},mounted:function(){this.lazy?this.addLazyLoadListener():this.loadImage()},beforeDestroy:function(){this.lazy&&this.removeLazyLoadListener()},methods:{loadImage:function(){var e=this;if(!this.$isServer){this.loading=!0,this.error=!1;var t=new Image;t.onload=function(n){return e.handleLoad(n,t)},t.onerror=this.handleError.bind(this),Object.keys(this.$attrs).forEach((function(n){var i=e.$attrs[n];t.setAttribute(n,i)})),t.src=this.src}},handleLoad:function(e,t){this.imageWidth=t.width,this.imageHeight=t.height,this.loading=!1},handleError:function(e){this.loading=!1,this.error=!0,this.$emit("error",e)},handleLazyLoad:function(){Object(Le["isInContainer"])(this.$el,this._scrollContainer)&&(this.show=!0,this.removeLazyLoadListener())},addLazyLoadListener:function(){if(!this.$isServer){var e=this.scrollContainer,t=null;t=Object(hh["isHtmlElement"])(e)?e:Object(hh["isString"])(e)?document.querySelector(e):Object(Le["getScrollContainer"])(this.$el),t&&(this._scrollContainer=t,this._lazyLoadHandler=jh()(200,this.handleLazyLoad),Object(Le["on"])(t,"scroll",this._lazyLoadHandler),this.handleLazyLoad())}},removeLazyLoadListener:function(){var e=this._scrollContainer,t=this._lazyLoadHandler;!this.$isServer&&e&&t&&(Object(Le["off"])(e,"scroll",t),this._scrollContainer=null,this._lazyLoadHandler=null)},getImageStyle:function(e){var t=this.imageWidth,n=this.imageHeight,i=this.$el,r=i.clientWidth,o=i.clientHeight;if(!t||!n||!r||!o)return{};var a=t/n<1;if(e===uv.SCALE_DOWN){var s=tr)return console.warn("[ElementCalendar]end time should be greater than start time"),[];if(Object(ao["validateRangeInOneMonth"])(i,r))return[[i,r]];var o=[],a=new Date(i.getFullYear(),i.getMonth()+1,1),s=this.toDate(a.getTime()-Dv);if(!Object(ao["validateRangeInOneMonth"])(a,r))return console.warn("[ElementCalendar]start time and end time interval must not exceed two months"),[];o.push([i,s]);var l=this.realFirstDayOfWeek,c=a.getDay(),u=0;return c!==l&&(0===l?u=7-c:(u=l-c,u=u>0?u:7+u)),a=this.toDate(a.getTime()+u*Dv),a.getDate()6?0:Math.floor(this.firstDayOfWeek)}},data:function(){return{selectedDay:"",now:new Date}}},Tv=Ev,Pv=s(Tv,vv,gv,!1,null,null,null);Pv.options.__file="packages/calendar/src/main.vue";var Mv=Pv.exports;Mv.install=function(e){e.component(Mv.name,Mv)};var Iv=Mv,Nv=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-fade-in"}},[e.visible?n("div",{staticClass:"el-backtop",style:{right:e.styleRight,bottom:e.styleBottom},on:{click:function(t){return t.stopPropagation(),e.handleClick(t)}}},[e._t("default",[n("el-icon",{attrs:{name:"caret-top"}})])],2):e._e()])},jv=[];Nv._withStripped=!0;var Av={name:"ElBacktop",props:{visibilityHeight:{type:Number,default:200},target:[String],right:{type:Number,default:40},bottom:{type:Number,default:40}},data:function(){return{el:null,container:null,visible:!1}},computed:{styleBottom:function(){return this.bottom+"px"},styleRight:function(){return this.right+"px"}},mounted:function(){this.init(),this.throttledScrollHandler=jh()(300,this.onScroll),this.container.addEventListener("scroll",this.throttledScrollHandler)},methods:{init:function(){if(this.container=document,this.el=document.documentElement,this.target){if(this.el=document.querySelector(this.target),!this.el)throw new Error("target is not existed: "+this.target);this.container=this.el}},onScroll:function(){var e=this.el.scrollTop;this.visible=e>=this.visibilityHeight},handleClick:function(e){this.scrollToTop(),this.$emit("click",e)},scrollToTop:function(){var e=this.el,t=0,n=setInterval((function(){e.scrollTop<=0?clearInterval(n):(t+=10,e.scrollTop-=t)}),20)}},beforeDestroy:function(){this.container.removeEventListener("scroll",this.throttledScrollHandler)}},Fv=Av,Lv=s(Fv,Nv,jv,!1,null,null,null);Lv.options.__file="packages/backtop/src/main.vue";var Vv=Lv.exports;Vv.install=function(e){e.component(Vv.name,Vv)};var zv=Vv,Bv=function(e,t){if(e===window&&(e=document.documentElement),1!==e.nodeType)return[];var n=window.getComputedStyle(e,null);return t?n[t]:n},Rv=function(e){return Object.keys(e||{}).map((function(t){return[t,e[t]]}))},Hv=function(e,t){return e===window||e===document?document.documentElement[t]:e[t]},Wv=function(e){return Hv(e,"offsetHeight")},qv=function(e){return Hv(e,"clientHeight")},Uv="ElInfiniteScroll",Yv={delay:{type:Number,default:200},distance:{type:Number,default:0},disabled:{type:Boolean,default:!1},immediate:{type:Boolean,default:!0}},Kv=function(e,t){return Object(hh["isHtmlElement"])(e)?Rv(Yv).reduce((function(n,i){var r=i[0],o=i[1],a=o.type,s=o.default,l=e.getAttribute("infinite-scroll-"+r);switch(l=Object(hh["isUndefined"])(t[l])?l:t[l],a){case Number:l=Number(l),l=Number.isNaN(l)?s:l;break;case Boolean:l=Object(hh["isDefined"])(l)?"false"!==l&&Boolean(l):s;break;default:l=a(l)}return n[r]=l,n}),{}):{}},Gv=function(e){return e.getBoundingClientRect().top},Xv=function(e){var t=this[Uv],n=t.el,i=t.vm,r=t.container,o=t.observer,a=Kv(n,i),s=a.distance,l=a.disabled;if(!l){var c=!1;if(r===n){var u=r.scrollTop+qv(r);c=r.scrollHeight-u<=s}else{var d=Wv(n)+Gv(n)-Gv(r),h=Wv(r),f=Number.parseFloat(Bv(r,"borderBottomWidth"));c=d-h+f<=s}c&&Object(hh["isFunction"])(e)?e.call(i):o&&(o.disconnect(),this[Uv].observer=null)}},Zv={name:"InfiniteScroll",inserted:function(e,t,n){var i=t.value,r=n.context,o=Object(Le["getScrollContainer"])(e,!0),a=Kv(e,r),s=a.delay,l=a.immediate,c=F()(s,Xv.bind(e,i));if(e[Uv]={el:e,vm:r,container:o,onScroll:c},o&&(o.addEventListener("scroll",c),l)){var u=e[Uv].observer=new MutationObserver(c);u.observe(o,{childList:!0,subtree:!0}),c()}},unbind:function(e){var t=e[Uv],n=t.container,i=t.onScroll;n&&n.removeEventListener("scroll",i)},install:function(e){e.directive(Zv.name,Zv)}},Jv=Zv,Qv=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-page-header"},[n("div",{staticClass:"el-page-header__left",on:{click:function(t){e.$emit("back")}}},[n("i",{staticClass:"el-icon-back"}),n("div",{staticClass:"el-page-header__title"},[e._t("title",[e._v(e._s(e.title))])],2)]),n("div",{staticClass:"el-page-header__content"},[e._t("content",[e._v(e._s(e.content))])],2)])},eg=[];Qv._withStripped=!0;var tg={name:"ElPageHeader",props:{title:{type:String,default:function(){return Object(ti["t"])("el.pageHeader.title")}},content:String}},ng=tg,ig=s(ng,Qv,eg,!1,null,null,null);ig.options.__file="packages/page-header/src/main.vue";var rg=ig.exports;rg.install=function(e){e.component(rg.name,rg)};var og=rg,ag=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:["el-cascader-panel",e.border&&"is-bordered"],on:{keydown:e.handleKeyDown}},e._l(e.menus,(function(e,t){return n("cascader-menu",{key:t,ref:"menu",refInFor:!0,attrs:{index:t,nodes:e}})})),1)},sg=[];ag._withStripped=!0;var lg,cg,ug=n(43),dg=n.n(ug),hg=function(e){return e.stopPropagation()},fg={inject:["panel"],components:{ElCheckbox:Ai.a,ElRadio:dg.a},props:{node:{required:!0},nodeId:String},computed:{config:function(){return this.panel.config},isLeaf:function(){return this.node.isLeaf},isDisabled:function(){return this.node.isDisabled},checkedValue:function(){return this.panel.checkedValue},isChecked:function(){return this.node.isSameNode(this.checkedValue)},inActivePath:function(){return this.isInPath(this.panel.activePath)},inCheckedPath:function(){var e=this;return!!this.config.checkStrictly&&this.panel.checkedNodePaths.some((function(t){return e.isInPath(t)}))},value:function(){return this.node.getValueByOption()}},methods:{handleExpand:function(){var e=this,t=this.panel,n=this.node,i=this.isDisabled,r=this.config,o=r.multiple,a=r.checkStrictly;!a&&i||n.loading||(r.lazy&&!n.loaded?t.lazyLoad(n,(function(){var t=e.isLeaf;if(t||e.handleExpand(),o){var i=!!t&&n.checked;e.handleMultiCheckChange(i)}})):t.handleExpand(n))},handleCheckChange:function(){var e=this.panel,t=this.value,n=this.node;e.handleCheckChange(t),e.handleExpand(n)},handleMultiCheckChange:function(e){this.node.doCheck(e),this.panel.calculateMultiCheckedValue()},isInPath:function(e){var t=this.node,n=e[t.level-1]||{};return n.uid===t.uid},renderPrefix:function(e){var t=this.isLeaf,n=this.isChecked,i=this.config,r=i.checkStrictly,o=i.multiple;return o?this.renderCheckbox(e):r?this.renderRadio(e):t&&n?this.renderCheckIcon(e):null},renderPostfix:function(e){var t=this.node,n=this.isLeaf;return t.loading?this.renderLoadingIcon(e):n?null:this.renderExpandIcon(e)},renderCheckbox:function(e){var t=this.node,n=this.config,i=this.isDisabled,r={on:{change:this.handleMultiCheckChange},nativeOn:{}};return n.checkStrictly&&(r.nativeOn.click=hg),e("el-checkbox",Ju()([{attrs:{value:t.checked,indeterminate:t.indeterminate,disabled:i}},r]))},renderRadio:function(e){var t=this.checkedValue,n=this.value,i=this.isDisabled;return Object(b["isEqual"])(n,t)&&(n=t),e("el-radio",{attrs:{value:t,label:n,disabled:i},on:{change:this.handleCheckChange},nativeOn:{click:hg}},[e("span")])},renderCheckIcon:function(e){return e("i",{class:"el-icon-check el-cascader-node__prefix"})},renderLoadingIcon:function(e){return e("i",{class:"el-icon-loading el-cascader-node__postfix"})},renderExpandIcon:function(e){return e("i",{class:"el-icon-arrow-right el-cascader-node__postfix"})},renderContent:function(e){var t=this.panel,n=this.node,i=t.renderLabelFn,r=i?i({node:n,data:n.data}):null;return e("span",{class:"el-cascader-node__label"},[r||n.label])}},render:function(e){var t=this,n=this.inActivePath,i=this.inCheckedPath,r=this.isChecked,o=this.isLeaf,a=this.isDisabled,s=this.config,l=this.nodeId,c=s.expandTrigger,u=s.checkStrictly,d=s.multiple,h=!u&&a,f={on:{}};return"click"===c?f.on.click=this.handleExpand:(f.on.mouseenter=function(e){t.handleExpand(),t.$emit("expand",e)},f.on.focus=function(e){t.handleExpand(),t.$emit("expand",e)}),!o||a||u||d||(f.on.click=this.handleCheckChange),e("li",Ju()([{attrs:{role:"menuitem",id:l,"aria-expanded":n,tabindex:h?null:-1},class:{"el-cascader-node":!0,"is-selectable":u,"in-active-path":n,"in-checked-path":i,"is-active":r,"is-disabled":h}},f]),[this.renderPrefix(e),this.renderContent(e),this.renderPostfix(e)])}},pg=fg,mg=s(pg,lg,cg,!1,null,null,null);mg.options.__file="packages/cascader-panel/src/cascader-node.vue";var vg,gg,bg=mg.exports,yg={name:"ElCascaderMenu",mixins:[g.a],inject:["panel"],components:{ElScrollbar:q.a,CascaderNode:bg},props:{nodes:{type:Array,required:!0},index:Number},data:function(){return{activeNode:null,hoverTimer:null,id:Object(b["generateId"])()}},computed:{isEmpty:function(){return!this.nodes.length},menuId:function(){return"cascader-menu-"+this.id+"-"+this.index}},methods:{handleExpand:function(e){this.activeNode=e.target},handleMouseMove:function(e){var t=this.activeNode,n=this.hoverTimer,i=this.$refs.hoverZone;if(t&&i)if(t.contains(e.target)){clearTimeout(n);var r=this.$el.getBoundingClientRect(),o=r.left,a=e.clientX-o,s=this.$el,l=s.offsetWidth,c=s.offsetHeight,u=t.offsetTop,d=u+t.offsetHeight;i.innerHTML='\n \n \n '}else n||(this.hoverTimer=setTimeout(this.clearHoverZone,this.panel.config.hoverThreshold))},clearHoverZone:function(){var e=this.$refs.hoverZone;e&&(e.innerHTML="")},renderEmptyText:function(e){return e("div",{class:"el-cascader-menu__empty-text"},[this.t("el.cascader.noData")])},renderNodeList:function(e){var t=this.menuId,n=this.panel.isHoverMenu,i={on:{}};n&&(i.on.expand=this.handleExpand);var r=this.nodes.map((function(n,r){var o=n.hasChildren;return e("cascader-node",Ju()([{key:n.uid,attrs:{node:n,"node-id":t+"-"+r,"aria-haspopup":o,"aria-owns":o?t:null}},i]))}));return[].concat(r,[n?e("svg",{ref:"hoverZone",class:"el-cascader-menu__hover-zone"}):null])}},render:function(e){var t=this.isEmpty,n=this.menuId,i={nativeOn:{}};return this.panel.isHoverMenu&&(i.nativeOn.mousemove=this.handleMouseMove),e("el-scrollbar",Ju()([{attrs:{tag:"ul",role:"menu",id:n,"wrap-class":"el-cascader-menu__wrap","view-class":{"el-cascader-menu__list":!0,"is-empty":t}},class:"el-cascader-menu"},i]),[t?this.renderEmptyText(e):this.renderNodeList(e)])}},_g=yg,xg=s(_g,vg,gg,!1,null,null,null);xg.options.__file="packages/cascader-panel/src/cascader-menu.vue";var wg=xg.exports,Cg=function(){function e(e,t){for(var n=0;n1?t-1:0),i=1;i1?i-1:0),o=1;o0},e.prototype.syncCheckState=function(e){var t=this.getValueByOption(),n=this.isSameNode(e,t);this.doCheck(n)},e.prototype.doCheck=function(e){this.checked!==e&&(this.config.checkStrictly?this.checked=e:(this.broadcast("check",e),this.setCheckState(e),this.emit("check")))},Cg(e,[{key:"isDisabled",get:function(){var e=this.data,t=this.parent,n=this.config,i=n.disabled,r=n.checkStrictly;return e[i]||!r&&t&&t.isDisabled}},{key:"isLeaf",get:function(){var e=this.data,t=this.loaded,n=this.hasChildren,i=this.children,r=this.config,o=r.lazy,a=r.leaf;if(o){var s=Object(Ot["isDef"])(e[a])?e[a]:!!t&&!i.length;return this.hasChildren=!s,s}return!n}}]),e}(),$g=Og;function Dg(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var Eg=function e(t,n){return t.reduce((function(t,i){return i.isLeaf?t.push(i):(!n&&t.push(i),t=t.concat(e(i.children,n))),t}),[])},Tg=function(){function e(t,n){Dg(this,e),this.config=n,this.initNodes(t)}return e.prototype.initNodes=function(e){var t=this;e=Object(b["coerceTruthyValueToArray"])(e),this.nodes=e.map((function(e){return new $g(e,t.config)})),this.flattedNodes=this.getFlattedNodes(!1,!1),this.leafNodes=this.getFlattedNodes(!0,!1)},e.prototype.appendNode=function(e,t){var n=new $g(e,this.config,t),i=t?t.children:this.nodes;i.push(n)},e.prototype.appendNodes=function(e,t){var n=this;e=Object(b["coerceTruthyValueToArray"])(e),e.forEach((function(e){return n.appendNode(e,t)}))},e.prototype.getNodes=function(){return this.nodes},e.prototype.getFlattedNodes=function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=e?this.leafNodes:this.flattedNodes;return t?n:Eg(this.nodes,e)},e.prototype.getNodeByValue=function(e){if(e){var t=this.getFlattedNodes(!1,!this.config.lazy).filter((function(t){return Object(b["valueEquals"])(t.path,e)||t.value===e}));return t&&t.length?t[0]:null}return null},e}(),Pg=Tg,Mg=Object.assign||function(e){for(var t=1;t0){var l=n.store.getNodeByValue(o);l.data[s]||n.lazyLoad(l,(function(){n.handleExpand(l)})),n.loadCount===n.checkedValue.length&&n.$parent.computePresentText()}}t&&t(i)};i.lazyLoad(e,r)},calculateMultiCheckedValue:function(){this.checkedValue=this.getCheckedNodes(this.leafOnly).map((function(e){return e.getValueByOption()}))},scrollIntoView:function(){if(!this.$isServer){var e=this.$refs.menu||[];e.forEach((function(e){var t=e.$el;if(t){var n=t.querySelector(".el-scrollbar__wrap"),i=t.querySelector(".el-cascader-node.is-active")||t.querySelector(".el-cascader-node.in-active-path");ri()(n,i)}}))}},getNodeByValue:function(e){return this.store.getNodeByValue(e)},getFlattedNodes:function(e){var t=!this.config.lazy;return this.store.getFlattedNodes(e,t)},getCheckedNodes:function(e){var t=this.checkedValue,n=this.multiple;if(n){var i=this.getFlattedNodes(e);return i.filter((function(e){return e.checked}))}return Object(b["isEmpty"])(t)?[]:[this.getNodeByValue(t)]},clearCheckedNodes:function(){var e=this.config,t=this.leafOnly,n=e.multiple,i=e.emitPath;n?(this.getCheckedNodes(t).filter((function(e){return!e.isDisabled})).forEach((function(e){return e.doCheck(!1)})),this.calculateMultiCheckedValue()):this.checkedValue=i?[]:null}}},Bg=zg,Rg=s(Bg,ag,sg,!1,null,null,null);Rg.options.__file="packages/cascader-panel/src/cascader-panel.vue";var Hg=Rg.exports;Hg.install=function(e){e.component(Hg.name,Hg)};var Wg,qg,Ug=Hg,Yg={name:"ElAvatar",props:{size:{type:[Number,String],validator:function(e){return"string"===typeof e?["large","medium","small"].includes(e):"number"===typeof e}},shape:{type:String,default:"circle",validator:function(e){return["circle","square"].includes(e)}},icon:String,src:String,alt:String,srcSet:String,error:Function,fit:{type:String,default:"cover"}},data:function(){return{isImageExist:!0}},computed:{avatarClass:function(){var e=this.size,t=this.icon,n=this.shape,i=["el-avatar"];return e&&"string"===typeof e&&i.push("el-avatar--"+e),t&&i.push("el-avatar--icon"),n&&i.push("el-avatar--"+n),i.join(" ")}},methods:{handleError:function(){var e=this.error,t=e?e():void 0;!1!==t&&(this.isImageExist=!1)},renderAvatar:function(){var e=this.$createElement,t=this.icon,n=this.src,i=this.alt,r=this.isImageExist,o=this.srcSet,a=this.fit;return r&&n?e("img",{attrs:{src:n,alt:i,srcSet:o},on:{error:this.handleError},style:{"object-fit":a}}):t?e("i",{class:t}):this.$slots.default}},render:function(){var e=arguments[0],t=this.avatarClass,n=this.size,i="number"===typeof n?{height:n+"px",width:n+"px",lineHeight:n+"px"}:{};return e("span",{class:t,style:i},[this.renderAvatar()])}},Kg=Yg,Gg=s(Kg,Wg,qg,!1,null,null,null);Gg.options.__file="packages/avatar/src/main.vue";var Xg=Gg.exports;Xg.install=function(e){e.component(Xg.name,Xg)};var Zg=Xg,Jg=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-drawer-fade"},on:{"after-enter":e.afterEnter,"after-leave":e.afterLeave}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-dialog__wrapper",attrs:{role:"presentation"}},[n("div",{staticClass:"el-drawer__container",class:e.visible&&"el-drawer__open",attrs:{role:"document",tabindex:"-1"},on:{click:function(t){return t.target!==t.currentTarget?null:e.handleWrapperClick(t)}}},[n("div",{ref:"drawer",staticClass:"el-drawer",class:[e.direction,e.customClass],style:e.isHorizontal?"width: "+e.size:"height: "+e.size,attrs:{"aria-modal":"true","aria-labelledby":"el-drawer__title",role:"presentation"}},[n("header",{staticClass:"el-drawer__header",attrs:{id:"el-drawer__title"}},[e._t("title",[n("span",{attrs:{role:"heading"}},[e._v(e._s(e.title))])]),e.showClose?n("button",{staticClass:"el-drawer__close-btn",attrs:{"aria-label":"close "+(e.title||"drawer"),type:"button"},on:{click:e.closeDrawer}},[n("i",{staticClass:"el-dialog__close el-icon el-icon-close"})]):e._e()],2),e.rendered?n("section",{staticClass:"el-drawer__body"},[e._t("default")],2):e._e()])])])])},Qg=[];Jg._withStripped=!0;var eb={name:"ElDrawer",mixins:[k.a,D.a,O.a],props:{appendToBody:{type:Boolean,default:!0},beforeClose:{type:Function},customClass:{type:String,default:""},destroyOnClose:{type:Boolean,default:!1},modal:{type:Boolean,default:!0},direction:{type:String,default:"rtl",validator:function(e){return-1!==["ltr","rtl","ttb","btt"].indexOf(e)}},showClose:{type:Boolean,default:!0},size:{type:String,default:"30%"},title:{type:String,default:""},visible:{type:Boolean},wrapperClosable:{type:Boolean,default:!0}},computed:{isHorizontal:function(){return"rtl"===this.direction||"ltr"===this.direction}},data:function(){return{closed:!1}},watch:{visible:function(e){e?(this.closed=!1,this.$emit("open"),this.appendToBody&&document.body.appendChild(this.$el)):this.closed||this.$emit("close")}},methods:{afterEnter:function(){this.$emit("opened")},afterLeave:function(){this.$emit("closed")},hide:function(e){!1!==e&&(this.$emit("update:visible",!1),this.$emit("close"),!0===this.destroyOnClose&&(this.rendered=!1),this.closed=!0)},handleWrapperClick:function(){this.wrapperClosable&&this.closeDrawer()},closeDrawer:function(){"function"===typeof this.beforeClose?this.beforeClose(this.hide):this.hide()}},mounted:function(){this.visible&&(this.rendered=!0,this.open())},destroyed:function(){this.appendToBody&&this.$el&&this.$el.parentNode&&this.$el.parentNode.removeChild(this.$el)}},tb=eb,nb=s(tb,Jg,Qg,!1,null,null,null);nb.options.__file="packages/drawer/src/main.vue";var ib=nb.exports;ib.install=function(e){e.component(ib.name,ib)};var rb=ib,ob=[_,I,re,fe,_e,$e,qe,et,ct,vt,Pt,Vt,Ut,en,ln,mn,wn,En,An,ui,di,bi,Si,Mi,Gr,io,Pa,Ha,ns,ds,fs,Hs,Xs,il,bl,Vl,Kl,Ql,Dc,Ac,hu,Fu,Vu,Ru,xd,Dd,jd,nh,ch,gh,kh,Ph,zh,qh,Qh,sf,pf,Ef,Ep,Rp,Gp,nm,cm,vm,Sm,Tm,Fm,Wm,Zm,mv,Iv,zv,og,Ug,Zg,rb,Ye.a],ab=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};ni.a.use(t.locale),ni.a.i18n(t.i18n),ob.forEach((function(t){e.component(t.name,t)})),e.use(Jv),e.use(Tu.directive),e.prototype.$ELEMENT={size:t.size||"",zIndex:t.zIndex||2e3},e.prototype.$loading=Tu.service,e.prototype.$msgbox=As,e.prototype.$alert=As.alert,e.prototype.$confirm=As.confirm,e.prototype.$prompt=As.prompt,e.prototype.$notify=Xc,e.prototype.$message=Gd};"undefined"!==typeof window&&window.Vue&&ab(window.Vue);t["default"]={version:"2.12.0",locale:ni.a.use,i18n:ni.a.i18n,install:ab,CollapseTransition:Ye.a,Loading:Tu,Pagination:_,Dialog:I,Autocomplete:re,Dropdown:fe,DropdownMenu:_e,DropdownItem:$e,Menu:qe,Submenu:et,MenuItem:ct,MenuItemGroup:vt,Input:Pt,InputNumber:Vt,Radio:Ut,RadioGroup:en,RadioButton:ln,Checkbox:mn,CheckboxButton:wn,CheckboxGroup:En,Switch:An,Select:ui,Option:di,OptionGroup:bi,Button:Si,ButtonGroup:Mi,Table:Gr,TableColumn:io,DatePicker:Pa,TimeSelect:Ha,TimePicker:ns,Popover:ds,Tooltip:fs,MessageBox:As,Breadcrumb:Hs,BreadcrumbItem:Xs,Form:il,FormItem:bl,Tabs:Vl,TabPane:Kl,Tag:Ql,Tree:Dc,Alert:Ac,Notification:Xc,Slider:hu,Icon:Fu,Row:Vu,Col:Ru,Upload:xd,Progress:Dd,Spinner:jd,Message:Gd,Badge:nh,Card:ch,Rate:gh,Steps:kh,Step:Ph,Carousel:zh,Scrollbar:qh,CarouselItem:Qh,Collapse:sf,CollapseItem:pf,Cascader:Ef,ColorPicker:Ep,Transfer:Rp,Container:Gp,Header:nm,Aside:cm,Main:vm,Footer:Sm,Timeline:Tm,TimelineItem:Fm,Link:Wm,Divider:Zm,Image:mv,Calendar:Iv,Backtop:zv,InfiniteScroll:Jv,PageHeader:og,CascaderPanel:Ug,Avatar:Zg,Drawer:rb}}])["default"]},"60ae":function(e,t,n){var i,r,o=n("da84"),a=n("b39a"),s=o.process,l=s&&s.versions,c=l&&l.v8;c?(i=c.split("."),r=i[0]+i[1]):a&&(i=a.match(/Chrome\/(\d+)/),i&&(r=i[1])),e.exports=r&&+r},"60da":function(e,t,n){"use strict";var i=n("83ab"),r=n("d039"),o=n("df75"),a=n("7418"),s=n("d1e7"),l=n("7b0b"),c=n("44ad"),u=Object.assign;e.exports=!u||r((function(){var e={},t={},n=Symbol(),i="abcdefghijklmnopqrst";return e[n]=7,i.split("").forEach((function(e){t[e]=e})),7!=u({},e)[n]||o(u({},t)).join("")!=i}))?function(e,t){var n=l(e),r=arguments.length,u=1,d=a.f,h=s.f;while(r>u){var f,p=c(arguments[u++]),m=d?o(p).concat(d(p)):o(p),v=m.length,g=0;while(v>g)f=m[g++],i&&!h.call(p,f)||(n[f]=p[f])}return n}:u},6167:function(e,t,n){"use strict";var i,r;"function"===typeof Symbol&&Symbol.iterator;(function(o,a){i=a,r="function"===typeof i?i.call(t,n,t,e):i,void 0===r||(e.exports=r)})(0,(function(){var e=window,t={placement:"bottom",gpuAcceleration:!0,offset:0,boundariesElement:"viewport",boundariesPadding:5,preventOverflowOrder:["left","right","top","bottom"],flipBehavior:"flip",arrowElement:"[x-arrow]",arrowOffset:0,modifiers:["shift","offset","preventOverflow","keepTogether","arrow","flip","applyStyle"],modifiersIgnored:[],forceAbsolute:!1};function n(e,n,i){this._reference=e.jquery?e[0]:e,this.state={};var r="undefined"===typeof n||null===n,o=n&&"[object Object]"===Object.prototype.toString.call(n);return this._popper=r||o?this.parse(o?n:{}):n.jquery?n[0]:n,this._options=Object.assign({},t,i),this._options.modifiers=this._options.modifiers.map(function(e){if(-1===this._options.modifiersIgnored.indexOf(e))return"applyStyle"===e&&this._popper.setAttribute("x-placement",this._options.placement),this.modifiers[e]||e}.bind(this)),this.state.position=this._getPosition(this._popper,this._reference),d(this._popper,{position:this.state.position,top:0}),this.update(),this._setupEventListeners(),this}function i(t){var n=t.style.display,i=t.style.visibility;t.style.display="block",t.style.visibility="hidden";t.offsetWidth;var r=e.getComputedStyle(t),o=parseFloat(r.marginTop)+parseFloat(r.marginBottom),a=parseFloat(r.marginLeft)+parseFloat(r.marginRight),s={width:t.offsetWidth+a,height:t.offsetHeight+o};return t.style.display=n,t.style.visibility=i,s}function r(e){var t={left:"right",right:"left",bottom:"top",top:"bottom"};return e.replace(/left|right|bottom|top/g,(function(e){return t[e]}))}function o(e){var t=Object.assign({},e);return t.right=t.left+t.width,t.bottom=t.top+t.height,t}function a(e,t){var n,i=0;for(n in e){if(e[n]===t)return i;i++}return null}function s(t,n){var i=e.getComputedStyle(t,null);return i[n]}function l(t){var n=t.offsetParent;return n!==e.document.body&&n?n:e.document.documentElement}function c(t){var n=t.parentNode;return n?n===e.document?e.document.body.scrollTop||e.document.body.scrollLeft?e.document.body:e.document.documentElement:-1!==["scroll","auto"].indexOf(s(n,"overflow"))||-1!==["scroll","auto"].indexOf(s(n,"overflow-x"))||-1!==["scroll","auto"].indexOf(s(n,"overflow-y"))?n:c(t.parentNode):t}function u(t){return t!==e.document.body&&("fixed"===s(t,"position")||(t.parentNode?u(t.parentNode):t))}function d(e,t){function n(e){return""!==e&&!isNaN(parseFloat(e))&&isFinite(e)}Object.keys(t).forEach((function(i){var r="";-1!==["width","height","top","right","bottom","left"].indexOf(i)&&n(t[i])&&(r="px"),e.style[i]=t[i]+r}))}function h(e){var t={};return e&&"[object Function]"===t.toString.call(e)}function f(e){var t={width:e.offsetWidth,height:e.offsetHeight,left:e.offsetLeft,top:e.offsetTop};return t.right=t.left+t.width,t.bottom=t.top+t.height,t}function p(e){var t=e.getBoundingClientRect(),n=-1!=navigator.userAgent.indexOf("MSIE"),i=n&&"HTML"===e.tagName?-e.scrollTop:t.top;return{left:t.left,top:i,right:t.right,bottom:t.bottom,width:t.right-t.left,height:t.bottom-i}}function m(e,t,n){var i=p(e),r=p(t);if(n){var o=c(t);r.top+=o.scrollTop,r.bottom+=o.scrollTop,r.left+=o.scrollLeft,r.right+=o.scrollLeft}var a={top:i.top-r.top,left:i.left-r.left,bottom:i.top-r.top+i.height,right:i.left-r.left+i.width,width:i.width,height:i.height};return a}function v(t){for(var n=["","ms","webkit","moz","o"],i=0;i1&&console.warn("WARNING: the given `parent` query("+t.parent+") matched more than one element, the first one will be used"),0===a.length)throw"ERROR: the given `parent` doesn't exists!";a=a[0]}return a.length>1&&a instanceof Element===!1&&(console.warn("WARNING: you have passed as parent a list of elements, the first one will be used"),a=a[0]),a.appendChild(r),r;function s(e,t){t.forEach((function(t){e.classList.add(t)}))}function l(e,t){t.forEach((function(t){e.setAttribute(t.split(":")[0],t.split(":")[1]||"")}))}},n.prototype._getPosition=function(e,t){var n=l(t);if(this._options.forceAbsolute)return"absolute";var i=u(t,n);return i?"fixed":"absolute"},n.prototype._getOffsets=function(e,t,n){n=n.split("-")[0];var r={};r.position=this.state.position;var o="fixed"===r.position,a=m(t,l(e),o),s=i(e);return-1!==["right","left"].indexOf(n)?(r.top=a.top+a.height/2-s.height/2,r.left="left"===n?a.left-s.width:a.right):(r.left=a.left+a.width/2-s.width/2,r.top="top"===n?a.top-s.height:a.bottom),r.width=s.width,r.height=s.height,{popper:r,reference:a}},n.prototype._setupEventListeners=function(){if(this.state.updateBound=this.update.bind(this),e.addEventListener("resize",this.state.updateBound),"window"!==this._options.boundariesElement){var t=c(this._reference);t!==e.document.body&&t!==e.document.documentElement||(t=e),t.addEventListener("scroll",this.state.updateBound),this.state.scrollTarget=t}},n.prototype._removeEventListeners=function(){e.removeEventListener("resize",this.state.updateBound),"window"!==this._options.boundariesElement&&this.state.scrollTarget&&(this.state.scrollTarget.removeEventListener("scroll",this.state.updateBound),this.state.scrollTarget=null),this.state.updateBound=null},n.prototype._getBoundaries=function(t,n,i){var r,o,a={};if("window"===i){var s=e.document.body,u=e.document.documentElement;o=Math.max(s.scrollHeight,s.offsetHeight,u.clientHeight,u.scrollHeight,u.offsetHeight),r=Math.max(s.scrollWidth,s.offsetWidth,u.clientWidth,u.scrollWidth,u.offsetWidth),a={top:0,right:r,bottom:o,left:0}}else if("viewport"===i){var d=l(this._popper),h=c(this._popper),p=f(d),m=function(e){return e==document.body?Math.max(document.documentElement.scrollTop,document.body.scrollTop):e.scrollTop},v=function(e){return e==document.body?Math.max(document.documentElement.scrollLeft,document.body.scrollLeft):e.scrollLeft},g="fixed"===t.offsets.popper.position?0:m(h),b="fixed"===t.offsets.popper.position?0:v(h);a={top:0-(p.top-g),right:e.document.documentElement.clientWidth-(p.left-b),bottom:e.document.documentElement.clientHeight-(p.top-g),left:0-(p.left-b)}}else a=l(this._popper)===i?{top:0,left:0,right:i.clientWidth,bottom:i.clientHeight}:f(i);return a.left+=n,a.right-=n,a.top=a.top+n,a.bottom=a.bottom-n,a},n.prototype.runModifiers=function(e,t,n){var i=t.slice();return void 0!==n&&(i=this._options.modifiers.slice(0,a(this._options.modifiers,n))),i.forEach(function(t){h(t)&&(e=t.call(this,e))}.bind(this)),e},n.prototype.isModifierRequired=function(e,t){var n=a(this._options.modifiers,e);return!!this._options.modifiers.slice(0,n).filter((function(e){return e===t})).length},n.prototype.modifiers={},n.prototype.modifiers.applyStyle=function(e){var t,n={position:e.offsets.popper.position},i=Math.round(e.offsets.popper.left),r=Math.round(e.offsets.popper.top);return this._options.gpuAcceleration&&(t=v("transform"))?(n[t]="translate3d("+i+"px, "+r+"px, 0)",n.top=0,n.left=0):(n.left=i,n.top=r),Object.assign(n,e.styles),d(this._popper,n),this._popper.setAttribute("x-placement",e.placement),this.isModifierRequired(this.modifiers.applyStyle,this.modifiers.arrow)&&e.offsets.arrow&&d(e.arrowElement,e.offsets.arrow),e},n.prototype.modifiers.shift=function(e){var t=e.placement,n=t.split("-")[0],i=t.split("-")[1];if(i){var r=e.offsets.reference,a=o(e.offsets.popper),s={y:{start:{top:r.top},end:{top:r.top+r.height-a.height}},x:{start:{left:r.left},end:{left:r.left+r.width-a.width}}},l=-1!==["bottom","top"].indexOf(n)?"x":"y";e.offsets.popper=Object.assign(a,s[l][i])}return e},n.prototype.modifiers.preventOverflow=function(e){var t=this._options.preventOverflowOrder,n=o(e.offsets.popper),i={left:function(){var t=n.left;return n.lefte.boundaries.right&&(t=Math.min(n.left,e.boundaries.right-n.width)),{left:t}},top:function(){var t=n.top;return n.tope.boundaries.bottom&&(t=Math.min(n.top,e.boundaries.bottom-n.height)),{top:t}}};return t.forEach((function(t){e.offsets.popper=Object.assign(n,i[t]())})),e},n.prototype.modifiers.keepTogether=function(e){var t=o(e.offsets.popper),n=e.offsets.reference,i=Math.floor;return t.righti(n.right)&&(e.offsets.popper.left=i(n.right)),t.bottomi(n.bottom)&&(e.offsets.popper.top=i(n.bottom)),e},n.prototype.modifiers.flip=function(e){if(!this.isModifierRequired(this.modifiers.flip,this.modifiers.preventOverflow))return console.warn("WARNING: preventOverflow modifier is required by flip modifier in order to work, be sure to include it before flip!"),e;if(e.flipped&&e.placement===e._originalPlacement)return e;var t=e.placement.split("-")[0],n=r(t),i=e.placement.split("-")[1]||"",a=[];return a="flip"===this._options.flipBehavior?[t,n]:this._options.flipBehavior,a.forEach(function(s,l){if(t===s&&a.length!==l+1){t=e.placement.split("-")[0],n=r(t);var c=o(e.offsets.popper),u=-1!==["right","bottom"].indexOf(t);(u&&Math.floor(e.offsets.reference[t])>Math.floor(c[n])||!u&&Math.floor(e.offsets.reference[t])s[f]&&(e.offsets.popper[d]+=l[d]+p-s[f]);var m=l[d]+(n||l[u]/2-p/2),v=m-s[d];return v=Math.max(Math.min(s[u]-p-8,v),8),r[d]=v,r[h]="",e.offsets.arrow=r,e.arrowElement=t,e},Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(e){if(void 0===e||null===e)throw new TypeError("Cannot convert first argument to object");for(var t=Object(e),n=1;n=e.length?(this._t=void 0,r(1)):r(0,"keys"==t?n:"values"==t?e[n]:[n,e[n]])}),"values"),o.Arguments=o.Array,i("keys"),i("values"),i("entries")},"693d":function(e,t,n){"use strict";var i=n("ef08"),r=n("9c0e"),o=n("0bad"),a=n("512c"),s=n("ba01"),l=n("e34a").KEY,c=n("4b8b"),u=n("b367"),d=n("92f0"),h=n("8b1a"),f=n("cc15"),p=n("fcd4"),m=n("e198"),v=n("0ae2"),g=n("4ebc"),b=n("77e9"),y=n("7a41"),_=n("0983"),x=n("6ca1"),w=n("3397"),C=n("10db"),k=n("6f4f"),S=n("1836"),O=n("4d20"),$=n("fed5"),D=n("1a14"),E=n("9876"),T=O.f,P=D.f,M=S.f,I=i.Symbol,N=i.JSON,j=N&&N.stringify,A="prototype",F=f("_hidden"),L=f("toPrimitive"),V={}.propertyIsEnumerable,z=u("symbol-registry"),B=u("symbols"),R=u("op-symbols"),H=Object[A],W="function"==typeof I&&!!$.f,q=i.QObject,U=!q||!q[A]||!q[A].findChild,Y=o&&c((function(){return 7!=k(P({},"a",{get:function(){return P(this,"a",{value:7}).a}})).a}))?function(e,t,n){var i=T(H,t);i&&delete H[t],P(e,t,n),i&&e!==H&&P(H,t,i)}:P,K=function(e){var t=B[e]=k(I[A]);return t._k=e,t},G=W&&"symbol"==typeof I.iterator?function(e){return"symbol"==typeof e}:function(e){return e instanceof I},X=function(e,t,n){return e===H&&X(R,t,n),b(e),t=w(t,!0),b(n),r(B,t)?(n.enumerable?(r(e,F)&&e[F][t]&&(e[F][t]=!1),n=k(n,{enumerable:C(0,!1)})):(r(e,F)||P(e,F,C(1,{})),e[F][t]=!0),Y(e,t,n)):P(e,t,n)},Z=function(e,t){b(e);var n,i=v(t=x(t)),r=0,o=i.length;while(o>r)X(e,n=i[r++],t[n]);return e},J=function(e,t){return void 0===t?k(e):Z(k(e),t)},Q=function(e){var t=V.call(this,e=w(e,!0));return!(this===H&&r(B,e)&&!r(R,e))&&(!(t||!r(this,e)||!r(B,e)||r(this,F)&&this[F][e])||t)},ee=function(e,t){if(e=x(e),t=w(t,!0),e!==H||!r(B,t)||r(R,t)){var n=T(e,t);return!n||!r(B,t)||r(e,F)&&e[F][t]||(n.enumerable=!0),n}},te=function(e){var t,n=M(x(e)),i=[],o=0;while(n.length>o)r(B,t=n[o++])||t==F||t==l||i.push(t);return i},ne=function(e){var t,n=e===H,i=M(n?R:x(e)),o=[],a=0;while(i.length>a)!r(B,t=i[a++])||n&&!r(H,t)||o.push(B[t]);return o};W||(I=function(){if(this instanceof I)throw TypeError("Symbol is not a constructor!");var e=h(arguments.length>0?arguments[0]:void 0),t=function(n){this===H&&t.call(R,n),r(this,F)&&r(this[F],e)&&(this[F][e]=!1),Y(this,e,C(1,n))};return o&&U&&Y(H,e,{configurable:!0,set:t}),K(e)},s(I[A],"toString",(function(){return this._k})),O.f=ee,D.f=X,n("6438").f=S.f=te,n("1917").f=Q,$.f=ne,o&&!n("e444")&&s(H,"propertyIsEnumerable",Q,!0),p.f=function(e){return K(f(e))}),a(a.G+a.W+a.F*!W,{Symbol:I});for(var ie="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),re=0;ie.length>re;)f(ie[re++]);for(var oe=E(f.store),ae=0;oe.length>ae;)m(oe[ae++]);a(a.S+a.F*!W,"Symbol",{for:function(e){return r(z,e+="")?z[e]:z[e]=I(e)},keyFor:function(e){if(!G(e))throw TypeError(e+" is not a symbol!");for(var t in z)if(z[t]===e)return t},useSetter:function(){U=!0},useSimple:function(){U=!1}}),a(a.S+a.F*!W,"Object",{create:J,defineProperty:X,defineProperties:Z,getOwnPropertyDescriptor:ee,getOwnPropertyNames:te,getOwnPropertySymbols:ne});var se=c((function(){$.f(1)}));a(a.S+a.F*se,"Object",{getOwnPropertySymbols:function(e){return $.f(_(e))}}),N&&a(a.S+a.F*(!W||c((function(){var e=I();return"[null]"!=j([e])||"{}"!=j({a:e})||"{}"!=j(Object(e))}))),"JSON",{stringify:function(e){var t,n,i=[e],r=1;while(arguments.length>r)i.push(arguments[r++]);if(n=t=i[1],(y(t)||void 0!==e)&&!G(e))return g(t)||(t=function(e,t){if("function"==typeof n&&(t=n.call(this,e,t)),!G(t))return t}),i[1]=t,j.apply(N,i)}}),I[A][L]||n("051b")(I[A],L,I[A].valueOf),d(I,"Symbol"),d(Math,"Math",!0),d(i.JSON,"JSON",!0)},"69f3":function(e,t,n){var i,r,o,a=n("7f9a"),s=n("da84"),l=n("861d"),c=n("9112"),u=n("5135"),d=n("f772"),h=n("d012"),f=s.WeakMap,p=function(e){return o(e)?r(e):i(e,{})},m=function(e){return function(t){var n;if(!l(t)||(n=r(t)).type!==e)throw TypeError("Incompatible receiver, "+e+" required");return n}};if(a){var v=new f,g=v.get,b=v.has,y=v.set;i=function(e,t){return y.call(v,e,t),t},r=function(e){return g.call(v,e)||{}},o=function(e){return b.call(v,e)}}else{var _=d("state");h[_]=!0,i=function(e,t){return c(e,_,t),t},r=function(e){return u(e,_)?e[_]:{}},o=function(e){return u(e,_)}}e.exports={set:i,get:r,has:o,enforce:p,getterFor:m}},"6b7c":function(e,t,n){"use strict";t.__esModule=!0;var i=n("4897");t.default={methods:{t:function(){for(var e=arguments.length,t=Array(e),n=0;n0},e.prototype.connect_=function(){i&&!this.connected_&&(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),u?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){i&&this.connected_&&(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(e){var t=e.propertyName,n=void 0===t?"":t,i=c.some((function(e){return!!~n.indexOf(e)}));i&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),h=function(e,t){for(var n=0,i=Object.keys(t);n0},e}(),D="undefined"!==typeof WeakMap?new WeakMap:new n,E=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var n=d.getInstance(),i=new $(t,n,this);D.set(this,i)}return e}();["observe","unobserve","disconnect"].forEach((function(e){E.prototype[e]=function(){var t;return(t=D.get(this))[e].apply(t,arguments)}}));var T=function(){return"undefined"!==typeof r.ResizeObserver?r.ResizeObserver:E}();t["default"]=T}.call(this,n("c8ba"))},"6eeb":function(e,t,n){var i=n("da84"),r=n("5692"),o=n("9112"),a=n("5135"),s=n("ce4e"),l=n("9e81"),c=n("69f3"),u=c.get,d=c.enforce,h=String(l).split("toString");r("inspectSource",(function(e){return l.call(e)})),(e.exports=function(e,t,n,r){var l=!!r&&!!r.unsafe,c=!!r&&!!r.enumerable,u=!!r&&!!r.noTargetGet;"function"==typeof n&&("string"!=typeof t||a(n,"name")||o(n,"name",t),d(n).source=h.join("string"==typeof t?t:"")),e!==i?(l?!u&&e[t]&&(c=!0):delete e[t],c?e[t]=n:o(e,t,n)):c?e[t]=n:s(t,n)})(Function.prototype,"toString",(function(){return"function"==typeof this&&u(this).source||l.call(this)}))},"6f4f":function(e,t,n){var i=n("77e9"),r=n("85e7"),o=n("9742"),a=n("5a94")("IE_PROTO"),s=function(){},l="prototype",c=function(){var e,t=n("05f5")("iframe"),i=o.length,r="<",a=">";t.style.display="none",n("9141").appendChild(t),t.src="javascript:",e=t.contentWindow.document,e.open(),e.write(r+"script"+a+"document.F=Object"+r+"/script"+a),e.close(),c=e.F;while(i--)delete c[l][o[i]];return c()};e.exports=Object.create||function(e,t){var n;return null!==e?(s[l]=i(e),n=new s,s[l]=null,n[a]=e):n=c(),void 0===t?n:r(n,t)}},"722f":function(e,t,n){"use strict";t.__esModule=!0;var i="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r=n("e452"),o=a(r);function a(e){return e&&e.__esModule?e:{default:e}}var s,l=l||{};l.Dialog=function(e,t,n){var r=this;if(this.dialogNode=e,null===this.dialogNode||"dialog"!==this.dialogNode.getAttribute("role"))throw new Error("Dialog() requires a DOM element with ARIA role of dialog.");"string"===typeof t?this.focusAfterClosed=document.getElementById(t):"object"===("undefined"===typeof t?"undefined":i(t))?this.focusAfterClosed=t:this.focusAfterClosed=null,"string"===typeof n?this.focusFirst=document.getElementById(n):"object"===("undefined"===typeof n?"undefined":i(n))?this.focusFirst=n:this.focusFirst=null,this.focusFirst?this.focusFirst.focus():o.default.focusFirstDescendant(this.dialogNode),this.lastFocus=document.activeElement,s=function(e){r.trapFocus(e)},this.addListeners()},l.Dialog.prototype.addListeners=function(){document.addEventListener("focus",s,!0)},l.Dialog.prototype.removeListeners=function(){document.removeEventListener("focus",s,!0)},l.Dialog.prototype.closeDialog=function(){var e=this;this.removeListeners(),this.focusAfterClosed&&setTimeout((function(){e.focusAfterClosed.focus()}))},l.Dialog.prototype.trapFocus=function(e){o.default.IgnoreUtilFocusChanges||(this.dialogNode.contains(e.target)?this.lastFocus=e.target:(o.default.focusFirstDescendant(this.dialogNode),this.lastFocus===document.activeElement&&o.default.focusLastDescendant(this.dialogNode),this.lastFocus=document.activeElement))},t.default=l.Dialog},7418:function(e,t){t.f=Object.getOwnPropertySymbols},"77e9":function(e,t,n){var i=n("7a41");e.exports=function(e){if(!i(e))throw TypeError(e+" is not an object!");return e}},7839:function(e,t){e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},"7a41":function(e,t){e.exports=function(e){return"object"===typeof e?null!==e:"function"===typeof e}},"7a77":function(e,t,n){"use strict";function i(e){this.message=e}i.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},i.prototype.__CANCEL__=!0,e.exports=i},"7aac":function(e,t,n){"use strict";var i=n("c532");e.exports=i.isStandardBrowserEnv()?function(){return{write:function(e,t,n,r,o,a){var s=[];s.push(e+"="+encodeURIComponent(t)),i.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),i.isString(r)&&s.push("path="+r),i.isString(o)&&s.push("domain="+o),!0===a&&s.push("secure"),document.cookie=s.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},"7b0b":function(e,t,n){var i=n("1d80");e.exports=function(e){return Object(i(e))}},"7b3e":function(e,t,n){"use strict";var i,r=n("a3de"); +/** + * Checks if an event is supported in the current execution environment. + * + * NOTE: This will not work correctly for non-generic events such as `change`, + * `reset`, `load`, `error`, and `select`. + * + * Borrows from Modernizr. + * + * @param {string} eventNameSuffix Event name, e.g. "click". + * @param {?boolean} capture Check if the capture phase is supported. + * @return {boolean} True if the event is supported. + * @internal + * @license Modernizr 3.0.0pre (Custom Build) | MIT + */ +function o(e,t){if(!r.canUseDOM||t&&!("addEventListener"in document))return!1;var n="on"+e,o=n in document;if(!o){var a=document.createElement("div");a.setAttribute(n,"return;"),o="function"===typeof a[n]}return!o&&i&&"wheel"===e&&(o=document.implementation.hasFeature("Events.wheel","3.0")),o}r.canUseDOM&&(i=document.implementation&&document.implementation.hasFeature&&!0!==document.implementation.hasFeature("","")),e.exports=o},"7c73":function(e,t,n){var i=n("825a"),r=n("37e8"),o=n("7839"),a=n("d012"),s=n("1be4"),l=n("cc12"),c=n("f772"),u=c("IE_PROTO"),d="prototype",h=function(){},f=function(){var e,t=l("iframe"),n=o.length,i="<",r="script",a=">",c="java"+r+":";t.style.display="none",s.appendChild(t),t.src=String(c),e=t.contentWindow.document,e.open(),e.write(i+r+a+"document.F=Object"+i+"/"+r+a),e.close(),f=e.F;while(n--)delete f[d][o[n]];return f()};e.exports=Object.create||function(e,t){var n;return null!==e?(h[d]=i(e),n=new h,h[d]=null,n[u]=e):n=f(),void 0===t?n:r(n,t)},a[u]=!0},"7dd0":function(e,t,n){"use strict";var i=n("23e7"),r=n("9ed3"),o=n("e163"),a=n("d2bb"),s=n("d44e"),l=n("9112"),c=n("6eeb"),u=n("b622"),d=n("c430"),h=n("3f8c"),f=n("ae93"),p=f.IteratorPrototype,m=f.BUGGY_SAFARI_ITERATORS,v=u("iterator"),g="keys",b="values",y="entries",_=function(){return this};e.exports=function(e,t,n,u,f,x,w){r(n,t,u);var C,k,S,O=function(e){if(e===f&&P)return P;if(!m&&e in E)return E[e];switch(e){case g:return function(){return new n(this,e)};case b:return function(){return new n(this,e)};case y:return function(){return new n(this,e)}}return function(){return new n(this)}},$=t+" Iterator",D=!1,E=e.prototype,T=E[v]||E["@@iterator"]||f&&E[f],P=!m&&T||O(f),M="Array"==t&&E.entries||T;if(M&&(C=o(M.call(new e)),p!==Object.prototype&&C.next&&(d||o(C)===p||(a?a(C,p):"function"!=typeof C[v]&&l(C,v,_)),s(C,$,!0,!0),d&&(h[$]=_))),f==b&&T&&T.name!==b&&(D=!0,P=function(){return T.call(this)}),d&&!w||E[v]===P||l(E,v,P),h[t]=P,f)if(k={values:O(b),keys:x?P:O(g),entries:O(y)},w)for(S in k)!m&&!D&&S in E||c(E,S,k[S]);else i({target:t,proto:!0,forced:m||D},k);return k}},"7f4d":function(e,t,n){"use strict";t.__esModule=!0,t.default=function(e){for(var t=1,n=arguments.length;t0&&void 0!==arguments[0]?arguments[0]:"";return String(e).replace(/[|\\{}()[\]^$+*?.]/g,"\\$&")};var p=t.arrayFindIndex=function(e,t){for(var n=0;n!==e.length;++n)if(t(e[n]))return n;return-1},m=(t.arrayFind=function(e,t){var n=p(e,t);return-1!==n?e[n]:void 0},t.coerceTruthyValueToArray=function(e){return Array.isArray(e)?e:e?[e]:[]},t.isIE=function(){return!o.default.prototype.$isServer&&!isNaN(Number(document.documentMode))},t.isEdge=function(){return!o.default.prototype.$isServer&&navigator.userAgent.indexOf("Edge")>-1},t.isFirefox=function(){return!o.default.prototype.$isServer&&!!window.navigator.userAgent.match(/firefox/i)},t.autoprefixer=function(e){if("object"!==("undefined"===typeof e?"undefined":i(e)))return e;var t=["transform","transition","animation"],n=["ms-","webkit-"];return t.forEach((function(t){var i=e[t];t&&i&&n.forEach((function(n){e[n+t]=i}))})),e},t.kebabCase=function(e){var t=/([^-])([A-Z])/g;return e.replace(t,"$1-$2").replace(t,"$1-$2").toLowerCase()},t.capitalize=function(e){return(0,a.isString)(e)?e.charAt(0).toUpperCase()+e.slice(1):e},t.looseEqual=function(e,t){var n=(0,a.isObject)(e),i=(0,a.isObject)(t);return n&&i?JSON.stringify(e)===JSON.stringify(t):!n&&!i&&String(e)===String(t)}),v=t.arrayEquals=function(e,t){if(e=e||[],t=t||[],e.length!==t.length)return!1;for(var n=0;nl)i.f(e,n=a[l++],t[n]);return e}},"861d":function(e,t){e.exports=function(e){return"object"===typeof e?null!==e:"function"===typeof e}},"8a0d":function(e,t){e.exports={}},"8b1a":function(e,t){var n=0,i=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+i).toString(36))}},"8bbc":function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=123)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},123:function(e,t,n){"use strict";n.r(t);var i,r,o={name:"ElTag",props:{text:String,closable:Boolean,type:String,hit:Boolean,disableTransitions:Boolean,color:String,size:String,effect:{type:String,default:"light",validator:function(e){return-1!==["dark","light","plain"].indexOf(e)}}},methods:{handleClose:function(e){e.stopPropagation(),this.$emit("close",e)},handleClick:function(e){this.$emit("click",e)}},computed:{tagSize:function(){return this.size||(this.$ELEMENT||{}).size}},render:function(e){var t=this.type,n=this.tagSize,i=this.hit,r=this.effect,o=["el-tag",t?"el-tag--"+t:"",n?"el-tag--"+n:"",r?"el-tag--"+r:"",i&&"is-hit"],a=e("span",{class:o,style:{backgroundColor:this.color},on:{click:this.handleClick}},[this.$slots.default,this.closable&&e("i",{class:"el-tag__close el-icon-close",on:{click:this.handleClose}})]);return this.disableTransitions?a:e("transition",{attrs:{name:"el-zoom-in-center"}},[a])}},a=o,s=n(0),l=Object(s["a"])(a,i,r,!1,null,null,null);l.options.__file="packages/tag/src/tag.vue";var c=l.exports;c.install=function(e){e.component(c.name,c)};t["default"]=c}})},"8c4f":function(e,t,n){"use strict"; +/*! + * vue-router v3.1.3 + * (c) 2019 Evan You + * @license MIT + */function i(e,t){0}function r(e){return Object.prototype.toString.call(e).indexOf("Error")>-1}function o(e,t){return t instanceof e||t&&(t.name===e.name||t._name===e._name)}function a(e,t){for(var n in t)e[n]=t[n];return e}var s={name:"RouterView",functional:!0,props:{name:{type:String,default:"default"}},render:function(e,t){var n=t.props,i=t.children,r=t.parent,o=t.data;o.routerView=!0;var s=r.$createElement,c=n.name,u=r.$route,d=r._routerViewCache||(r._routerViewCache={}),h=0,f=!1;while(r&&r._routerRoot!==r){var p=r.$vnode&&r.$vnode.data;p&&(p.routerView&&h++,p.keepAlive&&r._inactive&&(f=!0)),r=r.$parent}if(o.routerViewDepth=h,f)return s(d[c],o,i);var m=u.matched[h];if(!m)return d[c]=null,s();var v=d[c]=m.components[c];o.registerRouteInstance=function(e,t){var n=m.instances[c];(t&&n!==e||!t&&n===e)&&(m.instances[c]=t)},(o.hook||(o.hook={})).prepatch=function(e,t){m.instances[c]=t.componentInstance},o.hook.init=function(e){e.data.keepAlive&&e.componentInstance&&e.componentInstance!==m.instances[c]&&(m.instances[c]=e.componentInstance)};var g=o.props=l(u,m.props&&m.props[c]);if(g){g=o.props=a({},g);var b=o.attrs=o.attrs||{};for(var y in g)v.props&&y in v.props||(b[y]=g[y],delete g[y])}return s(v,o,i)}};function l(e,t){switch(typeof t){case"undefined":return;case"object":return t;case"function":return t(e);case"boolean":return t?e.params:void 0;default:0}}var c=/[!'()*]/g,u=function(e){return"%"+e.charCodeAt(0).toString(16)},d=/%2C/g,h=function(e){return encodeURIComponent(e).replace(c,u).replace(d,",")},f=decodeURIComponent;function p(e,t,n){void 0===t&&(t={});var i,r=n||m;try{i=r(e||"")}catch(a){i={}}for(var o in t)i[o]=t[o];return i}function m(e){var t={};return e=e.trim().replace(/^(\?|#|&)/,""),e?(e.split("&").forEach((function(e){var n=e.replace(/\+/g," ").split("="),i=f(n.shift()),r=n.length>0?f(n.join("=")):null;void 0===t[i]?t[i]=r:Array.isArray(t[i])?t[i].push(r):t[i]=[t[i],r]})),t):t}function v(e){var t=e?Object.keys(e).map((function(t){var n=e[t];if(void 0===n)return"";if(null===n)return h(t);if(Array.isArray(n)){var i=[];return n.forEach((function(e){void 0!==e&&(null===e?i.push(h(t)):i.push(h(t)+"="+h(e)))})),i.join("&")}return h(t)+"="+h(n)})).filter((function(e){return e.length>0})).join("&"):null;return t?"?"+t:""}var g=/\/?$/;function b(e,t,n,i){var r=i&&i.options.stringifyQuery,o=t.query||{};try{o=y(o)}catch(s){}var a={name:t.name||e&&e.name,meta:e&&e.meta||{},path:t.path||"/",hash:t.hash||"",query:o,params:t.params||{},fullPath:w(t,r),matched:e?x(e):[]};return n&&(a.redirectedFrom=w(n,r)),Object.freeze(a)}function y(e){if(Array.isArray(e))return e.map(y);if(e&&"object"===typeof e){var t={};for(var n in e)t[n]=y(e[n]);return t}return e}var _=b(null,{path:"/"});function x(e){var t=[];while(e)t.unshift(e),e=e.parent;return t}function w(e,t){var n=e.path,i=e.query;void 0===i&&(i={});var r=e.hash;void 0===r&&(r="");var o=t||v;return(n||"/")+o(i)+r}function C(e,t){return t===_?e===t:!!t&&(e.path&&t.path?e.path.replace(g,"")===t.path.replace(g,"")&&e.hash===t.hash&&k(e.query,t.query):!(!e.name||!t.name)&&(e.name===t.name&&e.hash===t.hash&&k(e.query,t.query)&&k(e.params,t.params)))}function k(e,t){if(void 0===e&&(e={}),void 0===t&&(t={}),!e||!t)return e===t;var n=Object.keys(e),i=Object.keys(t);return n.length===i.length&&n.every((function(n){var i=e[n],r=t[n];return"object"===typeof i&&"object"===typeof r?k(i,r):String(i)===String(r)}))}function S(e,t){return 0===e.path.replace(g,"/").indexOf(t.path.replace(g,"/"))&&(!t.hash||e.hash===t.hash)&&O(e.query,t.query)}function O(e,t){for(var n in t)if(!(n in e))return!1;return!0}function $(e,t,n){var i=e.charAt(0);if("/"===i)return e;if("?"===i||"#"===i)return t+e;var r=t.split("/");n&&r[r.length-1]||r.pop();for(var o=e.replace(/^\//,"").split("/"),a=0;a=0&&(t=e.slice(i),e=e.slice(0,i));var r=e.indexOf("?");return r>=0&&(n=e.slice(r+1),e=e.slice(0,r)),{path:e,query:n,hash:t}}function E(e){return e.replace(/\/\//g,"/")}var T=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)},P=X,M=F,I=L,N=B,j=G,A=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function F(e,t){var n,i=[],r=0,o=0,a="",s=t&&t.delimiter||"/";while(null!=(n=A.exec(e))){var l=n[0],c=n[1],u=n.index;if(a+=e.slice(o,u),o=u+l.length,c)a+=c[1];else{var d=e[o],h=n[2],f=n[3],p=n[4],m=n[5],v=n[6],g=n[7];a&&(i.push(a),a="");var b=null!=h&&null!=d&&d!==h,y="+"===v||"*"===v,_="?"===v||"*"===v,x=n[2]||s,w=p||m;i.push({name:f||r++,prefix:h||"",delimiter:x,optional:_,repeat:y,partial:b,asterisk:!!g,pattern:w?H(w):g?".*":"[^"+R(x)+"]+?"})}}return o1||!x.length)return 0===x.length?e():e("span",{},x)}if("a"===this.tag)_.on=y,_.attrs={href:l};else{var w=ae(this.$slots.default);if(w){w.isStatic=!1;var k=w.data=a({},w.data);for(var O in k.on=k.on||{},k.on){var $=k.on[O];O in y&&(k.on[O]=Array.isArray($)?$:[$])}for(var D in y)D in k.on?k.on[D].push(y[D]):k.on[D]=g;var E=w.data.attrs=a({},w.data.attrs);E.href=l}else _.on=y}return e(this.tag,_,this.$slots.default)}};function oe(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&(void 0===e.button||0===e.button)){if(e.currentTarget&&e.currentTarget.getAttribute){var t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function ae(e){if(e)for(var t,n=0;n-1&&(s.params[h]=n.params[h]);return s.path=J(c.path,s.params,'named route "'+l+'"'),u(c,s,a)}if(s.path){s.params={};for(var f=0;f=e.length?n():e[r]?t(e[r],(function(){i(r+1)})):i(r+1)};i(0)}function Fe(e){return function(t,n,i){var o=!1,a=0,s=null;Le(e,(function(e,t,n,l){if("function"===typeof e&&void 0===e.cid){o=!0,a++;var c,u=Re((function(t){Be(t)&&(t=t.default),e.resolved="function"===typeof t?t:ee.extend(t),n.components[l]=t,a--,a<=0&&i()})),d=Re((function(e){var t="Failed to resolve async component "+l+": "+e;s||(s=r(e)?e:new Error(t),i(s))}));try{c=e(u,d)}catch(f){d(f)}if(c)if("function"===typeof c.then)c.then(u,d);else{var h=c.component;h&&"function"===typeof h.then&&h.then(u,d)}}})),o||i()}}function Le(e,t){return Ve(e.map((function(e){return Object.keys(e.components).map((function(n){return t(e.components[n],e.instances[n],e,n)}))})))}function Ve(e){return Array.prototype.concat.apply([],e)}var ze="function"===typeof Symbol&&"symbol"===typeof Symbol.toStringTag;function Be(e){return e.__esModule||ze&&"Module"===e[Symbol.toStringTag]}function Re(e){var t=!1;return function(){var n=[],i=arguments.length;while(i--)n[i]=arguments[i];if(!t)return t=!0,e.apply(this,n)}}var He=function(e){function t(t){e.call(this),this.name=this._name="NavigationDuplicated",this.message='Navigating to current location ("'+t.fullPath+'") is not allowed',Object.defineProperty(this,"stack",{value:(new e).stack,writable:!0,configurable:!0})}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t}(Error);He._name="NavigationDuplicated";var We=function(e,t){this.router=e,this.base=qe(t),this.current=_,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[]};function qe(e){if(!e)if(le){var t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^https?:\/\/[^\/]+/,"")}else e="/";return"/"!==e.charAt(0)&&(e="/"+e),e.replace(/\/$/,"")}function Ue(e,t){var n,i=Math.max(e.length,t.length);for(n=0;n-1?decodeURI(e.slice(0,i))+e.slice(i):decodeURI(e)}else n>-1&&(e=decodeURI(e.slice(0,n))+e.slice(n));return e}function st(e){var t=window.location.href,n=t.indexOf("#"),i=n>=0?t.slice(0,n):t;return i+"#"+e}function lt(e){Ie?Ne(st(e)):window.location.hash=e}function ct(e){Ie?je(st(e)):window.location.replace(st(e))}var ut=function(e){function t(t,n){e.call(this,t,n),this.stack=[],this.index=-1}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.push=function(e,t,n){var i=this;this.transitionTo(e,(function(e){i.stack=i.stack.slice(0,i.index+1).concat(e),i.index++,t&&t(e)}),n)},t.prototype.replace=function(e,t,n){var i=this;this.transitionTo(e,(function(e){i.stack=i.stack.slice(0,i.index).concat(e),t&&t(e)}),n)},t.prototype.go=function(e){var t=this,n=this.index+e;if(!(n<0||n>=this.stack.length)){var i=this.stack[n];this.confirmTransition(i,(function(){t.index=n,t.updateRoute(i)}),(function(e){o(He,e)&&(t.index=n)}))}},t.prototype.getCurrentLocation=function(){var e=this.stack[this.stack.length-1];return e?e.fullPath:"/"},t.prototype.ensureURL=function(){},t}(We),dt=function(e){void 0===e&&(e={}),this.app=null,this.apps=[],this.options=e,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=fe(e.routes||[],this);var t=e.mode||"hash";switch(this.fallback="history"===t&&!Ie&&!1!==e.fallback,this.fallback&&(t="hash"),le||(t="abstract"),this.mode=t,t){case"history":this.history=new tt(this,e.base);break;case"hash":this.history=new it(this,e.base,this.fallback);break;case"abstract":this.history=new ut(this,e.base);break;default:0}},ht={currentRoute:{configurable:!0}};function ft(e,t){return e.push(t),function(){var n=e.indexOf(t);n>-1&&e.splice(n,1)}}function pt(e,t,n){var i="hash"===n?"#"+t:t;return e?E(e+"/"+i):i}dt.prototype.match=function(e,t,n){return this.matcher.match(e,t,n)},ht.currentRoute.get=function(){return this.history&&this.history.current},dt.prototype.init=function(e){var t=this;if(this.apps.push(e),e.$once("hook:destroyed",(function(){var n=t.apps.indexOf(e);n>-1&&t.apps.splice(n,1),t.app===e&&(t.app=t.apps[0]||null)})),!this.app){this.app=e;var n=this.history;if(n instanceof tt)n.transitionTo(n.getCurrentLocation());else if(n instanceof it){var i=function(){n.setupListeners()};n.transitionTo(n.getCurrentLocation(),i,i)}n.listen((function(e){t.apps.forEach((function(t){t._route=e}))}))}},dt.prototype.beforeEach=function(e){return ft(this.beforeHooks,e)},dt.prototype.beforeResolve=function(e){return ft(this.resolveHooks,e)},dt.prototype.afterEach=function(e){return ft(this.afterHooks,e)},dt.prototype.onReady=function(e,t){this.history.onReady(e,t)},dt.prototype.onError=function(e){this.history.onError(e)},dt.prototype.push=function(e,t,n){var i=this;if(!t&&!n&&"undefined"!==typeof Promise)return new Promise((function(t,n){i.history.push(e,t,n)}));this.history.push(e,t,n)},dt.prototype.replace=function(e,t,n){var i=this;if(!t&&!n&&"undefined"!==typeof Promise)return new Promise((function(t,n){i.history.replace(e,t,n)}));this.history.replace(e,t,n)},dt.prototype.go=function(e){this.history.go(e)},dt.prototype.back=function(){this.go(-1)},dt.prototype.forward=function(){this.go(1)},dt.prototype.getMatchedComponents=function(e){var t=e?e.matched?e:this.resolve(e).route:this.currentRoute;return t?[].concat.apply([],t.matched.map((function(e){return Object.keys(e.components).map((function(t){return e.components[t]}))}))):[]},dt.prototype.resolve=function(e,t,n){t=t||this.history.current;var i=Q(e,t,n,this),r=this.match(i,t),o=r.redirectedFrom||r.fullPath,a=this.history.base,s=pt(a,o,this.mode);return{location:i,route:r,href:s,normalizedTo:i,resolved:r}},dt.prototype.addRoutes=function(e){this.matcher.addRoutes(e),this.history.current!==_&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(dt.prototype,ht),dt.install=se,dt.version="3.1.3",le&&window.Vue&&window.Vue.use(dt),t["a"]=dt},"8df4":function(e,t,n){"use strict";var i=n("7a77");function r(e){if("function"!==typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise((function(e){t=e}));var n=this;e((function(e){n.reason||(n.reason=new i(e),t(n.reason))}))}r.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},r.source=function(){var e,t=new r((function(t){e=t}));return{token:t,cancel:e}},e.exports=r},"8eb7":function(e,t){var n,i,r,o,a,s,l,c,u,d,h,f,p,m,v,g=!1;function b(){if(!g){g=!0;var e=navigator.userAgent,t=/(?:MSIE.(\d+\.\d+))|(?:(?:Firefox|GranParadiso|Iceweasel).(\d+\.\d+))|(?:Opera(?:.+Version.|.)(\d+\.\d+))|(?:AppleWebKit.(\d+(?:\.\d+)?))|(?:Trident\/\d+\.\d+.*rv:(\d+\.\d+))/.exec(e),b=/(Mac OS X)|(Windows)|(Linux)/.exec(e);if(f=/\b(iPhone|iP[ao]d)/.exec(e),p=/\b(iP[ao]d)/.exec(e),d=/Android/i.exec(e),m=/FBAN\/\w+;/i.exec(e),v=/Mobile/i.exec(e),h=!!/Win64/.exec(e),t){n=t[1]?parseFloat(t[1]):t[5]?parseFloat(t[5]):NaN,n&&document&&document.documentMode&&(n=document.documentMode);var y=/(?:Trident\/(\d+.\d+))/.exec(e);s=y?parseFloat(y[1])+4:n,i=t[2]?parseFloat(t[2]):NaN,r=t[3]?parseFloat(t[3]):NaN,o=t[4]?parseFloat(t[4]):NaN,o?(t=/(?:Chrome\/(\d+\.\d+))/.exec(e),a=t&&t[1]?parseFloat(t[1]):NaN):a=NaN}else n=i=r=a=o=NaN;if(b){if(b[1]){var _=/(?:Mac OS X (\d+(?:[._]\d+)?))/.exec(e);l=!_||parseFloat(_[1].replace("_","."))}else l=!1;c=!!b[2],u=!!b[3]}else l=c=u=!1}}var y={ie:function(){return b()||n},ieCompatibilityMode:function(){return b()||s>n},ie64:function(){return y.ie()&&h},firefox:function(){return b()||i},opera:function(){return b()||r},webkit:function(){return b()||o},safari:function(){return y.webkit()},chrome:function(){return b()||a},windows:function(){return b()||c},osx:function(){return b()||l},linux:function(){return b()||u},iphone:function(){return b()||f},mobile:function(){return b()||f||p||d||v},nativeApp:function(){return b()||m},android:function(){return b()||d},ipad:function(){return b()||p}};e.exports=y},"90e3":function(e,t){var n=0,i=Math.random();e.exports=function(e){return"Symbol("+String(void 0===e?"":e)+")_"+(++n+i).toString(36)}},9112:function(e,t,n){var i=n("83ab"),r=n("9bf2"),o=n("5c6c");e.exports=i?function(e,t,n){return r.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},9141:function(e,t,n){var i=n("ef08").document;e.exports=i&&i.documentElement},"92f0":function(e,t,n){var i=n("1a14").f,r=n("9c0e"),o=n("cc15")("toStringTag");e.exports=function(e,t,n){e&&!r(e=n?e:e.prototype,o)&&i(e,o,{configurable:!0,value:t})}},"92fa":function(e,t){var n=/^(attrs|props|on|nativeOn|class|style|hook)$/;function i(e,t){return function(){e&&e.apply(this,arguments),t&&t.apply(this,arguments)}}e.exports=function(e){return e.reduce((function(e,t){var r,o,a,s,l;for(a in t)if(r=e[a],o=t[a],r&&n.test(a))if("class"===a&&("string"===typeof r&&(l=r,e[a]=r={},r[l]=!0),"string"===typeof o&&(l=o,t[a]=o={},o[l]=!0)),"on"===a||"nativeOn"===a||"hook"===a)for(s in o)r[s]=i(r[s],o[s]);else if(Array.isArray(r))e[a]=r.concat(o);else if(Array.isArray(o))e[a]=[r].concat(o);else for(s in o)r[s]=o[s];else e[a]=t[a];return e}),{})}},"94ca":function(e,t,n){var i=n("d039"),r=/#|\.prototype\./,o=function(e,t){var n=s[a(e)];return n==c||n!=l&&("function"==typeof t?i(t):!!t)},a=o.normalize=function(e){return String(e).replace(r,".").toLowerCase()},s=o.data={},l=o.NATIVE="N",c=o.POLYFILL="P";e.exports=o},9619:function(e,t,n){var i=n("597f"),r=n("0e15");e.exports={throttle:i,debounce:r}},9742:function(e,t){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},9876:function(e,t,n){var i=n("03d6"),r=n("9742");e.exports=Object.keys||function(e){return i(e,r)}},"99af":function(e,t,n){"use strict";var i=n("23e7"),r=n("d039"),o=n("e8b5"),a=n("861d"),s=n("7b0b"),l=n("50c4"),c=n("8418"),u=n("65f0"),d=n("1dde"),h=n("b622"),f=n("60ae"),p=h("isConcatSpreadable"),m=9007199254740991,v="Maximum allowed index exceeded",g=f>=51||!r((function(){var e=[];return e[p]=!1,e.concat()[0]!==e})),b=d("concat"),y=function(e){if(!a(e))return!1;var t=e[p];return void 0!==t?!!t:o(e)},_=!g||!b;i({target:"Array",proto:!0,forced:_},{concat:function(e){var t,n,i,r,o,a=s(this),d=u(a,0),h=0;for(t=-1,i=arguments.length;tm)throw TypeError(v);for(n=0;n=m)throw TypeError(v);c(d,h++,o)}return d.length=h,d}})},"9bdd":function(e,t,n){var i=n("825a");e.exports=function(e,t,n,r){try{return r?t(i(n)[0],n[1]):t(n)}catch(a){var o=e["return"];throw void 0!==o&&i(o.call(e)),a}}},"9bf2":function(e,t,n){var i=n("83ab"),r=n("0cfb"),o=n("825a"),a=n("c04e"),s=Object.defineProperty;t.f=i?s:function(e,t,n){if(o(e),t=a(t,!0),o(n),r)try{return s(e,t,n)}catch(i){}if("get"in n||"set"in n)throw TypeError("Accessors not supported");return"value"in n&&(e[t]=n.value),e}},"9c0c":function(e,t,n){var i=n("1609");e.exports=function(e,t,n){if(i(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,i){return e.call(t,n,i)};case 3:return function(n,i,r){return e.call(t,n,i,r)}}return function(){return e.apply(t,arguments)}}},"9c0e":function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},"9d11":function(e,t,n){var i=n("fc5e"),r=Math.max,o=Math.min;e.exports=function(e,t){return e=i(e),e<0?r(e+t,0):o(e,t)}},"9d7e":function(e,t,n){"use strict";t.__esModule=!0;var i="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};t.default=function(e){function t(e){for(var t=arguments.length,n=Array(t>1?t-1:0),a=1;a=o)return e;switch(e){case"%s":return String(t[i++]);case"%d":return Number(t[i++]);case"%j":try{return JSON.stringify(t[i++])}catch(n){return"[Circular]"}break;default:return e}})),l=t[i];i()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,url:new RegExp("^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$","i"),hex:/^#?([a-f0-9]{6}|[a-f0-9]{3})$/i},C={integer:function(e){return C.number(e)&&parseInt(e,10)===e},float:function(e){return C.number(e)&&!C.integer(e)},array:function(e){return Array.isArray(e)},regexp:function(e){if(e instanceof RegExp)return!0;try{return!!new RegExp(e)}catch(t){return!1}},date:function(e){return"function"===typeof e.getTime&&"function"===typeof e.getMonth&&"function"===typeof e.getYear},number:function(e){return!isNaN(e)&&"number"===typeof e},object:function(e){return"object"===("undefined"===typeof e?"undefined":a()(e))&&!C.array(e)},method:function(e){return"function"===typeof e},email:function(e){return"string"===typeof e&&!!e.match(w.email)&&e.length<255},url:function(e){return"string"===typeof e&&!!e.match(w.url)},hex:function(e){return"string"===typeof e&&!!e.match(w.hex)}};function k(e,t,n,i,r){if(e.required&&void 0===t)y(e,t,n,i,r);else{var o=["integer","float","array","regexp","object","method","email","number","date","url","hex"],s=e.type;o.indexOf(s)>-1?C[s](t)||i.push(c(r.messages.types[s],e.fullField,e.type)):s&&("undefined"===typeof t?"undefined":a()(t))!==e.type&&i.push(c(r.messages.types[s],e.fullField,e.type))}}var S=k;function O(e,t,n,i,r){var o="number"===typeof e.len,a="number"===typeof e.min,s="number"===typeof e.max,l=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,u=t,d=null,h="number"===typeof t,f="string"===typeof t,p=Array.isArray(t);if(h?d="number":f?d="string":p&&(d="array"),!d)return!1;p&&(u=t.length),f&&(u=t.replace(l,"_").length),o?u!==e.len&&i.push(c(r.messages[d].len,e.fullField,e.len)):a&&!s&&ue.max?i.push(c(r.messages[d].max,e.fullField,e.max)):a&&s&&(ue.max)&&i.push(c(r.messages[d].range,e.fullField,e.min,e.max))}var $=O,D="enum";function E(e,t,n,i,r){e[D]=Array.isArray(e[D])?e[D]:[],-1===e[D].indexOf(t)&&i.push(c(r.messages[D],e.fullField,e[D].join(", ")))}var T=E;function P(e,t,n,i,r){if(e.pattern)if(e.pattern instanceof RegExp)e.pattern.lastIndex=0,e.pattern.test(t)||i.push(c(r.messages.pattern.mismatch,e.fullField,t,e.pattern));else if("string"===typeof e.pattern){var o=new RegExp(e.pattern);o.test(t)||i.push(c(r.messages.pattern.mismatch,e.fullField,t,e.pattern))}}var M=P,I={required:y,whitespace:x,type:S,range:$,enum:T,pattern:M};function N(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t,"string")&&!e.required)return n();I.required(e,t,i,o,r,"string"),d(t,"string")||(I.type(e,t,i,o,r),I.range(e,t,i,o,r),I.pattern(e,t,i,o,r),!0===e.whitespace&&I.whitespace(e,t,i,o,r))}n(o)}var j=N;function A(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),void 0!==t&&I.type(e,t,i,o,r)}n(o)}var F=A;function L(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),void 0!==t&&(I.type(e,t,i,o,r),I.range(e,t,i,o,r))}n(o)}var V=L;function z(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),void 0!==t&&I.type(e,t,i,o,r)}n(o)}var B=z;function R(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),d(t)||I.type(e,t,i,o,r)}n(o)}var H=R;function W(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),void 0!==t&&(I.type(e,t,i,o,r),I.range(e,t,i,o,r))}n(o)}var q=W;function U(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),void 0!==t&&(I.type(e,t,i,o,r),I.range(e,t,i,o,r))}n(o)}var Y=U;function K(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t,"array")&&!e.required)return n();I.required(e,t,i,o,r,"array"),d(t,"array")||(I.type(e,t,i,o,r),I.range(e,t,i,o,r))}n(o)}var G=K;function X(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),void 0!==t&&I.type(e,t,i,o,r)}n(o)}var Z=X,J="enum";function Q(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),t&&I[J](e,t,i,o,r)}n(o)}var ee=Q;function te(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t,"string")&&!e.required)return n();I.required(e,t,i,o,r),d(t,"string")||I.pattern(e,t,i,o,r)}n(o)}var ne=te;function ie(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();if(I.required(e,t,i,o,r),!d(t)){var s=void 0;s="number"===typeof t?new Date(t):t,I.type(e,s,i,o,r),s&&I.range(e,s.getTime(),i,o,r)}}n(o)}var re=ie;function oe(e,t,n,i,r){var o=[],s=Array.isArray(t)?"array":"undefined"===typeof t?"undefined":a()(t);I.required(e,t,i,o,r,s),n(o)}var ae=oe;function se(e,t,n,i,r){var o=e.type,a=[],s=e.required||!e.required&&i.hasOwnProperty(e.field);if(s){if(d(t,o)&&!e.required)return n();I.required(e,t,i,a,r,o),d(t,o)||I.type(e,t,i,a,r)}n(a)}var le=se,ce={string:j,method:F,number:V,boolean:B,regexp:H,integer:q,float:Y,array:G,object:Z,enum:ee,pattern:ne,date:re,url:le,hex:le,email:le,required:ae};function ue(){return{default:"Validation error on field %s",required:"%s is required",enum:"%s must be one of %s",whitespace:"%s cannot be empty",date:{format:"%s date %s is invalid for format %s",parse:"%s date could not be parsed, %s is invalid ",invalid:"%s date %s is invalid"},types:{string:"%s is not a %s",method:"%s is not a %s (function)",array:"%s is not an %s",object:"%s is not an %s",number:"%s is not a %s",date:"%s is not a %s",boolean:"%s is not a %s",integer:"%s is not an %s",float:"%s is not a %s",regexp:"%s is not a valid %s",email:"%s is not a valid %s",url:"%s is not a valid %s",hex:"%s is not a valid %s"},string:{len:"%s must be exactly %s characters",min:"%s must be at least %s characters",max:"%s cannot be longer than %s characters",range:"%s must be between %s and %s characters"},number:{len:"%s must equal %s",min:"%s cannot be less than %s",max:"%s cannot be greater than %s",range:"%s must be between %s and %s"},array:{len:"%s must be exactly %s in length",min:"%s cannot be less than %s in length",max:"%s cannot be greater than %s in length",range:"%s must be between %s and %s in length"},pattern:{mismatch:"%s value %s does not match pattern %s"},clone:function(){var e=JSON.parse(JSON.stringify(this));return e.clone=this.clone,e}}}var de=ue();function he(e){this.rules=null,this._messages=de,this.define(e)}he.prototype={messages:function(e){return e&&(this._messages=g(ue(),e)),this._messages},define:function(e){if(!e)throw new Error("Cannot configure a schema with no rules");if("object"!==("undefined"===typeof e?"undefined":a()(e))||Array.isArray(e))throw new Error("Rules must be an object");this.rules={};var t=void 0,n=void 0;for(t in e)e.hasOwnProperty(t)&&(n=e[t],this.rules[t]=Array.isArray(n)?n:[n])},validate:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments[2],o=e,s=n,u=i;if("function"===typeof s&&(u=s,s={}),this.rules&&0!==Object.keys(this.rules).length){if(s.messages){var d=this.messages();d===de&&(d=ue()),g(d,s.messages),s.messages=d}else s.messages=this.messages();var h=void 0,f=void 0,p={},b=s.keys||Object.keys(this.rules);b.forEach((function(n){h=t.rules[n],f=o[n],h.forEach((function(i){var a=i;"function"===typeof a.transform&&(o===e&&(o=r()({},o)),f=o[n]=a.transform(f)),a="function"===typeof a?{validator:a}:r()({},a),a.validator=t.getValidationMethod(a),a.field=n,a.fullField=a.fullField||n,a.type=t.getType(a),a.validator&&(p[n]=p[n]||[],p[n].push({rule:a,value:f,source:o,field:n}))}))}));var y={};m(p,s,(function(e,t){var n=e.rule,i=("object"===n.type||"array"===n.type)&&("object"===a()(n.fields)||"object"===a()(n.defaultField));function o(e,t){return r()({},t,{fullField:n.fullField+"."+e})}function u(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],u=a;if(Array.isArray(u)||(u=[u]),u.length&&l("async-validator:",u),u.length&&n.message&&(u=[].concat(n.message)),u=u.map(v(n)),s.first&&u.length)return y[n.field]=1,t(u);if(i){if(n.required&&!e.value)return u=n.message?[].concat(n.message).map(v(n)):s.error?[s.error(n,c(s.messages.required,n.field))]:[],t(u);var d={};if(n.defaultField)for(var h in e.value)e.value.hasOwnProperty(h)&&(d[h]=n.defaultField);for(var f in d=r()({},d,e.rule.fields),d)if(d.hasOwnProperty(f)){var p=Array.isArray(d[f])?d[f]:[d[f]];d[f]=p.map(o.bind(null,f))}var m=new he(d);m.messages(s.messages),e.rule.options&&(e.rule.options.messages=s.messages,e.rule.options.error=s.error),m.validate(e.value,e.rule.options||s,(function(e){t(e&&e.length?u.concat(e):e)}))}else t(u)}i=i&&(n.required||!n.required&&e.value),n.field=e.field;var d=n.validator(n,e.value,u,e.source,s);d&&d.then&&d.then((function(){return u()}),(function(e){return u(e)}))}),(function(e){_(e)}))}else u&&u();function _(e){var t=void 0,n=void 0,i=[],r={};function o(e){Array.isArray(e)?i=i.concat.apply(i,e):i.push(e)}for(t=0;tf)throw TypeError(p);for(u=l(b,i),m=0;my-i+n;m--)delete b[m-1]}else if(n>i)for(m=y-i;m>_;m--)v=m+i-1,g=m+n-1,v in b?b[g]=b[v]:delete b[g];for(m=0;m0?i:n)(e)}},a742:function(e,t,n){"use strict";function i(e){return"[object String]"===Object.prototype.toString.call(e)}function r(e){return"[object Object]"===Object.prototype.toString.call(e)}function o(e){return e&&e.nodeType===Node.ELEMENT_NODE}t.__esModule=!0,t.isString=i,t.isObject=r,t.isHtmlElement=o;t.isFunction=function(e){var t={};return e&&"[object Function]"===t.toString.call(e)},t.isUndefined=function(e){return void 0===e},t.isDefined=function(e){return void 0!==e&&null!==e}},a79d:function(e,t,n){"use strict";var i=n("23e7"),r=n("c430"),o=n("fea9"),a=n("d066"),s=n("4840"),l=n("cdf9"),c=n("6eeb");i({target:"Promise",proto:!0,real:!0},{finally:function(e){var t=s(this,a("Promise")),n="function"==typeof e;return this.then(n?function(n){return l(t,e()).then((function(){return n}))}:e,n?function(n){return l(t,e()).then((function(){throw n}))}:e)}}),r||"function"!=typeof o||o.prototype["finally"]||c(o.prototype,"finally",a("Promise").prototype["finally"])},ae93:function(e,t,n){"use strict";var i,r,o,a=n("e163"),s=n("9112"),l=n("5135"),c=n("b622"),u=n("c430"),d=c("iterator"),h=!1,f=function(){return this};[].keys&&(o=[].keys(),"next"in o?(r=a(a(o)),r!==Object.prototype&&(i=r)):h=!0),void 0==i&&(i={}),u||l(i,d)||s(i,d,f),e.exports={IteratorPrototype:i,BUGGY_SAFARI_ITERATORS:h}},b041:function(e,t,n){"use strict";var i=n("f5df"),r=n("b622"),o=r("toStringTag"),a={};a[o]="z",e.exports="[object z]"!==String(a)?function(){return"[object "+i(this)+"]"}:a.toString},b367:function(e,t,n){var i=n("5524"),r=n("ef08"),o="__core-js_shared__",a=r[o]||(r[o]={});(e.exports=function(e,t){return a[e]||(a[e]=void 0!==t?t:{})})("versions",[]).push({version:i.version,mode:n("e444")?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},b39a:function(e,t,n){var i=n("d066");e.exports=i("navigator","userAgent")||""},b50d:function(e,t,n){"use strict";var i=n("c532"),r=n("467f"),o=n("30b5"),a=n("c345"),s=n("3934"),l=n("2d83");e.exports=function(e){return new Promise((function(t,c){var u=e.data,d=e.headers;i.isFormData(u)&&delete d["Content-Type"];var h=new XMLHttpRequest;if(e.auth){var f=e.auth.username||"",p=e.auth.password||"";d.Authorization="Basic "+btoa(f+":"+p)}if(h.open(e.method.toUpperCase(),o(e.url,e.params,e.paramsSerializer),!0),h.timeout=e.timeout,h.onreadystatechange=function(){if(h&&4===h.readyState&&(0!==h.status||h.responseURL&&0===h.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in h?a(h.getAllResponseHeaders()):null,i=e.responseType&&"text"!==e.responseType?h.response:h.responseText,o={data:i,status:h.status,statusText:h.statusText,headers:n,config:e,request:h};r(t,c,o),h=null}},h.onerror=function(){c(l("Network Error",e,null,h)),h=null},h.ontimeout=function(){c(l("timeout of "+e.timeout+"ms exceeded",e,"ECONNABORTED",h)),h=null},i.isStandardBrowserEnv()){var m=n("7aac"),v=(e.withCredentials||s(e.url))&&e.xsrfCookieName?m.read(e.xsrfCookieName):void 0;v&&(d[e.xsrfHeaderName]=v)}if("setRequestHeader"in h&&i.forEach(d,(function(e,t){"undefined"===typeof u&&"content-type"===t.toLowerCase()?delete d[t]:h.setRequestHeader(t,e)})),e.withCredentials&&(h.withCredentials=!0),e.responseType)try{h.responseType=e.responseType}catch(g){if("json"!==e.responseType)throw g}"function"===typeof e.onDownloadProgress&&h.addEventListener("progress",e.onDownloadProgress),"function"===typeof e.onUploadProgress&&h.upload&&h.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then((function(e){h&&(h.abort(),c(e),h=null)})),void 0===u&&(u=null),h.send(u)}))}},b575:function(e,t,n){var i,r,o,a,s,l,c,u,d=n("da84"),h=n("06cf").f,f=n("c6b6"),p=n("2cf4").set,m=n("b39a"),v=d.MutationObserver||d.WebKitMutationObserver,g=d.process,b=d.Promise,y="process"==f(g),_=h(d,"queueMicrotask"),x=_&&_.value;x||(i=function(){var e,t;y&&(e=g.domain)&&e.exit();while(r){t=r.fn,r=r.next;try{t()}catch(n){throw r?a():o=void 0,n}}o=void 0,e&&e.enter()},y?a=function(){g.nextTick(i)}:v&&!/(iphone|ipod|ipad).*applewebkit/i.test(m)?(s=!0,l=document.createTextNode(""),new v(i).observe(l,{characterData:!0}),a=function(){l.data=s=!s}):b&&b.resolve?(c=b.resolve(void 0),u=c.then,a=function(){u.call(c,i)}):a=function(){p.call(d,i)}),e.exports=x||function(e){var t={fn:e,next:void 0};o&&(o.next=t),r||(r=t,a()),o=t}},b622:function(e,t,n){var i=n("da84"),r=n("5692"),o=n("90e3"),a=n("4930"),s=i.Symbol,l=r("wks");e.exports=function(e){return l[e]||(l[e]=a&&s[e]||(a?s:o)("Symbol."+e))}},b9c7:function(e,t,n){n("e507"),e.exports=n("5524").Object.assign},ba01:function(e,t,n){e.exports=n("051b")},bc3a:function(e,t,n){e.exports=n("cee4")},c04e:function(e,t,n){var i=n("861d");e.exports=function(e,t){if(!i(e))return e;var n,r;if(t&&"function"==typeof(n=e.toString)&&!i(r=n.call(e)))return r;if("function"==typeof(n=e.valueOf)&&!i(r=n.call(e)))return r;if(!t&&"function"==typeof(n=e.toString)&&!i(r=n.call(e)))return r;throw TypeError("Can't convert object to primitive value")}},c098:function(e,t,n){e.exports=n("d4af")},c284:function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=88)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},88:function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-progress",class:["el-progress--"+e.type,e.status?"is-"+e.status:"",{"el-progress--without-text":!e.showText,"el-progress--text-inside":e.textInside}],attrs:{role:"progressbar","aria-valuenow":e.percentage,"aria-valuemin":"0","aria-valuemax":"100"}},["line"===e.type?n("div",{staticClass:"el-progress-bar"},[n("div",{staticClass:"el-progress-bar__outer",style:{height:e.strokeWidth+"px"}},[n("div",{staticClass:"el-progress-bar__inner",style:e.barStyle},[e.showText&&e.textInside?n("div",{staticClass:"el-progress-bar__innerText"},[e._v(e._s(e.content))]):e._e()])])]):n("div",{staticClass:"el-progress-circle",style:{height:e.width+"px",width:e.width+"px"}},[n("svg",{attrs:{viewBox:"0 0 100 100"}},[n("path",{staticClass:"el-progress-circle__track",style:e.trailPathStyle,attrs:{d:e.trackPath,stroke:"#e5e9f2","stroke-width":e.relativeStrokeWidth,fill:"none"}}),n("path",{staticClass:"el-progress-circle__path",style:e.circlePathStyle,attrs:{d:e.trackPath,stroke:e.stroke,fill:"none","stroke-linecap":"round","stroke-width":e.percentage?e.relativeStrokeWidth:0}})])]),e.showText&&!e.textInside?n("div",{staticClass:"el-progress__text",style:{fontSize:e.progressTextSize+"px"}},[e.status?n("i",{class:e.iconClass}):[e._v(e._s(e.content))]],2):e._e()])},r=[];i._withStripped=!0;var o={name:"ElProgress",props:{type:{type:String,default:"line",validator:function(e){return["line","circle","dashboard"].indexOf(e)>-1}},percentage:{type:Number,default:0,required:!0,validator:function(e){return e>=0&&e<=100}},status:{type:String,validator:function(e){return["success","exception","warning"].indexOf(e)>-1}},strokeWidth:{type:Number,default:6},textInside:{type:Boolean,default:!1},width:{type:Number,default:126},showText:{type:Boolean,default:!0},color:{type:[String,Array,Function],default:""},format:Function},computed:{barStyle:function(){var e={};return e.width=this.percentage+"%",e.backgroundColor=this.getCurrentColor(this.percentage),e},relativeStrokeWidth:function(){return(this.strokeWidth/this.width*100).toFixed(1)},radius:function(){return"circle"===this.type||"dashboard"===this.type?parseInt(50-parseFloat(this.relativeStrokeWidth)/2,10):0},trackPath:function(){var e=this.radius,t="dashboard"===this.type;return"\n M 50 50\n m 0 "+(t?"":"-")+e+"\n a "+e+" "+e+" 0 1 1 0 "+(t?"-":"")+2*e+"\n a "+e+" "+e+" 0 1 1 0 "+(t?"":"-")+2*e+"\n "},perimeter:function(){return 2*Math.PI*this.radius},rate:function(){return"dashboard"===this.type?.75:1},strokeDashoffset:function(){var e=-1*this.perimeter*(1-this.rate)/2;return e+"px"},trailPathStyle:function(){return{strokeDasharray:this.perimeter*this.rate+"px, "+this.perimeter+"px",strokeDashoffset:this.strokeDashoffset}},circlePathStyle:function(){return{strokeDasharray:this.perimeter*this.rate*(this.percentage/100)+"px, "+this.perimeter+"px",strokeDashoffset:this.strokeDashoffset,transition:"stroke-dasharray 0.6s ease 0s, stroke 0.6s ease"}},stroke:function(){var e=void 0;if(this.color)e=this.getCurrentColor(this.percentage);else switch(this.status){case"success":e="#13ce66";break;case"exception":e="#ff4949";break;case"warning":e="#e6a23c";break;default:e="#20a0ff"}return e},iconClass:function(){return"warning"===this.status?"el-icon-warning":"line"===this.type?"success"===this.status?"el-icon-circle-check":"el-icon-circle-close":"success"===this.status?"el-icon-check":"el-icon-close"},progressTextSize:function(){return"line"===this.type?12+.4*this.strokeWidth:.111111*this.width+2},content:function(){return"function"===typeof this.format?this.format(this.percentage)||"":this.percentage+"%"}},methods:{getCurrentColor:function(e){return"function"===typeof this.color?this.color(e):"string"===typeof this.color?this.color:this.getLevelColor(e)},getLevelColor:function(e){for(var t=this.getColorArray().sort((function(e,t){return e.percentage-t.percentage})),n=0;ne)return t[n].color;return t[t.length-1].color},getColorArray:function(){var e=this.color,t=100/e.length;return e.map((function(e,n){return"string"===typeof e?{color:e,progress:(n+1)*t}:e}))}}},a=o,s=n(0),l=Object(s["a"])(a,i,r,!1,null,null,null);l.options.__file="packages/progress/src/progress.vue";var c=l.exports;c.install=function(e){e.component(c.name,c)};t["default"]=c}})},c345:function(e,t,n){"use strict";var i=n("c532"),r=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,o,a={};return e?(i.forEach(e.split("\n"),(function(e){if(o=e.indexOf(":"),t=i.trim(e.substr(0,o)).toLowerCase(),n=i.trim(e.substr(o+1)),t){if(a[t]&&r.indexOf(t)>=0)return;a[t]="set-cookie"===t?(a[t]?a[t]:[]).concat([n]):a[t]?a[t]+", "+n:n}})),a):a}},c401:function(e,t,n){"use strict";var i=n("c532");e.exports=function(e,t,n){return i.forEach(n,(function(n){e=n(e,t)})),e}},c430:function(e,t){e.exports=!1},c532:function(e,t,n){"use strict";var i=n("1d2b"),r=n("c7ce"),o=Object.prototype.toString;function a(e){return"[object Array]"===o.call(e)}function s(e){return"[object ArrayBuffer]"===o.call(e)}function l(e){return"undefined"!==typeof FormData&&e instanceof FormData}function c(e){var t;return t="undefined"!==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer,t}function u(e){return"string"===typeof e}function d(e){return"number"===typeof e}function h(e){return"undefined"===typeof e}function f(e){return null!==e&&"object"===typeof e}function p(e){return"[object Date]"===o.call(e)}function m(e){return"[object File]"===o.call(e)}function v(e){return"[object Blob]"===o.call(e)}function g(e){return"[object Function]"===o.call(e)}function b(e){return f(e)&&g(e.pipe)}function y(e){return"undefined"!==typeof URLSearchParams&&e instanceof URLSearchParams}function _(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function x(){return("undefined"===typeof navigator||"ReactNative"!==navigator.product)&&("undefined"!==typeof window&&"undefined"!==typeof document)}function w(e,t){if(null!==e&&"undefined"!==typeof e)if("object"!==typeof e&&(e=[e]),a(e))for(var n=0,i=e.length;n2&&void 0!==arguments[2]?arguments[2]:300,i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(!e||!t)throw new Error("instance & callback is required");var r=!1,o=function(){r||(r=!0,t&&t.apply(null,arguments))};i?e.$once("after-leave",o):e.$on("after-leave",o),setTimeout((function(){o()}),n+100)}},c6b6:function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},c6cd:function(e,t,n){var i=n("da84"),r=n("ce4e"),o="__core-js_shared__",a=i[o]||r(o,{});e.exports=a},c7ce:function(e,t){ +/*! + * Determine if an object is a Buffer + * + * @author Feross Aboukhadijeh + * @license MIT + */ +e.exports=function(e){return null!=e&&null!=e.constructor&&"function"===typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}},c8af:function(e,t,n){"use strict";var i=n("c532");e.exports=function(e,t){i.forEach(e,(function(n,i){i!==t&&i.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[i])}))}},c8ba:function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(i){"object"===typeof window&&(n=window)}e.exports=n},c901:function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},ca84:function(e,t,n){var i=n("5135"),r=n("fc6a"),o=n("4d64").indexOf,a=n("d012");e.exports=function(e,t){var n,s=r(e),l=0,c=[];for(n in s)!i(a,n)&&i(s,n)&&c.push(n);while(t.length>l)i(s,n=t[l++])&&(~o(c,n)||c.push(n));return c}},cc12:function(e,t,n){var i=n("da84"),r=n("861d"),o=i.document,a=r(o)&&r(o.createElement);e.exports=function(e){return a?o.createElement(e):{}}},cc15:function(e,t,n){var i=n("b367")("wks"),r=n("8b1a"),o=n("ef08").Symbol,a="function"==typeof o,s=e.exports=function(e){return i[e]||(i[e]=a&&o[e]||(a?o:r)("Symbol."+e))};s.store=i},cca6:function(e,t,n){var i=n("23e7"),r=n("60da");i({target:"Object",stat:!0,forced:Object.assign!==r},{assign:r})},cdf9:function(e,t,n){var i=n("825a"),r=n("861d"),o=n("f069");e.exports=function(e,t){if(i(e),r(t)&&t.constructor===e)return t;var n=o.f(e),a=n.resolve;return a(t),n.promise}},ce4e:function(e,t,n){var i=n("da84"),r=n("9112");e.exports=function(e,t){try{r(i,e,t)}catch(n){i[e]=t}return t}},ce7a:function(e,t,n){var i=n("9c0e"),r=n("0983"),o=n("5a94")("IE_PROTO"),a=Object.prototype;e.exports=Object.getPrototypeOf||function(e){return e=r(e),i(e,o)?e[o]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?a:null}},cee4:function(e,t,n){"use strict";var i=n("c532"),r=n("1d2b"),o=n("0a06"),a=n("2444");function s(e){var t=new o(e),n=r(o.prototype.request,t);return i.extend(n,o.prototype,t),i.extend(n,t),n}var l=s(a);l.Axios=o,l.create=function(e){return s(i.merge(a,e))},l.Cancel=n("7a77"),l.CancelToken=n("8df4"),l.isCancel=n("2e67"),l.all=function(e){return Promise.all(e)},l.spread=n("0df6"),e.exports=l,e.exports.default=l},d010:function(e,t,n){"use strict";function i(e,t,n){this.$children.forEach((function(r){var o=r.$options.componentName;o===e?r.$emit.apply(r,[t].concat(n)):i.apply(r,[e,t].concat([n]))}))}t.__esModule=!0,t.default={methods:{dispatch:function(e,t,n){var i=this.$parent||this.$root,r=i.$options.componentName;while(i&&(!r||r!==e))i=i.$parent,i&&(r=i.$options.componentName);i&&i.$emit.apply(i,[t].concat(n))},broadcast:function(e,t,n){i.call(this,e,t,n)}}}},d012:function(e,t){e.exports={}},d039:function(e,t){e.exports=function(e){try{return!!e()}catch(t){return!0}}},d066:function(e,t,n){var i=n("428f"),r=n("da84"),o=function(e){return"function"==typeof e?e:void 0};e.exports=function(e,t){return arguments.length<2?o(i[e])||o(r[e]):i[e]&&i[e][t]||r[e]&&r[e][t]}},d16a:function(e,t,n){var i=n("fc5e"),r=Math.min;e.exports=function(e){return e>0?r(i(e),9007199254740991):0}},d1e7:function(e,t,n){"use strict";var i={}.propertyIsEnumerable,r=Object.getOwnPropertyDescriptor,o=r&&!i.call({1:2},1);t.f=o?function(e){var t=r(this,e);return!!t&&t.enumerable}:i},d2bb:function(e,t,n){var i=n("825a"),r=n("3bbe");e.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var e,t=!1,n={};try{e=Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set,e.call(n,[]),t=n instanceof Array}catch(o){}return function(n,o){return i(n),r(o),t?e.call(n,o):n.__proto__=o,n}}():void 0)},d397:function(e,t,n){"use strict";function i(e){return void 0!==e&&null!==e}function r(e){var t=/([(\uAC00-\uD7AF)|(\u3130-\u318F)])+/gi;return t.test(e)}t.__esModule=!0,t.isDef=i,t.isKorean=r},d3b7:function(e,t,n){var i=n("6eeb"),r=n("b041"),o=Object.prototype;r!==o.toString&&i(o,"toString",r,{unsafe:!0})},d44e:function(e,t,n){var i=n("9bf2").f,r=n("5135"),o=n("b622"),a=o("toStringTag");e.exports=function(e,t,n){e&&!r(e=n?e:e.prototype,a)&&i(e,a,{configurable:!0,value:t})}},d4af:function(e,t,n){"use strict";var i=n("8eb7"),r=n("7b3e"),o=10,a=40,s=800;function l(e){var t=0,n=0,i=0,r=0;return"detail"in e&&(n=e.detail),"wheelDelta"in e&&(n=-e.wheelDelta/120),"wheelDeltaY"in e&&(n=-e.wheelDeltaY/120),"wheelDeltaX"in e&&(t=-e.wheelDeltaX/120),"axis"in e&&e.axis===e.HORIZONTAL_AXIS&&(t=n,n=0),i=t*o,r=n*o,"deltaY"in e&&(r=e.deltaY),"deltaX"in e&&(i=e.deltaX),(i||r)&&e.deltaMode&&(1==e.deltaMode?(i*=a,r*=a):(i*=s,r*=s)),i&&!t&&(t=i<1?-1:1),r&&!n&&(n=r<1?-1:1),{spinX:t,spinY:n,pixelX:i,pixelY:r}}l.getEventType=function(){return i.firefox()?"DOMMouseScroll":r("wheel")?"wheel":"mousewheel"},e.exports=l},d7d1:function(e,t,n){"use strict";var i;(function(r){var o={},a=/d{1,4}|M{1,4}|yy(?:yy)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g,s="\\d\\d?",l="\\d{3}",c="\\d{4}",u="[^\\s]+",d=/\[([^]*?)\]/gm,h=function(){};function f(e){return e.replace(/[|\\{()[^$+*?.-]/g,"\\$&")}function p(e,t){for(var n=[],i=0,r=e.length;i3?0:(e-e%10!==10)*e%10]}};var x={D:function(e){return e.getDay()},DD:function(e){return v(e.getDay())},Do:function(e,t){return t.DoFn(e.getDate())},d:function(e){return e.getDate()},dd:function(e){return v(e.getDate())},ddd:function(e,t){return t.dayNamesShort[e.getDay()]},dddd:function(e,t){return t.dayNames[e.getDay()]},M:function(e){return e.getMonth()+1},MM:function(e){return v(e.getMonth()+1)},MMM:function(e,t){return t.monthNamesShort[e.getMonth()]},MMMM:function(e,t){return t.monthNames[e.getMonth()]},yy:function(e){return v(String(e.getFullYear()),4).substr(2)},yyyy:function(e){return v(e.getFullYear(),4)},h:function(e){return e.getHours()%12||12},hh:function(e){return v(e.getHours()%12||12)},H:function(e){return e.getHours()},HH:function(e){return v(e.getHours())},m:function(e){return e.getMinutes()},mm:function(e){return v(e.getMinutes())},s:function(e){return e.getSeconds()},ss:function(e){return v(e.getSeconds())},S:function(e){return Math.round(e.getMilliseconds()/100)},SS:function(e){return v(Math.round(e.getMilliseconds()/10),2)},SSS:function(e){return v(e.getMilliseconds(),3)},a:function(e,t){return e.getHours()<12?t.amPm[0]:t.amPm[1]},A:function(e,t){return e.getHours()<12?t.amPm[0].toUpperCase():t.amPm[1].toUpperCase()},ZZ:function(e){var t=e.getTimezoneOffset();return(t>0?"-":"+")+v(100*Math.floor(Math.abs(t)/60)+Math.abs(t)%60,4)}},w={d:[s,function(e,t){e.day=t}],Do:[s+u,function(e,t){e.day=parseInt(t,10)}],M:[s,function(e,t){e.month=t-1}],yy:[s,function(e,t){var n=new Date,i=+(""+n.getFullYear()).substr(0,2);e.year=""+(t>68?i-1:i)+t}],h:[s,function(e,t){e.hour=t}],m:[s,function(e,t){e.minute=t}],s:[s,function(e,t){e.second=t}],yyyy:[c,function(e,t){e.year=t}],S:["\\d",function(e,t){e.millisecond=100*t}],SS:["\\d{2}",function(e,t){e.millisecond=10*t}],SSS:[l,function(e,t){e.millisecond=t}],D:[s,h],ddd:[u,h],MMM:[u,m("monthNamesShort")],MMMM:[u,m("monthNames")],a:[u,function(e,t,n){var i=t.toLowerCase();i===n.amPm[0]?e.isPm=!1:i===n.amPm[1]&&(e.isPm=!0)}],ZZ:["[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z",function(e,t){var n,i=(t+"").match(/([+-]|\d\d)/gi);i&&(n=60*i[1]+parseInt(i[2],10),e.timezoneOffset="+"===i[0]?n:-n)}]};w.dd=w.d,w.dddd=w.ddd,w.DD=w.D,w.mm=w.m,w.hh=w.H=w.HH=w.h,w.MM=w.M,w.ss=w.s,w.A=w.a,o.masks={default:"ddd MMM dd yyyy HH:mm:ss",shortDate:"M/D/yy",mediumDate:"MMM d, yyyy",longDate:"MMMM d, yyyy",fullDate:"dddd, MMMM d, yyyy",shortTime:"HH:mm",mediumTime:"HH:mm:ss",longTime:"HH:mm:ss.SSS"},o.format=function(e,t,n){var i=n||o.i18n;if("number"===typeof e&&(e=new Date(e)),"[object Date]"!==Object.prototype.toString.call(e)||isNaN(e.getTime()))throw new Error("Invalid Date in fecha.format");t=o.masks[t]||t||o.masks["default"];var r=[];return t=t.replace(d,(function(e,t){return r.push(t),"@@@"})),t=t.replace(a,(function(t){return t in x?x[t](e,i):t.slice(1,t.length-1)})),t.replace(/@@@/g,(function(){return r.shift()}))},o.parse=function(e,t,n){var i=n||o.i18n;if("string"!==typeof t)throw new Error("Invalid format in fecha.parse");if(t=o.masks[t]||t,e.length>1e3)return null;var r={},s=[],l=[];t=t.replace(d,(function(e,t){return l.push(t),"@@@"}));var c=f(t).replace(a,(function(e){if(w[e]){var t=w[e];return s.push(t[1]),"("+t[0]+")"}return e}));c=c.replace(/@@@/g,(function(){return l.shift()}));var u=e.match(new RegExp(c,"i"));if(!u)return null;for(var h=1;h1&&void 0!==arguments[1]?arguments[1]:1;return new Date(e.getFullYear(),e.getMonth(),e.getDate()-t)});t.nextDate=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t)},t.getStartDateOfMonth=function(e,t){var n=new Date(e,t,1),i=n.getDay();return m(n,0===i?7:i)},t.getWeekNumber=function(e){if(!h(e))return null;var t=new Date(e.getTime());t.setHours(0,0,0,0),t.setDate(t.getDate()+3-(t.getDay()+6)%7);var n=new Date(t.getFullYear(),0,4);return 1+Math.round(((t.getTime()-n.getTime())/864e5-3+(n.getDay()+6)%7)/7)},t.getRangeHours=function(e){var t=[],n=[];if((e||[]).forEach((function(e){var t=e.map((function(e){return e.getHours()}));n=n.concat(c(t[0],t[1]))})),n.length)for(var i=0;i<24;i++)t[i]=-1===n.indexOf(i);else for(var r=0;r<24;r++)t[r]=!1;return t},t.getPrevMonthLastDays=function(e,t){if(t<=0)return[];var n=new Date(e.getTime());n.setDate(0);var i=n.getDate();return g(t).map((function(e,n){return i-(t-n-1)}))},t.getMonthDays=function(e){var t=new Date(e.getFullYear(),e.getMonth()+1,0),n=t.getDate();return g(n).map((function(e,t){return t+1}))};function v(e,t,n,i){for(var r=t;r0?e.forEach((function(e){var i=e[0],r=e[1],o=i.getHours(),a=i.getMinutes(),s=r.getHours(),l=r.getMinutes();o===t&&s!==t?v(n,a,60,!0):o===t&&s===t?v(n,a,l+1,!0):o!==t&&s===t?v(n,0,l+1,!0):ot&&v(n,0,60,!0)})):v(n,0,60,!0),n};var g=t.range=function(e){return Array.apply(null,{length:e}).map((function(e,t){return t}))},b=t.modifyDate=function(e,t,n,i){return new Date(t,n,i,e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds())},y=t.modifyTime=function(e,t,n,i){return new Date(e.getFullYear(),e.getMonth(),e.getDate(),t,n,i,e.getMilliseconds())},_=(t.modifyWithTimeString=function(e,t){return null!=e&&t?(t=f(t,"HH:mm:ss"),y(e,t.getHours(),t.getMinutes(),t.getSeconds())):e},t.clearTime=function(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate())},t.clearMilliseconds=function(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds(),0)},t.limitTimeRange=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"HH:mm:ss";if(0===t.length)return e;var i=function(e){return r.default.parse(r.default.format(e,n),n)},o=i(e),a=t.map((function(e){return e.map(i)}));if(a.some((function(e){return o>=e[0]&&o<=e[1]})))return e;var s=a[0][0],l=a[0][0];a.forEach((function(e){s=new Date(Math.min(e[0],s)),l=new Date(Math.max(e[1],s))}));var c=o1&&void 0!==arguments[1]?arguments[1]:1,n=e.getFullYear(),i=e.getMonth();return x(e,n-t,i)},t.nextYear=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=e.getFullYear(),i=e.getMonth();return x(e,n+t,i)},t.extractDateFormat=function(e){return e.replace(/\W?m{1,2}|\W?ZZ/g,"").replace(/\W?h{1,2}|\W?s{1,3}|\W?a/gi,"").trim()},t.extractTimeFormat=function(e){return e.replace(/\W?D{1,2}|\W?Do|\W?d{1,4}|\W?M{1,4}|\W?y{2,4}/g,"").trim()},t.validateRangeInOneMonth=function(e,t){return e.getMonth()===t.getMonth()&&e.getFullYear()===t.getFullYear()}},da84:function(e,t,n){(function(t){var n=function(e){return e&&e.Math==Math&&e};e.exports=n("object"==typeof globalThis&&globalThis)||n("object"==typeof window&&window)||n("object"==typeof self&&self)||n("object"==typeof t&&t)||Function("return this")()}).call(this,n("c8ba"))},dcdc:function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=98)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},4:function(e,t){e.exports=n("d010")},98:function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("label",{staticClass:"el-checkbox",class:[e.border&&e.checkboxSize?"el-checkbox--"+e.checkboxSize:"",{"is-disabled":e.isDisabled},{"is-bordered":e.border},{"is-checked":e.isChecked}],attrs:{id:e.id}},[n("span",{staticClass:"el-checkbox__input",class:{"is-disabled":e.isDisabled,"is-checked":e.isChecked,"is-indeterminate":e.indeterminate,"is-focus":e.focus},attrs:{tabindex:!!e.indeterminate&&0,role:!!e.indeterminate&&"checkbox","aria-checked":!!e.indeterminate&&"mixed"}},[n("span",{staticClass:"el-checkbox__inner"}),e.trueLabel||e.falseLabel?n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],staticClass:"el-checkbox__original",attrs:{type:"checkbox","aria-hidden":e.indeterminate?"true":"false",name:e.name,disabled:e.isDisabled,"true-value":e.trueLabel,"false-value":e.falseLabel},domProps:{checked:Array.isArray(e.model)?e._i(e.model,null)>-1:e._q(e.model,e.trueLabel)},on:{change:[function(t){var n=e.model,i=t.target,r=i.checked?e.trueLabel:e.falseLabel;if(Array.isArray(n)){var o=null,a=e._i(n,o);i.checked?a<0&&(e.model=n.concat([o])):a>-1&&(e.model=n.slice(0,a).concat(n.slice(a+1)))}else e.model=r},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}}):n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],staticClass:"el-checkbox__original",attrs:{type:"checkbox","aria-hidden":e.indeterminate?"true":"false",disabled:e.isDisabled,name:e.name},domProps:{value:e.label,checked:Array.isArray(e.model)?e._i(e.model,e.label)>-1:e.model},on:{change:[function(t){var n=e.model,i=t.target,r=!!i.checked;if(Array.isArray(n)){var o=e.label,a=e._i(n,o);i.checked?a<0&&(e.model=n.concat([o])):a>-1&&(e.model=n.slice(0,a).concat(n.slice(a+1)))}else e.model=r},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}})]),e.$slots.default||e.label?n("span",{staticClass:"el-checkbox__label"},[e._t("default"),e.$slots.default?e._e():[e._v(e._s(e.label))]],2):e._e()])},r=[];i._withStripped=!0;var o=n(4),a=n.n(o),s={name:"ElCheckbox",mixins:[a.a],inject:{elForm:{default:""},elFormItem:{default:""}},componentName:"ElCheckbox",data:function(){return{selfModel:!1,focus:!1,isLimitExceeded:!1}},computed:{model:{get:function(){return this.isGroup?this.store:void 0!==this.value?this.value:this.selfModel},set:function(e){this.isGroup?(this.isLimitExceeded=!1,void 0!==this._checkboxGroup.min&&e.lengththis._checkboxGroup.max&&(this.isLimitExceeded=!0),!1===this.isLimitExceeded&&this.dispatch("ElCheckboxGroup","input",[e])):(this.$emit("input",e),this.selfModel=e)}},isChecked:function(){return"[object Boolean]"==={}.toString.call(this.model)?this.model:Array.isArray(this.model)?this.model.indexOf(this.label)>-1:null!==this.model&&void 0!==this.model?this.model===this.trueLabel:void 0},isGroup:function(){var e=this.$parent;while(e){if("ElCheckboxGroup"===e.$options.componentName)return this._checkboxGroup=e,!0;e=e.$parent}return!1},store:function(){return this._checkboxGroup?this._checkboxGroup.value:this.value},isLimitDisabled:function(){var e=this._checkboxGroup,t=e.max,n=e.min;return!(!t&&!n)&&this.model.length>=t&&!this.isChecked||this.model.length<=n&&this.isChecked},isDisabled:function(){return this.isGroup?this._checkboxGroup.disabled||this.disabled||(this.elForm||{}).disabled||this.isLimitDisabled:this.disabled||(this.elForm||{}).disabled},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},checkboxSize:function(){var e=this.size||this._elFormItemSize||(this.$ELEMENT||{}).size;return this.isGroup&&this._checkboxGroup.checkboxGroupSize||e}},props:{value:{},label:{},indeterminate:Boolean,disabled:Boolean,checked:Boolean,name:String,trueLabel:[String,Number],falseLabel:[String,Number],id:String,controls:String,border:Boolean,size:String},methods:{addToStore:function(){Array.isArray(this.model)&&-1===this.model.indexOf(this.label)?this.model.push(this.label):this.model=this.trueLabel||!0},handleChange:function(e){var t=this;if(!this.isLimitExceeded){var n=void 0;n=e.target.checked?void 0===this.trueLabel||this.trueLabel:void 0!==this.falseLabel&&this.falseLabel,this.$emit("change",n,e),this.$nextTick((function(){t.isGroup&&t.dispatch("ElCheckboxGroup","change",[t._checkboxGroup.value])}))}}},created:function(){this.checked&&this.addToStore()},mounted:function(){this.indeterminate&&this.$el.setAttribute("aria-controls",this.controls)},watch:{value:function(e){this.dispatch("ElFormItem","el.form.change",e)}}},l=s,c=n(0),u=Object(c["a"])(l,i,r,!1,null,null,null);u.options.__file="packages/checkbox/src/checkbox.vue";var d=u.exports;d.install=function(e){e.component(d.name,d)};t["default"]=d}})},df75:function(e,t,n){var i=n("ca84"),r=n("7839");e.exports=Object.keys||function(e){return i(e,r)}},df7c:function(e,t,n){(function(e){function n(e,t){for(var n=0,i=e.length-1;i>=0;i--){var r=e[i];"."===r?e.splice(i,1):".."===r?(e.splice(i,1),n++):n&&(e.splice(i,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}function i(e){"string"!==typeof e&&(e+="");var t,n=0,i=-1,r=!0;for(t=e.length-1;t>=0;--t)if(47===e.charCodeAt(t)){if(!r){n=t+1;break}}else-1===i&&(r=!1,i=t+1);return-1===i?"":e.slice(n,i)}function r(e,t){if(e.filter)return e.filter(t);for(var n=[],i=0;i=-1&&!i;o--){var a=o>=0?arguments[o]:e.cwd();if("string"!==typeof a)throw new TypeError("Arguments to path.resolve must be strings");a&&(t=a+"/"+t,i="/"===a.charAt(0))}return t=n(r(t.split("/"),(function(e){return!!e})),!i).join("/"),(i?"/":"")+t||"."},t.normalize=function(e){var i=t.isAbsolute(e),a="/"===o(e,-1);return e=n(r(e.split("/"),(function(e){return!!e})),!i).join("/"),e||i||(e="."),e&&a&&(e+="/"),(i?"/":"")+e},t.isAbsolute=function(e){return"/"===e.charAt(0)},t.join=function(){var e=Array.prototype.slice.call(arguments,0);return t.normalize(r(e,(function(e,t){if("string"!==typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},t.relative=function(e,n){function i(e){for(var t=0;t=0;n--)if(""!==e[n])break;return t>n?[]:e.slice(t,n-t+1)}e=t.resolve(e).substr(1),n=t.resolve(n).substr(1);for(var r=i(e.split("/")),o=i(n.split("/")),a=Math.min(r.length,o.length),s=a,l=0;l=1;--o)if(t=e.charCodeAt(o),47===t){if(!r){i=o;break}}else r=!1;return-1===i?n?"/":".":n&&1===i?"/":e.slice(0,i)},t.basename=function(e,t){var n=i(e);return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},t.extname=function(e){"string"!==typeof e&&(e+="");for(var t=-1,n=0,i=-1,r=!0,o=0,a=e.length-1;a>=0;--a){var s=e.charCodeAt(a);if(47!==s)-1===i&&(r=!1,i=a+1),46===s?-1===t?t=a:1!==o&&(o=1):-1!==t&&(o=-1);else if(!r){n=a+1;break}}return-1===t||-1===i||0===o||1===o&&t===i-1&&t===n+1?"":e.slice(t,i)};var o="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)}}).call(this,n("4362"))},dfe5:function(e,t){},e163:function(e,t,n){var i=n("5135"),r=n("7b0b"),o=n("f772"),a=n("e177"),s=o("IE_PROTO"),l=Object.prototype;e.exports=a?Object.getPrototypeOf:function(e){return e=r(e),i(e,s)?e[s]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?l:null}},e177:function(e,t,n){var i=n("d039");e.exports=!i((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype}))},e198:function(e,t,n){var i=n("ef08"),r=n("5524"),o=n("e444"),a=n("fcd4"),s=n("1a14").f;e.exports=function(e){var t=r.Symbol||(r.Symbol=o?{}:i.Symbol||{});"_"==e.charAt(0)||e in t||s(t,e,{value:a.f(e)})}},e260:function(e,t,n){"use strict";var i=n("fc6a"),r=n("44d2"),o=n("3f8c"),a=n("69f3"),s=n("7dd0"),l="Array Iterator",c=a.set,u=a.getterFor(l);e.exports=s(Array,"Array",(function(e,t){c(this,{type:l,target:i(e),index:0,kind:t})}),(function(){var e=u(this),t=e.target,n=e.kind,i=e.index++;return!t||i>=t.length?(e.target=void 0,{value:void 0,done:!0}):"keys"==n?{value:i,done:!1}:"values"==n?{value:t[i],done:!1}:{value:[i,t[i]],done:!1}}),"values"),o.Arguments=o.Array,r("keys"),r("values"),r("entries")},e2cc:function(e,t,n){var i=n("6eeb");e.exports=function(e,t,n){for(var r in t)i(e,r,t[r],n);return e}},e34a:function(e,t,n){var i=n("8b1a")("meta"),r=n("7a41"),o=n("9c0e"),a=n("1a14").f,s=0,l=Object.isExtensible||function(){return!0},c=!n("4b8b")((function(){return l(Object.preventExtensions({}))})),u=function(e){a(e,i,{value:{i:"O"+ ++s,w:{}}})},d=function(e,t){if(!r(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!o(e,i)){if(!l(e))return"F";if(!t)return"E";u(e)}return e[i].i},h=function(e,t){if(!o(e,i)){if(!l(e))return!0;if(!t)return!1;u(e)}return e[i].w},f=function(e){return c&&p.NEED&&l(e)&&!o(e,i)&&u(e),e},p=e.exports={KEY:i,NEED:!1,fastKey:d,getWeak:h,onFreeze:f}},e444:function(e,t){e.exports=!0},e450:function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=111)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},11:function(e,t){e.exports=n("f3ad")},111:function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:["el-input-number",e.inputNumberSize?"el-input-number--"+e.inputNumberSize:"",{"is-disabled":e.inputNumberDisabled},{"is-without-controls":!e.controls},{"is-controls-right":e.controlsAtRight}],on:{dragstart:function(e){e.preventDefault()}}},[e.controls?n("span",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.decrease,expression:"decrease"}],staticClass:"el-input-number__decrease",class:{"is-disabled":e.minDisabled},attrs:{role:"button"},on:{keydown:function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.decrease(t):null}}},[n("i",{class:"el-icon-"+(e.controlsAtRight?"arrow-down":"minus")})]):e._e(),e.controls?n("span",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.increase,expression:"increase"}],staticClass:"el-input-number__increase",class:{"is-disabled":e.maxDisabled},attrs:{role:"button"},on:{keydown:function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.increase(t):null}}},[n("i",{class:"el-icon-"+(e.controlsAtRight?"arrow-up":"plus")})]):e._e(),n("el-input",{ref:"input",attrs:{value:e.displayValue,placeholder:e.placeholder,disabled:e.inputNumberDisabled,size:e.inputNumberSize,max:e.max,min:e.min,name:e.name,label:e.label},on:{blur:e.handleBlur,focus:e.handleFocus,input:e.handleInput,change:e.handleInputChange},nativeOn:{keydown:[function(t){return"button"in t||!e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"])?(t.preventDefault(),e.increase(t)):null},function(t){return"button"in t||!e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"])?(t.preventDefault(),e.decrease(t)):null}]}})],1)},r=[];i._withStripped=!0;var o=n(11),a=n.n(o),s=n(22),l=n.n(s),c=n(30),u={name:"ElInputNumber",mixins:[l()("input")],inject:{elForm:{default:""},elFormItem:{default:""}},directives:{repeatClick:c["a"]},components:{ElInput:a.a},props:{step:{type:Number,default:1},stepStrictly:{type:Boolean,default:!1},max:{type:Number,default:1/0},min:{type:Number,default:-1/0},value:{},disabled:Boolean,size:String,controls:{type:Boolean,default:!0},controlsPosition:{type:String,default:""},name:String,label:String,placeholder:String,precision:{type:Number,validator:function(e){return e>=0&&e===parseInt(e,10)}}},data:function(){return{currentValue:0,userInput:null}},watch:{value:{immediate:!0,handler:function(e){var t=void 0===e?e:Number(e);if(void 0!==t){if(isNaN(t))return;if(this.stepStrictly){var n=this.getPrecision(this.step),i=Math.pow(10,n);t=Math.round(t/this.step)*i*this.step/i}void 0!==this.precision&&(t=this.toPrecision(t,this.precision))}t>=this.max&&(t=this.max),t<=this.min&&(t=this.min),this.currentValue=t,this.userInput=null,this.$emit("input",t)}}},computed:{minDisabled:function(){return this._decrease(this.value,this.step)this.max},numPrecision:function(){var e=this.value,t=this.step,n=this.getPrecision,i=this.precision,r=n(t);return void 0!==i?(r>i&&console.warn("[Element Warn][InputNumber]precision should not be less than the decimal places of step"),i):Math.max(n(e),r)},controlsAtRight:function(){return this.controls&&"right"===this.controlsPosition},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},inputNumberSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},inputNumberDisabled:function(){return this.disabled||(this.elForm||{}).disabled},displayValue:function(){if(null!==this.userInput)return this.userInput;var e=this.currentValue;if("number"===typeof e){if(this.stepStrictly){var t=this.getPrecision(this.step),n=Math.pow(10,t);e=Math.round(e/this.step)*n*this.step/n}void 0!==this.precision&&(e=e.toFixed(this.precision))}return e}},methods:{toPrecision:function(e,t){return void 0===t&&(t=this.numPrecision),parseFloat(Math.round(e*Math.pow(10,t))/Math.pow(10,t))},getPrecision:function(e){if(void 0===e)return 0;var t=e.toString(),n=t.indexOf("."),i=0;return-1!==n&&(i=t.length-n-1),i},_increase:function(e,t){if("number"!==typeof e&&void 0!==e)return this.currentValue;var n=Math.pow(10,this.numPrecision);return this.toPrecision((n*e+n*t)/n)},_decrease:function(e,t){if("number"!==typeof e&&void 0!==e)return this.currentValue;var n=Math.pow(10,this.numPrecision);return this.toPrecision((n*e-n*t)/n)},increase:function(){if(!this.inputNumberDisabled&&!this.maxDisabled){var e=this.value||0,t=this._increase(e,this.step);this.setCurrentValue(t)}},decrease:function(){if(!this.inputNumberDisabled&&!this.minDisabled){var e=this.value||0,t=this._decrease(e,this.step);this.setCurrentValue(t)}},handleBlur:function(e){this.$emit("blur",e)},handleFocus:function(e){this.$emit("focus",e)},setCurrentValue:function(e){var t=this.currentValue;"number"===typeof e&&void 0!==this.precision&&(e=this.toPrecision(e,this.precision)),e>=this.max&&(e=this.max),e<=this.min&&(e=this.min),t!==e&&(this.userInput=null,this.$emit("input",e),this.$emit("change",e,t),this.currentValue=e)},handleInput:function(e){this.userInput=e},handleInputChange:function(e){var t=""===e?void 0:Number(e);isNaN(t)&&""!==e||this.setCurrentValue(t),this.userInput=null},select:function(){this.$refs.input.select()}},mounted:function(){var e=this.$refs.input.$refs.input;e.setAttribute("role","spinbutton"),e.setAttribute("aria-valuemax",this.max),e.setAttribute("aria-valuemin",this.min),e.setAttribute("aria-valuenow",this.currentValue),e.setAttribute("aria-disabled",this.inputNumberDisabled)},updated:function(){if(this.$refs&&this.$refs.input){var e=this.$refs.input.$refs.input;e.setAttribute("aria-valuenow",this.currentValue)}}},d=u,h=n(0),f=Object(h["a"])(d,i,r,!1,null,null,null);f.options.__file="packages/input-number/src/input-number.vue";var p=f.exports;p.install=function(e){e.component(p.name,p)};t["default"]=p},2:function(e,t){e.exports=n("5924")},22:function(e,t){e.exports=n("12f2")},30:function(e,t,n){"use strict";var i=n(2);t["a"]={bind:function(e,t,n){var r=null,o=void 0,a=function(){return n.context[t.expression].apply()},s=function(){Date.now()-o<100&&a(),clearInterval(r),r=null};Object(i["on"])(e,"mousedown",(function(e){0===e.button&&(o=Date.now(),Object(i["once"])(document,"mouseup",s),clearInterval(r),r=setInterval(a,100))}))}}}})},e452:function(e,t,n){"use strict";t.__esModule=!0;var i=i||{};i.Utils=i.Utils||{},i.Utils.focusFirstDescendant=function(e){for(var t=0;t=0;t--){var n=e.childNodes[t];if(i.Utils.attemptFocus(n)||i.Utils.focusLastDescendant(n))return!0}return!1},i.Utils.attemptFocus=function(e){if(!i.Utils.isFocusable(e))return!1;i.Utils.IgnoreUtilFocusChanges=!0;try{e.focus()}catch(t){}return i.Utils.IgnoreUtilFocusChanges=!1,document.activeElement===e},i.Utils.isFocusable=function(e){if(e.tabIndex>0||0===e.tabIndex&&null!==e.getAttribute("tabIndex"))return!0;if(e.disabled)return!1;switch(e.nodeName){case"A":return!!e.href&&"ignore"!==e.rel;case"INPUT":return"hidden"!==e.type&&"file"!==e.type;case"BUTTON":case"SELECT":case"TEXTAREA":return!0;default:return!1}},i.Utils.triggerEvent=function(e,t){var n=void 0;n=/^mouse|click/.test(t)?"MouseEvents":/^key/.test(t)?"KeyboardEvent":"HTMLEvents";for(var i=document.createEvent(n),r=arguments.length,o=Array(r>2?r-2:0),a=2;a=51&&/native code/.test(L))return!1;var e=L.resolve(1),t=function(e){e((function(){}),(function(){}))},n=e.constructor={};return n[I]=t,!(e.then((function(){}))instanceof t)})),te=ee||!x((function(e){L.all(e)["catch"]((function(){}))})),ne=function(e){var t;return!(!v(e)||"function"!=typeof(t=e.then))&&t},ie=function(e,t,n){if(!t.notified){t.notified=!0;var i=t.reactions;k((function(){var r=t.value,o=t.state==X,a=0;while(i.length>a){var s,l,c,u=i[a++],d=o?u.ok:u.fail,h=u.resolve,f=u.reject,p=u.domain;try{d?(o||(t.rejection===Q&&se(e,t),t.rejection=J),!0===d?s=r:(p&&p.enter(),s=d(r),p&&(p.exit(),c=!0)),s===u.promise?f(V("Promise-chain cycle")):(l=ne(s))?l.call(s,h,f):h(s)):f(r)}catch(m){p&&!c&&p.exit(),f(m)}}t.reactions=[],t.notified=!1,n&&!t.rejection&&oe(e,t)}))}},re=function(e,t,n){var i,r;U?(i=z.createEvent("Event"),i.promise=t,i.reason=n,i.initEvent(e,!1,!0),c.dispatchEvent(i)):i={promise:t,reason:n},(r=c["on"+e])?r(i):e===Y&&O("Unhandled promise rejection",n)},oe=function(e,t){C.call(c,(function(){var n,i=t.value,r=ae(t);if(r&&(n=D((function(){q?B.emit("unhandledRejection",i,e):re(Y,e,i)})),t.rejection=q||ae(t)?Q:J,n.error))throw n.value}))},ae=function(e){return e.rejection!==J&&!e.parent},se=function(e,t){C.call(c,(function(){q?B.emit("rejectionHandled",e):re(K,e,t.value)}))},le=function(e,t,n,i){return function(r){e(t,n,r,i)}},ce=function(e,t,n,i){t.done||(t.done=!0,i&&(t=i),t.value=n,t.state=Z,ie(e,t,!0))},ue=function(e,t,n,i){if(!t.done){t.done=!0,i&&(t=i);try{if(e===n)throw V("Promise can't be resolved itself");var r=ne(n);r?k((function(){var i={done:!1};try{r.call(n,le(ue,e,i,t),le(ce,e,i,t))}catch(o){ce(e,i,o,t)}})):(t.value=n,t.state=X,ie(e,t,!1))}catch(o){ce(e,{done:!1},o,t)}}};ee&&(L=function(e){b(this,L,N),g(e),i.call(this);var t=j(this);try{e(le(ue,this,t),le(ce,this,t))}catch(n){ce(this,t,n)}},i=function(e){A(this,{type:N,done:!1,notified:!1,parent:!1,reactions:[],rejection:!1,state:G,value:void 0})},i.prototype=f(L.prototype,{then:function(e,t){var n=F(this),i=H(w(this,L));return i.ok="function"!=typeof e||e,i.fail="function"==typeof t&&t,i.domain=q?B.domain:void 0,n.parent=!0,n.reactions.push(i),n.state!=G&&ie(this,n,!1),i.promise},catch:function(e){return this.then(void 0,e)}}),r=function(){var e=new i,t=j(e);this.promise=e,this.resolve=le(ue,e,t),this.reject=le(ce,e,t)},$.f=H=function(e){return e===L||e===o?new r(e):W(e)},l||"function"!=typeof d||(a=d.prototype.then,h(d.prototype,"then",(function(e,t){var n=this;return new L((function(e,t){a.call(n,e,t)})).then(e,t)}),{unsafe:!0}),"function"==typeof R&&s({global:!0,enumerable:!0,forced:!0},{fetch:function(e){return S(L,R.apply(c,arguments))}}))),s({global:!0,wrap:!0,forced:ee},{Promise:L}),p(L,N,!1,!0),m(N),o=u(N),s({target:N,stat:!0,forced:ee},{reject:function(e){var t=H(this);return t.reject.call(void 0,e),t.promise}}),s({target:N,stat:!0,forced:l||ee},{resolve:function(e){return S(l&&this===o?L:this,e)}}),s({target:N,stat:!0,forced:te},{all:function(e){var t=this,n=H(t),i=n.resolve,r=n.reject,o=D((function(){var n=g(t.resolve),o=[],a=0,s=1;_(e,(function(e){var l=a++,c=!1;o.push(void 0),s++,n.call(t,e).then((function(e){c||(c=!0,o[l]=e,--s||i(o))}),r)})),--s||i(o)}));return o.error&&r(o.value),n.promise},race:function(e){var t=this,n=H(t),i=n.reject,r=D((function(){var r=g(t.resolve);_(e,(function(e){r.call(t,e).then(n.resolve,i)}))}));return r.error&&i(r.value),n.promise}})},e772:function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=52)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},3:function(e,t){e.exports=n("8122")},33:function(e,t,n){"use strict";var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-select-dropdown__item",class:{selected:e.itemSelected,"is-disabled":e.disabled||e.groupDisabled||e.limitReached,hover:e.hover},on:{mouseenter:e.hoverItem,click:function(t){return t.stopPropagation(),e.selectOptionClick(t)}}},[e._t("default",[n("span",[e._v(e._s(e.currentLabel))])])],2)},r=[];i._withStripped=!0;var o=n(4),a=n.n(o),s=n(3),l="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c={mixins:[a.a],name:"ElOption",componentName:"ElOption",inject:["select"],props:{value:{required:!0},label:[String,Number],created:Boolean,disabled:{type:Boolean,default:!1}},data:function(){return{index:-1,groupDisabled:!1,visible:!0,hitState:!1,hover:!1}},computed:{isObject:function(){return"[object object]"===Object.prototype.toString.call(this.value).toLowerCase()},currentLabel:function(){return this.label||(this.isObject?"":this.value)},currentValue:function(){return this.value||this.label||""},itemSelected:function(){return this.select.multiple?this.contains(this.select.value,this.value):this.isEqual(this.value,this.select.value)},limitReached:function(){return!!this.select.multiple&&(!this.itemSelected&&(this.select.value||[]).length>=this.select.multipleLimit&&this.select.multipleLimit>0)}},watch:{currentLabel:function(){this.created||this.select.remote||this.dispatch("ElSelect","setSelected")},value:function(e,t){var n=this.select,i=n.remote,r=n.valueKey;if(!this.created&&!i){if(r&&"object"===("undefined"===typeof e?"undefined":l(e))&&"object"===("undefined"===typeof t?"undefined":l(t))&&e[r]===t[r])return;this.dispatch("ElSelect","setSelected")}}},methods:{isEqual:function(e,t){if(this.isObject){var n=this.select.valueKey;return Object(s["getValueByPath"])(e,n)===Object(s["getValueByPath"])(t,n)}return e===t},contains:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1];if(this.isObject){var n=this.select.valueKey;return e&&e.some((function(e){return Object(s["getValueByPath"])(e,n)===Object(s["getValueByPath"])(t,n)}))}return e&&e.indexOf(t)>-1},handleGroupDisabled:function(e){this.groupDisabled=e},hoverItem:function(){this.disabled||this.groupDisabled||(this.select.hoverIndex=this.select.options.indexOf(this))},selectOptionClick:function(){!0!==this.disabled&&!0!==this.groupDisabled&&this.dispatch("ElSelect","handleOptionClick",[this,!0])},queryChange:function(e){this.visible=new RegExp(Object(s["escapeRegexpString"])(e),"i").test(this.currentLabel)||this.created,this.visible||this.select.filteredOptionsCount--}},created:function(){this.select.options.push(this),this.select.cachedOptions.push(this),this.select.optionsCount++,this.select.filteredOptionsCount++,this.$on("queryChange",this.queryChange),this.$on("handleGroupDisabled",this.handleGroupDisabled)},beforeDestroy:function(){var e=this.select.cachedOptions.indexOf(this);e>-1&&this.select.cachedOptions.splice(e,1),this.select.onOptionDestroy(this.select.options.indexOf(this))}},u=c,d=n(0),h=Object(d["a"])(u,i,r,!1,null,null,null);h.options.__file="packages/select/src/option.vue";t["a"]=h.exports},4:function(e,t){e.exports=n("d010")},52:function(e,t,n){"use strict";n.r(t);var i=n(33);i["a"].install=function(e){e.component(i["a"].name,i["a"])},t["default"]=i["a"]}})},e893:function(e,t,n){var i=n("5135"),r=n("56ef"),o=n("06cf"),a=n("9bf2");e.exports=function(e,t){for(var n=r(t),s=a.f,l=o.f,c=0;c-1?"center "+n:n+" center"}},appendArrow:function(e){var t=void 0;if(!this.appended){for(var n in this.appended=!0,e.attributes)if(/^_v-/.test(e.attributes[n].name)){t=e.attributes[n].name;break}var i=document.createElement("div");t&&i.setAttribute(t,""),i.setAttribute("x-arrow",""),i.className="popper__arrow",e.appendChild(i)}}},beforeDestroy:function(){this.doDestroy(!0),this.popperElm&&this.popperElm.parentNode===document.body&&(this.popperElm.removeEventListener("click",l),document.body.removeChild(this.popperElm))},deactivated:function(){this.$options.beforeDestroy[0].call(this)}}},ea34:function(e,t){e.exports=function(e,t){return{value:t,done:!!e}}},eedf:function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=118)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},118:function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("button",{staticClass:"el-button",class:[e.type?"el-button--"+e.type:"",e.buttonSize?"el-button--"+e.buttonSize:"",{"is-disabled":e.buttonDisabled,"is-loading":e.loading,"is-plain":e.plain,"is-round":e.round,"is-circle":e.circle}],attrs:{disabled:e.buttonDisabled||e.loading,autofocus:e.autofocus,type:e.nativeType},on:{click:e.handleClick}},[e.loading?n("i",{staticClass:"el-icon-loading"}):e._e(),e.icon&&!e.loading?n("i",{class:e.icon}):e._e(),e.$slots.default?n("span",[e._t("default")],2):e._e()])},r=[];i._withStripped=!0;var o={name:"ElButton",inject:{elForm:{default:""},elFormItem:{default:""}},props:{type:{type:String,default:"default"},size:String,icon:{type:String,default:""},nativeType:{type:String,default:"button"},loading:Boolean,disabled:Boolean,plain:Boolean,autofocus:Boolean,round:Boolean,circle:Boolean},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},buttonSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},buttonDisabled:function(){return this.disabled||(this.elForm||{}).disabled}},methods:{handleClick:function(e){this.$emit("click",e)}}},a=o,s=n(0),l=Object(s["a"])(a,i,r,!1,null,null,null);l.options.__file="packages/button/src/button.vue";var c=l.exports;c.install=function(e){e.component(c.name,c)};t["default"]=c}})},ef08:function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},f069:function(e,t,n){"use strict";var i=n("1c0b"),r=function(e){var t,n;this.promise=new e((function(e,i){if(void 0!==t||void 0!==n)throw TypeError("Bad Promise constructor");t=e,n=i})),this.resolve=i(t),this.reject=i(n)};e.exports.f=function(e){return new r(e)}},f0d9:function(e,t,n){"use strict";t.__esModule=!0,t.default={el:{colorpicker:{confirm:"确定",clear:"清空"},datepicker:{now:"此刻",today:"今天",cancel:"取消",clear:"清空",confirm:"确定",selectDate:"选择日期",selectTime:"选择时间",startDate:"开始日期",startTime:"开始时间",endDate:"结束日期",endTime:"结束时间",prevYear:"前一年",nextYear:"后一年",prevMonth:"上个月",nextMonth:"下个月",year:"年",month1:"1 月",month2:"2 月",month3:"3 月",month4:"4 月",month5:"5 月",month6:"6 月",month7:"7 月",month8:"8 月",month9:"9 月",month10:"10 月",month11:"11 月",month12:"12 月",weeks:{sun:"日",mon:"一",tue:"二",wed:"三",thu:"四",fri:"五",sat:"六"},months:{jan:"一月",feb:"二月",mar:"三月",apr:"四月",may:"五月",jun:"六月",jul:"七月",aug:"八月",sep:"九月",oct:"十月",nov:"十一月",dec:"十二月"}},select:{loading:"加载中",noMatch:"无匹配数据",noData:"无数据",placeholder:"请选择"},cascader:{noMatch:"无匹配数据",loading:"加载中",placeholder:"请选择",noData:"暂无数据"},pagination:{goto:"前往",pagesize:"条/页",total:"共 {total} 条",pageClassifier:"页"},messagebox:{title:"提示",confirm:"确定",cancel:"取消",error:"输入的数据不合法!"},upload:{deleteTip:"按 delete 键可删除",delete:"删除",preview:"查看图片",continue:"继续上传"},table:{emptyText:"暂无数据",confirmFilter:"筛选",resetFilter:"重置",clearFilter:"全部",sumText:"合计"},tree:{emptyText:"暂无数据"},transfer:{noMatch:"无匹配数据",noData:"无数据",titles:["列表 1","列表 2"],filterPlaceholder:"请输入搜索内容",noCheckedFormat:"共 {total} 项",hasCheckedFormat:"已选 {checked}/{total} 项"},image:{error:"加载失败"},pageHeader:{title:"返回"}}}},f3ad:function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=74)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},10:function(e,t){e.exports=n("2bb5")},21:function(e,t){e.exports=n("d397")},4:function(e,t){e.exports=n("d010")},74:function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:["textarea"===e.type?"el-textarea":"el-input",e.inputSize?"el-input--"+e.inputSize:"",{"is-disabled":e.inputDisabled,"is-exceed":e.inputExceed,"el-input-group":e.$slots.prepend||e.$slots.append,"el-input-group--append":e.$slots.append,"el-input-group--prepend":e.$slots.prepend,"el-input--prefix":e.$slots.prefix||e.prefixIcon,"el-input--suffix":e.$slots.suffix||e.suffixIcon||e.clearable||e.showPassword}],on:{mouseenter:function(t){e.hovering=!0},mouseleave:function(t){e.hovering=!1}}},["textarea"!==e.type?[e.$slots.prepend?n("div",{staticClass:"el-input-group__prepend"},[e._t("prepend")],2):e._e(),"textarea"!==e.type?n("input",e._b({ref:"input",staticClass:"el-input__inner",attrs:{tabindex:e.tabindex,type:e.showPassword?e.passwordVisible?"text":"password":e.type,disabled:e.inputDisabled,readonly:e.readonly,autocomplete:e.autoComplete||e.autocomplete,"aria-label":e.label},on:{compositionstart:e.handleCompositionStart,compositionupdate:e.handleCompositionUpdate,compositionend:e.handleCompositionEnd,input:e.handleInput,focus:e.handleFocus,blur:e.handleBlur,change:e.handleChange}},"input",e.$attrs,!1)):e._e(),e.$slots.prefix||e.prefixIcon?n("span",{staticClass:"el-input__prefix"},[e._t("prefix"),e.prefixIcon?n("i",{staticClass:"el-input__icon",class:e.prefixIcon}):e._e()],2):e._e(),e.getSuffixVisible()?n("span",{staticClass:"el-input__suffix"},[n("span",{staticClass:"el-input__suffix-inner"},[e.showClear&&e.showPwdVisible&&e.isWordLimitVisible?e._e():[e._t("suffix"),e.suffixIcon?n("i",{staticClass:"el-input__icon",class:e.suffixIcon}):e._e()],e.showClear?n("i",{staticClass:"el-input__icon el-icon-circle-close el-input__clear",on:{mousedown:function(e){e.preventDefault()},click:e.clear}}):e._e(),e.showPwdVisible?n("i",{staticClass:"el-input__icon el-icon-view el-input__clear",on:{click:e.handlePasswordVisible}}):e._e(),e.isWordLimitVisible?n("span",{staticClass:"el-input__count"},[n("span",{staticClass:"el-input__count-inner"},[e._v("\n "+e._s(e.textLength)+"/"+e._s(e.upperLimit)+"\n ")])]):e._e()],2),e.validateState?n("i",{staticClass:"el-input__icon",class:["el-input__validateIcon",e.validateIcon]}):e._e()]):e._e(),e.$slots.append?n("div",{staticClass:"el-input-group__append"},[e._t("append")],2):e._e()]:n("textarea",e._b({ref:"textarea",staticClass:"el-textarea__inner",style:e.textareaStyle,attrs:{tabindex:e.tabindex,disabled:e.inputDisabled,readonly:e.readonly,autocomplete:e.autoComplete||e.autocomplete,"aria-label":e.label},on:{compositionstart:e.handleCompositionStart,compositionupdate:e.handleCompositionUpdate,compositionend:e.handleCompositionEnd,input:e.handleInput,focus:e.handleFocus,blur:e.handleBlur,change:e.handleChange}},"textarea",e.$attrs,!1)),e.isWordLimitVisible&&"textarea"===e.type?n("span",{staticClass:"el-input__count"},[e._v(e._s(e.textLength)+"/"+e._s(e.upperLimit))]):e._e()],2)},r=[];i._withStripped=!0;var o=n(4),a=n.n(o),s=n(10),l=n.n(s),c=void 0,u="\n height:0 !important;\n visibility:hidden !important;\n overflow:hidden !important;\n position:absolute !important;\n z-index:-1000 !important;\n top:0 !important;\n right:0 !important\n",d=["letter-spacing","line-height","padding-top","padding-bottom","font-family","font-weight","font-size","text-rendering","text-transform","width","text-indent","padding-left","padding-right","border-width","box-sizing"];function h(e){var t=window.getComputedStyle(e),n=t.getPropertyValue("box-sizing"),i=parseFloat(t.getPropertyValue("padding-bottom"))+parseFloat(t.getPropertyValue("padding-top")),r=parseFloat(t.getPropertyValue("border-bottom-width"))+parseFloat(t.getPropertyValue("border-top-width")),o=d.map((function(e){return e+":"+t.getPropertyValue(e)})).join(";");return{contextStyle:o,paddingSize:i,borderSize:r,boxSizing:n}}function f(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;c||(c=document.createElement("textarea"),document.body.appendChild(c));var i=h(e),r=i.paddingSize,o=i.borderSize,a=i.boxSizing,s=i.contextStyle;c.setAttribute("style",s+";"+u),c.value=e.value||e.placeholder||"";var l=c.scrollHeight,d={};"border-box"===a?l+=o:"content-box"===a&&(l-=r),c.value="";var f=c.scrollHeight-r;if(null!==t){var p=f*t;"border-box"===a&&(p=p+r+o),l=Math.max(p,l),d.minHeight=p+"px"}if(null!==n){var m=f*n;"border-box"===a&&(m=m+r+o),l=Math.min(m,l)}return d.height=l+"px",c.parentNode&&c.parentNode.removeChild(c),c=null,d}var p=n(9),m=n.n(p),v=n(21),g={name:"ElInput",componentName:"ElInput",mixins:[a.a,l.a],inheritAttrs:!1,inject:{elForm:{default:""},elFormItem:{default:""}},data:function(){return{textareaCalcStyle:{},hovering:!1,focused:!1,isComposing:!1,passwordVisible:!1}},props:{value:[String,Number],size:String,resize:String,form:String,disabled:Boolean,readonly:Boolean,type:{type:String,default:"text"},autosize:{type:[Boolean,Object],default:!1},autocomplete:{type:String,default:"off"},autoComplete:{type:String,validator:function(e){return!0}},validateEvent:{type:Boolean,default:!0},suffixIcon:String,prefixIcon:String,label:String,clearable:{type:Boolean,default:!1},showPassword:{type:Boolean,default:!1},showWordLimit:{type:Boolean,default:!1},tabindex:String},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},validateState:function(){return this.elFormItem?this.elFormItem.validateState:""},needStatusIcon:function(){return!!this.elForm&&this.elForm.statusIcon},validateIcon:function(){return{validating:"el-icon-loading",success:"el-icon-circle-check",error:"el-icon-circle-close"}[this.validateState]},textareaStyle:function(){return m()({},this.textareaCalcStyle,{resize:this.resize})},inputSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},inputDisabled:function(){return this.disabled||(this.elForm||{}).disabled},nativeInputValue:function(){return null===this.value||void 0===this.value?"":String(this.value)},showClear:function(){return this.clearable&&!this.inputDisabled&&!this.readonly&&this.nativeInputValue&&(this.focused||this.hovering)},showPwdVisible:function(){return this.showPassword&&!this.inputDisabled&&!this.readonly&&(!!this.nativeInputValue||this.focused)},isWordLimitVisible:function(){return this.showWordLimit&&this.$attrs.maxlength&&("text"===this.type||"textarea"===this.type)&&!this.inputDisabled&&!this.readonly&&!this.showPassword},upperLimit:function(){return this.$attrs.maxlength},textLength:function(){return"number"===typeof this.value?String(this.value).length:(this.value||"").length},inputExceed:function(){return this.isWordLimitVisible&&this.textLength>this.upperLimit}},watch:{value:function(e){this.$nextTick(this.resizeTextarea),this.validateEvent&&this.dispatch("ElFormItem","el.form.change",[e])},nativeInputValue:function(){this.setNativeInputValue()},type:function(){var e=this;this.$nextTick((function(){e.setNativeInputValue(),e.resizeTextarea(),e.updateIconOffset()}))}},methods:{focus:function(){this.getInput().focus()},blur:function(){this.getInput().blur()},getMigratingConfig:function(){return{props:{icon:"icon is removed, use suffix-icon / prefix-icon instead.","on-icon-click":"on-icon-click is removed."},events:{click:"click is removed."}}},handleBlur:function(e){this.focused=!1,this.$emit("blur",e),this.validateEvent&&this.dispatch("ElFormItem","el.form.blur",[this.value])},select:function(){this.getInput().select()},resizeTextarea:function(){if(!this.$isServer){var e=this.autosize,t=this.type;if("textarea"===t)if(e){var n=e.minRows,i=e.maxRows;this.textareaCalcStyle=f(this.$refs.textarea,n,i)}else this.textareaCalcStyle={minHeight:f(this.$refs.textarea).minHeight}}},setNativeInputValue:function(){var e=this.getInput();e&&e.value!==this.nativeInputValue&&(e.value=this.nativeInputValue)},handleFocus:function(e){this.focused=!0,this.$emit("focus",e)},handleCompositionStart:function(){this.isComposing=!0},handleCompositionUpdate:function(e){var t=e.target.value,n=t[t.length-1]||"";this.isComposing=!Object(v["isKorean"])(n)},handleCompositionEnd:function(e){this.isComposing&&(this.isComposing=!1,this.handleInput(e))},handleInput:function(e){this.isComposing||e.target.value!==this.nativeInputValue&&(this.$emit("input",e.target.value),this.$nextTick(this.setNativeInputValue))},handleChange:function(e){this.$emit("change",e.target.value)},calcIconOffset:function(e){var t=[].slice.call(this.$el.querySelectorAll(".el-input__"+e)||[]);if(t.length){for(var n=null,i=0;i0?i:n)(e)}},fc6a:function(e,t,n){var i=n("44ad"),r=n("1d80");e.exports=function(e){return i(r(e))}},fcd4:function(e,t,n){t.f=n("cc15")},fea9:function(e,t,n){var i=n("da84");e.exports=i.Promise},fed5:function(e,t){t.f=Object.getOwnPropertySymbols}}]); \ No newline at end of file diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/public/favicon.ico" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/templates/favicon.ico" similarity index 100% rename from "Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/public/favicon.ico" rename to "Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/templates/favicon.ico" diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/templates/index.html" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/templates/index.html" new file mode 100644 index 0000000000000000000000000000000000000000..56ded40e910065a106bf266f908f208db26f2a28 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble/templates/index.html" @@ -0,0 +1 @@ +bubble清单
\ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble_frontend" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble_frontend" new file mode 160000 index 0000000000000000000000000000000000000000..e73fe137738716ae73ee5e596fb096813e7cd2c7 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson25/bubble_frontend" @@ -0,0 +1 @@ +Subproject commit e73fe137738716ae73ee5e596fb096813e7cd2c7 diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/controller/controller.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/controller/controller.go" new file mode 100644 index 0000000000000000000000000000000000000000..6e49c04f0aaf51e62acf60ba5b6a94111d0b1b72 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/controller/controller.go" @@ -0,0 +1,118 @@ +/** + * @Description 控制器 + * @Author 陌溪 + * @Date 2020/9/18 20:06 + **/ +package controller + +import ( + "bubble/entity" + "github.com/gin-gonic/gin" + "net/http" +) + + + +/** url -> controller -> service -> dao -> entity 【请求来了 -> 控制器 -> 业务逻辑 -> 模型层的增删改查】 + * @Description 访问首页 + * @Param + * @return + **/ +func IndexHandler(context *gin.Context) { + context.HTML(http.StatusOK, "index.html", nil) +} + +/** + * @Description 创建Todo + * @Param + * @return + **/ +func CreateTodo(context *gin.Context) { + // 从请求中把数据取出来 + var todo entity.Todo + context.BindJSON(&todo) + // 存入数据库 + err := entity.CreateTodo(&todo) + // 响应 + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "error": err.Error(), + }) + } else { + context.JSON(http.StatusOK, todo) + } +} + +/** + * @Description 查看所有代表事项 + * @Param + * @return + **/ +func GetTodoList(context *gin.Context) { + // 查询所有数据 + todoList, err := entity.GetTodoList() + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "error": err.Error(), + }) + } else { + context.JSON(http.StatusOK, todoList) + } +} + +/** + * @Description 更新代办事项 + * @Param + * @return + **/ +func UpdateTodo(context *gin.Context) { + id, ok := context.Params.Get("id") + if !ok { + context.JSON(http.StatusOK, gin.H{ + "error": "err", + }) + } else { + + todo, err := entity.GetTodoById(id) + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "error": err.Error(), + }) + } else { + // 将内容进行修改 + context.BindJSON(&todo) + err = entity.UpdateTodo(todo) + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "error": err.Error(), + }) + } else { + context.JSON(http.StatusOK, todo) + } + } + } +} + +/** + * @Description 删除代办事项 + * @Param + * @return + **/ +func DeleteTodo(context *gin.Context) { + id, ok := context.Params.Get("id") + if !ok { + context.JSON(http.StatusOK, gin.H{ + "error": "err", + }) + } else { + var todo entity.Todo + err := entity.DeleteTodo(id) + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "error": err, + }) + } else { + context.JSON(http.StatusOK, todo) + } + } +} diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/dao/mysql.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/dao/mysql.go" new file mode 100644 index 0000000000000000000000000000000000000000..53ade112bb2e1cfbd428d936f92cc22f1755d784 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/dao/mysql.go" @@ -0,0 +1,33 @@ +/** + * @Description 通过GORM操作MySQL数据库 + * @Author 陌溪 + * @Date 2020/9/18 20:15 + **/ +package dao + +import ( + "fmt" + "github.com/jinzhu/gorm" +) + +/** + * @Description 定义全局的数据库对象 + **/ +var ( + DB *gorm.DB +) + +/** + * @Description 初始化mysql + * @Param + * @return err + **/ +func InitMySQL() (err error) { + DB, err = gorm.Open("mysql", "root:root@(localhost)/mogu_demo?charset=utf8mb4&parseTime=True&loc=Local") + if err != nil { + fmt.Printf("connect msyql failed, err: %v \n", err) + return + } + // 测试是否能够连通 + return DB.DB().Ping() +} diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/entity/todo.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/entity/todo.go" new file mode 100644 index 0000000000000000000000000000000000000000..d4c6e71fd46ab5226f3dca3987bcb9a66f8f2408 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/entity/todo.go" @@ -0,0 +1,78 @@ +/** + * @Description todo实体类 + * @Author 陌溪 + * @Date 2020/9/18 20:18 + **/ +package entity + +import ( + "bubble/dao" +) + +type Todo struct { + ID int `json:"id"` + Title string `json:"title"` + Status bool `json:"status"` +} + +/** + * @Description 增加todo + * @Param + * @return + **/ +func CreateTodo(todo *Todo) (err error) { + err = dao.DB.Create(&todo).Error + // 响应 + if err != nil { + return err + } + return +} + +/** + * @Description 获取todo列表 + * @Param + * @return + **/ +func GetTodoList() (todoList[] *Todo, err error) { + err = dao.DB.Find(&todoList).Error + if err != nil { + return nil, err + } + return todoList, nil +} + +/** + * @Description 获取Todo通过ID + * @Param + * @return + **/ +func GetTodoById(id string) (todo *Todo, err error) { + todo = new(Todo) + err = dao.DB.Where("id=?", id).Find(&todo).Error + if err != nil { + return nil, err + } + return todo, nil +} + + +/** + * @Description 获取todo列表 + * @Param + * @return + **/ +func UpdateTodo(todo *Todo) (err error) { + err = dao.DB.Save(&todo).Error + return +} + +/** + * @Description 获取todo列表 + * @Param + * @return + **/ +func DeleteTodo(id string) (err error) { + err = dao.DB.Where("id=?", id).Delete(&Todo{}).Error + return +} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/go.mod" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/go.mod" new file mode 100644 index 0000000000000000000000000000000000000000..31fa1c4aee00a07890efec202b6c057f36c502b6 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/go.mod" @@ -0,0 +1,17 @@ +module bubble + +go 1.14 + +require ( + github.com/gin-gonic/gin v1.6.3 + github.com/go-playground/validator/v10 v10.3.0 // indirect + github.com/golang/protobuf v1.4.2 // indirect + github.com/jinzhu/gorm v1.9.16 + github.com/json-iterator/go v1.1.10 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/ugorji/go v1.1.8 // indirect + golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20 // indirect + google.golang.org/protobuf v1.25.0 // indirect + gopkg.in/yaml.v2 v2.3.0 // indirect +) diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/go.sum" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/go.sum" new file mode 100644 index 0000000000000000000000000000000000000000..abc31678f8628d2c0284322e2b2661cbc5c9f925 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/go.sum" @@ -0,0 +1,146 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.3.0 h1:nZU+7q+yJoFmwvNgv/LnPUkwPal62+b2xXj0AU1Es7o= +github.com/go-playground/validator/v10 v10.3.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= +github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.1.8 h1:/D9x7IRpfMHDlizVOgxrag5Fh+/NY+LtI8bsr+AswRA= +github.com/ugorji/go v1.1.8/go.mod h1:0lNM99SwWUIRhCXnigEMClngXBk/EmpTXa7mgiewYWA= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.1.8 h1:4dryPvxMP9OtkjIbuNeK2nb27M38XMHLGlfNSNph/5s= +github.com/ugorji/go/codec v1.1.8/go.mod h1:X00B19HDtwvKbQY2DcYjvZxKQp8mzrJoQ6EgoIY/D2E= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20 h1:4X356008q5SA3YXu8PiRap39KFmy4Lf6sGlceJKZQsU= +golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/main.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..af285eb0eae7bc367a18ede3185a175b65dadebb --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/main.go" @@ -0,0 +1,30 @@ +/** + * @Description 待办事项后台接口 + * @Author 陌溪 + * @Date 2020/9/18 16:02 + **/ +package main + +import ( + "bubble/dao" + "bubble/entity" + "bubble/routers" + "fmt" + _ "github.com/jinzhu/gorm/dialects/mysql" +) + +func main() { + err := dao.InitMySQL() + if err != nil { + panic(err) + } else { + fmt.Println("connect mysql success") + } + // 延迟关闭数据库 + defer dao.DB.Close() + // 模型关闭 自动迁移【把结构体和数据表进行对应】 + dao.DB.AutoMigrate(&entity.Todo{}) + // 注册路由 + r := routers.SetRouter() + r.Run(":8090") +} diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/routers/routers.go" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/routers/routers.go" new file mode 100644 index 0000000000000000000000000000000000000000..22a0c896e05a2894ce94b204a80df60491a783ac --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/routers/routers.go" @@ -0,0 +1,43 @@ +/** + * @Description + * @Author 陌溪 + * @Date 2020/9/18 20:41 + **/ +package routers + +import ( + "bubble/controller" + "github.com/gin-gonic/gin" +) + +/** + * @Description 注册路由 + * @Param + * @return + **/ +func SetRouter() *gin.Engine { + // 定义Gin默认路由 + r := gin.Default() + // 告诉Gin框架模板文件引用的静态文件去哪里找 + r.Static("/static", "static") + // 告诉Gin框架去哪里找模板文件 + r.LoadHTMLGlob("templates/*") + + // 访问待办事项首页 + r.GET("/", controller.IndexHandler) + + // v1 待办事项 + // 前端页面填写代办事项,点击提交就会发送请求到这里 + v1Group := r.Group("v1") + { + // 添加 + v1Group.POST("/todo", controller.CreateTodo) + // 查看【查看所有】 + v1Group.GET("/todo", controller.GetTodoList) + // 修改 + v1Group.PUT("/todo/:id", controller.UpdateTodo) + // 删除 + v1Group.DELETE("/todo/:id",controller.DeleteTodo) + } + return r +} diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/css/app.224ec165.css" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/css/app.224ec165.css" new file mode 100644 index 0000000000000000000000000000000000000000..779676cc13e4d30ec2cd70a043b4f8146687f83b --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/css/app.224ec165.css" @@ -0,0 +1 @@ +.el-table .warning-row{background:#fdf5e6}.el-table .success-row{text-decoration:line-through}.el-footer,.el-header{background-color:#409eff;color:#fff;text-align:center;line-height:60px}.el-footer{background-color:#909399;display:block;width:100%;position:fixed;bottom:0}body{margin:0} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/css/chunk-vendors.57db8905.css" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/css/chunk-vendors.57db8905.css" new file mode 100644 index 0000000000000000000000000000000000000000..384bb0163ba60c7b3e475fc8bb61d730267b442c --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/css/chunk-vendors.57db8905.css" @@ -0,0 +1 @@ +.el-pagination--small .arrow.disabled,.el-table--hidden,.el-table .hidden-columns,.el-table td.is-hidden>*,.el-table th.is-hidden>*{visibility:hidden}.el-dropdown .el-dropdown-selfdefine:focus:active,.el-dropdown .el-dropdown-selfdefine:focus:not(.focusing),.el-message__closeBtn:focus,.el-message__content:focus,.el-popover:focus,.el-popover:focus:active,.el-popover__reference:focus:hover,.el-popover__reference:focus:not(.focusing),.el-rate:active,.el-rate:focus,.el-tooltip:focus:hover,.el-tooltip:focus:not(.focusing),.el-upload-list__item.is-success:active,.el-upload-list__item.is-success:not(.focusing):focus{outline-width:0}.el-input__suffix,.el-tree.is-dragging .el-tree-node__content *{pointer-events:none}@font-face{font-family:element-icons;src:url(../../static/fonts/element-icons.535877f5.woff) format("woff"),url(../../static/fonts/element-icons.732389de.ttf) format("truetype");font-weight:400;font-display:"auto";font-style:normal}[class*=" el-icon-"],[class^=el-icon-]{font-family:element-icons!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;vertical-align:baseline;display:inline-block;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.el-icon-ice-cream-round:before{content:"\e6a0"}.el-icon-ice-cream-square:before{content:"\e6a3"}.el-icon-lollipop:before{content:"\e6a4"}.el-icon-potato-strips:before{content:"\e6a5"}.el-icon-milk-tea:before{content:"\e6a6"}.el-icon-ice-drink:before{content:"\e6a7"}.el-icon-ice-tea:before{content:"\e6a9"}.el-icon-coffee:before{content:"\e6aa"}.el-icon-orange:before{content:"\e6ab"}.el-icon-pear:before{content:"\e6ac"}.el-icon-apple:before{content:"\e6ad"}.el-icon-cherry:before{content:"\e6ae"}.el-icon-watermelon:before{content:"\e6af"}.el-icon-grape:before{content:"\e6b0"}.el-icon-refrigerator:before{content:"\e6b1"}.el-icon-goblet-square-full:before{content:"\e6b2"}.el-icon-goblet-square:before{content:"\e6b3"}.el-icon-goblet-full:before{content:"\e6b4"}.el-icon-goblet:before{content:"\e6b5"}.el-icon-cold-drink:before{content:"\e6b6"}.el-icon-coffee-cup:before{content:"\e6b8"}.el-icon-water-cup:before{content:"\e6b9"}.el-icon-hot-water:before{content:"\e6ba"}.el-icon-ice-cream:before{content:"\e6bb"}.el-icon-dessert:before{content:"\e6bc"}.el-icon-sugar:before{content:"\e6bd"}.el-icon-tableware:before{content:"\e6be"}.el-icon-burger:before{content:"\e6bf"}.el-icon-knife-fork:before{content:"\e6c1"}.el-icon-fork-spoon:before{content:"\e6c2"}.el-icon-chicken:before{content:"\e6c3"}.el-icon-food:before{content:"\e6c4"}.el-icon-dish-1:before{content:"\e6c5"}.el-icon-dish:before{content:"\e6c6"}.el-icon-moon-night:before{content:"\e6ee"}.el-icon-moon:before{content:"\e6f0"}.el-icon-cloudy-and-sunny:before{content:"\e6f1"}.el-icon-partly-cloudy:before{content:"\e6f2"}.el-icon-cloudy:before{content:"\e6f3"}.el-icon-sunny:before{content:"\e6f6"}.el-icon-sunset:before{content:"\e6f7"}.el-icon-sunrise-1:before{content:"\e6f8"}.el-icon-sunrise:before{content:"\e6f9"}.el-icon-heavy-rain:before{content:"\e6fa"}.el-icon-lightning:before{content:"\e6fb"}.el-icon-light-rain:before{content:"\e6fc"}.el-icon-wind-power:before{content:"\e6fd"}.el-icon-baseball:before{content:"\e712"}.el-icon-soccer:before{content:"\e713"}.el-icon-football:before{content:"\e715"}.el-icon-basketball:before{content:"\e716"}.el-icon-ship:before{content:"\e73f"}.el-icon-truck:before{content:"\e740"}.el-icon-bicycle:before{content:"\e741"}.el-icon-mobile-phone:before{content:"\e6d3"}.el-icon-service:before{content:"\e6d4"}.el-icon-key:before{content:"\e6e2"}.el-icon-unlock:before{content:"\e6e4"}.el-icon-lock:before{content:"\e6e5"}.el-icon-watch:before{content:"\e6fe"}.el-icon-watch-1:before{content:"\e6ff"}.el-icon-timer:before{content:"\e702"}.el-icon-alarm-clock:before{content:"\e703"}.el-icon-map-location:before{content:"\e704"}.el-icon-delete-location:before{content:"\e705"}.el-icon-add-location:before{content:"\e706"}.el-icon-location-information:before{content:"\e707"}.el-icon-location-outline:before{content:"\e708"}.el-icon-location:before{content:"\e79e"}.el-icon-place:before{content:"\e709"}.el-icon-discover:before{content:"\e70a"}.el-icon-first-aid-kit:before{content:"\e70b"}.el-icon-trophy-1:before{content:"\e70c"}.el-icon-trophy:before{content:"\e70d"}.el-icon-medal:before{content:"\e70e"}.el-icon-medal-1:before{content:"\e70f"}.el-icon-stopwatch:before{content:"\e710"}.el-icon-mic:before{content:"\e711"}.el-icon-copy-document:before{content:"\e718"}.el-icon-full-screen:before{content:"\e719"}.el-icon-switch-button:before{content:"\e71b"}.el-icon-aim:before{content:"\e71c"}.el-icon-crop:before{content:"\e71d"}.el-icon-odometer:before{content:"\e71e"}.el-icon-time:before{content:"\e71f"}.el-icon-bangzhu:before{content:"\e724"}.el-icon-close-notification:before{content:"\e726"}.el-icon-microphone:before{content:"\e727"}.el-icon-turn-off-microphone:before{content:"\e728"}.el-icon-position:before{content:"\e729"}.el-icon-postcard:before{content:"\e72a"}.el-icon-message:before{content:"\e72b"}.el-icon-chat-line-square:before{content:"\e72d"}.el-icon-chat-dot-square:before{content:"\e72e"}.el-icon-chat-dot-round:before{content:"\e72f"}.el-icon-chat-square:before{content:"\e730"}.el-icon-chat-line-round:before{content:"\e731"}.el-icon-chat-round:before{content:"\e732"}.el-icon-set-up:before{content:"\e733"}.el-icon-turn-off:before{content:"\e734"}.el-icon-open:before{content:"\e735"}.el-icon-connection:before{content:"\e736"}.el-icon-link:before{content:"\e737"}.el-icon-cpu:before{content:"\e738"}.el-icon-thumb:before{content:"\e739"}.el-icon-female:before{content:"\e73a"}.el-icon-male:before{content:"\e73b"}.el-icon-guide:before{content:"\e73c"}.el-icon-news:before{content:"\e73e"}.el-icon-price-tag:before{content:"\e744"}.el-icon-discount:before{content:"\e745"}.el-icon-wallet:before{content:"\e747"}.el-icon-coin:before{content:"\e748"}.el-icon-money:before{content:"\e749"}.el-icon-bank-card:before{content:"\e74a"}.el-icon-box:before{content:"\e74b"}.el-icon-present:before{content:"\e74c"}.el-icon-sell:before{content:"\e6d5"}.el-icon-sold-out:before{content:"\e6d6"}.el-icon-shopping-bag-2:before{content:"\e74d"}.el-icon-shopping-bag-1:before{content:"\e74e"}.el-icon-shopping-cart-2:before{content:"\e74f"}.el-icon-shopping-cart-1:before{content:"\e750"}.el-icon-shopping-cart-full:before{content:"\e751"}.el-icon-smoking:before{content:"\e752"}.el-icon-no-smoking:before{content:"\e753"}.el-icon-house:before{content:"\e754"}.el-icon-table-lamp:before{content:"\e755"}.el-icon-school:before{content:"\e756"}.el-icon-office-building:before{content:"\e757"}.el-icon-toilet-paper:before{content:"\e758"}.el-icon-notebook-2:before{content:"\e759"}.el-icon-notebook-1:before{content:"\e75a"}.el-icon-files:before{content:"\e75b"}.el-icon-collection:before{content:"\e75c"}.el-icon-receiving:before{content:"\e75d"}.el-icon-suitcase-1:before{content:"\e760"}.el-icon-suitcase:before{content:"\e761"}.el-icon-film:before{content:"\e763"}.el-icon-collection-tag:before{content:"\e765"}.el-icon-data-analysis:before{content:"\e766"}.el-icon-pie-chart:before{content:"\e767"}.el-icon-data-board:before{content:"\e768"}.el-icon-data-line:before{content:"\e76d"}.el-icon-reading:before{content:"\e769"}.el-icon-magic-stick:before{content:"\e76a"}.el-icon-coordinate:before{content:"\e76b"}.el-icon-mouse:before{content:"\e76c"}.el-icon-brush:before{content:"\e76e"}.el-icon-headset:before{content:"\e76f"}.el-icon-umbrella:before{content:"\e770"}.el-icon-scissors:before{content:"\e771"}.el-icon-mobile:before{content:"\e773"}.el-icon-attract:before{content:"\e774"}.el-icon-monitor:before{content:"\e775"}.el-icon-search:before{content:"\e778"}.el-icon-takeaway-box:before{content:"\e77a"}.el-icon-paperclip:before{content:"\e77d"}.el-icon-printer:before{content:"\e77e"}.el-icon-document-add:before{content:"\e782"}.el-icon-document:before{content:"\e785"}.el-icon-document-checked:before{content:"\e786"}.el-icon-document-copy:before{content:"\e787"}.el-icon-document-delete:before{content:"\e788"}.el-icon-document-remove:before{content:"\e789"}.el-icon-tickets:before{content:"\e78b"}.el-icon-folder-checked:before{content:"\e77f"}.el-icon-folder-delete:before{content:"\e780"}.el-icon-folder-remove:before{content:"\e781"}.el-icon-folder-add:before{content:"\e783"}.el-icon-folder-opened:before{content:"\e784"}.el-icon-folder:before{content:"\e78a"}.el-icon-edit-outline:before{content:"\e764"}.el-icon-edit:before{content:"\e78c"}.el-icon-date:before{content:"\e78e"}.el-icon-c-scale-to-original:before{content:"\e7c6"}.el-icon-view:before{content:"\e6ce"}.el-icon-loading:before{content:"\e6cf"}.el-icon-rank:before{content:"\e6d1"}.el-icon-sort-down:before{content:"\e7c4"}.el-icon-sort-up:before{content:"\e7c5"}.el-icon-sort:before{content:"\e6d2"}.el-icon-finished:before{content:"\e6cd"}.el-icon-refresh-left:before{content:"\e6c7"}.el-icon-refresh-right:before{content:"\e6c8"}.el-icon-refresh:before{content:"\e6d0"}.el-icon-video-play:before{content:"\e7c0"}.el-icon-video-pause:before{content:"\e7c1"}.el-icon-d-arrow-right:before{content:"\e6dc"}.el-icon-d-arrow-left:before{content:"\e6dd"}.el-icon-arrow-up:before{content:"\e6e1"}.el-icon-arrow-down:before{content:"\e6df"}.el-icon-arrow-right:before{content:"\e6e0"}.el-icon-arrow-left:before{content:"\e6de"}.el-icon-top-right:before{content:"\e6e7"}.el-icon-top-left:before{content:"\e6e8"}.el-icon-top:before{content:"\e6e6"}.el-icon-bottom:before{content:"\e6eb"}.el-icon-right:before{content:"\e6e9"}.el-icon-back:before{content:"\e6ea"}.el-icon-bottom-right:before{content:"\e6ec"}.el-icon-bottom-left:before{content:"\e6ed"}.el-icon-caret-top:before{content:"\e78f"}.el-icon-caret-bottom:before{content:"\e790"}.el-icon-caret-right:before{content:"\e791"}.el-icon-caret-left:before{content:"\e792"}.el-icon-d-caret:before{content:"\e79a"}.el-icon-share:before{content:"\e793"}.el-icon-menu:before{content:"\e798"}.el-icon-s-grid:before{content:"\e7a6"}.el-icon-s-check:before{content:"\e7a7"}.el-icon-s-data:before{content:"\e7a8"}.el-icon-s-opportunity:before{content:"\e7aa"}.el-icon-s-custom:before{content:"\e7ab"}.el-icon-s-claim:before{content:"\e7ad"}.el-icon-s-finance:before{content:"\e7ae"}.el-icon-s-comment:before{content:"\e7af"}.el-icon-s-flag:before{content:"\e7b0"}.el-icon-s-marketing:before{content:"\e7b1"}.el-icon-s-shop:before{content:"\e7b4"}.el-icon-s-open:before{content:"\e7b5"}.el-icon-s-management:before{content:"\e7b6"}.el-icon-s-ticket:before{content:"\e7b7"}.el-icon-s-release:before{content:"\e7b8"}.el-icon-s-home:before{content:"\e7b9"}.el-icon-s-promotion:before{content:"\e7ba"}.el-icon-s-operation:before{content:"\e7bb"}.el-icon-s-unfold:before{content:"\e7bc"}.el-icon-s-fold:before{content:"\e7a9"}.el-icon-s-platform:before{content:"\e7bd"}.el-icon-s-order:before{content:"\e7be"}.el-icon-s-cooperation:before{content:"\e7bf"}.el-icon-bell:before{content:"\e725"}.el-icon-message-solid:before{content:"\e799"}.el-icon-video-camera:before{content:"\e772"}.el-icon-video-camera-solid:before{content:"\e796"}.el-icon-camera:before{content:"\e779"}.el-icon-camera-solid:before{content:"\e79b"}.el-icon-download:before{content:"\e77c"}.el-icon-upload2:before{content:"\e77b"}.el-icon-upload:before{content:"\e7c3"}.el-icon-picture-outline-round:before{content:"\e75f"}.el-icon-picture-outline:before{content:"\e75e"}.el-icon-picture:before{content:"\e79f"}.el-icon-close:before{content:"\e6db"}.el-icon-check:before{content:"\e6da"}.el-icon-plus:before{content:"\e6d9"}.el-icon-minus:before{content:"\e6d8"}.el-icon-help:before{content:"\e73d"}.el-icon-s-help:before{content:"\e7b3"}.el-icon-circle-close:before{content:"\e78d"}.el-icon-circle-check:before{content:"\e720"}.el-icon-circle-plus-outline:before{content:"\e723"}.el-icon-remove-outline:before{content:"\e722"}.el-icon-zoom-out:before{content:"\e776"}.el-icon-zoom-in:before{content:"\e777"}.el-icon-error:before{content:"\e79d"}.el-icon-success:before{content:"\e79c"}.el-icon-circle-plus:before{content:"\e7a0"}.el-icon-remove:before{content:"\e7a2"}.el-icon-info:before{content:"\e7a1"}.el-icon-question:before{content:"\e7a4"}.el-icon-warning-outline:before{content:"\e6c9"}.el-icon-warning:before{content:"\e7a3"}.el-icon-goods:before{content:"\e7c2"}.el-icon-s-goods:before{content:"\e7b2"}.el-icon-star-off:before{content:"\e717"}.el-icon-star-on:before{content:"\e797"}.el-icon-more-outline:before{content:"\e6cc"}.el-icon-more:before{content:"\e794"}.el-icon-phone-outline:before{content:"\e6cb"}.el-icon-phone:before{content:"\e795"}.el-icon-user:before{content:"\e6e3"}.el-icon-user-solid:before{content:"\e7a5"}.el-icon-setting:before{content:"\e6ca"}.el-icon-s-tools:before{content:"\e7ac"}.el-icon-delete:before{content:"\e6d7"}.el-icon-delete-solid:before{content:"\e7c9"}.el-icon-eleme:before{content:"\e7c7"}.el-icon-platform-eleme:before{content:"\e7ca"}.el-icon-loading{-webkit-animation:rotating 2s linear infinite;animation:rotating 2s linear infinite}.el-icon--right{margin-left:5px}.el-icon--left{margin-right:5px}@-webkit-keyframes rotating{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotating{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.el-pagination{white-space:nowrap;padding:2px 5px;color:#303133;font-weight:700}.el-pagination:after,.el-pagination:before{display:table;content:""}.el-pagination:after{clear:both}.el-pagination button,.el-pagination span:not([class*=suffix]){display:inline-block;font-size:13px;min-width:35.5px;height:28px;line-height:28px;vertical-align:top;-webkit-box-sizing:border-box;box-sizing:border-box}.el-pagination .el-input__inner{text-align:center;-moz-appearance:textfield;line-height:normal}.el-pagination .el-input__suffix{right:0;-webkit-transform:scale(.8);transform:scale(.8)}.el-pagination .el-select .el-input{width:100px;margin:0 5px}.el-pagination .el-select .el-input .el-input__inner{padding-right:25px;border-radius:3px}.el-pagination button{border:none;padding:0 6px;background:0 0}.el-pagination button:focus{outline:0}.el-pagination button:hover{color:#409eff}.el-pagination button:disabled{color:#c0c4cc;background-color:#fff;cursor:not-allowed}.el-pagination .btn-next,.el-pagination .btn-prev{background:50% no-repeat #fff;background-size:16px;cursor:pointer;margin:0;color:#303133}.el-pagination .btn-next .el-icon,.el-pagination .btn-prev .el-icon{display:block;font-size:12px;font-weight:700}.el-pagination .btn-prev{padding-right:12px}.el-pagination .btn-next{padding-left:12px}.el-pagination .el-pager li.disabled{color:#c0c4cc;cursor:not-allowed}.el-pager li,.el-pager li.btn-quicknext:hover,.el-pager li.btn-quickprev:hover{cursor:pointer}.el-pagination--small .btn-next,.el-pagination--small .btn-prev,.el-pagination--small .el-pager li,.el-pagination--small .el-pager li.btn-quicknext,.el-pagination--small .el-pager li.btn-quickprev,.el-pagination--small .el-pager li:last-child{border-color:transparent;font-size:12px;line-height:22px;height:22px;min-width:22px}.el-pagination--small .more:before,.el-pagination--small li.more:before{line-height:24px}.el-pagination--small button,.el-pagination--small span:not([class*=suffix]){height:22px;line-height:22px}.el-pagination--small .el-pagination__editor,.el-pagination--small .el-pagination__editor.el-input .el-input__inner{height:22px}.el-pagination__sizes{margin:0 10px 0 0;font-weight:400;color:#606266}.el-pagination__sizes .el-input .el-input__inner{font-size:13px;padding-left:8px}.el-pagination__sizes .el-input .el-input__inner:hover{border-color:#409eff}.el-pagination__total{margin-right:10px;font-weight:400;color:#606266}.el-pagination__jump{margin-left:24px;font-weight:400;color:#606266}.el-pagination__jump .el-input__inner{padding:0 3px}.el-pagination__rightwrapper{float:right}.el-pagination__editor{line-height:18px;padding:0 2px;height:28px;text-align:center;margin:0 2px;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:3px}.el-pager,.el-pagination.is-background .btn-next,.el-pagination.is-background .btn-prev{padding:0}.el-pagination__editor.el-input{width:50px}.el-pagination__editor.el-input .el-input__inner{height:28px}.el-pagination__editor .el-input__inner::-webkit-inner-spin-button,.el-pagination__editor .el-input__inner::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.el-pagination.is-background .btn-next,.el-pagination.is-background .btn-prev,.el-pagination.is-background .el-pager li{margin:0 5px;background-color:#f4f4f5;color:#606266;min-width:30px;border-radius:2px}.el-pagination.is-background .btn-next.disabled,.el-pagination.is-background .btn-next:disabled,.el-pagination.is-background .btn-prev.disabled,.el-pagination.is-background .btn-prev:disabled,.el-pagination.is-background .el-pager li.disabled{color:#c0c4cc}.el-pagination.is-background .el-pager li:not(.disabled):hover{color:#409eff}.el-pagination.is-background .el-pager li:not(.disabled).active{background-color:#409eff;color:#fff}.el-dialog,.el-pager li{background:#fff;-webkit-box-sizing:border-box}.el-pagination.is-background.el-pagination--small .btn-next,.el-pagination.is-background.el-pagination--small .btn-prev,.el-pagination.is-background.el-pagination--small .el-pager li{margin:0 3px;min-width:22px}.el-pager,.el-pager li{vertical-align:top;margin:0;display:inline-block}.el-pager{-moz-user-select:none;user-select:none;list-style:none;font-size:0}.el-date-table,.el-pager,.el-table th{-webkit-user-select:none;-ms-user-select:none}.el-pager .more:before{line-height:30px}.el-pager li{padding:0 4px;font-size:13px;min-width:35.5px;height:28px;line-height:28px;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center}.el-menu--collapse .el-menu .el-submenu,.el-menu--popup{min-width:200px}.el-pager li.btn-quicknext,.el-pager li.btn-quickprev{line-height:28px;color:#303133}.el-pager li.btn-quicknext.disabled,.el-pager li.btn-quickprev.disabled{color:#c0c4cc}.el-pager li.active+li{border-left:0}.el-pager li:hover{color:#409eff}.el-pager li.active{color:#409eff;cursor:default}@-webkit-keyframes v-modal-in{0%{opacity:0}}@-webkit-keyframes v-modal-out{to{opacity:0}}.el-dialog{position:relative;margin:0 auto 50px;border-radius:2px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.3);box-shadow:0 1px 3px rgba(0,0,0,.3);-webkit-box-sizing:border-box;box-sizing:border-box;width:50%}.el-dialog.is-fullscreen{width:100%;margin-top:0;margin-bottom:0;height:100%;overflow:auto}.el-dialog__wrapper{position:fixed;top:0;right:0;bottom:0;left:0;overflow:auto;margin:0}.el-dialog__header{padding:20px 20px 10px}.el-dialog__headerbtn{position:absolute;top:20px;right:20px;padding:0;background:0 0;border:none;outline:0;cursor:pointer;font-size:16px}.el-dialog__headerbtn .el-dialog__close{color:#909399}.el-dialog__headerbtn:focus .el-dialog__close,.el-dialog__headerbtn:hover .el-dialog__close{color:#409eff}.el-dialog__title{line-height:24px;font-size:18px;color:#303133}.el-dialog__body{padding:30px 20px;color:#606266;font-size:14px;word-break:break-all}.el-dialog__footer{padding:10px 20px 20px;text-align:right;-webkit-box-sizing:border-box;box-sizing:border-box}.el-dialog--center{text-align:center}.el-dialog--center .el-dialog__body{text-align:initial;padding:25px 25px 30px}.el-dialog--center .el-dialog__footer{text-align:inherit}.dialog-fade-enter-active{-webkit-animation:dialog-fade-in .3s;animation:dialog-fade-in .3s}.dialog-fade-leave-active{-webkit-animation:dialog-fade-out .3s;animation:dialog-fade-out .3s}@-webkit-keyframes dialog-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes dialog-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@-webkit-keyframes dialog-fade-out{0%{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}to{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes dialog-fade-out{0%{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}to{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.el-autocomplete{position:relative;display:inline-block}.el-autocomplete-suggestion{margin:5px 0;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:4px;border:1px solid #e4e7ed;-webkit-box-sizing:border-box;box-sizing:border-box;background-color:#fff}.el-dropdown-menu,.el-menu--collapse .el-submenu .el-menu{z-index:10;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-autocomplete-suggestion__wrap{max-height:280px;padding:10px 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-autocomplete-suggestion__list{margin:0;padding:0}.el-autocomplete-suggestion li{padding:0 20px;margin:0;line-height:34px;cursor:pointer;color:#606266;font-size:14px;list-style:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.el-autocomplete-suggestion li.highlighted,.el-autocomplete-suggestion li:hover{background-color:#f5f7fa}.el-autocomplete-suggestion li.divider{margin-top:6px;border-top:1px solid #000}.el-autocomplete-suggestion li.divider:last-child{margin-bottom:-6px}.el-autocomplete-suggestion.is-loading li{text-align:center;height:100px;line-height:100px;font-size:20px;color:#999}.el-autocomplete-suggestion.is-loading li:after{display:inline-block;content:"";height:100%;vertical-align:middle}.el-autocomplete-suggestion.is-loading li:hover{background-color:#fff}.el-autocomplete-suggestion.is-loading .el-icon-loading{vertical-align:middle}.el-dropdown{display:inline-block;position:relative;color:#606266;font-size:14px}.el-dropdown .el-button-group{display:block}.el-dropdown .el-button-group .el-button{float:none}.el-dropdown .el-dropdown__caret-button{padding-left:5px;padding-right:5px;position:relative;border-left:none}.el-dropdown .el-dropdown__caret-button:before{content:"";position:absolute;display:block;width:1px;top:5px;bottom:5px;left:0;background:hsla(0,0%,100%,.5)}.el-dropdown .el-dropdown__caret-button.el-button--default:before{background:rgba(220,223,230,.5)}.el-dropdown .el-dropdown__caret-button:hover:before{top:0;bottom:0}.el-dropdown .el-dropdown__caret-button .el-dropdown__icon{padding-left:0}.el-dropdown__icon{font-size:12px;margin:0 3px}.el-dropdown-menu{position:absolute;top:0;left:0;padding:10px 0;margin:5px 0;background-color:#fff;border:1px solid #ebeef5;border-radius:4px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-dropdown-menu__item{list-style:none;line-height:36px;padding:0 20px;margin:0;font-size:14px;color:#606266;cursor:pointer;outline:0}.el-dropdown-menu__item:focus,.el-dropdown-menu__item:not(.is-disabled):hover{background-color:#ecf5ff;color:#66b1ff}.el-dropdown-menu__item i{margin-right:5px}.el-dropdown-menu__item--divided{position:relative;margin-top:6px;border-top:1px solid #ebeef5}.el-dropdown-menu__item--divided:before{content:"";height:6px;display:block;margin:0 -20px;background-color:#fff}.el-dropdown-menu__item.is-disabled{cursor:default;color:#bbb;pointer-events:none}.el-dropdown-menu--medium{padding:6px 0}.el-dropdown-menu--medium .el-dropdown-menu__item{line-height:30px;padding:0 17px;font-size:14px}.el-dropdown-menu--medium .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:6px}.el-dropdown-menu--medium .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:6px;margin:0 -17px}.el-dropdown-menu--small{padding:6px 0}.el-dropdown-menu--small .el-dropdown-menu__item{line-height:27px;padding:0 15px;font-size:13px}.el-dropdown-menu--small .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:4px}.el-dropdown-menu--small .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:4px;margin:0 -15px}.el-dropdown-menu--mini{padding:3px 0}.el-dropdown-menu--mini .el-dropdown-menu__item{line-height:24px;padding:0 10px;font-size:12px}.el-dropdown-menu--mini .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:3px}.el-dropdown-menu--mini .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:3px;margin:0 -10px}.el-menu{border-right:1px solid #e6e6e6;list-style:none;position:relative;margin:0;padding-left:0}.el-menu,.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus,.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,.el-menu--horizontal>.el-submenu .el-submenu__title:hover{background-color:#fff}.el-menu:after,.el-menu:before{display:table;content:""}.el-menu:after{clear:both}.el-menu.el-menu--horizontal{border-bottom:1px solid #e6e6e6}.el-menu--horizontal{border-right:none}.el-menu--horizontal>.el-menu-item{float:left;height:60px;line-height:60px;margin:0;border-bottom:2px solid transparent;color:#909399}.el-menu--horizontal>.el-menu-item a,.el-menu--horizontal>.el-menu-item a:hover{color:inherit}.el-menu--horizontal>.el-submenu{float:left}.el-menu--horizontal>.el-submenu:focus,.el-menu--horizontal>.el-submenu:hover{outline:0}.el-menu--horizontal>.el-submenu:focus .el-submenu__title,.el-menu--horizontal>.el-submenu:hover .el-submenu__title{color:#303133}.el-menu--horizontal>.el-submenu.is-active .el-submenu__title{border-bottom:2px solid #409eff;color:#303133}.el-menu--horizontal>.el-submenu .el-submenu__title{height:60px;line-height:60px;border-bottom:2px solid transparent;color:#909399}.el-menu--horizontal>.el-submenu .el-submenu__icon-arrow{position:static;vertical-align:middle;margin-left:8px;margin-top:-3px}.el-menu--horizontal .el-menu .el-menu-item,.el-menu--horizontal .el-menu .el-submenu__title{background-color:#fff;float:none;height:36px;line-height:36px;padding:0 10px;color:#909399}.el-menu--horizontal .el-menu .el-menu-item.is-active,.el-menu--horizontal .el-menu .el-submenu.is-active>.el-submenu__title{color:#303133}.el-menu--horizontal .el-menu-item:not(.is-disabled):focus,.el-menu--horizontal .el-menu-item:not(.is-disabled):hover{outline:0;color:#303133}.el-menu--horizontal>.el-menu-item.is-active{border-bottom:2px solid #409eff;color:#303133}.el-menu--collapse{width:64px}.el-menu--collapse>.el-menu-item [class^=el-icon-],.el-menu--collapse>.el-submenu>.el-submenu__title [class^=el-icon-]{margin:0;vertical-align:middle;width:24px;text-align:center}.el-menu--collapse>.el-menu-item .el-submenu__icon-arrow,.el-menu--collapse>.el-submenu>.el-submenu__title .el-submenu__icon-arrow{display:none}.el-menu--collapse>.el-menu-item span,.el-menu--collapse>.el-submenu>.el-submenu__title span{height:0;width:0;overflow:hidden;visibility:hidden;display:inline-block}.el-menu--collapse>.el-menu-item.is-active i{color:inherit}.el-menu--collapse .el-submenu{position:relative}.el-menu--collapse .el-submenu .el-menu{position:absolute;margin-left:5px;top:0;left:100%;border:1px solid #e4e7ed;border-radius:2px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-menu-item,.el-submenu__title{height:56px;line-height:56px;position:relative;-webkit-box-sizing:border-box;white-space:nowrap;list-style:none}.el-menu--collapse .el-submenu.is-opened>.el-submenu__title .el-submenu__icon-arrow{-webkit-transform:none;transform:none}.el-menu--popup{z-index:100;border:none;padding:5px 0;border-radius:2px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-menu--popup-bottom-start{margin-top:5px}.el-menu--popup-right-start{margin-left:5px;margin-right:5px}.el-menu-item{font-size:14px;color:#303133;padding:0 20px;cursor:pointer;-webkit-transition:border-color .3s,background-color .3s,color .3s;transition:border-color .3s,background-color .3s,color .3s;-webkit-box-sizing:border-box;box-sizing:border-box}.el-menu-item *{vertical-align:middle}.el-menu-item i{color:#909399}.el-menu-item:focus,.el-menu-item:hover{outline:0;background-color:#ecf5ff}.el-menu-item.is-disabled{opacity:.25;cursor:not-allowed;background:0 0!important}.el-menu-item [class^=el-icon-]{margin-right:5px;width:24px;text-align:center;font-size:18px;vertical-align:middle}.el-menu-item.is-active{color:#409eff}.el-menu-item.is-active i{color:inherit}.el-submenu{list-style:none;margin:0;padding-left:0}.el-submenu__title{font-size:14px;color:#303133;padding:0 20px;cursor:pointer;-webkit-transition:border-color .3s,background-color .3s,color .3s;transition:border-color .3s,background-color .3s,color .3s;-webkit-box-sizing:border-box;box-sizing:border-box}.el-submenu__title *{vertical-align:middle}.el-submenu__title i{color:#909399}.el-submenu__title:focus,.el-submenu__title:hover{outline:0;background-color:#ecf5ff}.el-submenu__title.is-disabled{opacity:.25;cursor:not-allowed;background:0 0!important}.el-submenu__title:hover{background-color:#ecf5ff}.el-submenu .el-menu{border:none}.el-submenu .el-menu-item{height:50px;line-height:50px;padding:0 45px;min-width:200px}.el-submenu__icon-arrow{position:absolute;top:50%;right:20px;margin-top:-7px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-size:12px}.el-submenu.is-active .el-submenu__title{border-bottom-color:#409eff}.el-submenu.is-opened>.el-submenu__title .el-submenu__icon-arrow{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.el-submenu.is-disabled .el-menu-item,.el-submenu.is-disabled .el-submenu__title{opacity:.25;cursor:not-allowed;background:0 0!important}.el-submenu [class^=el-icon-]{vertical-align:middle;margin-right:5px;width:24px;text-align:center;font-size:18px}.el-menu-item-group>ul{padding:0}.el-menu-item-group__title{padding:7px 0 7px 20px;line-height:normal;font-size:12px;color:#909399}.el-radio-button__inner,.el-radio-group{display:inline-block;line-height:1;vertical-align:middle}.horizontal-collapse-transition .el-submenu__title .el-submenu__icon-arrow{-webkit-transition:.2s;transition:.2s;opacity:0}.el-radio-group{font-size:0}.el-radio-button{position:relative;display:inline-block;outline:0}.el-radio-button__inner{white-space:nowrap;background:#fff;border:1px solid #dcdfe6;font-weight:500;border-left:0;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;position:relative;cursor:pointer;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);padding:12px 20px;font-size:14px;border-radius:0}.el-radio-button__inner.is-round{padding:12px 20px}.el-radio-button__inner:hover{color:#409eff}.el-radio-button__inner [class*=el-icon-]{line-height:.9}.el-radio-button__inner [class*=el-icon-]+span{margin-left:5px}.el-radio-button:first-child .el-radio-button__inner{border-left:1px solid #dcdfe6;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.el-radio-button__orig-radio{opacity:0;outline:0;position:absolute;z-index:-1}.el-radio-button__orig-radio:checked+.el-radio-button__inner{color:#fff;background-color:#409eff;border-color:#409eff;-webkit-box-shadow:-1px 0 0 0 #409eff;box-shadow:-1px 0 0 0 #409eff}.el-radio-button__orig-radio:disabled+.el-radio-button__inner{color:#c0c4cc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#ebeef5;-webkit-box-shadow:none;box-shadow:none}.el-radio-button__orig-radio:disabled:checked+.el-radio-button__inner{background-color:#f2f6fc}.el-radio-button:last-child .el-radio-button__inner{border-radius:0 4px 4px 0}.el-popover,.el-radio-button:first-child:last-child .el-radio-button__inner{border-radius:4px}.el-radio-button--medium .el-radio-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.el-radio-button--medium .el-radio-button__inner.is-round{padding:10px 20px}.el-radio-button--small .el-radio-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.el-radio-button--small .el-radio-button__inner.is-round{padding:9px 15px}.el-radio-button--mini .el-radio-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.el-radio-button--mini .el-radio-button__inner.is-round{padding:7px 15px}.el-radio-button:focus:not(.is-focus):not(:active):not(.is-disabled){-webkit-box-shadow:0 0 2px 2px #409eff;box-shadow:0 0 2px 2px #409eff}.el-switch{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;position:relative;font-size:14px;line-height:20px;height:20px;vertical-align:middle}.el-switch__core,.el-switch__label{display:inline-block;cursor:pointer}.el-switch.is-disabled .el-switch__core,.el-switch.is-disabled .el-switch__label{cursor:not-allowed}.el-switch__label{-webkit-transition:.2s;transition:.2s;height:20px;font-size:14px;font-weight:500;vertical-align:middle;color:#303133}.el-switch__label.is-active{color:#409eff}.el-switch__label--left{margin-right:10px}.el-switch__label--right{margin-left:10px}.el-switch__label *{line-height:1;font-size:14px;display:inline-block}.el-switch__input{position:absolute;width:0;height:0;opacity:0;margin:0}.el-switch__core{margin:0;position:relative;width:40px;height:20px;border:1px solid #dcdfe6;outline:0;border-radius:10px;-webkit-box-sizing:border-box;box-sizing:border-box;background:#dcdfe6;-webkit-transition:border-color .3s,background-color .3s;transition:border-color .3s,background-color .3s;vertical-align:middle}.el-switch__core:after{content:"";position:absolute;top:1px;left:1px;border-radius:100%;-webkit-transition:all .3s;transition:all .3s;width:16px;height:16px;background-color:#fff}.el-switch.is-checked .el-switch__core{border-color:#409eff;background-color:#409eff}.el-switch.is-checked .el-switch__core:after{left:100%;margin-left:-17px}.el-switch.is-disabled{opacity:.6}.el-switch--wide .el-switch__label.el-switch__label--left span{left:10px}.el-switch--wide .el-switch__label.el-switch__label--right span{right:10px}.el-switch .label-fade-enter,.el-switch .label-fade-leave-active{opacity:0}.el-select-dropdown{position:absolute;z-index:1001;border:1px solid #e4e7ed;border-radius:4px;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-box-sizing:border-box;box-sizing:border-box;margin:5px 0}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected{color:#409eff;background-color:#fff}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected.hover{background-color:#f5f7fa}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected:after{position:absolute;right:20px;font-family:element-icons;content:"\e6da";font-size:12px;font-weight:700;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.el-select-dropdown .el-scrollbar.is-empty .el-select-dropdown__list{padding:0}.el-select-dropdown__empty{padding:10px 0;margin:0;text-align:center;color:#999;font-size:14px}.el-select-dropdown__wrap{max-height:274px}.el-select-dropdown__list{list-style:none;padding:6px 0;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-select-dropdown__item{font-size:14px;padding:0 20px;position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#606266;height:34px;line-height:34px;box-sizing:border-box;cursor:pointer}.el-select-dropdown__item,.el-select .el-tag,.el-table{-webkit-box-sizing:border-box}.el-select-dropdown__item.is-disabled{color:#c0c4cc;cursor:not-allowed}.el-select-dropdown__item.is-disabled:hover{background-color:#fff}.el-select-dropdown__item.hover,.el-select-dropdown__item:hover{background-color:#f5f7fa}.el-select-dropdown__item.selected{color:#409eff;font-weight:700}.el-select-group{margin:0;padding:0}.el-select-group__wrap{position:relative;list-style:none;margin:0;padding:0}.el-select-group__wrap:not(:last-of-type){padding-bottom:24px}.el-select-group__wrap:not(:last-of-type):after{content:"";position:absolute;display:block;left:20px;right:20px;bottom:12px;height:1px;background:#e4e7ed}.el-select-group__title{padding-left:20px;font-size:12px;color:#909399;line-height:30px}.el-select-group .el-select-dropdown__item{padding-left:20px}.el-select{display:inline-block;position:relative}.el-select .el-select__tags>span{display:contents}.el-select:hover .el-input__inner{border-color:#c0c4cc}.el-select .el-input__inner{cursor:pointer;padding-right:35px}.el-select .el-input__inner:focus{border-color:#409eff}.el-select .el-input .el-select__caret{color:#c0c4cc;font-size:14px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;-webkit-transform:rotate(180deg);transform:rotate(180deg);cursor:pointer}.el-select .el-input .el-select__caret.is-reverse{-webkit-transform:rotate(0);transform:rotate(0)}.el-select .el-input .el-select__caret.is-show-close{font-size:14px;text-align:center;-webkit-transform:rotate(180deg);transform:rotate(180deg);border-radius:100%;color:#c0c4cc;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.el-select .el-input .el-select__caret.is-show-close:hover{color:#909399}.el-select .el-input.is-disabled .el-input__inner{cursor:not-allowed}.el-select .el-input.is-disabled .el-input__inner:hover{border-color:#e4e7ed}.el-select .el-input.is-focus .el-input__inner{border-color:#409eff}.el-select>.el-input{display:block}.el-select__input{border:none;outline:0;padding:0;margin-left:15px;color:#666;font-size:14px;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:28px;background-color:transparent}.el-select__input.is-mini{height:14px}.el-select__close{cursor:pointer;position:absolute;top:8px;z-index:1000;right:25px;color:#c0c4cc;line-height:18px;font-size:14px}.el-select__close:hover{color:#909399}.el-select__tags{position:absolute;line-height:normal;white-space:normal;z-index:1;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-wrap:wrap;flex-wrap:wrap}.el-select .el-tag__close{margin-top:-2px}.el-select .el-tag{-webkit-box-sizing:border-box;box-sizing:border-box;border-color:transparent;margin:2px 0 2px 6px;background-color:#f0f2f5}.el-select .el-tag__close.el-icon-close{background-color:#c0c4cc;right:-7px;top:0;color:#fff}.el-select .el-tag__close.el-icon-close:hover{background-color:#909399}.el-table,.el-table__expanded-cell{background-color:#fff}.el-select .el-tag__close.el-icon-close:before{display:block;-webkit-transform:translateY(.5px);transform:translateY(.5px)}.el-table{position:relative;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-flex:1;-ms-flex:1;flex:1;width:100%;max-width:100%;font-size:14px;color:#606266}.el-table--mini,.el-table--small,.el-table__expand-icon{font-size:12px}.el-table__empty-block{min-height:60px;text-align:center;width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-table__empty-text{line-height:60px;width:50%;color:#909399}.el-table__expand-column .cell{padding:0;text-align:center}.el-table__expand-icon{position:relative;cursor:pointer;color:#666;-webkit-transition:-webkit-transform .2s ease-in-out;transition:-webkit-transform .2s ease-in-out;transition:transform .2s ease-in-out;transition:transform .2s ease-in-out,-webkit-transform .2s ease-in-out;height:20px}.el-table__expand-icon--expanded{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-table__expand-icon>.el-icon{position:absolute;left:50%;top:50%;margin-left:-5px;margin-top:-5px}.el-table__expanded-cell[class*=cell]{padding:20px 50px}.el-table__expanded-cell:hover{background-color:transparent!important}.el-table__placeholder{display:inline-block;width:20px}.el-table__append-wrapper{overflow:hidden}.el-table--fit{border-right:0;border-bottom:0}.el-table--fit td.gutter,.el-table--fit th.gutter{border-right-width:1px}.el-table--scrollable-x .el-table__body-wrapper{overflow-x:auto}.el-table--scrollable-y .el-table__body-wrapper{overflow-y:auto}.el-table thead{color:#909399;font-weight:500}.el-table thead.is-group th{background:#f5f7fa}.el-table th,.el-table tr{background-color:#fff}.el-table td,.el-table th{padding:12px 0;min-width:0;-webkit-box-sizing:border-box;box-sizing:border-box;text-overflow:ellipsis;vertical-align:middle;position:relative;text-align:left}.el-table td.is-center,.el-table th.is-center{text-align:center}.el-table td.is-right,.el-table th.is-right{text-align:right}.el-table td.gutter,.el-table th.gutter{width:15px;border-right-width:0;border-bottom-width:0;padding:0}.el-table--medium td,.el-table--medium th{padding:10px 0}.el-table--small td,.el-table--small th{padding:8px 0}.el-table--mini td,.el-table--mini th{padding:6px 0}.el-table .cell,.el-table th div{padding-right:10px;overflow:hidden;text-overflow:ellipsis}.el-table--border td:first-child .cell,.el-table--border th:first-child .cell,.el-table .cell,.el-table th div{padding-left:10px}.el-table tr input[type=checkbox]{margin:0}.el-table td,.el-table th.is-leaf{border-bottom:1px solid #ebeef5}.el-table th.is-sortable{cursor:pointer}.el-table th{white-space:nowrap;overflow:hidden;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.el-table th div{line-height:40px;white-space:nowrap}.el-table th>.cell,.el-table th div{display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box}.el-table th>.cell{position:relative;word-wrap:normal;text-overflow:ellipsis;vertical-align:middle;width:100%}.el-table th>.cell.highlight{color:#409eff}.el-table th.required>div:before{display:inline-block;content:"";width:8px;height:8px;border-radius:50%;background:#ff4d51;margin-right:5px;vertical-align:middle}.el-table td div{-webkit-box-sizing:border-box;box-sizing:border-box}.el-table td.gutter{width:0}.el-table .cell{-webkit-box-sizing:border-box;box-sizing:border-box;white-space:normal;word-break:break-all;line-height:23px}.el-table .cell.el-tooltip{white-space:nowrap;min-width:50px}.el-table--border,.el-table--group{border:1px solid #ebeef5}.el-table--border:after,.el-table--group:after,.el-table:before{content:"";position:absolute;background-color:#ebeef5;z-index:1}.el-table--border:after,.el-table--group:after{top:0;right:0;width:1px;height:100%}.el-table:before{left:0;bottom:0;width:100%;height:1px}.el-table--border{border-right:none;border-bottom:none}.el-table--border.el-loading-parent--relative{border-color:transparent}.el-table--border td,.el-table--border th,.el-table__body-wrapper .el-table--border.is-scrolling-left~.el-table__fixed{border-right:1px solid #ebeef5}.el-table--border th.gutter:last-of-type{border-bottom:1px solid #ebeef5;border-bottom-width:1px}.el-table--border th,.el-table__fixed-right-patch{border-bottom:1px solid #ebeef5}.el-table__fixed,.el-table__fixed-right{position:absolute;top:0;left:0;overflow-x:hidden;overflow-y:hidden;-webkit-box-shadow:0 0 10px rgba(0,0,0,.12);box-shadow:0 0 10px rgba(0,0,0,.12)}.el-table__fixed-right:before,.el-table__fixed:before{content:"";position:absolute;left:0;bottom:0;width:100%;height:1px;background-color:#ebeef5;z-index:4}.el-table__fixed-right-patch{position:absolute;top:-1px;right:0;background-color:#fff}.el-table__fixed-right{top:0;left:auto;right:0}.el-table__fixed-right .el-table__fixed-body-wrapper,.el-table__fixed-right .el-table__fixed-footer-wrapper,.el-table__fixed-right .el-table__fixed-header-wrapper{left:auto;right:0}.el-table__fixed-header-wrapper{position:absolute;left:0;top:0;z-index:3}.el-table__fixed-footer-wrapper{position:absolute;left:0;bottom:0;z-index:3}.el-table__fixed-footer-wrapper tbody td{border-top:1px solid #ebeef5;background-color:#f5f7fa;color:#606266}.el-table__fixed-body-wrapper{position:absolute;left:0;top:37px;overflow:hidden;z-index:3}.el-table__body-wrapper,.el-table__footer-wrapper,.el-table__header-wrapper{width:100%}.el-table__footer-wrapper{margin-top:-1px}.el-table__footer-wrapper td{border-top:1px solid #ebeef5}.el-table__body,.el-table__footer,.el-table__header{table-layout:fixed;border-collapse:separate}.el-table__footer-wrapper,.el-table__header-wrapper{overflow:hidden}.el-table__footer-wrapper tbody td,.el-table__header-wrapper tbody td{background-color:#f5f7fa;color:#606266}.el-table__body-wrapper{overflow:hidden;position:relative}.el-table__body-wrapper.is-scrolling-left~.el-table__fixed,.el-table__body-wrapper.is-scrolling-none~.el-table__fixed,.el-table__body-wrapper.is-scrolling-none~.el-table__fixed-right,.el-table__body-wrapper.is-scrolling-right~.el-table__fixed-right{-webkit-box-shadow:none;box-shadow:none}.el-picker-panel,.el-table-filter{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-table__body-wrapper .el-table--border.is-scrolling-right~.el-table__fixed-right{border-left:1px solid #ebeef5}.el-table .caret-wrapper{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:34px;width:24px;vertical-align:middle;cursor:pointer;overflow:initial;position:relative}.el-table .sort-caret{width:0;height:0;border:5px solid transparent;position:absolute;left:7px}.el-table .sort-caret.ascending{border-bottom-color:#c0c4cc;top:5px}.el-table .sort-caret.descending{border-top-color:#c0c4cc;bottom:7px}.el-table .ascending .sort-caret.ascending{border-bottom-color:#409eff}.el-table .descending .sort-caret.descending{border-top-color:#409eff}.el-table .hidden-columns{position:absolute;z-index:-1}.el-table--striped .el-table__body tr.el-table__row--striped td{background:#fafafa}.el-table--striped .el-table__body tr.el-table__row--striped.current-row td{background-color:#ecf5ff}.el-table__body tr.hover-row.current-row>td,.el-table__body tr.hover-row.el-table__row--striped.current-row>td,.el-table__body tr.hover-row.el-table__row--striped>td,.el-table__body tr.hover-row>td{background-color:#f5f7fa}.el-table__body tr.current-row>td{background-color:#ecf5ff}.el-table__column-resize-proxy{position:absolute;left:200px;top:0;bottom:0;width:0;border-left:1px solid #ebeef5;z-index:10}.el-table__column-filter-trigger{display:inline-block;line-height:34px;cursor:pointer}.el-table__column-filter-trigger i{color:#909399;font-size:12px;-webkit-transform:scale(.75);transform:scale(.75)}.el-table--enable-row-transition .el-table__body td{-webkit-transition:background-color .25s ease;transition:background-color .25s ease}.el-table--enable-row-hover .el-table__body tr:hover>td{background-color:#f5f7fa}.el-table--fluid-height .el-table__fixed,.el-table--fluid-height .el-table__fixed-right{bottom:0;overflow:hidden}.el-table [class*=el-table__row--level] .el-table__expand-icon{display:inline-block;width:20px;line-height:20px;height:20px;text-align:center;margin-right:3px}.el-table-column--selection .cell{padding-left:14px;padding-right:14px}.el-table-filter{border:1px solid #ebeef5;border-radius:2px;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-box-sizing:border-box;box-sizing:border-box;margin:2px 0}.el-date-table td,.el-date-table td div{height:30px;-webkit-box-sizing:border-box}.el-table-filter__list{padding:5px 0;margin:0;list-style:none;min-width:100px}.el-table-filter__list-item{line-height:36px;padding:0 10px;cursor:pointer;font-size:14px}.el-table-filter__list-item:hover{background-color:#ecf5ff;color:#66b1ff}.el-table-filter__list-item.is-active{background-color:#409eff;color:#fff}.el-table-filter__content{min-width:100px}.el-table-filter__bottom{border-top:1px solid #ebeef5;padding:8px}.el-table-filter__bottom button{background:0 0;border:none;color:#606266;cursor:pointer;font-size:13px;padding:0 3px}.el-date-table.is-week-mode .el-date-table__row.current div,.el-date-table.is-week-mode .el-date-table__row:hover div,.el-date-table td.in-range div,.el-date-table td.in-range div:hover{background-color:#f2f6fc}.el-table-filter__bottom button:hover{color:#409eff}.el-table-filter__bottom button:focus{outline:0}.el-table-filter__bottom button.is-disabled{color:#c0c4cc;cursor:not-allowed}.el-table-filter__wrap{max-height:280px}.el-table-filter__checkbox-group{padding:10px}.el-table-filter__checkbox-group label.el-checkbox{display:block;margin-right:5px;margin-bottom:8px;margin-left:5px}.el-table-filter__checkbox-group .el-checkbox:last-child{margin-bottom:0}.el-date-table{font-size:12px;-moz-user-select:none;user-select:none}.el-date-table,.el-slider__button-wrapper,.el-time-panel{-webkit-user-select:none;-ms-user-select:none}.el-date-table.is-week-mode .el-date-table__row:hover td.available:hover{color:#606266}.el-date-table.is-week-mode .el-date-table__row:hover td:first-child div{margin-left:5px;border-top-left-radius:15px;border-bottom-left-radius:15px}.el-date-table.is-week-mode .el-date-table__row:hover td:last-child div{margin-right:5px;border-top-right-radius:15px;border-bottom-right-radius:15px}.el-date-table td{width:32px;padding:4px 0;text-align:center;cursor:pointer;position:relative}.el-date-table td,.el-date-table td div{-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-table td div{padding:3px 0}.el-date-table td span{width:24px;height:24px;display:block;margin:0 auto;line-height:24px;position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);border-radius:50%}.el-date-table td.next-month,.el-date-table td.prev-month{color:#c0c4cc}.el-date-table td.today{position:relative}.el-date-table td.today span{color:#409eff;font-weight:700}.el-date-table td.today.end-date span,.el-date-table td.today.start-date span{color:#fff}.el-date-table td.available:hover{color:#409eff}.el-date-table td.current:not(.disabled) span{color:#fff;background-color:#409eff}.el-date-table td.end-date div,.el-date-table td.start-date div{color:#fff}.el-date-table td.end-date span,.el-date-table td.start-date span{background-color:#409eff}.el-date-table td.start-date div{margin-left:5px;border-top-left-radius:15px;border-bottom-left-radius:15px}.el-date-table td.end-date div{margin-right:5px;border-top-right-radius:15px;border-bottom-right-radius:15px}.el-date-table td.disabled div{background-color:#f5f7fa;opacity:1;cursor:not-allowed;color:#c0c4cc}.el-date-table td.selected div{margin-left:5px;margin-right:5px;background-color:#f2f6fc;border-radius:15px}.el-date-table td.selected div:hover{background-color:#f2f6fc}.el-date-table td.selected span{background-color:#409eff;color:#fff;border-radius:15px}.el-date-table td.week{font-size:80%;color:#606266}.el-month-table,.el-year-table{font-size:12px;border-collapse:collapse}.el-date-table th{padding:5px;color:#606266;font-weight:400;border-bottom:1px solid #ebeef5}.el-month-table{margin:-1px}.el-month-table td{text-align:center;padding:8px 0;cursor:pointer}.el-month-table td div{height:48px;padding:6px 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-month-table td.today .cell{color:#409eff;font-weight:700}.el-month-table td.today.end-date .cell,.el-month-table td.today.start-date .cell{color:#fff}.el-month-table td.disabled .cell{background-color:#f5f7fa;cursor:not-allowed;color:#c0c4cc}.el-month-table td.disabled .cell:hover{color:#c0c4cc}.el-month-table td .cell{width:60px;height:36px;display:block;line-height:36px;color:#606266;margin:0 auto;border-radius:18px}.el-month-table td .cell:hover{color:#409eff}.el-month-table td.in-range div,.el-month-table td.in-range div:hover{background-color:#f2f6fc}.el-month-table td.end-date div,.el-month-table td.start-date div{color:#fff}.el-month-table td.end-date .cell,.el-month-table td.start-date .cell{color:#fff;background-color:#409eff}.el-month-table td.start-date div{border-top-left-radius:24px;border-bottom-left-radius:24px}.el-month-table td.end-date div{border-top-right-radius:24px;border-bottom-right-radius:24px}.el-month-table td.current:not(.disabled) .cell{color:#409eff}.el-year-table{margin:-1px}.el-year-table .el-icon{color:#303133}.el-year-table td{text-align:center;padding:20px 3px;cursor:pointer}.el-year-table td.today .cell{color:#409eff;font-weight:700}.el-year-table td.disabled .cell{background-color:#f5f7fa;cursor:not-allowed;color:#c0c4cc}.el-year-table td.disabled .cell:hover{color:#c0c4cc}.el-year-table td .cell{width:48px;height:32px;display:block;line-height:32px;color:#606266;margin:0 auto}.el-year-table td .cell:hover,.el-year-table td.current:not(.disabled) .cell{color:#409eff}.el-date-range-picker{width:646px}.el-date-range-picker.has-sidebar{width:756px}.el-date-range-picker table{table-layout:fixed;width:100%}.el-date-range-picker .el-picker-panel__body{min-width:513px}.el-date-range-picker .el-picker-panel__content{margin:0}.el-date-range-picker__header{position:relative;text-align:center;height:28px}.el-date-range-picker__header [class*=arrow-left]{float:left}.el-date-range-picker__header [class*=arrow-right]{float:right}.el-date-range-picker__header div{font-size:16px;font-weight:500;margin-right:50px}.el-date-range-picker__content{float:left;width:50%;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:16px}.el-date-range-picker__content.is-left{border-right:1px solid #e4e4e4}.el-date-range-picker__content .el-date-range-picker__header div{margin-left:50px;margin-right:50px}.el-date-range-picker__editors-wrap{-webkit-box-sizing:border-box;box-sizing:border-box;display:table-cell}.el-date-range-picker__editors-wrap.is-right{text-align:right}.el-date-range-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-range-picker__time-header>.el-icon-arrow-right{font-size:20px;vertical-align:middle;display:table-cell;color:#303133}.el-date-range-picker__time-picker-wrap{position:relative;display:table-cell;padding:0 5px}.el-date-range-picker__time-picker-wrap .el-picker-panel{position:absolute;top:13px;right:0;z-index:1;background:#fff}.el-date-picker{width:322px}.el-date-picker.has-sidebar.has-time{width:434px}.el-date-picker.has-sidebar{width:438px}.el-date-picker.has-time .el-picker-panel__body-wrapper{position:relative}.el-date-picker .el-picker-panel__content{width:292px}.el-date-picker table{table-layout:fixed;width:100%}.el-date-picker__editor-wrap{position:relative;display:table-cell;padding:0 5px}.el-date-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-picker__header{margin:12px;text-align:center}.el-date-picker__header--bordered{margin-bottom:0;padding-bottom:12px;border-bottom:1px solid #ebeef5}.el-date-picker__header--bordered+.el-picker-panel__content{margin-top:0}.el-date-picker__header-label{font-size:16px;font-weight:500;padding:0 5px;line-height:22px;text-align:center;cursor:pointer;color:#606266}.el-date-picker__header-label.active,.el-date-picker__header-label:hover{color:#409eff}.el-date-picker__prev-btn{float:left}.el-date-picker__next-btn{float:right}.el-date-picker__time-wrap{padding:10px;text-align:center}.el-date-picker__time-label{float:left;cursor:pointer;line-height:30px;margin-left:10px}.time-select{margin:5px 0;min-width:0}.time-select .el-picker-panel__content{max-height:200px;margin:0}.time-select-item{padding:8px 10px;font-size:14px;line-height:20px}.time-select-item.selected:not(.disabled){color:#409eff;font-weight:700}.time-select-item.disabled{color:#e4e7ed;cursor:not-allowed}.time-select-item:hover{background-color:#f5f7fa;font-weight:700;cursor:pointer}.el-date-editor{position:relative;display:inline-block;text-align:left}.el-date-editor.el-input,.el-date-editor.el-input__inner{width:220px}.el-date-editor--monthrange.el-input,.el-date-editor--monthrange.el-input__inner{width:300px}.el-date-editor--daterange.el-input,.el-date-editor--daterange.el-input__inner,.el-date-editor--timerange.el-input,.el-date-editor--timerange.el-input__inner{width:350px}.el-date-editor--datetimerange.el-input,.el-date-editor--datetimerange.el-input__inner{width:400px}.el-date-editor--dates .el-input__inner{text-overflow:ellipsis;white-space:nowrap}.el-date-editor .el-icon-circle-close{cursor:pointer}.el-date-editor .el-range__icon{font-size:14px;margin-left:-5px;color:#c0c4cc;float:left;line-height:32px}.el-date-editor .el-range-input,.el-date-editor .el-range-separator{height:100%;margin:0;text-align:center;display:inline-block;font-size:14px}.el-date-editor .el-range-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;outline:0;padding:0;width:39%;color:#606266}.el-date-editor .el-range-input::-webkit-input-placeholder{color:#c0c4cc}.el-date-editor .el-range-input:-ms-input-placeholder{color:#c0c4cc}.el-date-editor .el-range-input::-ms-input-placeholder{color:#c0c4cc}.el-date-editor .el-range-input::-moz-placeholder{color:#c0c4cc}.el-date-editor .el-range-input::placeholder{color:#c0c4cc}.el-date-editor .el-range-separator{padding:0 5px;line-height:32px;width:5%;color:#303133}.el-date-editor .el-range__close-icon{font-size:14px;color:#c0c4cc;width:25px;display:inline-block;float:right;line-height:32px}.el-range-editor.el-input__inner{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:3px 10px}.el-range-editor .el-range-input{line-height:1}.el-range-editor.is-active,.el-range-editor.is-active:hover{border-color:#409eff}.el-range-editor--medium.el-input__inner{height:36px}.el-range-editor--medium .el-range-separator{line-height:28px;font-size:14px}.el-range-editor--medium .el-range-input{font-size:14px}.el-range-editor--medium .el-range__close-icon,.el-range-editor--medium .el-range__icon{line-height:28px}.el-range-editor--small.el-input__inner{height:32px}.el-range-editor--small .el-range-separator{line-height:24px;font-size:13px}.el-range-editor--small .el-range-input{font-size:13px}.el-range-editor--small .el-range__close-icon,.el-range-editor--small .el-range__icon{line-height:24px}.el-range-editor--mini.el-input__inner{height:28px}.el-range-editor--mini .el-range-separator{line-height:20px;font-size:12px}.el-range-editor--mini .el-range-input{font-size:12px}.el-range-editor--mini .el-range__close-icon,.el-range-editor--mini .el-range__icon{line-height:20px}.el-range-editor.is-disabled{background-color:#f5f7fa;border-color:#e4e7ed;color:#c0c4cc;cursor:not-allowed}.el-range-editor.is-disabled:focus,.el-range-editor.is-disabled:hover{border-color:#e4e7ed}.el-range-editor.is-disabled input{background-color:#f5f7fa;color:#c0c4cc;cursor:not-allowed}.el-range-editor.is-disabled input::-webkit-input-placeholder{color:#c0c4cc}.el-range-editor.is-disabled input:-ms-input-placeholder{color:#c0c4cc}.el-range-editor.is-disabled input::-ms-input-placeholder{color:#c0c4cc}.el-range-editor.is-disabled input::-moz-placeholder{color:#c0c4cc}.el-range-editor.is-disabled input::placeholder{color:#c0c4cc}.el-range-editor.is-disabled .el-range-separator{color:#c0c4cc}.el-picker-panel{color:#606266;border:1px solid #e4e7ed;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);background:#fff;border-radius:4px;line-height:30px;margin:5px 0}.el-picker-panel,.el-popover,.el-time-panel{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-picker-panel__body-wrapper:after,.el-picker-panel__body:after{content:"";display:table;clear:both}.el-picker-panel__content{position:relative;margin:15px}.el-picker-panel__footer{border-top:1px solid #e4e4e4;padding:4px;text-align:right;background-color:#fff;position:relative;font-size:0}.el-picker-panel__shortcut{display:block;width:100%;border:0;background-color:transparent;line-height:28px;font-size:14px;color:#606266;padding-left:12px;text-align:left;outline:0;cursor:pointer}.el-picker-panel__shortcut:hover{color:#409eff}.el-picker-panel__shortcut.active{background-color:#e6f1fe;color:#409eff}.el-picker-panel__btn{border:1px solid #dcdcdc;color:#333;line-height:24px;border-radius:2px;padding:0 20px;cursor:pointer;background-color:transparent;outline:0;font-size:12px}.el-picker-panel__btn[disabled]{color:#ccc;cursor:not-allowed}.el-picker-panel__icon-btn{font-size:12px;color:#303133;border:0;background:0 0;cursor:pointer;outline:0;margin-top:8px}.el-picker-panel__icon-btn:hover{color:#409eff}.el-picker-panel__icon-btn.is-disabled{color:#bbb}.el-picker-panel__icon-btn.is-disabled:hover{cursor:not-allowed}.el-picker-panel__link-btn{vertical-align:middle}.el-picker-panel [slot=sidebar],.el-picker-panel__sidebar{position:absolute;top:0;bottom:0;width:110px;border-right:1px solid #e4e4e4;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;background-color:#fff;overflow:auto}.el-picker-panel [slot=sidebar]+.el-picker-panel__body,.el-picker-panel__sidebar+.el-picker-panel__body{margin-left:110px}.el-time-spinner.has-seconds .el-time-spinner__wrapper{width:33.3%}.el-time-spinner__wrapper{max-height:190px;overflow:auto;display:inline-block;width:50%;vertical-align:top;position:relative}.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default){padding-bottom:15px}.el-time-spinner__input.el-input .el-input__inner,.el-time-spinner__list{padding:0;text-align:center}.el-time-spinner__wrapper.is-arrow{-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;overflow:hidden}.el-time-spinner__wrapper.is-arrow .el-time-spinner__list{-webkit-transform:translateY(-32px);transform:translateY(-32px)}.el-time-spinner__wrapper.is-arrow .el-time-spinner__item:hover:not(.disabled):not(.active){background:#fff;cursor:default}.el-time-spinner__arrow{font-size:12px;color:#909399;position:absolute;left:0;width:100%;z-index:1;text-align:center;height:30px;line-height:30px;cursor:pointer}.el-time-spinner__arrow:hover{color:#409eff}.el-time-spinner__arrow.el-icon-arrow-up{top:10px}.el-time-spinner__arrow.el-icon-arrow-down{bottom:10px}.el-time-spinner__input.el-input{width:70%}.el-time-spinner__list{margin:0;list-style:none}.el-time-spinner__list:after,.el-time-spinner__list:before{content:"";display:block;width:100%;height:80px}.el-time-spinner__item{height:32px;line-height:32px;font-size:12px;color:#606266}.el-time-spinner__item:hover:not(.disabled):not(.active){background:#f5f7fa;cursor:pointer}.el-time-spinner__item.active:not(.disabled){color:#303133;font-weight:700}.el-time-spinner__item.disabled{color:#c0c4cc;cursor:not-allowed}.el-time-panel{margin:5px 0;border:1px solid #e4e7ed;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:2px;position:absolute;width:180px;left:0;z-index:1000;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;-webkit-box-sizing:content-box;box-sizing:content-box}.el-time-panel__content{font-size:0;position:relative;overflow:hidden}.el-time-panel__content:after,.el-time-panel__content:before{content:"";top:50%;position:absolute;margin-top:-15px;height:32px;z-index:-1;left:0;right:0;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;text-align:left;border-top:1px solid #e4e7ed;border-bottom:1px solid #e4e7ed}.el-time-panel__content:after{left:50%;margin-left:12%;margin-right:12%}.el-time-panel__content:before{padding-left:50%;margin-right:12%;margin-left:12%}.el-time-panel__content.has-seconds:after{left:66.66667%}.el-time-panel__content.has-seconds:before{padding-left:33.33333%}.el-time-panel__footer{border-top:1px solid #e4e4e4;padding:4px;height:36px;line-height:25px;text-align:right;-webkit-box-sizing:border-box;box-sizing:border-box}.el-time-panel__btn{border:none;line-height:28px;padding:0 5px;margin:0 5px;cursor:pointer;background-color:transparent;outline:0;font-size:12px;color:#303133}.el-time-panel__btn.confirm{font-weight:800;color:#409eff}.el-time-range-picker{width:354px;overflow:visible}.el-time-range-picker__content{position:relative;text-align:center;padding:10px}.el-time-range-picker__cell{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:4px 7px 7px;width:50%;display:inline-block}.el-time-range-picker__header{margin-bottom:5px;text-align:center;font-size:14px}.el-time-range-picker__body{border-radius:2px;border:1px solid #e4e7ed}.el-popover{position:absolute;background:#fff;min-width:150px;border:1px solid #ebeef5;padding:12px;z-index:2000;color:#606266;line-height:1.4;text-align:justify;font-size:14px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);word-break:break-all}.el-popover--plain{padding:18px 20px}.el-popover__title{color:#303133;font-size:16px;line-height:1;margin-bottom:12px}.v-modal-enter{-webkit-animation:v-modal-in .2s ease;animation:v-modal-in .2s ease}.v-modal-leave{-webkit-animation:v-modal-out .2s ease forwards;animation:v-modal-out .2s ease forwards}@keyframes v-modal-in{0%{opacity:0}}@keyframes v-modal-out{to{opacity:0}}.v-modal{position:fixed;left:0;top:0;width:100%;height:100%;opacity:.5;background:#000}.el-popup-parent--hidden{overflow:hidden}.el-message-box{display:inline-block;width:420px;padding-bottom:10px;vertical-align:middle;background-color:#fff;border-radius:4px;border:1px solid #ebeef5;font-size:18px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);text-align:left;overflow:hidden;-webkit-backface-visibility:hidden;backface-visibility:hidden}.el-message-box__wrapper{position:fixed;top:0;bottom:0;left:0;right:0;text-align:center}.el-message-box__wrapper:after{content:"";display:inline-block;height:100%;width:0;vertical-align:middle}.el-message-box__header{position:relative;padding:15px 15px 10px}.el-message-box__title{padding-left:0;margin-bottom:0;font-size:18px;line-height:1;color:#303133}.el-message-box__headerbtn{position:absolute;top:15px;right:15px;padding:0;border:none;outline:0;background:0 0;font-size:16px;cursor:pointer}.el-form-item.is-error .el-input__inner,.el-form-item.is-error .el-input__inner:focus,.el-form-item.is-error .el-textarea__inner,.el-form-item.is-error .el-textarea__inner:focus,.el-message-box__input input.invalid,.el-message-box__input input.invalid:focus{border-color:#f56c6c}.el-message-box__headerbtn .el-message-box__close{color:#909399}.el-message-box__headerbtn:focus .el-message-box__close,.el-message-box__headerbtn:hover .el-message-box__close{color:#409eff}.el-message-box__content{position:relative;padding:10px 15px;color:#606266;font-size:14px}.el-message-box__input{padding-top:15px}.el-message-box__status{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);font-size:24px!important}.el-message-box__status:before{padding-left:1px}.el-message-box__status+.el-message-box__message{padding-left:36px;padding-right:12px}.el-message-box__status.el-icon-success{color:#67c23a}.el-message-box__status.el-icon-info{color:#909399}.el-message-box__status.el-icon-warning{color:#e6a23c}.el-message-box__status.el-icon-error{color:#f56c6c}.el-message-box__message{margin:0}.el-message-box__message p{margin:0;line-height:24px}.el-message-box__errormsg{color:#f56c6c;font-size:12px;min-height:18px;margin-top:2px}.el-message-box__btns{padding:5px 15px 0;text-align:right}.el-message-box__btns button:nth-child(2){margin-left:10px}.el-message-box__btns-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.el-container,.el-container.is-vertical,.el-drawer,.el-link,.el-steps--vertical{-webkit-box-direction:normal}.el-message-box--center{padding-bottom:30px}.el-message-box--center .el-message-box__header{padding-top:30px}.el-message-box--center .el-message-box__title{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-message-box--center .el-message-box__status{position:relative;top:auto;padding-right:5px;text-align:center;-webkit-transform:translateY(-1px);transform:translateY(-1px)}.el-message-box--center .el-message-box__message{margin-left:0}.el-message-box--center .el-message-box__btns,.el-message-box--center .el-message-box__content{text-align:center}.el-message-box--center .el-message-box__content{padding-left:27px;padding-right:27px}.msgbox-fade-enter-active{-webkit-animation:msgbox-fade-in .3s;animation:msgbox-fade-in .3s}.msgbox-fade-leave-active{-webkit-animation:msgbox-fade-out .3s;animation:msgbox-fade-out .3s}@-webkit-keyframes msgbox-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes msgbox-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@-webkit-keyframes msgbox-fade-out{0%{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}to{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes msgbox-fade-out{0%{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}to{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.el-breadcrumb{font-size:14px;line-height:1}.el-breadcrumb:after,.el-breadcrumb:before{display:table;content:""}.el-breadcrumb:after{clear:both}.el-breadcrumb__separator{margin:0 9px;font-weight:700;color:#c0c4cc}.el-breadcrumb__separator[class*=icon]{margin:0 6px;font-weight:400}.el-breadcrumb__item{float:left}.el-breadcrumb__inner{color:#606266}.el-breadcrumb__inner.is-link,.el-breadcrumb__inner a{font-weight:700;text-decoration:none;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1);color:#303133}.el-breadcrumb__inner.is-link:hover,.el-breadcrumb__inner a:hover{color:#409eff;cursor:pointer}.el-breadcrumb__item:last-child .el-breadcrumb__inner,.el-breadcrumb__item:last-child .el-breadcrumb__inner:hover,.el-breadcrumb__item:last-child .el-breadcrumb__inner a,.el-breadcrumb__item:last-child .el-breadcrumb__inner a:hover{font-weight:400;color:#606266;cursor:text}.el-breadcrumb__item:last-child .el-breadcrumb__separator{display:none}.el-form--label-left .el-form-item__label{text-align:left}.el-form--label-top .el-form-item__label{float:none;display:inline-block;text-align:left;padding:0 0 10px}.el-form--inline .el-form-item{display:inline-block;margin-right:10px;vertical-align:top}.el-form--inline .el-form-item__label{float:none;display:inline-block}.el-form--inline .el-form-item__content{display:inline-block;vertical-align:top}.el-form--inline.el-form--label-top .el-form-item__content{display:block}.el-form-item{margin-bottom:22px}.el-form-item:after,.el-form-item:before{display:table;content:""}.el-form-item:after{clear:both}.el-form-item .el-form-item{margin-bottom:0}.el-form-item--mini.el-form-item,.el-form-item--small.el-form-item{margin-bottom:18px}.el-form-item .el-input__validateIcon{display:none}.el-form-item--medium .el-form-item__content,.el-form-item--medium .el-form-item__label{line-height:36px}.el-form-item--small .el-form-item__content,.el-form-item--small .el-form-item__label{line-height:32px}.el-form-item--small .el-form-item__error{padding-top:2px}.el-form-item--mini .el-form-item__content,.el-form-item--mini .el-form-item__label{line-height:28px}.el-form-item--mini .el-form-item__error{padding-top:1px}.el-form-item__label-wrap{float:left}.el-form-item__label-wrap .el-form-item__label{display:inline-block;float:none}.el-form-item__label{text-align:right;vertical-align:middle;float:left;font-size:14px;color:#606266;line-height:40px;padding:0 12px 0 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-form-item__content{line-height:40px;position:relative;font-size:14px}.el-form-item__content:after,.el-form-item__content:before{display:table;content:""}.el-form-item__content:after{clear:both}.el-form-item__content .el-input-group{vertical-align:top}.el-form-item__error{color:#f56c6c;font-size:12px;line-height:1;padding-top:4px;position:absolute;top:100%;left:0}.el-form-item__error--inline{position:relative;top:auto;left:auto;display:inline-block;margin-left:10px}.el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap>.el-form-item__label:before,.el-form-item.is-required:not(.is-no-asterisk)>.el-form-item__label:before{content:"*";color:#f56c6c;margin-right:4px}.el-form-item.is-error .el-input-group__append .el-input__inner,.el-form-item.is-error .el-input-group__prepend .el-input__inner{border-color:transparent}.el-form-item.is-error .el-input__validateIcon{color:#f56c6c}.el-form-item--feedback .el-input__validateIcon{display:inline-block}.el-tabs__header{padding:0;position:relative;margin:0 0 15px}.el-tabs__active-bar{position:absolute;bottom:0;left:0;height:2px;background-color:#409eff;z-index:1;-webkit-transition:-webkit-transform .3s cubic-bezier(.645,.045,.355,1);transition:-webkit-transform .3s cubic-bezier(.645,.045,.355,1);transition:transform .3s cubic-bezier(.645,.045,.355,1);transition:transform .3s cubic-bezier(.645,.045,.355,1),-webkit-transform .3s cubic-bezier(.645,.045,.355,1);list-style:none}.el-tabs__new-tab{float:right;border:1px solid #d3dce6;height:18px;width:18px;line-height:18px;margin:12px 0 9px 10px;border-radius:3px;text-align:center;font-size:12px;color:#d3dce6;cursor:pointer;-webkit-transition:all .15s;transition:all .15s}.el-collapse-item__arrow,.el-tabs__nav{-webkit-transition:-webkit-transform .3s}.el-tabs__new-tab .el-icon-plus{-webkit-transform:scale(.8);transform:scale(.8)}.el-tabs__new-tab:hover{color:#409eff}.el-tabs__nav-wrap{overflow:hidden;margin-bottom:-1px;position:relative}.el-tabs__nav-wrap:after{content:"";position:absolute;left:0;bottom:0;width:100%;height:2px;background-color:#e4e7ed;z-index:1}.el-tabs--border-card>.el-tabs__header .el-tabs__nav-wrap:after,.el-tabs--card>.el-tabs__header .el-tabs__nav-wrap:after{content:none}.el-tabs__nav-wrap.is-scrollable{padding:0 20px;-webkit-box-sizing:border-box;box-sizing:border-box}.el-tabs__nav-scroll{overflow:hidden}.el-tabs__nav-next,.el-tabs__nav-prev{position:absolute;cursor:pointer;line-height:44px;font-size:12px;color:#909399}.el-tabs__nav-next{right:0}.el-tabs__nav-prev{left:0}.el-tabs__nav{white-space:nowrap;position:relative;transition:-webkit-transform .3s;-webkit-transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;float:left;z-index:2}.el-tabs__nav.is-stretch{min-width:100%;display:-webkit-box;display:-ms-flexbox;display:flex}.el-tabs__nav.is-stretch>*{-webkit-box-flex:1;-ms-flex:1;flex:1;text-align:center}.el-tabs__item{padding:0 20px;height:40px;-webkit-box-sizing:border-box;box-sizing:border-box;line-height:40px;display:inline-block;list-style:none;font-size:14px;font-weight:500;color:#303133;position:relative}.el-tabs__item:focus,.el-tabs__item:focus:active{outline:0}.el-tabs__item:focus.is-active.is-focus:not(:active){-webkit-box-shadow:0 0 2px 2px #409eff inset;box-shadow:inset 0 0 2px 2px #409eff;border-radius:3px}.el-tabs__item .el-icon-close{border-radius:50%;text-align:center;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);margin-left:5px}.el-tabs__item .el-icon-close:before{-webkit-transform:scale(.9);transform:scale(.9);display:inline-block}.el-tabs__item .el-icon-close:hover{background-color:#c0c4cc;color:#fff}.el-tabs__item.is-active{color:#409eff}.el-tabs__item:hover{color:#409eff;cursor:pointer}.el-tabs__item.is-disabled{color:#c0c4cc;cursor:default}.el-tabs__content{overflow:hidden;position:relative}.el-tabs--card>.el-tabs__header{border-bottom:1px solid #e4e7ed}.el-tabs--card>.el-tabs__header .el-tabs__nav{border:1px solid #e4e7ed;border-bottom:none;border-radius:4px 4px 0 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-tabs--card>.el-tabs__header .el-tabs__active-bar{display:none}.el-tabs--card>.el-tabs__header .el-tabs__item .el-icon-close{position:relative;font-size:12px;width:0;height:14px;vertical-align:middle;line-height:15px;overflow:hidden;top:-1px;right:-2px;-webkit-transform-origin:100% 50%;transform-origin:100% 50%}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active.is-closable .el-icon-close,.el-tabs--card>.el-tabs__header .el-tabs__item.is-closable:hover .el-icon-close{width:14px}.el-tabs--card>.el-tabs__header .el-tabs__item{border-bottom:1px solid transparent;border-left:1px solid #e4e7ed;-webkit-transition:color .3s cubic-bezier(.645,.045,.355,1),padding .3s cubic-bezier(.645,.045,.355,1);transition:color .3s cubic-bezier(.645,.045,.355,1),padding .3s cubic-bezier(.645,.045,.355,1)}.el-tabs--card>.el-tabs__header .el-tabs__item:first-child{border-left:none}.el-tabs--card>.el-tabs__header .el-tabs__item.is-closable:hover{padding-left:13px;padding-right:13px}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active{border-bottom-color:#fff}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active.is-closable{padding-left:20px;padding-right:20px}.el-tabs--border-card{background:#fff;border:1px solid #dcdfe6;-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04);box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04)}.el-tabs--border-card>.el-tabs__content{padding:15px}.el-tabs--border-card>.el-tabs__header{background-color:#f5f7fa;border-bottom:1px solid #e4e7ed;margin:0}.el-tabs--border-card>.el-tabs__header .el-tabs__item{-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);border:1px solid transparent;margin-top:-1px;color:#909399}.el-tabs--border-card>.el-tabs__header .el-tabs__item+.el-tabs__item,.el-tabs--border-card>.el-tabs__header .el-tabs__item:first-child{margin-left:-1px}.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active{color:#409eff;background-color:#fff;border-right-color:#dcdfe6;border-left-color:#dcdfe6}.el-tabs--border-card>.el-tabs__header .el-tabs__item:not(.is-disabled):hover{color:#409eff}.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-disabled{color:#c0c4cc}.el-tabs--border-card>.el-tabs__header .is-scrollable .el-tabs__item:first-child{margin-left:0}.el-tabs--bottom .el-tabs__item.is-bottom:nth-child(2),.el-tabs--bottom .el-tabs__item.is-top:nth-child(2),.el-tabs--top .el-tabs__item.is-bottom:nth-child(2),.el-tabs--top .el-tabs__item.is-top:nth-child(2){padding-left:0}.el-tabs--bottom .el-tabs__item.is-bottom:last-child,.el-tabs--bottom .el-tabs__item.is-top:last-child,.el-tabs--top .el-tabs__item.is-bottom:last-child,.el-tabs--top .el-tabs__item.is-top:last-child{padding-right:0}.el-tabs--bottom.el-tabs--border-card>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--bottom.el-tabs--card>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--bottom .el-tabs--left>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--bottom .el-tabs--right>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--top.el-tabs--border-card>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--top.el-tabs--card>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--top .el-tabs--left>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--top .el-tabs--right>.el-tabs__header .el-tabs__item:nth-child(2){padding-left:20px}.el-tabs--bottom.el-tabs--border-card>.el-tabs__header .el-tabs__item:last-child,.el-tabs--bottom.el-tabs--card>.el-tabs__header .el-tabs__item:last-child,.el-tabs--bottom .el-tabs--left>.el-tabs__header .el-tabs__item:last-child,.el-tabs--bottom .el-tabs--right>.el-tabs__header .el-tabs__item:last-child,.el-tabs--top.el-tabs--border-card>.el-tabs__header .el-tabs__item:last-child,.el-tabs--top.el-tabs--card>.el-tabs__header .el-tabs__item:last-child,.el-tabs--top .el-tabs--left>.el-tabs__header .el-tabs__item:last-child,.el-tabs--top .el-tabs--right>.el-tabs__header .el-tabs__item:last-child{padding-right:20px}.el-tabs--bottom .el-tabs__header.is-bottom{margin-bottom:0;margin-top:10px}.el-tabs--bottom.el-tabs--border-card .el-tabs__header.is-bottom{border-bottom:0;border-top:1px solid #dcdfe6}.el-tabs--bottom.el-tabs--border-card .el-tabs__nav-wrap.is-bottom{margin-top:-1px;margin-bottom:0}.el-tabs--bottom.el-tabs--border-card .el-tabs__item.is-bottom:not(.is-active){border:1px solid transparent}.el-tabs--bottom.el-tabs--border-card .el-tabs__item.is-bottom{margin:0 -1px -1px}.el-tabs--left,.el-tabs--right{overflow:hidden}.el-tabs--left .el-tabs__header.is-left,.el-tabs--left .el-tabs__header.is-right,.el-tabs--left .el-tabs__nav-scroll,.el-tabs--left .el-tabs__nav-wrap.is-left,.el-tabs--left .el-tabs__nav-wrap.is-right,.el-tabs--right .el-tabs__header.is-left,.el-tabs--right .el-tabs__header.is-right,.el-tabs--right .el-tabs__nav-scroll,.el-tabs--right .el-tabs__nav-wrap.is-left,.el-tabs--right .el-tabs__nav-wrap.is-right{height:100%}.el-tabs--left .el-tabs__active-bar.is-left,.el-tabs--left .el-tabs__active-bar.is-right,.el-tabs--right .el-tabs__active-bar.is-left,.el-tabs--right .el-tabs__active-bar.is-right{top:0;bottom:auto;width:2px;height:auto}.el-tabs--left .el-tabs__nav-wrap.is-left,.el-tabs--left .el-tabs__nav-wrap.is-right,.el-tabs--right .el-tabs__nav-wrap.is-left,.el-tabs--right .el-tabs__nav-wrap.is-right{margin-bottom:0}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-next,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev{height:30px;line-height:30px;width:100%;text-align:center;cursor:pointer}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-next i,.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev i,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-next i,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev i,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-next i,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev i,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-next i,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev i{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev{left:auto;top:0}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-next{right:auto;bottom:0}.el-tabs--left .el-tabs__active-bar.is-left,.el-tabs--left .el-tabs__nav-wrap.is-left:after{right:0;left:auto}.el-tabs--left .el-tabs__nav-wrap.is-left.is-scrollable,.el-tabs--left .el-tabs__nav-wrap.is-right.is-scrollable,.el-tabs--right .el-tabs__nav-wrap.is-left.is-scrollable,.el-tabs--right .el-tabs__nav-wrap.is-right.is-scrollable{padding:30px 0}.el-tabs--left .el-tabs__nav-wrap.is-left:after,.el-tabs--left .el-tabs__nav-wrap.is-right:after,.el-tabs--right .el-tabs__nav-wrap.is-left:after,.el-tabs--right .el-tabs__nav-wrap.is-right:after{height:100%;width:2px;bottom:auto;top:0}.el-tabs--left .el-tabs__nav.is-left,.el-tabs--left .el-tabs__nav.is-right,.el-tabs--right .el-tabs__nav.is-left,.el-tabs--right .el-tabs__nav.is-right{float:none}.el-tabs--left .el-tabs__item.is-left,.el-tabs--left .el-tabs__item.is-right,.el-tabs--right .el-tabs__item.is-left,.el-tabs--right .el-tabs__item.is-right{display:block}.el-tabs--left.el-tabs--card .el-tabs__active-bar.is-left,.el-tabs--right.el-tabs--card .el-tabs__active-bar.is-right{display:none}.el-tabs--left .el-tabs__header.is-left{float:left;margin-bottom:0;margin-right:10px}.el-tabs--left .el-tabs__nav-wrap.is-left{margin-right:-1px}.el-tabs--left .el-tabs__item.is-left{text-align:right}.el-tabs--left.el-tabs--card .el-tabs__item.is-left{border-left:none;border-right:1px solid #e4e7ed;border-bottom:none;border-top:1px solid #e4e7ed;text-align:left}.el-tabs--left.el-tabs--card .el-tabs__item.is-left:first-child{border-right:1px solid #e4e7ed;border-top:none}.el-tabs--left.el-tabs--card .el-tabs__item.is-left.is-active{border:1px solid #e4e7ed;border-right-color:#fff;border-left:none;border-bottom:none}.el-tabs--left.el-tabs--card .el-tabs__item.is-left.is-active:first-child{border-top:none}.el-tabs--left.el-tabs--card .el-tabs__item.is-left.is-active:last-child{border-bottom:none}.el-tabs--left.el-tabs--card .el-tabs__nav{border-radius:4px 0 0 4px;border-bottom:1px solid #e4e7ed;border-right:none}.el-tabs--left.el-tabs--card .el-tabs__new-tab{float:none}.el-tabs--left.el-tabs--border-card .el-tabs__header.is-left{border-right:1px solid #dfe4ed}.el-tabs--left.el-tabs--border-card .el-tabs__item.is-left{border:1px solid transparent;margin:-1px 0 -1px -1px}.el-tabs--left.el-tabs--border-card .el-tabs__item.is-left.is-active{border-color:#d1dbe5 transparent}.el-tabs--right .el-tabs__header.is-right{float:right;margin-bottom:0;margin-left:10px}.el-tabs--right .el-tabs__nav-wrap.is-right{margin-left:-1px}.el-tabs--right .el-tabs__nav-wrap.is-right:after{left:0;right:auto}.el-tabs--right .el-tabs__active-bar.is-right{left:0}.el-tabs--right.el-tabs--card .el-tabs__item.is-right{border-bottom:none;border-top:1px solid #e4e7ed}.el-tabs--right.el-tabs--card .el-tabs__item.is-right:first-child{border-left:1px solid #e4e7ed;border-top:none}.el-tabs--right.el-tabs--card .el-tabs__item.is-right.is-active{border:1px solid #e4e7ed;border-left-color:#fff;border-right:none;border-bottom:none}.el-tabs--right.el-tabs--card .el-tabs__item.is-right.is-active:first-child{border-top:none}.el-tabs--right.el-tabs--card .el-tabs__item.is-right.is-active:last-child{border-bottom:none}.el-tabs--right.el-tabs--card .el-tabs__nav{border-radius:0 4px 4px 0;border-bottom:1px solid #e4e7ed;border-left:none}.el-tabs--right.el-tabs--border-card .el-tabs__header.is-right{border-left:1px solid #dfe4ed}.el-tabs--right.el-tabs--border-card .el-tabs__item.is-right{border:1px solid transparent;margin:-1px -1px -1px 0}.el-tabs--right.el-tabs--border-card .el-tabs__item.is-right.is-active{border-color:#d1dbe5 transparent}.slideInLeft-transition,.slideInRight-transition{display:inline-block}.slideInRight-enter{-webkit-animation:slideInRight-enter .3s;animation:slideInRight-enter .3s}.slideInRight-leave{position:absolute;left:0;right:0;-webkit-animation:slideInRight-leave .3s;animation:slideInRight-leave .3s}.slideInLeft-enter{-webkit-animation:slideInLeft-enter .3s;animation:slideInLeft-enter .3s}.slideInLeft-leave{position:absolute;left:0;right:0;-webkit-animation:slideInLeft-leave .3s;animation:slideInLeft-leave .3s}@-webkit-keyframes slideInRight-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInRight-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes slideInRight-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%);opacity:0}}@keyframes slideInRight-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%);opacity:0}}@-webkit-keyframes slideInLeft-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInLeft-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes slideInLeft-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%);opacity:0}}@keyframes slideInLeft-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}to{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%);opacity:0}}.el-tree{position:relative;cursor:default;background:#fff;color:#606266}.el-tree__empty-block{position:relative;min-height:60px;text-align:center;width:100%;height:100%}.el-tree__empty-text{position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);color:#909399}.el-tree__drop-indicator{position:absolute;left:0;right:0;height:1px;background-color:#409eff}.el-tree-node{white-space:nowrap;outline:0}.el-tree-node:focus>.el-tree-node__content{background-color:#f5f7fa}.el-tree-node.is-drop-inner>.el-tree-node__content .el-tree-node__label{background-color:#409eff;color:#fff}.el-tree-node__content{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:26px;cursor:pointer}.el-tree-node__content>.el-tree-node__expand-icon{padding:6px}.el-tree-node__content>label.el-checkbox{margin-right:8px}.el-tree-node__content:hover{background-color:#f5f7fa}.el-tree.is-dragging .el-tree-node__content{cursor:move}.el-tree.is-dragging.is-drop-not-allow .el-tree-node__content{cursor:not-allowed}.el-tree-node__expand-icon{cursor:pointer;color:#c0c4cc;font-size:12px;-webkit-transform:rotate(0);transform:rotate(0);-webkit-transition:-webkit-transform .3s ease-in-out;transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;transition:transform .3s ease-in-out,-webkit-transform .3s ease-in-out}.el-tree-node__expand-icon.expanded{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-tree-node__expand-icon.is-leaf{color:transparent;cursor:default}.el-tree-node__label{font-size:14px}.el-tree-node__loading-icon{margin-right:8px;font-size:14px;color:#c0c4cc}.el-tree-node>.el-tree-node__children{overflow:hidden;background-color:transparent}.el-tree-node.is-expanded>.el-tree-node__children{display:block}.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content{background-color:#f0f7ff}.el-alert{width:100%;padding:8px 16px;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;position:relative;background-color:#fff;overflow:hidden;opacity:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-transition:opacity .2s;transition:opacity .2s}.el-alert.is-light .el-alert__closebtn{color:#c0c4cc}.el-alert.is-dark .el-alert__closebtn,.el-alert.is-dark .el-alert__description{color:#fff}.el-alert.is-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-alert--success.is-light{background-color:#f0f9eb;color:#67c23a}.el-alert--success.is-light .el-alert__description{color:#67c23a}.el-alert--success.is-dark{background-color:#67c23a;color:#fff}.el-alert--info.is-light{background-color:#f4f4f5;color:#909399}.el-alert--info.is-dark{background-color:#909399;color:#fff}.el-alert--info .el-alert__description{color:#909399}.el-alert--warning.is-light{background-color:#fdf6ec;color:#e6a23c}.el-alert--warning.is-light .el-alert__description{color:#e6a23c}.el-alert--warning.is-dark{background-color:#e6a23c;color:#fff}.el-alert--error.is-light{background-color:#fef0f0;color:#f56c6c}.el-alert--error.is-light .el-alert__description{color:#f56c6c}.el-alert--error.is-dark{background-color:#f56c6c;color:#fff}.el-alert__content{display:table-cell;padding:0 8px}.el-alert__icon{font-size:16px;width:16px}.el-alert__icon.is-big{font-size:28px;width:28px}.el-alert__title{font-size:13px;line-height:18px}.el-alert__title.is-bold{font-weight:700}.el-alert .el-alert__description{font-size:12px;margin:5px 0 0}.el-alert__closebtn{font-size:12px;opacity:1;position:absolute;top:12px;right:15px;cursor:pointer}.el-alert-fade-enter,.el-alert-fade-leave-active,.el-loading-fade-enter,.el-loading-fade-leave-active,.el-notification-fade-leave-active{opacity:0}.el-alert__closebtn.is-customed{font-style:normal;font-size:13px;top:9px}.el-notification{display:-webkit-box;display:-ms-flexbox;display:flex;width:330px;padding:14px 26px 14px 13px;border-radius:8px;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #ebeef5;position:fixed;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-transition:opacity .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;transition:opacity .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;transition:opacity .3s,transform .3s,left .3s,right .3s,top .4s,bottom .3s;transition:opacity .3s,transform .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;overflow:hidden}.el-notification.right{right:16px}.el-notification.left{left:16px}.el-notification__group{margin-left:13px;margin-right:8px}.el-notification__title{font-weight:700;font-size:16px;color:#303133;margin:0}.el-notification__content{font-size:14px;line-height:21px;margin:6px 0 0;color:#606266;text-align:justify}.el-notification__content p{margin:0}.el-notification__icon{height:24px;width:24px;font-size:24px}.el-notification__closeBtn{position:absolute;top:18px;right:15px;cursor:pointer;color:#909399;font-size:16px}.el-notification__closeBtn:hover{color:#606266}.el-notification .el-icon-success{color:#67c23a}.el-notification .el-icon-error{color:#f56c6c}.el-notification .el-icon-info{color:#909399}.el-notification .el-icon-warning{color:#e6a23c}.el-notification-fade-enter.right{right:0;-webkit-transform:translateX(100%);transform:translateX(100%)}.el-notification-fade-enter.left{left:0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}.el-input-number{position:relative;display:inline-block;width:180px;line-height:38px}.el-input-number .el-input{display:block}.el-input-number .el-input__inner{-webkit-appearance:none;padding-left:50px;padding-right:50px;text-align:center}.el-input-number__decrease,.el-input-number__increase{position:absolute;z-index:1;top:1px;width:40px;height:auto;text-align:center;background:#f5f7fa;color:#606266;cursor:pointer;font-size:13px}.el-input-number__decrease:hover,.el-input-number__increase:hover{color:#409eff}.el-input-number__decrease:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled),.el-input-number__increase:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled){border-color:#409eff}.el-input-number__decrease.is-disabled,.el-input-number__increase.is-disabled{color:#c0c4cc;cursor:not-allowed}.el-input-number__increase{right:1px;border-radius:0 4px 4px 0;border-left:1px solid #dcdfe6}.el-input-number__decrease{left:1px;border-radius:4px 0 0 4px;border-right:1px solid #dcdfe6}.el-input-number.is-disabled .el-input-number__decrease,.el-input-number.is-disabled .el-input-number__increase{border-color:#e4e7ed;color:#e4e7ed}.el-input-number.is-disabled .el-input-number__decrease:hover,.el-input-number.is-disabled .el-input-number__increase:hover{color:#e4e7ed;cursor:not-allowed}.el-input-number--medium{width:200px;line-height:34px}.el-input-number--medium .el-input-number__decrease,.el-input-number--medium .el-input-number__increase{width:36px;font-size:14px}.el-input-number--medium .el-input__inner{padding-left:43px;padding-right:43px}.el-input-number--small{width:130px;line-height:30px}.el-input-number--small .el-input-number__decrease,.el-input-number--small .el-input-number__increase{width:32px;font-size:13px}.el-input-number--small .el-input-number__decrease [class*=el-icon],.el-input-number--small .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.9);transform:scale(.9)}.el-input-number--small .el-input__inner{padding-left:39px;padding-right:39px}.el-input-number--mini{width:130px;line-height:26px}.el-input-number--mini .el-input-number__decrease,.el-input-number--mini .el-input-number__increase{width:28px;font-size:12px}.el-input-number--mini .el-input-number__decrease [class*=el-icon],.el-input-number--mini .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.8);transform:scale(.8)}.el-input-number--mini .el-input__inner{padding-left:35px;padding-right:35px}.el-input-number.is-without-controls .el-input__inner{padding-left:15px;padding-right:15px}.el-input-number.is-controls-right .el-input__inner{padding-left:15px;padding-right:50px}.el-input-number.is-controls-right .el-input-number__decrease,.el-input-number.is-controls-right .el-input-number__increase{height:auto;line-height:19px}.el-input-number.is-controls-right .el-input-number__decrease [class*=el-icon],.el-input-number.is-controls-right .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.8);transform:scale(.8)}.el-input-number.is-controls-right .el-input-number__increase{border-radius:0 4px 0 0;border-bottom:1px solid #dcdfe6}.el-input-number.is-controls-right .el-input-number__decrease{right:1px;bottom:1px;top:auto;left:auto;border-right:none;border-left:1px solid #dcdfe6;border-radius:0 0 4px}.el-input-number.is-controls-right[class*=medium] [class*=decrease],.el-input-number.is-controls-right[class*=medium] [class*=increase]{line-height:17px}.el-input-number.is-controls-right[class*=small] [class*=decrease],.el-input-number.is-controls-right[class*=small] [class*=increase]{line-height:15px}.el-input-number.is-controls-right[class*=mini] [class*=decrease],.el-input-number.is-controls-right[class*=mini] [class*=increase]{line-height:13px}.el-tooltip__popper{position:absolute;border-radius:4px;padding:10px;z-index:2000;font-size:12px;line-height:1.2;min-width:10px;word-wrap:break-word}.el-tooltip__popper .popper__arrow,.el-tooltip__popper .popper__arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-tooltip__popper .popper__arrow{border-width:6px}.el-tooltip__popper .popper__arrow:after{content:" ";border-width:5px}.el-progress-bar__inner:after,.el-row:after,.el-row:before,.el-slider:after,.el-slider:before,.el-slider__button-wrapper:after,.el-upload-cover:after{content:""}.el-tooltip__popper[x-placement^=top]{margin-bottom:12px}.el-tooltip__popper[x-placement^=top] .popper__arrow{bottom:-6px;border-top-color:#303133;border-bottom-width:0}.el-tooltip__popper[x-placement^=top] .popper__arrow:after{bottom:1px;margin-left:-5px;border-top-color:#303133;border-bottom-width:0}.el-tooltip__popper[x-placement^=bottom]{margin-top:12px}.el-tooltip__popper[x-placement^=bottom] .popper__arrow{top:-6px;border-top-width:0;border-bottom-color:#303133}.el-tooltip__popper[x-placement^=bottom] .popper__arrow:after{top:1px;margin-left:-5px;border-top-width:0;border-bottom-color:#303133}.el-tooltip__popper[x-placement^=right]{margin-left:12px}.el-tooltip__popper[x-placement^=right] .popper__arrow{left:-6px;border-right-color:#303133;border-left-width:0}.el-tooltip__popper[x-placement^=right] .popper__arrow:after{bottom:-5px;left:1px;border-right-color:#303133;border-left-width:0}.el-tooltip__popper[x-placement^=left]{margin-right:12px}.el-tooltip__popper[x-placement^=left] .popper__arrow{right:-6px;border-right-width:0;border-left-color:#303133}.el-tooltip__popper[x-placement^=left] .popper__arrow:after{right:1px;bottom:-5px;margin-left:-5px;border-right-width:0;border-left-color:#303133}.el-tooltip__popper.is-dark{background:#303133;color:#fff}.el-tooltip__popper.is-light{background:#fff;border:1px solid #303133}.el-tooltip__popper.is-light[x-placement^=top] .popper__arrow{border-top-color:#303133}.el-tooltip__popper.is-light[x-placement^=top] .popper__arrow:after{border-top-color:#fff}.el-tooltip__popper.is-light[x-placement^=bottom] .popper__arrow{border-bottom-color:#303133}.el-tooltip__popper.is-light[x-placement^=bottom] .popper__arrow:after{border-bottom-color:#fff}.el-tooltip__popper.is-light[x-placement^=left] .popper__arrow{border-left-color:#303133}.el-tooltip__popper.is-light[x-placement^=left] .popper__arrow:after{border-left-color:#fff}.el-tooltip__popper.is-light[x-placement^=right] .popper__arrow{border-right-color:#303133}.el-tooltip__popper.is-light[x-placement^=right] .popper__arrow:after{border-right-color:#fff}.el-slider:after,.el-slider:before{display:table}.el-slider__button-wrapper .el-tooltip,.el-slider__button-wrapper:after{vertical-align:middle;display:inline-block}.el-slider:after{clear:both}.el-slider__runway{width:100%;height:6px;margin:16px 0;background-color:#e4e7ed;border-radius:3px;position:relative;cursor:pointer;vertical-align:middle}.el-slider__runway.show-input{margin-right:160px;width:auto}.el-slider__runway.disabled{cursor:default}.el-slider__runway.disabled .el-slider__bar{background-color:#c0c4cc}.el-slider__runway.disabled .el-slider__button{border-color:#c0c4cc}.el-slider__runway.disabled .el-slider__button-wrapper.dragging,.el-slider__runway.disabled .el-slider__button-wrapper.hover,.el-slider__runway.disabled .el-slider__button-wrapper:hover{cursor:not-allowed}.el-slider__runway.disabled .el-slider__button.dragging,.el-slider__runway.disabled .el-slider__button.hover,.el-slider__runway.disabled .el-slider__button:hover{-webkit-transform:scale(1);transform:scale(1);cursor:not-allowed}.el-slider__button-wrapper,.el-slider__stop{-webkit-transform:translateX(-50%);position:absolute}.el-slider__input{float:right;margin-top:3px;width:130px}.el-slider__input.el-input-number--mini{margin-top:5px}.el-slider__input.el-input-number--medium{margin-top:0}.el-slider__input.el-input-number--large{margin-top:-2px}.el-slider__bar{height:6px;background-color:#409eff;border-top-left-radius:3px;border-bottom-left-radius:3px;position:absolute}.el-slider__button-wrapper{height:36px;width:36px;z-index:1001;top:-15px;-webkit-transform:translateX(-50%);transform:translateX(-50%);background-color:transparent;text-align:center;user-select:none;line-height:normal}.el-slider__button,.el-slider__button-wrapper,.el-step__icon-inner{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.el-slider__button-wrapper:after{height:100%}.el-slider__button-wrapper.hover,.el-slider__button-wrapper:hover{cursor:-webkit-grab;cursor:grab}.el-slider__button-wrapper.dragging{cursor:-webkit-grabbing;cursor:grabbing}.el-slider__button{width:16px;height:16px;border:2px solid #409eff;background-color:#fff;border-radius:50%;-webkit-transition:.2s;transition:.2s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.el-slider__button.dragging,.el-slider__button.hover,.el-slider__button:hover{-webkit-transform:scale(1.2);transform:scale(1.2)}.el-slider__button.hover,.el-slider__button:hover{cursor:-webkit-grab;cursor:grab}.el-slider__button.dragging{cursor:-webkit-grabbing;cursor:grabbing}.el-slider__stop{height:6px;width:6px;border-radius:100%;background-color:#fff;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.el-slider__marks{top:0;left:12px;width:18px;height:100%}.el-slider__marks-text{position:absolute;-webkit-transform:translateX(-50%);transform:translateX(-50%);font-size:14px;color:#909399;margin-top:15px}.el-slider.is-vertical{position:relative}.el-slider.is-vertical .el-slider__runway{width:6px;height:100%;margin:0 16px}.el-slider.is-vertical .el-slider__bar{width:6px;height:auto;border-radius:0 0 3px 3px}.el-slider.is-vertical .el-slider__button-wrapper{top:auto;left:-15px}.el-slider.is-vertical .el-slider__button-wrapper,.el-slider.is-vertical .el-slider__stop{-webkit-transform:translateY(50%);transform:translateY(50%)}.el-slider.is-vertical.el-slider--with-input{padding-bottom:58px}.el-slider.is-vertical.el-slider--with-input .el-slider__input{overflow:visible;float:none;position:absolute;bottom:22px;width:36px;margin-top:15px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input__inner{text-align:center;padding-left:5px;padding-right:5px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__decrease,.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase{top:32px;margin-top:-1px;border:1px solid #dcdfe6;line-height:20px;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__decrease{width:18px;right:18px;border-bottom-left-radius:4px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase{width:19px;border-bottom-right-radius:4px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase~.el-input .el-input__inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.el-slider.is-vertical.el-slider--with-input .el-slider__input:hover .el-input-number__decrease,.el-slider.is-vertical.el-slider--with-input .el-slider__input:hover .el-input-number__increase{border-color:#c0c4cc}.el-slider.is-vertical.el-slider--with-input .el-slider__input:active .el-input-number__decrease,.el-slider.is-vertical.el-slider--with-input .el-slider__input:active .el-input-number__increase{border-color:#409eff}.el-slider.is-vertical .el-slider__marks-text{margin-top:0;left:15px;-webkit-transform:translateY(50%);transform:translateY(50%)}.el-loading-parent--relative{position:relative!important}.el-loading-parent--hidden{overflow:hidden!important}.el-loading-mask{position:absolute;z-index:2000;background-color:hsla(0,0%,100%,.9);margin:0;top:0;right:0;bottom:0;left:0;-webkit-transition:opacity .3s;transition:opacity .3s}.el-loading-mask.is-fullscreen{position:fixed}.el-loading-mask.is-fullscreen .el-loading-spinner{margin-top:-25px}.el-loading-mask.is-fullscreen .el-loading-spinner .circular{height:50px;width:50px}.el-loading-spinner{top:50%;margin-top:-21px;width:100%;text-align:center;position:absolute}.el-col-pull-0,.el-col-pull-1,.el-col-pull-2,.el-col-pull-3,.el-col-pull-4,.el-col-pull-5,.el-col-pull-6,.el-col-pull-7,.el-col-pull-8,.el-col-pull-9,.el-col-pull-10,.el-col-pull-11,.el-col-pull-13,.el-col-pull-14,.el-col-pull-15,.el-col-pull-16,.el-col-pull-17,.el-col-pull-18,.el-col-pull-19,.el-col-pull-20,.el-col-pull-21,.el-col-pull-22,.el-col-pull-23,.el-col-pull-24,.el-col-push-0,.el-col-push-1,.el-col-push-2,.el-col-push-3,.el-col-push-4,.el-col-push-5,.el-col-push-6,.el-col-push-7,.el-col-push-8,.el-col-push-9,.el-col-push-10,.el-col-push-11,.el-col-push-12,.el-col-push-13,.el-col-push-14,.el-col-push-15,.el-col-push-16,.el-col-push-17,.el-col-push-18,.el-col-push-19,.el-col-push-20,.el-col-push-21,.el-col-push-22,.el-col-push-23,.el-col-push-24,.el-row{position:relative}.el-loading-spinner .el-loading-text{color:#409eff;margin:3px 0;font-size:14px}.el-loading-spinner .circular{height:42px;width:42px;-webkit-animation:loading-rotate 2s linear infinite;animation:loading-rotate 2s linear infinite}.el-loading-spinner .path{-webkit-animation:loading-dash 1.5s ease-in-out infinite;animation:loading-dash 1.5s ease-in-out infinite;stroke-dasharray:90,150;stroke-dashoffset:0;stroke-width:2;stroke:#409eff;stroke-linecap:round}.el-loading-spinner i{color:#409eff}@-webkit-keyframes loading-rotate{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes loading-rotate{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@-webkit-keyframes loading-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40px}to{stroke-dasharray:90,150;stroke-dashoffset:-120px}}@keyframes loading-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40px}to{stroke-dasharray:90,150;stroke-dashoffset:-120px}}.el-row{-webkit-box-sizing:border-box;box-sizing:border-box}.el-row:after,.el-row:before{display:table}.el-row:after{clear:both}.el-row--flex{display:-webkit-box;display:-ms-flexbox;display:flex}.el-col-0,.el-row--flex:after,.el-row--flex:before{display:none}.el-row--flex.is-justify-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-row--flex.is-justify-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.el-row--flex.is-justify-space-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.el-row--flex.is-justify-space-around{-ms-flex-pack:distribute;justify-content:space-around}.el-row--flex.is-align-middle{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-row--flex.is-align-bottom{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}[class*=el-col-]{float:left;-webkit-box-sizing:border-box;box-sizing:border-box}.el-upload--picture-card,.el-upload-dragger{-webkit-box-sizing:border-box;cursor:pointer}.el-col-0{width:0}.el-col-offset-0{margin-left:0}.el-col-pull-0{right:0}.el-col-push-0{left:0}.el-col-1{width:4.16667%}.el-col-offset-1{margin-left:4.16667%}.el-col-pull-1{right:4.16667%}.el-col-push-1{left:4.16667%}.el-col-2{width:8.33333%}.el-col-offset-2{margin-left:8.33333%}.el-col-pull-2{right:8.33333%}.el-col-push-2{left:8.33333%}.el-col-3{width:12.5%}.el-col-offset-3{margin-left:12.5%}.el-col-pull-3{right:12.5%}.el-col-push-3{left:12.5%}.el-col-4{width:16.66667%}.el-col-offset-4{margin-left:16.66667%}.el-col-pull-4{right:16.66667%}.el-col-push-4{left:16.66667%}.el-col-5{width:20.83333%}.el-col-offset-5{margin-left:20.83333%}.el-col-pull-5{right:20.83333%}.el-col-push-5{left:20.83333%}.el-col-6{width:25%}.el-col-offset-6{margin-left:25%}.el-col-pull-6{right:25%}.el-col-push-6{left:25%}.el-col-7{width:29.16667%}.el-col-offset-7{margin-left:29.16667%}.el-col-pull-7{right:29.16667%}.el-col-push-7{left:29.16667%}.el-col-8{width:33.33333%}.el-col-offset-8{margin-left:33.33333%}.el-col-pull-8{right:33.33333%}.el-col-push-8{left:33.33333%}.el-col-9{width:37.5%}.el-col-offset-9{margin-left:37.5%}.el-col-pull-9{right:37.5%}.el-col-push-9{left:37.5%}.el-col-10{width:41.66667%}.el-col-offset-10{margin-left:41.66667%}.el-col-pull-10{right:41.66667%}.el-col-push-10{left:41.66667%}.el-col-11{width:45.83333%}.el-col-offset-11{margin-left:45.83333%}.el-col-pull-11{right:45.83333%}.el-col-push-11{left:45.83333%}.el-col-12{width:50%}.el-col-offset-12{margin-left:50%}.el-col-pull-12{position:relative;right:50%}.el-col-push-12{left:50%}.el-col-13{width:54.16667%}.el-col-offset-13{margin-left:54.16667%}.el-col-pull-13{right:54.16667%}.el-col-push-13{left:54.16667%}.el-col-14{width:58.33333%}.el-col-offset-14{margin-left:58.33333%}.el-col-pull-14{right:58.33333%}.el-col-push-14{left:58.33333%}.el-col-15{width:62.5%}.el-col-offset-15{margin-left:62.5%}.el-col-pull-15{right:62.5%}.el-col-push-15{left:62.5%}.el-col-16{width:66.66667%}.el-col-offset-16{margin-left:66.66667%}.el-col-pull-16{right:66.66667%}.el-col-push-16{left:66.66667%}.el-col-17{width:70.83333%}.el-col-offset-17{margin-left:70.83333%}.el-col-pull-17{right:70.83333%}.el-col-push-17{left:70.83333%}.el-col-18{width:75%}.el-col-offset-18{margin-left:75%}.el-col-pull-18{right:75%}.el-col-push-18{left:75%}.el-col-19{width:79.16667%}.el-col-offset-19{margin-left:79.16667%}.el-col-pull-19{right:79.16667%}.el-col-push-19{left:79.16667%}.el-col-20{width:83.33333%}.el-col-offset-20{margin-left:83.33333%}.el-col-pull-20{right:83.33333%}.el-col-push-20{left:83.33333%}.el-col-21{width:87.5%}.el-col-offset-21{margin-left:87.5%}.el-col-pull-21{right:87.5%}.el-col-push-21{left:87.5%}.el-col-22{width:91.66667%}.el-col-offset-22{margin-left:91.66667%}.el-col-pull-22{right:91.66667%}.el-col-push-22{left:91.66667%}.el-col-23{width:95.83333%}.el-col-offset-23{margin-left:95.83333%}.el-col-pull-23{right:95.83333%}.el-col-push-23{left:95.83333%}.el-col-24{width:100%}.el-col-offset-24{margin-left:100%}.el-col-pull-24{right:100%}.el-col-push-24{left:100%}@media only screen and (max-width:767px){.el-col-xs-0{display:none;width:0}.el-col-xs-offset-0{margin-left:0}.el-col-xs-pull-0{position:relative;right:0}.el-col-xs-push-0{position:relative;left:0}.el-col-xs-1{width:4.16667%}.el-col-xs-offset-1{margin-left:4.16667%}.el-col-xs-pull-1{position:relative;right:4.16667%}.el-col-xs-push-1{position:relative;left:4.16667%}.el-col-xs-2{width:8.33333%}.el-col-xs-offset-2{margin-left:8.33333%}.el-col-xs-pull-2{position:relative;right:8.33333%}.el-col-xs-push-2{position:relative;left:8.33333%}.el-col-xs-3{width:12.5%}.el-col-xs-offset-3{margin-left:12.5%}.el-col-xs-pull-3{position:relative;right:12.5%}.el-col-xs-push-3{position:relative;left:12.5%}.el-col-xs-4{width:16.66667%}.el-col-xs-offset-4{margin-left:16.66667%}.el-col-xs-pull-4{position:relative;right:16.66667%}.el-col-xs-push-4{position:relative;left:16.66667%}.el-col-xs-5{width:20.83333%}.el-col-xs-offset-5{margin-left:20.83333%}.el-col-xs-pull-5{position:relative;right:20.83333%}.el-col-xs-push-5{position:relative;left:20.83333%}.el-col-xs-6{width:25%}.el-col-xs-offset-6{margin-left:25%}.el-col-xs-pull-6{position:relative;right:25%}.el-col-xs-push-6{position:relative;left:25%}.el-col-xs-7{width:29.16667%}.el-col-xs-offset-7{margin-left:29.16667%}.el-col-xs-pull-7{position:relative;right:29.16667%}.el-col-xs-push-7{position:relative;left:29.16667%}.el-col-xs-8{width:33.33333%}.el-col-xs-offset-8{margin-left:33.33333%}.el-col-xs-pull-8{position:relative;right:33.33333%}.el-col-xs-push-8{position:relative;left:33.33333%}.el-col-xs-9{width:37.5%}.el-col-xs-offset-9{margin-left:37.5%}.el-col-xs-pull-9{position:relative;right:37.5%}.el-col-xs-push-9{position:relative;left:37.5%}.el-col-xs-10{width:41.66667%}.el-col-xs-offset-10{margin-left:41.66667%}.el-col-xs-pull-10{position:relative;right:41.66667%}.el-col-xs-push-10{position:relative;left:41.66667%}.el-col-xs-11{width:45.83333%}.el-col-xs-offset-11{margin-left:45.83333%}.el-col-xs-pull-11{position:relative;right:45.83333%}.el-col-xs-push-11{position:relative;left:45.83333%}.el-col-xs-12{width:50%}.el-col-xs-offset-12{margin-left:50%}.el-col-xs-pull-12{position:relative;right:50%}.el-col-xs-push-12{position:relative;left:50%}.el-col-xs-13{width:54.16667%}.el-col-xs-offset-13{margin-left:54.16667%}.el-col-xs-pull-13{position:relative;right:54.16667%}.el-col-xs-push-13{position:relative;left:54.16667%}.el-col-xs-14{width:58.33333%}.el-col-xs-offset-14{margin-left:58.33333%}.el-col-xs-pull-14{position:relative;right:58.33333%}.el-col-xs-push-14{position:relative;left:58.33333%}.el-col-xs-15{width:62.5%}.el-col-xs-offset-15{margin-left:62.5%}.el-col-xs-pull-15{position:relative;right:62.5%}.el-col-xs-push-15{position:relative;left:62.5%}.el-col-xs-16{width:66.66667%}.el-col-xs-offset-16{margin-left:66.66667%}.el-col-xs-pull-16{position:relative;right:66.66667%}.el-col-xs-push-16{position:relative;left:66.66667%}.el-col-xs-17{width:70.83333%}.el-col-xs-offset-17{margin-left:70.83333%}.el-col-xs-pull-17{position:relative;right:70.83333%}.el-col-xs-push-17{position:relative;left:70.83333%}.el-col-xs-18{width:75%}.el-col-xs-offset-18{margin-left:75%}.el-col-xs-pull-18{position:relative;right:75%}.el-col-xs-push-18{position:relative;left:75%}.el-col-xs-19{width:79.16667%}.el-col-xs-offset-19{margin-left:79.16667%}.el-col-xs-pull-19{position:relative;right:79.16667%}.el-col-xs-push-19{position:relative;left:79.16667%}.el-col-xs-20{width:83.33333%}.el-col-xs-offset-20{margin-left:83.33333%}.el-col-xs-pull-20{position:relative;right:83.33333%}.el-col-xs-push-20{position:relative;left:83.33333%}.el-col-xs-21{width:87.5%}.el-col-xs-offset-21{margin-left:87.5%}.el-col-xs-pull-21{position:relative;right:87.5%}.el-col-xs-push-21{position:relative;left:87.5%}.el-col-xs-22{width:91.66667%}.el-col-xs-offset-22{margin-left:91.66667%}.el-col-xs-pull-22{position:relative;right:91.66667%}.el-col-xs-push-22{position:relative;left:91.66667%}.el-col-xs-23{width:95.83333%}.el-col-xs-offset-23{margin-left:95.83333%}.el-col-xs-pull-23{position:relative;right:95.83333%}.el-col-xs-push-23{position:relative;left:95.83333%}.el-col-xs-24{width:100%}.el-col-xs-offset-24{margin-left:100%}.el-col-xs-pull-24{position:relative;right:100%}.el-col-xs-push-24{position:relative;left:100%}}@media only screen and (min-width:768px){.el-col-sm-0{display:none;width:0}.el-col-sm-offset-0{margin-left:0}.el-col-sm-pull-0{position:relative;right:0}.el-col-sm-push-0{position:relative;left:0}.el-col-sm-1{width:4.16667%}.el-col-sm-offset-1{margin-left:4.16667%}.el-col-sm-pull-1{position:relative;right:4.16667%}.el-col-sm-push-1{position:relative;left:4.16667%}.el-col-sm-2{width:8.33333%}.el-col-sm-offset-2{margin-left:8.33333%}.el-col-sm-pull-2{position:relative;right:8.33333%}.el-col-sm-push-2{position:relative;left:8.33333%}.el-col-sm-3{width:12.5%}.el-col-sm-offset-3{margin-left:12.5%}.el-col-sm-pull-3{position:relative;right:12.5%}.el-col-sm-push-3{position:relative;left:12.5%}.el-col-sm-4{width:16.66667%}.el-col-sm-offset-4{margin-left:16.66667%}.el-col-sm-pull-4{position:relative;right:16.66667%}.el-col-sm-push-4{position:relative;left:16.66667%}.el-col-sm-5{width:20.83333%}.el-col-sm-offset-5{margin-left:20.83333%}.el-col-sm-pull-5{position:relative;right:20.83333%}.el-col-sm-push-5{position:relative;left:20.83333%}.el-col-sm-6{width:25%}.el-col-sm-offset-6{margin-left:25%}.el-col-sm-pull-6{position:relative;right:25%}.el-col-sm-push-6{position:relative;left:25%}.el-col-sm-7{width:29.16667%}.el-col-sm-offset-7{margin-left:29.16667%}.el-col-sm-pull-7{position:relative;right:29.16667%}.el-col-sm-push-7{position:relative;left:29.16667%}.el-col-sm-8{width:33.33333%}.el-col-sm-offset-8{margin-left:33.33333%}.el-col-sm-pull-8{position:relative;right:33.33333%}.el-col-sm-push-8{position:relative;left:33.33333%}.el-col-sm-9{width:37.5%}.el-col-sm-offset-9{margin-left:37.5%}.el-col-sm-pull-9{position:relative;right:37.5%}.el-col-sm-push-9{position:relative;left:37.5%}.el-col-sm-10{width:41.66667%}.el-col-sm-offset-10{margin-left:41.66667%}.el-col-sm-pull-10{position:relative;right:41.66667%}.el-col-sm-push-10{position:relative;left:41.66667%}.el-col-sm-11{width:45.83333%}.el-col-sm-offset-11{margin-left:45.83333%}.el-col-sm-pull-11{position:relative;right:45.83333%}.el-col-sm-push-11{position:relative;left:45.83333%}.el-col-sm-12{width:50%}.el-col-sm-offset-12{margin-left:50%}.el-col-sm-pull-12{position:relative;right:50%}.el-col-sm-push-12{position:relative;left:50%}.el-col-sm-13{width:54.16667%}.el-col-sm-offset-13{margin-left:54.16667%}.el-col-sm-pull-13{position:relative;right:54.16667%}.el-col-sm-push-13{position:relative;left:54.16667%}.el-col-sm-14{width:58.33333%}.el-col-sm-offset-14{margin-left:58.33333%}.el-col-sm-pull-14{position:relative;right:58.33333%}.el-col-sm-push-14{position:relative;left:58.33333%}.el-col-sm-15{width:62.5%}.el-col-sm-offset-15{margin-left:62.5%}.el-col-sm-pull-15{position:relative;right:62.5%}.el-col-sm-push-15{position:relative;left:62.5%}.el-col-sm-16{width:66.66667%}.el-col-sm-offset-16{margin-left:66.66667%}.el-col-sm-pull-16{position:relative;right:66.66667%}.el-col-sm-push-16{position:relative;left:66.66667%}.el-col-sm-17{width:70.83333%}.el-col-sm-offset-17{margin-left:70.83333%}.el-col-sm-pull-17{position:relative;right:70.83333%}.el-col-sm-push-17{position:relative;left:70.83333%}.el-col-sm-18{width:75%}.el-col-sm-offset-18{margin-left:75%}.el-col-sm-pull-18{position:relative;right:75%}.el-col-sm-push-18{position:relative;left:75%}.el-col-sm-19{width:79.16667%}.el-col-sm-offset-19{margin-left:79.16667%}.el-col-sm-pull-19{position:relative;right:79.16667%}.el-col-sm-push-19{position:relative;left:79.16667%}.el-col-sm-20{width:83.33333%}.el-col-sm-offset-20{margin-left:83.33333%}.el-col-sm-pull-20{position:relative;right:83.33333%}.el-col-sm-push-20{position:relative;left:83.33333%}.el-col-sm-21{width:87.5%}.el-col-sm-offset-21{margin-left:87.5%}.el-col-sm-pull-21{position:relative;right:87.5%}.el-col-sm-push-21{position:relative;left:87.5%}.el-col-sm-22{width:91.66667%}.el-col-sm-offset-22{margin-left:91.66667%}.el-col-sm-pull-22{position:relative;right:91.66667%}.el-col-sm-push-22{position:relative;left:91.66667%}.el-col-sm-23{width:95.83333%}.el-col-sm-offset-23{margin-left:95.83333%}.el-col-sm-pull-23{position:relative;right:95.83333%}.el-col-sm-push-23{position:relative;left:95.83333%}.el-col-sm-24{width:100%}.el-col-sm-offset-24{margin-left:100%}.el-col-sm-pull-24{position:relative;right:100%}.el-col-sm-push-24{position:relative;left:100%}}@media only screen and (min-width:992px){.el-col-md-0{display:none;width:0}.el-col-md-offset-0{margin-left:0}.el-col-md-pull-0{position:relative;right:0}.el-col-md-push-0{position:relative;left:0}.el-col-md-1{width:4.16667%}.el-col-md-offset-1{margin-left:4.16667%}.el-col-md-pull-1{position:relative;right:4.16667%}.el-col-md-push-1{position:relative;left:4.16667%}.el-col-md-2{width:8.33333%}.el-col-md-offset-2{margin-left:8.33333%}.el-col-md-pull-2{position:relative;right:8.33333%}.el-col-md-push-2{position:relative;left:8.33333%}.el-col-md-3{width:12.5%}.el-col-md-offset-3{margin-left:12.5%}.el-col-md-pull-3{position:relative;right:12.5%}.el-col-md-push-3{position:relative;left:12.5%}.el-col-md-4{width:16.66667%}.el-col-md-offset-4{margin-left:16.66667%}.el-col-md-pull-4{position:relative;right:16.66667%}.el-col-md-push-4{position:relative;left:16.66667%}.el-col-md-5{width:20.83333%}.el-col-md-offset-5{margin-left:20.83333%}.el-col-md-pull-5{position:relative;right:20.83333%}.el-col-md-push-5{position:relative;left:20.83333%}.el-col-md-6{width:25%}.el-col-md-offset-6{margin-left:25%}.el-col-md-pull-6{position:relative;right:25%}.el-col-md-push-6{position:relative;left:25%}.el-col-md-7{width:29.16667%}.el-col-md-offset-7{margin-left:29.16667%}.el-col-md-pull-7{position:relative;right:29.16667%}.el-col-md-push-7{position:relative;left:29.16667%}.el-col-md-8{width:33.33333%}.el-col-md-offset-8{margin-left:33.33333%}.el-col-md-pull-8{position:relative;right:33.33333%}.el-col-md-push-8{position:relative;left:33.33333%}.el-col-md-9{width:37.5%}.el-col-md-offset-9{margin-left:37.5%}.el-col-md-pull-9{position:relative;right:37.5%}.el-col-md-push-9{position:relative;left:37.5%}.el-col-md-10{width:41.66667%}.el-col-md-offset-10{margin-left:41.66667%}.el-col-md-pull-10{position:relative;right:41.66667%}.el-col-md-push-10{position:relative;left:41.66667%}.el-col-md-11{width:45.83333%}.el-col-md-offset-11{margin-left:45.83333%}.el-col-md-pull-11{position:relative;right:45.83333%}.el-col-md-push-11{position:relative;left:45.83333%}.el-col-md-12{width:50%}.el-col-md-offset-12{margin-left:50%}.el-col-md-pull-12{position:relative;right:50%}.el-col-md-push-12{position:relative;left:50%}.el-col-md-13{width:54.16667%}.el-col-md-offset-13{margin-left:54.16667%}.el-col-md-pull-13{position:relative;right:54.16667%}.el-col-md-push-13{position:relative;left:54.16667%}.el-col-md-14{width:58.33333%}.el-col-md-offset-14{margin-left:58.33333%}.el-col-md-pull-14{position:relative;right:58.33333%}.el-col-md-push-14{position:relative;left:58.33333%}.el-col-md-15{width:62.5%}.el-col-md-offset-15{margin-left:62.5%}.el-col-md-pull-15{position:relative;right:62.5%}.el-col-md-push-15{position:relative;left:62.5%}.el-col-md-16{width:66.66667%}.el-col-md-offset-16{margin-left:66.66667%}.el-col-md-pull-16{position:relative;right:66.66667%}.el-col-md-push-16{position:relative;left:66.66667%}.el-col-md-17{width:70.83333%}.el-col-md-offset-17{margin-left:70.83333%}.el-col-md-pull-17{position:relative;right:70.83333%}.el-col-md-push-17{position:relative;left:70.83333%}.el-col-md-18{width:75%}.el-col-md-offset-18{margin-left:75%}.el-col-md-pull-18{position:relative;right:75%}.el-col-md-push-18{position:relative;left:75%}.el-col-md-19{width:79.16667%}.el-col-md-offset-19{margin-left:79.16667%}.el-col-md-pull-19{position:relative;right:79.16667%}.el-col-md-push-19{position:relative;left:79.16667%}.el-col-md-20{width:83.33333%}.el-col-md-offset-20{margin-left:83.33333%}.el-col-md-pull-20{position:relative;right:83.33333%}.el-col-md-push-20{position:relative;left:83.33333%}.el-col-md-21{width:87.5%}.el-col-md-offset-21{margin-left:87.5%}.el-col-md-pull-21{position:relative;right:87.5%}.el-col-md-push-21{position:relative;left:87.5%}.el-col-md-22{width:91.66667%}.el-col-md-offset-22{margin-left:91.66667%}.el-col-md-pull-22{position:relative;right:91.66667%}.el-col-md-push-22{position:relative;left:91.66667%}.el-col-md-23{width:95.83333%}.el-col-md-offset-23{margin-left:95.83333%}.el-col-md-pull-23{position:relative;right:95.83333%}.el-col-md-push-23{position:relative;left:95.83333%}.el-col-md-24{width:100%}.el-col-md-offset-24{margin-left:100%}.el-col-md-pull-24{position:relative;right:100%}.el-col-md-push-24{position:relative;left:100%}}@media only screen and (min-width:1200px){.el-col-lg-0{display:none;width:0}.el-col-lg-offset-0{margin-left:0}.el-col-lg-pull-0{position:relative;right:0}.el-col-lg-push-0{position:relative;left:0}.el-col-lg-1{width:4.16667%}.el-col-lg-offset-1{margin-left:4.16667%}.el-col-lg-pull-1{position:relative;right:4.16667%}.el-col-lg-push-1{position:relative;left:4.16667%}.el-col-lg-2{width:8.33333%}.el-col-lg-offset-2{margin-left:8.33333%}.el-col-lg-pull-2{position:relative;right:8.33333%}.el-col-lg-push-2{position:relative;left:8.33333%}.el-col-lg-3{width:12.5%}.el-col-lg-offset-3{margin-left:12.5%}.el-col-lg-pull-3{position:relative;right:12.5%}.el-col-lg-push-3{position:relative;left:12.5%}.el-col-lg-4{width:16.66667%}.el-col-lg-offset-4{margin-left:16.66667%}.el-col-lg-pull-4{position:relative;right:16.66667%}.el-col-lg-push-4{position:relative;left:16.66667%}.el-col-lg-5{width:20.83333%}.el-col-lg-offset-5{margin-left:20.83333%}.el-col-lg-pull-5{position:relative;right:20.83333%}.el-col-lg-push-5{position:relative;left:20.83333%}.el-col-lg-6{width:25%}.el-col-lg-offset-6{margin-left:25%}.el-col-lg-pull-6{position:relative;right:25%}.el-col-lg-push-6{position:relative;left:25%}.el-col-lg-7{width:29.16667%}.el-col-lg-offset-7{margin-left:29.16667%}.el-col-lg-pull-7{position:relative;right:29.16667%}.el-col-lg-push-7{position:relative;left:29.16667%}.el-col-lg-8{width:33.33333%}.el-col-lg-offset-8{margin-left:33.33333%}.el-col-lg-pull-8{position:relative;right:33.33333%}.el-col-lg-push-8{position:relative;left:33.33333%}.el-col-lg-9{width:37.5%}.el-col-lg-offset-9{margin-left:37.5%}.el-col-lg-pull-9{position:relative;right:37.5%}.el-col-lg-push-9{position:relative;left:37.5%}.el-col-lg-10{width:41.66667%}.el-col-lg-offset-10{margin-left:41.66667%}.el-col-lg-pull-10{position:relative;right:41.66667%}.el-col-lg-push-10{position:relative;left:41.66667%}.el-col-lg-11{width:45.83333%}.el-col-lg-offset-11{margin-left:45.83333%}.el-col-lg-pull-11{position:relative;right:45.83333%}.el-col-lg-push-11{position:relative;left:45.83333%}.el-col-lg-12{width:50%}.el-col-lg-offset-12{margin-left:50%}.el-col-lg-pull-12{position:relative;right:50%}.el-col-lg-push-12{position:relative;left:50%}.el-col-lg-13{width:54.16667%}.el-col-lg-offset-13{margin-left:54.16667%}.el-col-lg-pull-13{position:relative;right:54.16667%}.el-col-lg-push-13{position:relative;left:54.16667%}.el-col-lg-14{width:58.33333%}.el-col-lg-offset-14{margin-left:58.33333%}.el-col-lg-pull-14{position:relative;right:58.33333%}.el-col-lg-push-14{position:relative;left:58.33333%}.el-col-lg-15{width:62.5%}.el-col-lg-offset-15{margin-left:62.5%}.el-col-lg-pull-15{position:relative;right:62.5%}.el-col-lg-push-15{position:relative;left:62.5%}.el-col-lg-16{width:66.66667%}.el-col-lg-offset-16{margin-left:66.66667%}.el-col-lg-pull-16{position:relative;right:66.66667%}.el-col-lg-push-16{position:relative;left:66.66667%}.el-col-lg-17{width:70.83333%}.el-col-lg-offset-17{margin-left:70.83333%}.el-col-lg-pull-17{position:relative;right:70.83333%}.el-col-lg-push-17{position:relative;left:70.83333%}.el-col-lg-18{width:75%}.el-col-lg-offset-18{margin-left:75%}.el-col-lg-pull-18{position:relative;right:75%}.el-col-lg-push-18{position:relative;left:75%}.el-col-lg-19{width:79.16667%}.el-col-lg-offset-19{margin-left:79.16667%}.el-col-lg-pull-19{position:relative;right:79.16667%}.el-col-lg-push-19{position:relative;left:79.16667%}.el-col-lg-20{width:83.33333%}.el-col-lg-offset-20{margin-left:83.33333%}.el-col-lg-pull-20{position:relative;right:83.33333%}.el-col-lg-push-20{position:relative;left:83.33333%}.el-col-lg-21{width:87.5%}.el-col-lg-offset-21{margin-left:87.5%}.el-col-lg-pull-21{position:relative;right:87.5%}.el-col-lg-push-21{position:relative;left:87.5%}.el-col-lg-22{width:91.66667%}.el-col-lg-offset-22{margin-left:91.66667%}.el-col-lg-pull-22{position:relative;right:91.66667%}.el-col-lg-push-22{position:relative;left:91.66667%}.el-col-lg-23{width:95.83333%}.el-col-lg-offset-23{margin-left:95.83333%}.el-col-lg-pull-23{position:relative;right:95.83333%}.el-col-lg-push-23{position:relative;left:95.83333%}.el-col-lg-24{width:100%}.el-col-lg-offset-24{margin-left:100%}.el-col-lg-pull-24{position:relative;right:100%}.el-col-lg-push-24{position:relative;left:100%}}@media only screen and (min-width:1920px){.el-col-xl-0{display:none;width:0}.el-col-xl-offset-0{margin-left:0}.el-col-xl-pull-0{position:relative;right:0}.el-col-xl-push-0{position:relative;left:0}.el-col-xl-1{width:4.16667%}.el-col-xl-offset-1{margin-left:4.16667%}.el-col-xl-pull-1{position:relative;right:4.16667%}.el-col-xl-push-1{position:relative;left:4.16667%}.el-col-xl-2{width:8.33333%}.el-col-xl-offset-2{margin-left:8.33333%}.el-col-xl-pull-2{position:relative;right:8.33333%}.el-col-xl-push-2{position:relative;left:8.33333%}.el-col-xl-3{width:12.5%}.el-col-xl-offset-3{margin-left:12.5%}.el-col-xl-pull-3{position:relative;right:12.5%}.el-col-xl-push-3{position:relative;left:12.5%}.el-col-xl-4{width:16.66667%}.el-col-xl-offset-4{margin-left:16.66667%}.el-col-xl-pull-4{position:relative;right:16.66667%}.el-col-xl-push-4{position:relative;left:16.66667%}.el-col-xl-5{width:20.83333%}.el-col-xl-offset-5{margin-left:20.83333%}.el-col-xl-pull-5{position:relative;right:20.83333%}.el-col-xl-push-5{position:relative;left:20.83333%}.el-col-xl-6{width:25%}.el-col-xl-offset-6{margin-left:25%}.el-col-xl-pull-6{position:relative;right:25%}.el-col-xl-push-6{position:relative;left:25%}.el-col-xl-7{width:29.16667%}.el-col-xl-offset-7{margin-left:29.16667%}.el-col-xl-pull-7{position:relative;right:29.16667%}.el-col-xl-push-7{position:relative;left:29.16667%}.el-col-xl-8{width:33.33333%}.el-col-xl-offset-8{margin-left:33.33333%}.el-col-xl-pull-8{position:relative;right:33.33333%}.el-col-xl-push-8{position:relative;left:33.33333%}.el-col-xl-9{width:37.5%}.el-col-xl-offset-9{margin-left:37.5%}.el-col-xl-pull-9{position:relative;right:37.5%}.el-col-xl-push-9{position:relative;left:37.5%}.el-col-xl-10{width:41.66667%}.el-col-xl-offset-10{margin-left:41.66667%}.el-col-xl-pull-10{position:relative;right:41.66667%}.el-col-xl-push-10{position:relative;left:41.66667%}.el-col-xl-11{width:45.83333%}.el-col-xl-offset-11{margin-left:45.83333%}.el-col-xl-pull-11{position:relative;right:45.83333%}.el-col-xl-push-11{position:relative;left:45.83333%}.el-col-xl-12{width:50%}.el-col-xl-offset-12{margin-left:50%}.el-col-xl-pull-12{position:relative;right:50%}.el-col-xl-push-12{position:relative;left:50%}.el-col-xl-13{width:54.16667%}.el-col-xl-offset-13{margin-left:54.16667%}.el-col-xl-pull-13{position:relative;right:54.16667%}.el-col-xl-push-13{position:relative;left:54.16667%}.el-col-xl-14{width:58.33333%}.el-col-xl-offset-14{margin-left:58.33333%}.el-col-xl-pull-14{position:relative;right:58.33333%}.el-col-xl-push-14{position:relative;left:58.33333%}.el-col-xl-15{width:62.5%}.el-col-xl-offset-15{margin-left:62.5%}.el-col-xl-pull-15{position:relative;right:62.5%}.el-col-xl-push-15{position:relative;left:62.5%}.el-col-xl-16{width:66.66667%}.el-col-xl-offset-16{margin-left:66.66667%}.el-col-xl-pull-16{position:relative;right:66.66667%}.el-col-xl-push-16{position:relative;left:66.66667%}.el-col-xl-17{width:70.83333%}.el-col-xl-offset-17{margin-left:70.83333%}.el-col-xl-pull-17{position:relative;right:70.83333%}.el-col-xl-push-17{position:relative;left:70.83333%}.el-col-xl-18{width:75%}.el-col-xl-offset-18{margin-left:75%}.el-col-xl-pull-18{position:relative;right:75%}.el-col-xl-push-18{position:relative;left:75%}.el-col-xl-19{width:79.16667%}.el-col-xl-offset-19{margin-left:79.16667%}.el-col-xl-pull-19{position:relative;right:79.16667%}.el-col-xl-push-19{position:relative;left:79.16667%}.el-col-xl-20{width:83.33333%}.el-col-xl-offset-20{margin-left:83.33333%}.el-col-xl-pull-20{position:relative;right:83.33333%}.el-col-xl-push-20{position:relative;left:83.33333%}.el-col-xl-21{width:87.5%}.el-col-xl-offset-21{margin-left:87.5%}.el-col-xl-pull-21{position:relative;right:87.5%}.el-col-xl-push-21{position:relative;left:87.5%}.el-col-xl-22{width:91.66667%}.el-col-xl-offset-22{margin-left:91.66667%}.el-col-xl-pull-22{position:relative;right:91.66667%}.el-col-xl-push-22{position:relative;left:91.66667%}.el-col-xl-23{width:95.83333%}.el-col-xl-offset-23{margin-left:95.83333%}.el-col-xl-pull-23{position:relative;right:95.83333%}.el-col-xl-push-23{position:relative;left:95.83333%}.el-col-xl-24{width:100%}.el-col-xl-offset-24{margin-left:100%}.el-col-xl-pull-24{position:relative;right:100%}.el-col-xl-push-24{position:relative;left:100%}}@-webkit-keyframes progress{0%{background-position:0 0}to{background-position:32px 0}}.el-upload{display:inline-block;text-align:center;cursor:pointer;outline:0}.el-upload__input{display:none}.el-upload__tip{font-size:12px;color:#606266;margin-top:7px}.el-upload iframe{position:absolute;z-index:-1;top:0;left:0;opacity:0;filter:alpha(opacity=0)}.el-upload--picture-card{background-color:#fbfdff;border:1px dashed #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:148px;height:148px;line-height:146px;vertical-align:top}.el-upload--picture-card i{font-size:28px;color:#8c939d}.el-upload--picture-card:hover,.el-upload:focus{border-color:#409eff;color:#409eff}.el-upload:focus .el-upload-dragger{border-color:#409eff}.el-upload-dragger{background-color:#fff;border:1px dashed #d9d9d9;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:360px;height:180px;text-align:center;position:relative;overflow:hidden}.el-upload-dragger .el-icon-upload{font-size:67px;color:#c0c4cc;margin:40px 0 16px;line-height:50px}.el-upload-dragger+.el-upload__tip{text-align:center}.el-upload-dragger~.el-upload__files{border-top:1px solid #dcdfe6;margin-top:7px;padding-top:5px}.el-upload-dragger .el-upload__text{color:#606266;font-size:14px;text-align:center}.el-upload-dragger .el-upload__text em{color:#409eff;font-style:normal}.el-upload-dragger:hover{border-color:#409eff}.el-upload-dragger.is-dragover{background-color:rgba(32,159,255,.06);border:2px dashed #409eff}.el-upload-list{margin:0;padding:0;list-style:none}.el-upload-list__item{-webkit-transition:all .5s cubic-bezier(.55,0,.1,1);transition:all .5s cubic-bezier(.55,0,.1,1);font-size:14px;color:#606266;line-height:1.8;margin-top:5px;position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;width:100%}.el-upload-list__item .el-progress{position:absolute;top:20px;width:100%}.el-upload-list__item .el-progress__text{position:absolute;right:0;top:-13px}.el-upload-list__item .el-progress-bar{margin-right:0;padding-right:0}.el-upload-list__item:first-child{margin-top:10px}.el-upload-list__item .el-icon-upload-success{color:#67c23a}.el-upload-list__item .el-icon-close{display:none;position:absolute;top:5px;right:5px;cursor:pointer;opacity:.75;color:#606266}.el-upload-list__item .el-icon-close:hover{opacity:1}.el-upload-list__item .el-icon-close-tip{display:none;position:absolute;top:5px;right:5px;font-size:12px;cursor:pointer;opacity:1;color:#409eff}.el-upload-list__item:hover{background-color:#f5f7fa}.el-upload-list__item:hover .el-icon-close{display:inline-block}.el-upload-list__item:hover .el-progress__text{display:none}.el-upload-list__item.is-success .el-upload-list__item-status-label{display:block}.el-upload-list__item.is-success .el-upload-list__item-name:focus,.el-upload-list__item.is-success .el-upload-list__item-name:hover{color:#409eff;cursor:pointer}.el-upload-list__item.is-success:focus:not(:hover) .el-icon-close-tip{display:inline-block}.el-upload-list__item.is-success:active .el-icon-close-tip,.el-upload-list__item.is-success:focus .el-upload-list__item-status-label,.el-upload-list__item.is-success:hover .el-upload-list__item-status-label,.el-upload-list__item.is-success:not(.focusing):focus .el-icon-close-tip{display:none}.el-upload-list.is-disabled .el-upload-list__item:hover .el-upload-list__item-status-label{display:block}.el-upload-list__item-name{color:#606266;display:block;margin-right:40px;overflow:hidden;padding-left:4px;text-overflow:ellipsis;-webkit-transition:color .3s;transition:color .3s;white-space:nowrap}.el-upload-list__item-name [class^=el-icon]{height:100%;margin-right:7px;color:#909399;line-height:inherit}.el-upload-list__item-status-label{position:absolute;right:5px;top:0;line-height:inherit;display:none}.el-upload-list__item-delete{position:absolute;right:10px;top:0;font-size:12px;color:#606266;display:none}.el-upload-list__item-delete:hover{color:#409eff}.el-upload-list--picture-card{margin:0;display:inline;vertical-align:top}.el-upload-list--picture-card .el-upload-list__item{overflow:hidden;background-color:#fff;border:1px solid #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:148px;height:148px;margin:0 8px 8px 0;display:inline-block}.el-upload-list--picture-card .el-upload-list__item .el-icon-check,.el-upload-list--picture-card .el-upload-list__item .el-icon-circle-check{color:#fff}.el-upload-list--picture-card .el-upload-list__item .el-icon-close,.el-upload-list--picture-card .el-upload-list__item:hover .el-upload-list__item-status-label{display:none}.el-upload-list--picture-card .el-upload-list__item:hover .el-progress__text{display:block}.el-upload-list--picture-card .el-upload-list__item-name{display:none}.el-upload-list--picture-card .el-upload-list__item-thumbnail{width:100%;height:100%}.el-upload-list--picture-card .el-upload-list__item-status-label{position:absolute;right:-15px;top:-6px;width:40px;height:24px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 0 1pc 1px rgba(0,0,0,.2);box-shadow:0 0 1pc 1px rgba(0,0,0,.2)}.el-upload-list--picture-card .el-upload-list__item-status-label i{font-size:12px;margin-top:11px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.el-upload-list--picture-card .el-upload-list__item-actions{position:absolute;width:100%;height:100%;left:0;top:0;cursor:default;text-align:center;color:#fff;opacity:0;font-size:20px;background-color:rgba(0,0,0,.5);-webkit-transition:opacity .3s;transition:opacity .3s}.el-upload-list--picture-card .el-upload-list__item-actions:after{display:inline-block;content:"";height:100%;vertical-align:middle}.el-upload-list--picture-card .el-upload-list__item-actions span{display:none;cursor:pointer}.el-upload-list--picture-card .el-upload-list__item-actions span+span{margin-left:15px}.el-upload-list--picture-card .el-upload-list__item-actions .el-upload-list__item-delete{position:static;font-size:inherit;color:inherit}.el-upload-list--picture-card .el-upload-list__item-actions:hover{opacity:1}.el-upload-list--picture-card .el-upload-list__item-actions:hover span{display:inline-block}.el-upload-list--picture-card .el-progress{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);bottom:auto;width:126px}.el-upload-list--picture-card .el-progress .el-progress__text{top:50%}.el-upload-list--picture .el-upload-list__item{overflow:hidden;z-index:0;background-color:#fff;border:1px solid #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:10px;padding:10px 10px 10px 90px;height:92px}.el-upload-list--picture .el-upload-list__item .el-icon-check,.el-upload-list--picture .el-upload-list__item .el-icon-circle-check{color:#fff}.el-upload-list--picture .el-upload-list__item:hover .el-upload-list__item-status-label{background:0 0;-webkit-box-shadow:none;box-shadow:none;top:-2px;right:-12px}.el-upload-list--picture .el-upload-list__item:hover .el-progress__text{display:block}.el-upload-list--picture .el-upload-list__item.is-success .el-upload-list__item-name{line-height:70px;margin-top:0}.el-upload-list--picture .el-upload-list__item.is-success .el-upload-list__item-name i{display:none}.el-upload-list--picture .el-upload-list__item-thumbnail{vertical-align:middle;display:inline-block;width:70px;height:70px;float:left;position:relative;z-index:1;margin-left:-80px;background-color:#fff}.el-upload-list--picture .el-upload-list__item-name{display:block;margin-top:20px}.el-upload-list--picture .el-upload-list__item-name i{font-size:70px;line-height:1;position:absolute;left:9px;top:10px}.el-upload-list--picture .el-upload-list__item-status-label{position:absolute;right:-17px;top:-7px;width:46px;height:26px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 1px 1px #ccc;box-shadow:0 1px 1px #ccc}.el-upload-list--picture .el-upload-list__item-status-label i{font-size:12px;margin-top:12px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.el-upload-list--picture .el-progress{position:relative;top:-7px}.el-upload-cover{position:absolute;left:0;top:0;width:100%;height:100%;overflow:hidden;z-index:10;cursor:default}.el-upload-cover:after{display:inline-block;height:100%;vertical-align:middle}.el-upload-cover img{display:block;width:100%;height:100%}.el-upload-cover__label{position:absolute;right:-15px;top:-6px;width:40px;height:24px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 0 1pc 1px rgba(0,0,0,.2);box-shadow:0 0 1pc 1px rgba(0,0,0,.2)}.el-upload-cover__label i{font-size:12px;margin-top:11px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);color:#fff}.el-upload-cover__progress{display:inline-block;vertical-align:middle;position:static;width:243px}.el-upload-cover__progress+.el-upload__inner{opacity:0}.el-upload-cover__content{position:absolute;top:0;left:0;width:100%;height:100%}.el-upload-cover__interact{position:absolute;bottom:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.72);text-align:center}.el-upload-cover__interact .btn{display:inline-block;color:#fff;font-size:14px;cursor:pointer;vertical-align:middle;-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);margin-top:60px}.el-upload-cover__interact .btn span{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.el-upload-cover__interact .btn:not(:first-child){margin-left:35px}.el-upload-cover__interact .btn:hover{-webkit-transform:translateY(-13px);transform:translateY(-13px)}.el-upload-cover__interact .btn:hover span{opacity:1}.el-upload-cover__interact .btn i{color:#fff;display:block;font-size:24px;line-height:inherit;margin:0 auto 5px}.el-upload-cover__title{position:absolute;bottom:0;left:0;background-color:#fff;height:36px;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:400;text-align:left;padding:0 10px;margin:0;line-height:36px;font-size:14px;color:#303133}.el-upload-cover+.el-upload__inner{opacity:0;position:relative;z-index:1}.el-progress{position:relative;line-height:1}.el-progress__text{font-size:14px;color:#606266;display:inline-block;vertical-align:middle;margin-left:10px;line-height:1}.el-progress__text i{vertical-align:middle;display:block}.el-progress--circle,.el-progress--dashboard{display:inline-block}.el-progress--circle .el-progress__text,.el-progress--dashboard .el-progress__text{position:absolute;top:50%;left:0;width:100%;text-align:center;margin:0;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-progress--circle .el-progress__text i,.el-progress--dashboard .el-progress__text i{vertical-align:middle;display:inline-block}.el-progress--without-text .el-progress__text{display:none}.el-progress--without-text .el-progress-bar{padding-right:0;margin-right:0;display:block}.el-progress-bar,.el-progress-bar__inner:after,.el-progress-bar__innerText,.el-spinner{display:inline-block;vertical-align:middle}.el-progress--text-inside .el-progress-bar{padding-right:0;margin-right:0}.el-progress.is-success .el-progress-bar__inner{background-color:#67c23a}.el-progress.is-success .el-progress__text{color:#67c23a}.el-progress.is-warning .el-progress-bar__inner{background-color:#e6a23c}.el-progress.is-warning .el-progress__text{color:#e6a23c}.el-progress.is-exception .el-progress-bar__inner{background-color:#f56c6c}.el-progress.is-exception .el-progress__text{color:#f56c6c}.el-progress-bar{padding-right:50px;width:100%;margin-right:-55px;-webkit-box-sizing:border-box;box-sizing:border-box}.el-progress-bar__outer{height:6px;border-radius:100px;background-color:#ebeef5;overflow:hidden;position:relative;vertical-align:middle}.el-progress-bar__inner{position:absolute;left:0;top:0;height:100%;background-color:#409eff;text-align:right;border-radius:100px;line-height:1;white-space:nowrap;-webkit-transition:width .6s ease;transition:width .6s ease}.el-card,.el-message{border-radius:4px;overflow:hidden}.el-progress-bar__inner:after{height:100%}.el-progress-bar__innerText{color:#fff;font-size:12px;margin:0 5px}@keyframes progress{0%{background-position:0 0}to{background-position:32px 0}}.el-time-spinner{width:100%;white-space:nowrap}.el-spinner-inner{-webkit-animation:rotate 2s linear infinite;animation:rotate 2s linear infinite;width:50px;height:50px}.el-spinner-inner .path{stroke:#ececec;stroke-linecap:round;-webkit-animation:dash 1.5s ease-in-out infinite;animation:dash 1.5s ease-in-out infinite}@-webkit-keyframes rotate{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotate{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@-webkit-keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}.el-message{min-width:380px;-webkit-box-sizing:border-box;box-sizing:border-box;border-width:1px;border-style:solid;border-color:#ebeef5;position:fixed;left:50%;top:20px;-webkit-transform:translateX(-50%);transform:translateX(-50%);background-color:#edf2fc;-webkit-transition:opacity .3s,top .4s,-webkit-transform .4s;transition:opacity .3s,top .4s,-webkit-transform .4s;transition:opacity .3s,transform .4s,top .4s;transition:opacity .3s,transform .4s,top .4s,-webkit-transform .4s;padding:15px 15px 15px 20px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-message.is-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-message.is-closable .el-message__content{padding-right:16px}.el-message p{margin:0}.el-message--info .el-message__content{color:#909399}.el-message--success{background-color:#f0f9eb;border-color:#e1f3d8}.el-message--success .el-message__content{color:#67c23a}.el-message--warning{background-color:#fdf6ec;border-color:#faecd8}.el-message--warning .el-message__content{color:#e6a23c}.el-message--error{background-color:#fef0f0;border-color:#fde2e2}.el-message--error .el-message__content{color:#f56c6c}.el-message__icon{margin-right:10px}.el-message__content{padding:0;font-size:14px;line-height:1}.el-message__closeBtn{position:absolute;top:50%;right:15px;-webkit-transform:translateY(-50%);transform:translateY(-50%);cursor:pointer;color:#c0c4cc;font-size:16px}.el-message__closeBtn:hover{color:#909399}.el-message .el-icon-success{color:#67c23a}.el-message .el-icon-error{color:#f56c6c}.el-message .el-icon-info{color:#909399}.el-message .el-icon-warning{color:#e6a23c}.el-message-fade-enter,.el-message-fade-leave-active{opacity:0;-webkit-transform:translate(-50%,-100%);transform:translate(-50%,-100%)}.el-badge{position:relative;vertical-align:middle;display:inline-block}.el-badge__content{background-color:#f56c6c;border-radius:10px;color:#fff;display:inline-block;font-size:12px;height:18px;line-height:18px;padding:0 6px;text-align:center;white-space:nowrap;border:1px solid #fff}.el-badge__content.is-fixed{position:absolute;top:0;right:10px;-webkit-transform:translateY(-50%) translateX(100%);transform:translateY(-50%) translateX(100%)}.el-rate__icon,.el-rate__item{position:relative;display:inline-block}.el-badge__content.is-fixed.is-dot{right:5px}.el-badge__content.is-dot{height:8px;width:8px;padding:0;right:0;border-radius:50%}.el-badge__content--primary{background-color:#409eff}.el-badge__content--success{background-color:#67c23a}.el-badge__content--warning{background-color:#e6a23c}.el-badge__content--info{background-color:#909399}.el-badge__content--danger{background-color:#f56c6c}.el-card{border:1px solid #ebeef5;background-color:#fff;color:#303133;-webkit-transition:.3s;transition:.3s}.el-card.is-always-shadow,.el-card.is-hover-shadow:focus,.el-card.is-hover-shadow:hover{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-card__header{padding:18px 20px;border-bottom:1px solid #ebeef5;-webkit-box-sizing:border-box;box-sizing:border-box}.el-card__body{padding:20px}.el-rate{height:20px;line-height:1}.el-rate__item{font-size:0;vertical-align:middle}.el-rate__icon{font-size:18px;margin-right:6px;color:#c0c4cc;-webkit-transition:.3s;transition:.3s}.el-rate__decimal,.el-rate__icon .path2{position:absolute;top:0;left:0}.el-rate__icon.hover{-webkit-transform:scale(1.15);transform:scale(1.15)}.el-rate__decimal{display:inline-block;overflow:hidden}.el-step.is-vertical,.el-steps{display:-webkit-box;display:-ms-flexbox}.el-rate__text{font-size:14px;vertical-align:middle}.el-steps{display:-webkit-box;display:-ms-flexbox;display:flex}.el-steps--simple{padding:13px 8%;border-radius:4px;background:#f5f7fa}.el-steps--horizontal{white-space:nowrap}.el-steps--vertical{height:100%;-webkit-box-orient:vertical;-ms-flex-flow:column;flex-flow:column}.el-step{position:relative;-ms-flex-negative:1;flex-shrink:1}.el-step:last-of-type .el-step__line{display:none}.el-step:last-of-type.is-flex{-ms-flex-preferred-size:auto!important;flex-basis:auto!important;-ms-flex-negative:0;flex-shrink:0;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.el-step:last-of-type .el-step__description,.el-step:last-of-type .el-step__main{padding-right:0}.el-step__head{position:relative;width:100%}.el-step__head.is-process{color:#303133;border-color:#303133}.el-step__head.is-wait{color:#c0c4cc;border-color:#c0c4cc}.el-step__head.is-success{color:#67c23a;border-color:#67c23a}.el-step__head.is-error{color:#f56c6c;border-color:#f56c6c}.el-step__head.is-finish{color:#409eff;border-color:#409eff}.el-step__icon{position:relative;z-index:1;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:24px;height:24px;font-size:14px;-webkit-box-sizing:border-box;box-sizing:border-box;background:#fff;-webkit-transition:.15s ease-out;transition:.15s ease-out}.el-step__icon.is-text{border-radius:50%;border:2px solid;border-color:inherit}.el-step__icon.is-icon{width:40px}.el-step__icon-inner{display:inline-block;user-select:none;text-align:center;font-weight:700;line-height:1;color:inherit}.el-button,.el-checkbox,.el-image-viewer__btn,.el-step__icon-inner{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.el-step__icon-inner[class*=el-icon]:not(.is-status){font-size:25px;font-weight:400}.el-step__icon-inner.is-status{-webkit-transform:translateY(1px);transform:translateY(1px)}.el-step__line{position:absolute;border-color:inherit;background-color:#c0c4cc}.el-step__line-inner{display:block;border-width:1px;border-style:solid;border-color:inherit;-webkit-transition:.15s ease-out;transition:.15s ease-out;-webkit-box-sizing:border-box;box-sizing:border-box;width:0;height:0}.el-step__main{white-space:normal;text-align:left}.el-step__title{font-size:16px;line-height:38px}.el-step__title.is-process{font-weight:700;color:#303133}.el-step__title.is-wait{color:#c0c4cc}.el-step__title.is-success{color:#67c23a}.el-step__title.is-error{color:#f56c6c}.el-step__title.is-finish{color:#409eff}.el-step__description{padding-right:10%;margin-top:-5px;font-size:12px;line-height:20px;font-weight:400}.el-step__description.is-process{color:#303133}.el-step__description.is-wait{color:#c0c4cc}.el-step__description.is-success{color:#67c23a}.el-step__description.is-error{color:#f56c6c}.el-step__description.is-finish{color:#409eff}.el-step.is-horizontal{display:inline-block}.el-step.is-horizontal .el-step__line{height:2px;top:11px;left:0;right:0}.el-step.is-vertical{display:-webkit-box;display:-ms-flexbox;display:flex}.el-step.is-vertical .el-step__head{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;width:24px}.el-step.is-vertical .el-step__main{padding-left:10px;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.el-step.is-vertical .el-step__title{line-height:24px;padding-bottom:8px}.el-step.is-vertical .el-step__line{width:2px;top:0;bottom:0;left:11px}.el-step.is-vertical .el-step__icon.is-icon{width:24px}.el-step.is-center .el-step__head,.el-step.is-center .el-step__main{text-align:center}.el-step.is-center .el-step__description{padding-left:20%;padding-right:20%}.el-step.is-center .el-step__line{left:50%;right:-50%}.el-step.is-simple{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-step.is-simple .el-step__head{width:auto;font-size:0;padding-right:10px}.el-step.is-simple .el-step__icon{background:0 0;width:16px;height:16px;font-size:12px}.el-step.is-simple .el-step__icon-inner[class*=el-icon]:not(.is-status){font-size:18px}.el-step.is-simple .el-step__icon-inner.is-status{-webkit-transform:scale(.8) translateY(1px);transform:scale(.8) translateY(1px)}.el-step.is-simple .el-step__main{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.el-step.is-simple .el-step__title{font-size:16px;line-height:20px}.el-step.is-simple:not(:last-of-type) .el-step__title{max-width:50%;word-break:break-all}.el-step.is-simple .el-step__arrow{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-step.is-simple .el-step__arrow:after,.el-step.is-simple .el-step__arrow:before{content:"";display:inline-block;position:absolute;height:15px;width:1px;background:#c0c4cc}.el-step.is-simple .el-step__arrow:before{-webkit-transform:rotate(-45deg) translateY(-4px);transform:rotate(-45deg) translateY(-4px);-webkit-transform-origin:0 0;transform-origin:0 0}.el-step.is-simple .el-step__arrow:after{-webkit-transform:rotate(45deg) translateY(4px);transform:rotate(45deg) translateY(4px);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}.el-step.is-simple:last-of-type .el-step__arrow{display:none}.el-carousel{position:relative}.el-carousel--horizontal{overflow-x:hidden}.el-carousel--vertical{overflow-y:hidden}.el-carousel__container{position:relative;height:300px}.el-carousel__arrow{border:none;outline:0;padding:0;margin:0;height:36px;width:36px;cursor:pointer;-webkit-transition:.3s;transition:.3s;border-radius:50%;background-color:rgba(31,45,61,.11);color:#fff;position:absolute;top:50%;z-index:10;-webkit-transform:translateY(-50%);transform:translateY(-50%);text-align:center;font-size:12px}.el-carousel__arrow--left{left:16px}.el-carousel__arrow--right{right:16px}.el-carousel__arrow:hover{background-color:rgba(31,45,61,.23)}.el-carousel__arrow i{cursor:pointer}.el-carousel__indicators{position:absolute;list-style:none;margin:0;padding:0;z-index:2}.el-carousel__indicators--horizontal{bottom:0;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.el-carousel__indicators--vertical{right:0;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-carousel__indicators--outside{bottom:26px;text-align:center;position:static;-webkit-transform:none;transform:none}.el-carousel__indicators--outside .el-carousel__indicator:hover button{opacity:.64}.el-carousel__indicators--outside button{background-color:#c0c4cc;opacity:.24}.el-carousel__indicators--labels{left:0;right:0;-webkit-transform:none;transform:none;text-align:center}.el-carousel__indicators--labels .el-carousel__button{height:auto;width:auto;padding:2px 18px;font-size:12px}.el-carousel__indicators--labels .el-carousel__indicator{padding:6px 4px}.el-carousel__indicator{background-color:transparent;cursor:pointer}.el-carousel__indicator:hover button{opacity:.72}.el-carousel__indicator--horizontal{display:inline-block;padding:12px 4px}.el-carousel__indicator--vertical{padding:4px 12px}.el-carousel__indicator--vertical .el-carousel__button{width:2px;height:15px}.el-carousel__indicator.is-active button{opacity:1}.el-carousel__button{display:block;opacity:.48;width:30px;height:2px;background-color:#fff;border:none;outline:0;padding:0;margin:0;cursor:pointer;-webkit-transition:.3s;transition:.3s}.el-carousel__item,.el-carousel__mask{height:100%;top:0;left:0;position:absolute}.carousel-arrow-left-enter,.carousel-arrow-left-leave-active{-webkit-transform:translateY(-50%) translateX(-10px);transform:translateY(-50%) translateX(-10px);opacity:0}.carousel-arrow-right-enter,.carousel-arrow-right-leave-active{-webkit-transform:translateY(-50%) translateX(10px);transform:translateY(-50%) translateX(10px);opacity:0}.el-carousel__item{width:100%;display:inline-block;overflow:hidden;z-index:0}.el-carousel__item.is-active{z-index:2}.el-carousel__item--card,.el-carousel__item.is-animating{-webkit-transition:-webkit-transform .4s ease-in-out;transition:-webkit-transform .4s ease-in-out;transition:transform .4s ease-in-out;transition:transform .4s ease-in-out,-webkit-transform .4s ease-in-out}.el-carousel__item--card{width:50%}.el-carousel__item--card.is-in-stage{cursor:pointer;z-index:1}.el-carousel__item--card.is-in-stage.is-hover .el-carousel__mask,.el-carousel__item--card.is-in-stage:hover .el-carousel__mask{opacity:.12}.el-carousel__item--card.is-active{z-index:2}.el-carousel__mask{width:100%;background-color:#fff;opacity:.24;-webkit-transition:.2s;transition:.2s}.el-fade-in-enter,.el-fade-in-leave-active,.el-fade-in-linear-enter,.el-fade-in-linear-leave,.el-fade-in-linear-leave-active,.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active{opacity:0}.el-fade-in-linear-enter-active,.el-fade-in-linear-leave-active,.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.el-fade-in-enter-active,.el-fade-in-leave-active,.el-zoom-in-center-enter-active,.el-zoom-in-center-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.el-zoom-in-center-enter,.el-zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.el-zoom-in-top-enter-active,.el-zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center top;transform-origin:center top}.el-zoom-in-top-enter,.el-zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.el-zoom-in-bottom-enter-active,.el-zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center bottom;transform-origin:center bottom}.el-zoom-in-bottom-enter,.el-zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.el-zoom-in-left-enter-active,.el-zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1);transform:scale(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:top left;transform-origin:top left}.el-zoom-in-left-enter,.el-zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45);transform:scale(.45)}.collapse-transition{-webkit-transition:height .3s ease-in-out,padding-top .3s ease-in-out,padding-bottom .3s ease-in-out;transition:height .3s ease-in-out,padding-top .3s ease-in-out,padding-bottom .3s ease-in-out}.horizontal-collapse-transition{-webkit-transition:width .3s ease-in-out,padding-left .3s ease-in-out,padding-right .3s ease-in-out;transition:width .3s ease-in-out,padding-left .3s ease-in-out,padding-right .3s ease-in-out}.el-list-enter-active,.el-list-leave-active{-webkit-transition:all 1s;transition:all 1s}.el-list-enter,.el-list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.el-opacity-transition{-webkit-transition:opacity .3s cubic-bezier(.55,0,.1,1);transition:opacity .3s cubic-bezier(.55,0,.1,1)}.el-collapse{border-top:1px solid #ebeef5;border-bottom:1px solid #ebeef5}.el-collapse-item.is-disabled .el-collapse-item__header{color:#bbb;cursor:not-allowed}.el-collapse-item__header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:48px;line-height:48px;background-color:#fff;color:#303133;cursor:pointer;border-bottom:1px solid #ebeef5;font-size:13px;font-weight:500;-webkit-transition:border-bottom-color .3s;transition:border-bottom-color .3s;outline:0}.el-collapse-item__arrow{margin:0 8px 0 auto;transition:-webkit-transform .3s;-webkit-transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-weight:300}.el-collapse-item__arrow.is-active{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-collapse-item__header.focusing:focus:not(:hover){color:#409eff}.el-collapse-item__header.is-active{border-bottom-color:transparent}.el-collapse-item__wrap{will-change:height;background-color:#fff;overflow:hidden;box-sizing:border-box;border-bottom:1px solid #ebeef5}.el-cascader__tags,.el-collapse-item__wrap,.el-tag{-webkit-box-sizing:border-box}.el-collapse-item__content{padding-bottom:25px;font-size:13px;color:#303133;line-height:1.769230769230769}.el-collapse-item:last-child{margin-bottom:-1px}.el-popper .popper__arrow,.el-popper .popper__arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0,0,0,.03));filter:drop-shadow(0 2px 12px rgba(0,0,0,.03))}.el-popper .popper__arrow:after{content:" ";border-width:6px}.el-popper[x-placement^=top]{margin-bottom:12px}.el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#ebeef5;border-bottom-width:0}.el-popper[x-placement^=top] .popper__arrow:after{bottom:1px;margin-left:-6px;border-top-color:#fff;border-bottom-width:0}.el-popper[x-placement^=bottom]{margin-top:12px}.el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#ebeef5}.el-popper[x-placement^=bottom] .popper__arrow:after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#fff}.el-popper[x-placement^=right]{margin-left:12px}.el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#ebeef5;border-left-width:0}.el-popper[x-placement^=right] .popper__arrow:after{bottom:-6px;left:1px;border-right-color:#fff;border-left-width:0}.el-popper[x-placement^=left]{margin-right:12px}.el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#ebeef5}.el-popper[x-placement^=left] .popper__arrow:after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#fff}.el-tag{background-color:#ecf5ff;border-color:#d9ecff;display:inline-block;height:32px;padding:0 10px;line-height:30px;font-size:12px;color:#409eff;border-width:1px;border-style:solid;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}.el-tag.is-hit{border-color:#409eff}.el-tag .el-tag__close{color:#409eff}.el-tag .el-tag__close:hover{color:#fff;background-color:#409eff}.el-tag.el-tag--info{background-color:#f4f4f5;border-color:#e9e9eb;color:#909399}.el-tag.el-tag--info.is-hit{border-color:#909399}.el-tag.el-tag--info .el-tag__close{color:#909399}.el-tag.el-tag--info .el-tag__close:hover{color:#fff;background-color:#909399}.el-tag.el-tag--success{background-color:#f0f9eb;border-color:#e1f3d8;color:#67c23a}.el-tag.el-tag--success.is-hit{border-color:#67c23a}.el-tag.el-tag--success .el-tag__close{color:#67c23a}.el-tag.el-tag--success .el-tag__close:hover{color:#fff;background-color:#67c23a}.el-tag.el-tag--warning{background-color:#fdf6ec;border-color:#faecd8;color:#e6a23c}.el-tag.el-tag--warning.is-hit{border-color:#e6a23c}.el-tag.el-tag--warning .el-tag__close{color:#e6a23c}.el-tag.el-tag--warning .el-tag__close:hover{color:#fff;background-color:#e6a23c}.el-tag.el-tag--danger{background-color:#fef0f0;border-color:#fde2e2;color:#f56c6c}.el-tag.el-tag--danger.is-hit{border-color:#f56c6c}.el-tag.el-tag--danger .el-tag__close{color:#f56c6c}.el-tag.el-tag--danger .el-tag__close:hover{color:#fff;background-color:#f56c6c}.el-tag .el-icon-close{border-radius:50%;text-align:center;position:relative;cursor:pointer;font-size:12px;height:16px;width:16px;line-height:16px;vertical-align:middle;top:-1px;right:-5px}.el-tag .el-icon-close:before{display:block}.el-tag--dark{background-color:#409eff;color:#fff}.el-tag--dark,.el-tag--dark.is-hit{border-color:#409eff}.el-tag--dark .el-tag__close{color:#fff}.el-tag--dark .el-tag__close:hover{color:#fff;background-color:#66b1ff}.el-tag--dark.el-tag--info{background-color:#909399;border-color:#909399;color:#fff}.el-tag--dark.el-tag--info.is-hit{border-color:#909399}.el-tag--dark.el-tag--info .el-tag__close{color:#fff}.el-tag--dark.el-tag--info .el-tag__close:hover{color:#fff;background-color:#a6a9ad}.el-tag--dark.el-tag--success{background-color:#67c23a;border-color:#67c23a;color:#fff}.el-tag--dark.el-tag--success.is-hit{border-color:#67c23a}.el-tag--dark.el-tag--success .el-tag__close{color:#fff}.el-tag--dark.el-tag--success .el-tag__close:hover{color:#fff;background-color:#85ce61}.el-tag--dark.el-tag--warning{background-color:#e6a23c;border-color:#e6a23c;color:#fff}.el-tag--dark.el-tag--warning.is-hit{border-color:#e6a23c}.el-tag--dark.el-tag--warning .el-tag__close{color:#fff}.el-tag--dark.el-tag--warning .el-tag__close:hover{color:#fff;background-color:#ebb563}.el-tag--dark.el-tag--danger{background-color:#f56c6c;border-color:#f56c6c;color:#fff}.el-tag--dark.el-tag--danger.is-hit{border-color:#f56c6c}.el-tag--dark.el-tag--danger .el-tag__close{color:#fff}.el-tag--dark.el-tag--danger .el-tag__close:hover{color:#fff;background-color:#f78989}.el-tag--plain{background-color:#fff;border-color:#b3d8ff;color:#409eff}.el-tag--plain.is-hit{border-color:#409eff}.el-tag--plain .el-tag__close{color:#409eff}.el-tag--plain .el-tag__close:hover{color:#fff;background-color:#409eff}.el-tag--plain.el-tag--info{background-color:#fff;border-color:#d3d4d6;color:#909399}.el-tag--plain.el-tag--info.is-hit{border-color:#909399}.el-tag--plain.el-tag--info .el-tag__close{color:#909399}.el-tag--plain.el-tag--info .el-tag__close:hover{color:#fff;background-color:#909399}.el-tag--plain.el-tag--success{background-color:#fff;border-color:#c2e7b0;color:#67c23a}.el-tag--plain.el-tag--success.is-hit{border-color:#67c23a}.el-tag--plain.el-tag--success .el-tag__close{color:#67c23a}.el-tag--plain.el-tag--success .el-tag__close:hover{color:#fff;background-color:#67c23a}.el-tag--plain.el-tag--warning{background-color:#fff;border-color:#f5dab1;color:#e6a23c}.el-tag--plain.el-tag--warning.is-hit{border-color:#e6a23c}.el-tag--plain.el-tag--warning .el-tag__close{color:#e6a23c}.el-tag--plain.el-tag--warning .el-tag__close:hover{color:#fff;background-color:#e6a23c}.el-tag--plain.el-tag--danger{background-color:#fff;border-color:#fbc4c4;color:#f56c6c}.el-tag--plain.el-tag--danger.is-hit{border-color:#f56c6c}.el-tag--plain.el-tag--danger .el-tag__close{color:#f56c6c}.el-tag--plain.el-tag--danger .el-tag__close:hover{color:#fff;background-color:#f56c6c}.el-tag--medium{height:28px;line-height:26px}.el-tag--medium .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.el-tag--small{height:24px;padding:0 8px;line-height:22px}.el-tag--small .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.el-tag--mini{height:20px;padding:0 5px;line-height:19px}.el-tag--mini .el-icon-close{margin-left:-3px;-webkit-transform:scale(.7);transform:scale(.7)}.el-cascader{display:inline-block;position:relative;font-size:14px;line-height:40px}.el-cascader:not(.is-disabled):hover .el-input__inner{cursor:pointer;border-color:#c0c4cc}.el-cascader .el-input .el-input__inner:focus,.el-cascader .el-input.is-focus .el-input__inner{border-color:#409eff}.el-cascader .el-input{cursor:pointer}.el-cascader .el-input .el-input__inner{text-overflow:ellipsis}.el-cascader .el-input .el-icon-arrow-down{-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-size:14px}.el-cascader .el-input .el-icon-arrow-down.is-reverse{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.el-cascader .el-input .el-icon-circle-close:hover{color:#909399}.el-cascader--medium{font-size:14px;line-height:36px}.el-cascader--small{font-size:13px;line-height:32px}.el-cascader--mini{font-size:12px;line-height:28px}.el-cascader.is-disabled .el-cascader__label{z-index:2;color:#c0c4cc}.el-cascader__dropdown{margin:5px 0;font-size:14px;background:#fff;border:1px solid #e4e7ed;border-radius:4px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-cascader__tags{position:absolute;left:0;right:30px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;line-height:normal;text-align:left;-webkit-box-sizing:border-box;box-sizing:border-box}.el-cascader__tags .el-tag{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;max-width:100%;margin:2px 0 2px 6px;text-overflow:ellipsis;background:#f0f2f5}.el-cascader__tags .el-tag:not(.is-hit){border-color:transparent}.el-cascader__tags .el-tag>span{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:hidden;text-overflow:ellipsis}.el-cascader__tags .el-tag .el-icon-close{-webkit-box-flex:0;-ms-flex:none;flex:none;background-color:#c0c4cc;color:#fff}.el-cascader__tags .el-tag .el-icon-close:hover{background-color:#909399}.el-cascader__suggestion-panel{border-radius:4px}.el-cascader__suggestion-list{max-height:204px;margin:0;padding:6px 0;font-size:14px;color:#606266;text-align:center}.el-cascader__suggestion-item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:34px;padding:0 15px;text-align:left;outline:0;cursor:pointer}.el-cascader__suggestion-item:focus,.el-cascader__suggestion-item:hover{background:#f5f7fa}.el-cascader__suggestion-item.is-checked{color:#409eff;font-weight:700}.el-cascader__suggestion-item>span{margin-right:10px}.el-cascader__empty-text{margin:10px 0;color:#c0c4cc}.el-cascader__search-input{-webkit-box-flex:1;-ms-flex:1;flex:1;height:24px;min-width:60px;margin:2px 0 2px 15px;padding:0;color:#606266;border:none;outline:0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-cascader__search-input::-webkit-input-placeholder{color:#c0c4cc}.el-cascader__search-input:-ms-input-placeholder{color:#c0c4cc}.el-cascader__search-input::-ms-input-placeholder{color:#c0c4cc}.el-cascader__search-input::-moz-placeholder{color:#c0c4cc}.el-cascader__search-input::placeholder{color:#c0c4cc}.el-color-predefine{font-size:12px;margin-top:8px;width:280px}.el-color-predefine,.el-color-predefine__colors{display:-webkit-box;display:-ms-flexbox;display:flex}.el-color-predefine__colors{-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-wrap:wrap;flex-wrap:wrap}.el-color-predefine__color-selector{margin:0 0 8px 8px;width:20px;height:20px;border-radius:4px;cursor:pointer}.el-color-predefine__color-selector:nth-child(10n+1){margin-left:0}.el-color-predefine__color-selector.selected{-webkit-box-shadow:0 0 3px 2px #409eff;box-shadow:0 0 3px 2px #409eff}.el-color-predefine__color-selector>div{display:-webkit-box;display:-ms-flexbox;display:flex;height:100%;border-radius:3px}.el-color-predefine__color-selector.is-alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.el-color-hue-slider{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;width:280px;height:12px;background-color:red;padding:0 2px}.el-color-hue-slider__bar{position:relative;background:-webkit-gradient(linear,left top,right top,color-stop(0,red),color-stop(17%,#ff0),color-stop(33%,#0f0),color-stop(50%,#0ff),color-stop(67%,#00f),color-stop(83%,#f0f),to(red));background:linear-gradient(90deg,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red);height:100%}.el-color-hue-slider__thumb{position:absolute;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;left:0;top:0;width:4px;height:100%;border-radius:1px;background:#fff;border:1px solid #f0f0f0;-webkit-box-shadow:0 0 2px rgba(0,0,0,.6);box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.el-color-hue-slider.is-vertical{width:12px;height:180px;padding:2px 0}.el-color-hue-slider.is-vertical .el-color-hue-slider__bar{background:-webkit-gradient(linear,left top,left bottom,color-stop(0,red),color-stop(17%,#ff0),color-stop(33%,#0f0),color-stop(50%,#0ff),color-stop(67%,#00f),color-stop(83%,#f0f),to(red));background:linear-gradient(180deg,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red)}.el-color-hue-slider.is-vertical .el-color-hue-slider__thumb{left:0;top:0;width:100%;height:4px}.el-color-svpanel{position:relative;width:280px;height:180px}.el-color-svpanel__black,.el-color-svpanel__white{position:absolute;top:0;left:0;right:0;bottom:0}.el-color-svpanel__white{background:-webkit-gradient(linear,left top,right top,from(#fff),to(hsla(0,0%,100%,0)));background:linear-gradient(90deg,#fff,hsla(0,0%,100%,0))}.el-color-svpanel__black{background:-webkit-gradient(linear,left bottom,left top,from(#000),to(transparent));background:linear-gradient(0deg,#000,transparent)}.el-color-svpanel__cursor{position:absolute}.el-color-svpanel__cursor>div{cursor:head;width:4px;height:4px;-webkit-box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);border-radius:50%;-webkit-transform:translate(-2px,-2px);transform:translate(-2px,-2px)}.el-color-alpha-slider{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;width:280px;height:12px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.el-color-alpha-slider__bar{position:relative;background:-webkit-gradient(linear,left top,right top,color-stop(0,hsla(0,0%,100%,0)),to(#fff));background:linear-gradient(90deg,hsla(0,0%,100%,0) 0,#fff);height:100%}.el-color-alpha-slider__thumb{position:absolute;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;left:0;top:0;width:4px;height:100%;border-radius:1px;background:#fff;border:1px solid #f0f0f0;-webkit-box-shadow:0 0 2px rgba(0,0,0,.6);box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.el-color-alpha-slider.is-vertical{width:20px;height:180px}.el-color-alpha-slider.is-vertical .el-color-alpha-slider__bar{background:-webkit-gradient(linear,left top,left bottom,color-stop(0,hsla(0,0%,100%,0)),to(#fff));background:linear-gradient(180deg,hsla(0,0%,100%,0) 0,#fff)}.el-color-alpha-slider.is-vertical .el-color-alpha-slider__thumb{left:0;top:0;width:100%;height:4px}.el-color-dropdown{width:300px}.el-color-dropdown__main-wrapper{margin-bottom:6px}.el-color-dropdown__main-wrapper:after{content:"";display:table;clear:both}.el-color-dropdown__btns{margin-top:6px;text-align:right}.el-color-dropdown__value{float:left;line-height:26px;font-size:12px;color:#000;width:160px}.el-color-dropdown__btn{border:1px solid #dcdcdc;color:#333;line-height:24px;border-radius:2px;padding:0 20px;cursor:pointer;background-color:transparent;outline:0;font-size:12px}.el-color-dropdown__btn[disabled]{color:#ccc;cursor:not-allowed}.el-color-dropdown__btn:hover{color:#409eff;border-color:#409eff}.el-color-dropdown__link-btn{cursor:pointer;color:#409eff;text-decoration:none;padding:15px;font-size:12px}.el-color-dropdown__link-btn:hover{color:tint(#409eff,20%)}.el-color-picker{display:inline-block;position:relative;line-height:normal;height:40px}.el-color-picker.is-disabled .el-color-picker__trigger{cursor:not-allowed}.el-color-picker--medium{height:36px}.el-color-picker--medium .el-color-picker__trigger{height:36px;width:36px}.el-color-picker--medium .el-color-picker__mask{height:34px;width:34px}.el-color-picker--small{height:32px}.el-color-picker--small .el-color-picker__trigger{height:32px;width:32px}.el-color-picker--small .el-color-picker__mask{height:30px;width:30px}.el-color-picker--small .el-color-picker__empty,.el-color-picker--small .el-color-picker__icon{-webkit-transform:translate3d(-50%,-50%,0) scale(.8);transform:translate3d(-50%,-50%,0) scale(.8)}.el-color-picker--mini{height:28px}.el-color-picker--mini .el-color-picker__trigger{height:28px;width:28px}.el-color-picker--mini .el-color-picker__mask{height:26px;width:26px}.el-color-picker--mini .el-color-picker__empty,.el-color-picker--mini .el-color-picker__icon{-webkit-transform:translate3d(-50%,-50%,0) scale(.8);transform:translate3d(-50%,-50%,0) scale(.8)}.el-color-picker__mask{height:38px;width:38px;border-radius:4px;position:absolute;top:1px;left:1px;z-index:1;cursor:not-allowed;background-color:hsla(0,0%,100%,.7)}.el-color-picker__trigger{display:inline-block;height:40px;width:40px;padding:4px;border:1px solid #e6e6e6;border-radius:4px;font-size:0;cursor:pointer}.el-color-picker__color,.el-color-picker__trigger{-webkit-box-sizing:border-box;box-sizing:border-box;position:relative}.el-color-picker__color{display:block;border:1px solid #999;border-radius:2px;width:100%;height:100%;text-align:center}.el-color-picker__color.is-alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.el-color-picker__color-inner{position:absolute;left:0;top:0;right:0;bottom:0}.el-color-picker__empty,.el-color-picker__icon{top:50%;left:50%;font-size:12px;position:absolute}.el-color-picker__empty{color:#999}.el-color-picker__empty,.el-color-picker__icon{-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}.el-color-picker__icon{display:inline-block;width:100%;color:#fff;text-align:center}.el-color-picker__panel{position:absolute;z-index:10;padding:6px;-webkit-box-sizing:content-box;box-sizing:content-box;background-color:#fff;border:1px solid #ebeef5;border-radius:4px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;font-size:inherit;color:#606266;background-color:#fff;background-image:none;border:1px solid #dcdfe6;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.el-textarea__inner::-webkit-input-placeholder{color:#c0c4cc}.el-textarea__inner:-ms-input-placeholder{color:#c0c4cc}.el-textarea__inner::-ms-input-placeholder{color:#c0c4cc}.el-textarea__inner::-moz-placeholder{color:#c0c4cc}.el-textarea__inner::placeholder{color:#c0c4cc}.el-textarea__inner:hover{border-color:#c0c4cc}.el-textarea__inner:focus{outline:0;border-color:#409eff}.el-textarea .el-input__count{color:#909399;background:#fff;position:absolute;font-size:12px;bottom:5px;right:10px}.el-textarea.is-disabled .el-textarea__inner{background-color:#f5f7fa;border-color:#e4e7ed;color:#c0c4cc;cursor:not-allowed}.el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#c0c4cc}.el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#c0c4cc}.el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#c0c4cc}.el-textarea.is-disabled .el-textarea__inner::-moz-placeholder{color:#c0c4cc}.el-textarea.is-disabled .el-textarea__inner::placeholder{color:#c0c4cc}.el-textarea.is-exceed .el-textarea__inner{border-color:#f56c6c}.el-textarea.is-exceed .el-input__count{color:#f56c6c}.el-input{position:relative;font-size:14px;display:inline-block;width:100%}.el-input::-webkit-scrollbar{z-index:11;width:6px}.el-input::-webkit-scrollbar:horizontal{height:6px}.el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.el-input::-webkit-scrollbar-corner,.el-input::-webkit-scrollbar-track{background:#fff}.el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.el-input .el-input__clear{color:#c0c4cc;font-size:14px;cursor:pointer;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.el-input .el-input__clear:hover{color:#909399}.el-input .el-input__count{height:100%;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#909399;font-size:12px}.el-input .el-input__count .el-input__count-inner{background:#fff;line-height:normal;display:inline-block;padding:0 5px}.el-input__inner{-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;border:1px solid #dcdfe6;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;height:40px;line-height:40px;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.el-button,.el-input__inner,.el-transfer-panel{-webkit-box-sizing:border-box}.el-input__prefix,.el-input__suffix{position:absolute;top:0;-webkit-transition:all .3s;height:100%;color:#c0c4cc;text-align:center}.el-input__inner::-webkit-input-placeholder{color:#c0c4cc}.el-input__inner:-ms-input-placeholder{color:#c0c4cc}.el-input__inner::-ms-input-placeholder{color:#c0c4cc}.el-input__inner::-moz-placeholder{color:#c0c4cc}.el-input__inner::placeholder{color:#c0c4cc}.el-input__inner:hover{border-color:#c0c4cc}.el-input.is-active .el-input__inner,.el-input__inner:focus{border-color:#409eff;outline:0}.el-input__suffix{right:5px;-webkit-transition:all .3s;transition:all .3s}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{left:5px}.el-input__icon,.el-input__prefix{-webkit-transition:all .3s;transition:all .3s}.el-input__icon{height:100%;width:25px;text-align:center;line-height:40px}.el-input__icon:after{content:"";height:100%;width:0;display:inline-block;vertical-align:middle}.el-input__validateIcon{pointer-events:none}.el-input.is-disabled .el-input__inner{background-color:#f5f7fa;border-color:#e4e7ed;color:#c0c4cc;cursor:not-allowed}.el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__inner::-moz-placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__inner::placeholder{color:#c0c4cc}.el-input.is-disabled .el-input__icon{cursor:not-allowed}.el-input.is-exceed .el-input__inner{border-color:#f56c6c}.el-input.is-exceed .el-input__suffix .el-input__count{color:#f56c6c}.el-input--suffix .el-input__inner{padding-right:30px}.el-input--prefix .el-input__inner{padding-left:30px}.el-input--medium{font-size:14px}.el-input--medium .el-input__inner{height:36px;line-height:36px}.el-input--medium .el-input__icon{line-height:36px}.el-input--small{font-size:13px}.el-input--small .el-input__inner{height:32px;line-height:32px}.el-input--small .el-input__icon{line-height:32px}.el-input--mini{font-size:12px}.el-input--mini .el-input__inner{height:28px;line-height:28px}.el-input--mini .el-input__icon{line-height:28px}.el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate;border-spacing:0}.el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.el-input-group__append,.el-input-group__prepend{background-color:#f5f7fa;color:#909399;vertical-align:middle;display:table-cell;position:relative;border:1px solid #dcdfe6;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.el-input-group--prepend .el-input__inner,.el-input-group__append{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--append .el-input__inner,.el-input-group__prepend{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append:focus,.el-input-group__prepend:focus{outline:0}.el-input-group__append .el-button,.el-input-group__append .el-select,.el-input-group__prepend .el-button,.el-input-group__prepend .el-select{display:inline-block;margin:-10px -20px}.el-input-group__append button.el-button,.el-input-group__append div.el-select .el-input__inner,.el-input-group__append div.el-select:hover .el-input__inner,.el-input-group__prepend button.el-button,.el-input-group__prepend div.el-select .el-input__inner,.el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.el-input-group__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0}.el-input-group__append{border-left:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner,.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.el-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#fff;border:1px solid #dcdfe6;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:.1s;transition:.1s;font-weight:500;padding:12px 20px;font-size:14px;border-radius:4px}.el-button+.el-button{margin-left:10px}.el-button:focus,.el-button:hover{color:#409eff;border-color:#c6e2ff;background-color:#ecf5ff}.el-button:active{color:#3a8ee6;border-color:#3a8ee6;outline:0}.el-button::-moz-focus-inner{border:0}.el-button [class*=el-icon-]+span{margin-left:5px}.el-button.is-plain:focus,.el-button.is-plain:hover{background:#fff;border-color:#409eff;color:#409eff}.el-button.is-active,.el-button.is-plain:active{color:#3a8ee6;border-color:#3a8ee6}.el-button.is-plain:active{background:#fff;outline:0}.el-button.is-disabled,.el-button.is-disabled:focus,.el-button.is-disabled:hover{color:#c0c4cc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#ebeef5}.el-link,.el-transfer-panel__filter .el-icon-circle-close{cursor:pointer}.el-button.is-disabled.el-button--text{background-color:transparent}.el-button.is-disabled.is-plain,.el-button.is-disabled.is-plain:focus,.el-button.is-disabled.is-plain:hover{background-color:#fff;border-color:#ebeef5;color:#c0c4cc}.el-button.is-loading{position:relative;pointer-events:none}.el-button.is-loading:before{pointer-events:none;content:"";position:absolute;left:-1px;top:-1px;right:-1px;bottom:-1px;border-radius:inherit;background-color:hsla(0,0%,100%,.35)}.el-button.is-round{border-radius:20px;padding:12px 23px}.el-button.is-circle{border-radius:50%;padding:12px}.el-button--primary{color:#fff;background-color:#409eff;border-color:#409eff}.el-button--primary:focus,.el-button--primary:hover{background:#66b1ff;border-color:#66b1ff;color:#fff}.el-button--primary.is-active,.el-button--primary:active{background:#3a8ee6;border-color:#3a8ee6;color:#fff}.el-button--primary:active{outline:0}.el-button--primary.is-disabled,.el-button--primary.is-disabled:active,.el-button--primary.is-disabled:focus,.el-button--primary.is-disabled:hover{color:#fff;background-color:#a0cfff;border-color:#a0cfff}.el-button--primary.is-plain{color:#409eff;background:#ecf5ff;border-color:#b3d8ff}.el-button--primary.is-plain:focus,.el-button--primary.is-plain:hover{background:#409eff;border-color:#409eff;color:#fff}.el-button--primary.is-plain:active{background:#3a8ee6;border-color:#3a8ee6;color:#fff;outline:0}.el-button--primary.is-plain.is-disabled,.el-button--primary.is-plain.is-disabled:active,.el-button--primary.is-plain.is-disabled:focus,.el-button--primary.is-plain.is-disabled:hover{color:#8cc5ff;background-color:#ecf5ff;border-color:#d9ecff}.el-button--success{color:#fff;background-color:#67c23a;border-color:#67c23a}.el-button--success:focus,.el-button--success:hover{background:#85ce61;border-color:#85ce61;color:#fff}.el-button--success.is-active,.el-button--success:active{background:#5daf34;border-color:#5daf34;color:#fff}.el-button--success:active{outline:0}.el-button--success.is-disabled,.el-button--success.is-disabled:active,.el-button--success.is-disabled:focus,.el-button--success.is-disabled:hover{color:#fff;background-color:#b3e19d;border-color:#b3e19d}.el-button--success.is-plain{color:#67c23a;background:#f0f9eb;border-color:#c2e7b0}.el-button--success.is-plain:focus,.el-button--success.is-plain:hover{background:#67c23a;border-color:#67c23a;color:#fff}.el-button--success.is-plain:active{background:#5daf34;border-color:#5daf34;color:#fff;outline:0}.el-button--success.is-plain.is-disabled,.el-button--success.is-plain.is-disabled:active,.el-button--success.is-plain.is-disabled:focus,.el-button--success.is-plain.is-disabled:hover{color:#a4da89;background-color:#f0f9eb;border-color:#e1f3d8}.el-button--warning{color:#fff;background-color:#e6a23c;border-color:#e6a23c}.el-button--warning:focus,.el-button--warning:hover{background:#ebb563;border-color:#ebb563;color:#fff}.el-button--warning.is-active,.el-button--warning:active{background:#cf9236;border-color:#cf9236;color:#fff}.el-button--warning:active{outline:0}.el-button--warning.is-disabled,.el-button--warning.is-disabled:active,.el-button--warning.is-disabled:focus,.el-button--warning.is-disabled:hover{color:#fff;background-color:#f3d19e;border-color:#f3d19e}.el-button--warning.is-plain{color:#e6a23c;background:#fdf6ec;border-color:#f5dab1}.el-button--warning.is-plain:focus,.el-button--warning.is-plain:hover{background:#e6a23c;border-color:#e6a23c;color:#fff}.el-button--warning.is-plain:active{background:#cf9236;border-color:#cf9236;color:#fff;outline:0}.el-button--warning.is-plain.is-disabled,.el-button--warning.is-plain.is-disabled:active,.el-button--warning.is-plain.is-disabled:focus,.el-button--warning.is-plain.is-disabled:hover{color:#f0c78a;background-color:#fdf6ec;border-color:#faecd8}.el-button--danger{color:#fff;background-color:#f56c6c;border-color:#f56c6c}.el-button--danger:focus,.el-button--danger:hover{background:#f78989;border-color:#f78989;color:#fff}.el-button--danger.is-active,.el-button--danger:active{background:#dd6161;border-color:#dd6161;color:#fff}.el-button--danger:active{outline:0}.el-button--danger.is-disabled,.el-button--danger.is-disabled:active,.el-button--danger.is-disabled:focus,.el-button--danger.is-disabled:hover{color:#fff;background-color:#fab6b6;border-color:#fab6b6}.el-button--danger.is-plain{color:#f56c6c;background:#fef0f0;border-color:#fbc4c4}.el-button--danger.is-plain:focus,.el-button--danger.is-plain:hover{background:#f56c6c;border-color:#f56c6c;color:#fff}.el-button--danger.is-plain:active{background:#dd6161;border-color:#dd6161;color:#fff;outline:0}.el-button--danger.is-plain.is-disabled,.el-button--danger.is-plain.is-disabled:active,.el-button--danger.is-plain.is-disabled:focus,.el-button--danger.is-plain.is-disabled:hover{color:#f9a7a7;background-color:#fef0f0;border-color:#fde2e2}.el-button--info{color:#fff;background-color:#909399;border-color:#909399}.el-button--info:focus,.el-button--info:hover{background:#a6a9ad;border-color:#a6a9ad;color:#fff}.el-button--info.is-active,.el-button--info:active{background:#82848a;border-color:#82848a;color:#fff}.el-button--info:active{outline:0}.el-button--info.is-disabled,.el-button--info.is-disabled:active,.el-button--info.is-disabled:focus,.el-button--info.is-disabled:hover{color:#fff;background-color:#c8c9cc;border-color:#c8c9cc}.el-button--info.is-plain{color:#909399;background:#f4f4f5;border-color:#d3d4d6}.el-button--info.is-plain:focus,.el-button--info.is-plain:hover{background:#909399;border-color:#909399;color:#fff}.el-button--info.is-plain:active{background:#82848a;border-color:#82848a;color:#fff;outline:0}.el-button--info.is-plain.is-disabled,.el-button--info.is-plain.is-disabled:active,.el-button--info.is-plain.is-disabled:focus,.el-button--info.is-plain.is-disabled:hover{color:#bcbec2;background-color:#f4f4f5;border-color:#e9e9eb}.el-button--text,.el-button--text.is-disabled,.el-button--text.is-disabled:focus,.el-button--text.is-disabled:hover,.el-button--text:active{border-color:transparent}.el-button--medium{padding:10px 20px;font-size:14px;border-radius:4px}.el-button--mini,.el-button--small{font-size:12px;border-radius:3px}.el-button--medium.is-round{padding:10px 20px}.el-button--medium.is-circle{padding:10px}.el-button--small,.el-button--small.is-round{padding:9px 15px}.el-button--small.is-circle{padding:9px}.el-button--mini,.el-button--mini.is-round{padding:7px 15px}.el-button--mini.is-circle{padding:7px}.el-button--text{color:#409eff;background:0 0;padding-left:0;padding-right:0}.el-button--text:focus,.el-button--text:hover{color:#66b1ff;border-color:transparent;background-color:transparent}.el-button--text:active{color:#3a8ee6;background-color:transparent}.el-button-group{display:inline-block;vertical-align:middle}.el-button-group:after,.el-button-group:before{display:table;content:""}.el-button-group:after{clear:both}.el-button-group>.el-button{float:left;position:relative}.el-button-group>.el-button+.el-button{margin-left:0}.el-button-group>.el-button.is-disabled{z-index:1}.el-button-group>.el-button:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.el-button-group>.el-button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.el-button-group>.el-button:first-child:last-child{border-radius:4px}.el-button-group>.el-button:first-child:last-child.is-round{border-radius:20px}.el-button-group>.el-button:first-child:last-child.is-circle{border-radius:50%}.el-button-group>.el-button:not(:first-child):not(:last-child){border-radius:0}.el-button-group>.el-button:not(:last-child){margin-right:-1px}.el-button-group>.el-button.is-active,.el-button-group>.el-button:active,.el-button-group>.el-button:focus,.el-button-group>.el-button:hover{z-index:1}.el-button-group>.el-dropdown>.el-button{border-top-left-radius:0;border-bottom-left-radius:0;border-left-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--primary:first-child{border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--primary:last-child{border-left-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--primary:not(:first-child):not(:last-child){border-left-color:hsla(0,0%,100%,.5);border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--success:first-child{border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--success:last-child{border-left-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--success:not(:first-child):not(:last-child){border-left-color:hsla(0,0%,100%,.5);border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--warning:first-child{border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--warning:last-child{border-left-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--warning:not(:first-child):not(:last-child){border-left-color:hsla(0,0%,100%,.5);border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--danger:first-child{border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--danger:last-child{border-left-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--danger:not(:first-child):not(:last-child){border-left-color:hsla(0,0%,100%,.5);border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--info:first-child{border-right-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--info:last-child{border-left-color:hsla(0,0%,100%,.5)}.el-button-group .el-button--info:not(:first-child):not(:last-child){border-left-color:hsla(0,0%,100%,.5);border-right-color:hsla(0,0%,100%,.5)}.el-transfer{font-size:14px}.el-transfer__buttons{display:inline-block;vertical-align:middle;padding:0 30px}.el-transfer__button{display:block;margin:0 auto;padding:10px;border-radius:50%;color:#fff;background-color:#409eff;font-size:0}.el-transfer__button.is-with-texts{border-radius:4px}.el-transfer__button.is-disabled,.el-transfer__button.is-disabled:hover{border:1px solid #dcdfe6;background-color:#f5f7fa;color:#c0c4cc}.el-transfer__button:first-child{margin-bottom:10px}.el-transfer__button:nth-child(2){margin:0}.el-transfer__button i,.el-transfer__button span{font-size:14px}.el-transfer__button [class*=el-icon-]+span{margin-left:0}.el-transfer-panel{border:1px solid #ebeef5;border-radius:4px;overflow:hidden;background:#fff;display:inline-block;vertical-align:middle;width:200px;max-height:100%;-webkit-box-sizing:border-box;box-sizing:border-box;position:relative}.el-transfer-panel__body{height:246px}.el-transfer-panel__body.is-with-footer{padding-bottom:40px}.el-transfer-panel__list{margin:0;padding:6px 0;list-style:none;height:246px;overflow:auto;-webkit-box-sizing:border-box;box-sizing:border-box}.el-transfer-panel__list.is-filterable{height:194px;padding-top:0}.el-transfer-panel__item{height:30px;line-height:30px;padding-left:15px;display:block}.el-transfer-panel__item+.el-transfer-panel__item{margin-left:0;display:block!important}.el-transfer-panel__item.el-checkbox{color:#606266}.el-transfer-panel__item:hover{color:#409eff}.el-transfer-panel__item.el-checkbox .el-checkbox__label{width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;-webkit-box-sizing:border-box;box-sizing:border-box;padding-left:24px;line-height:30px}.el-transfer-panel__item .el-checkbox__input{position:absolute;top:8px}.el-transfer-panel__filter{text-align:center;margin:15px;-webkit-box-sizing:border-box;box-sizing:border-box;display:block;width:auto}.el-transfer-panel__filter .el-input__inner{height:32px;width:100%;font-size:12px;display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:16px;padding-right:10px;padding-left:30px}.el-transfer-panel__filter .el-input__icon{margin-left:5px}.el-transfer-panel .el-transfer-panel__header{height:40px;line-height:40px;background:#f5f7fa;margin:0;padding-left:15px;border-bottom:1px solid #ebeef5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#000}.el-transfer-panel .el-transfer-panel__header .el-checkbox{display:block;line-height:40px}.el-transfer-panel .el-transfer-panel__header .el-checkbox .el-checkbox__label{font-size:16px;color:#303133;font-weight:400}.el-transfer-panel .el-transfer-panel__header .el-checkbox .el-checkbox__label span{position:absolute;right:15px;color:#909399;font-size:12px;font-weight:400}.el-divider__text,.el-link{font-weight:500;font-size:14px}.el-transfer-panel .el-transfer-panel__footer{height:40px;background:#fff;margin:0;padding:0;border-top:1px solid #ebeef5;position:absolute;bottom:0;left:0;width:100%;z-index:1}.el-transfer-panel .el-transfer-panel__footer:after{display:inline-block;content:"";height:100%;vertical-align:middle}.el-container,.el-timeline-item__node{display:-webkit-box;display:-ms-flexbox}.el-transfer-panel .el-transfer-panel__footer .el-checkbox{padding-left:20px;color:#606266}.el-transfer-panel .el-transfer-panel__empty{margin:0;height:30px;line-height:30px;padding:6px 15px 0;color:#909399;text-align:center}.el-transfer-panel .el-checkbox__label{padding-left:8px}.el-transfer-panel .el-checkbox__inner{height:14px;width:14px;border-radius:3px}.el-transfer-panel .el-checkbox__inner:after{height:6px;width:3px;left:4px}.el-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-ms-flex-direction:row;flex-direction:row;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-preferred-size:auto;flex-basis:auto;box-sizing:border-box;min-width:0}.el-aside,.el-container,.el-header{-webkit-box-sizing:border-box}.el-container.is-vertical{-webkit-box-orient:vertical;-ms-flex-direction:column;flex-direction:column}.el-header{padding:0 20px}.el-aside,.el-header{-webkit-box-sizing:border-box;box-sizing:border-box;-ms-flex-negative:0;flex-shrink:0}.el-aside{overflow:auto}.el-footer,.el-main{-webkit-box-sizing:border-box}.el-main{display:block;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-preferred-size:auto;flex-basis:auto;overflow:auto;padding:20px}.el-footer,.el-main{-webkit-box-sizing:border-box;box-sizing:border-box}.el-footer{padding:0 20px;-ms-flex-negative:0;flex-shrink:0}.el-timeline{margin:0;font-size:14px;list-style:none}.el-timeline .el-timeline-item:last-child .el-timeline-item__tail{display:none}.el-timeline-item{position:relative;padding-bottom:20px}.el-timeline-item__wrapper{position:relative;padding-left:28px;top:-3px}.el-timeline-item__tail{position:absolute;left:4px;height:100%;border-left:2px solid #e4e7ed}.el-timeline-item__icon{color:#fff;font-size:13px}.el-timeline-item__node{position:absolute;background-color:#e4e7ed;border-radius:50%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-image__error,.el-timeline-item__dot{display:-webkit-box;display:-ms-flexbox}.el-timeline-item__node--normal{left:-1px;width:12px;height:12px}.el-timeline-item__node--large{left:-2px;width:14px;height:14px}.el-timeline-item__node--primary{background-color:#409eff}.el-timeline-item__node--success{background-color:#67c23a}.el-timeline-item__node--warning{background-color:#e6a23c}.el-timeline-item__node--danger{background-color:#f56c6c}.el-timeline-item__node--info{background-color:#909399}.el-timeline-item__dot{position:absolute;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-timeline-item__content{color:#303133}.el-timeline-item__timestamp{color:#909399;line-height:1;font-size:13px}.el-timeline-item__timestamp.is-top{margin-bottom:8px;padding-top:4px}.el-timeline-item__timestamp.is-bottom{margin-top:8px}.el-link{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:horizontal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;vertical-align:middle;position:relative;text-decoration:none;outline:0;padding:0}.el-link.is-underline:hover:after{content:"";position:absolute;left:0;right:0;height:0;bottom:0;border-bottom:1px solid #409eff}.el-link.el-link--default:after,.el-link.el-link--primary.is-underline:hover:after,.el-link.el-link--primary:after{border-color:#409eff}.el-link.is-disabled{cursor:not-allowed}.el-link [class*=el-icon-]+span{margin-left:5px}.el-link.el-link--default{color:#606266}.el-link.el-link--default:hover{color:#409eff}.el-link.el-link--default.is-disabled{color:#c0c4cc}.el-link.el-link--primary{color:#409eff}.el-link.el-link--primary:hover{color:#66b1ff}.el-link.el-link--primary.is-disabled{color:#a0cfff}.el-link.el-link--danger.is-underline:hover:after,.el-link.el-link--danger:after{border-color:#f56c6c}.el-link.el-link--danger{color:#f56c6c}.el-link.el-link--danger:hover{color:#f78989}.el-link.el-link--danger.is-disabled{color:#fab6b6}.el-link.el-link--success.is-underline:hover:after,.el-link.el-link--success:after{border-color:#67c23a}.el-link.el-link--success{color:#67c23a}.el-link.el-link--success:hover{color:#85ce61}.el-link.el-link--success.is-disabled{color:#b3e19d}.el-link.el-link--warning.is-underline:hover:after,.el-link.el-link--warning:after{border-color:#e6a23c}.el-link.el-link--warning{color:#e6a23c}.el-link.el-link--warning:hover{color:#ebb563}.el-link.el-link--warning.is-disabled{color:#f3d19e}.el-link.el-link--info.is-underline:hover:after,.el-link.el-link--info:after{border-color:#909399}.el-link.el-link--info{color:#909399}.el-link.el-link--info:hover{color:#a6a9ad}.el-link.el-link--info.is-disabled{color:#c8c9cc}.el-divider{background-color:#dcdfe6;position:relative}.el-divider--horizontal{display:block;height:1px;width:100%;margin:24px 0}.el-divider--vertical{display:inline-block;width:1px;height:1em;margin:0 8px;vertical-align:middle;position:relative}.el-divider__text{position:absolute;background-color:#fff;padding:0 20px;color:#303133}.el-image__error,.el-image__placeholder{background:#f5f7fa}.el-divider__text.is-left{left:20px;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-divider__text.is-center{left:50%;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%)}.el-divider__text.is-right{right:20px;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-image__error,.el-image__inner,.el-image__placeholder{width:100%;height:100%}.el-image{position:relative;display:inline-block;overflow:hidden}.el-image__inner{vertical-align:top}.el-image__inner--center{position:relative;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);display:block}.el-image__error{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:14px;color:#c0c4cc;vertical-align:middle}.el-image__preview{cursor:pointer}.el-image-viewer__wrapper{position:fixed;top:0;right:0;bottom:0;left:0}.el-image-viewer__btn{position:absolute;z-index:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;border-radius:50%;opacity:.8;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.el-image-viewer__close{top:40px;right:40px;width:40px;height:40px;font-size:40px}.el-image-viewer__canvas{width:100%;height:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-image-viewer__actions{left:50%;bottom:30px;-webkit-transform:translateX(-50%);transform:translateX(-50%);width:282px;height:44px;padding:0 23px;background-color:#606266;border-color:#fff;border-radius:22px}.el-image-viewer__actions__inner{width:100%;height:100%;text-align:justify;cursor:default;font-size:23px;color:#fff;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-pack:distribute;justify-content:space-around}.el-image-viewer__next,.el-image-viewer__prev{top:50%;width:44px;height:44px;font-size:24px;color:#fff;background-color:#606266;border-color:#fff}.el-image-viewer__prev{left:40px}.el-image-viewer__next,.el-image-viewer__prev{-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-image-viewer__next{right:40px;text-indent:2px}.el-image-viewer__mask{position:absolute;width:100%;height:100%;top:0;left:0;opacity:.5;background:#000}.viewer-fade-enter-active{-webkit-animation:viewer-fade-in .3s;animation:viewer-fade-in .3s}.viewer-fade-leave-active{-webkit-animation:viewer-fade-out .3s;animation:viewer-fade-out .3s}@-webkit-keyframes viewer-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes viewer-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@-webkit-keyframes viewer-fade-out{0%{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}to{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes viewer-fade-out{0%{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}to{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.el-calendar{background-color:#fff}.el-calendar__header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:12px 20px;border-bottom:1px solid #ebeef5}.el-backtop,.el-page-header{display:-webkit-box;display:-ms-flexbox}.el-calendar__title{color:#000;-ms-flex-item-align:center;align-self:center}.el-calendar__body{padding:12px 20px 35px}.el-calendar-table{table-layout:fixed;width:100%}.el-calendar-table thead th{padding:12px 0;color:#606266;font-weight:400}.el-calendar-table:not(.is-range) td.next,.el-calendar-table:not(.is-range) td.prev{color:#c0c4cc}.el-backtop,.el-calendar-table td.is-today{color:#409eff}.el-calendar-table td{border-bottom:1px solid #ebeef5;border-right:1px solid #ebeef5;vertical-align:top;-webkit-transition:background-color .2s ease;transition:background-color .2s ease}.el-calendar-table td.is-selected{background-color:#f2f8fe}.el-calendar-table tr:first-child td{border-top:1px solid #ebeef5}.el-calendar-table tr td:first-child{border-left:1px solid #ebeef5}.el-calendar-table tr.el-calendar-table__row--hide-border td{border-top:none}.el-calendar-table .el-calendar-day{-webkit-box-sizing:border-box;box-sizing:border-box;padding:8px;height:85px}.el-calendar-table .el-calendar-day:hover{cursor:pointer;background-color:#f2f8fe}.el-backtop{position:fixed;background-color:#fff;width:40px;height:40px;border-radius:50%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;font-size:20px;-webkit-box-shadow:0 0 6px rgba(0,0,0,.12);box-shadow:0 0 6px rgba(0,0,0,.12);cursor:pointer;z-index:5}.el-backtop:hover{background-color:#f2f6fc}.el-page-header{line-height:24px}.el-page-header,.el-page-header__left{display:-webkit-box;display:-ms-flexbox;display:flex}.el-page-header__left{cursor:pointer;margin-right:40px;position:relative}.el-page-header__left:after{content:"";position:absolute;width:1px;height:16px;right:-20px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);background-color:#dcdfe6}.el-checkbox,.el-checkbox__input{display:inline-block;position:relative;white-space:nowrap}.el-page-header__left .el-icon-back{font-size:18px;margin-right:6px;-ms-flex-item-align:center;align-self:center}.el-page-header__title{font-size:14px;font-weight:500}.el-page-header__content{font-size:18px;color:#303133}.el-checkbox{color:#606266;font-size:14px;cursor:pointer;user-select:none;margin-right:30px}.el-checkbox,.el-checkbox-button__inner,.el-radio{font-weight:500;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.el-checkbox.is-bordered{padding:9px 20px 9px 10px;border-radius:4px;border:1px solid #dcdfe6;-webkit-box-sizing:border-box;box-sizing:border-box;line-height:normal;height:40px}.el-checkbox.is-bordered.is-checked{border-color:#409eff}.el-checkbox.is-bordered.is-disabled{border-color:#ebeef5;cursor:not-allowed}.el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.el-checkbox.is-bordered.el-checkbox--medium{padding:7px 20px 7px 10px;border-radius:4px;height:36px}.el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__label{line-height:17px;font-size:14px}.el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__inner{height:14px;width:14px}.el-checkbox.is-bordered.el-checkbox--small{padding:5px 15px 5px 10px;border-radius:3px;height:32px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__label{line-height:15px;font-size:12px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner{height:12px;width:12px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner:after{height:6px;width:2px}.el-checkbox.is-bordered.el-checkbox--mini{padding:3px 15px 3px 10px;border-radius:3px;height:28px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__label{line-height:12px;font-size:12px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner{height:12px;width:12px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner:after{height:6px;width:2px}.el-checkbox__input{cursor:pointer;outline:0;line-height:1;vertical-align:middle}.el-checkbox__input.is-disabled .el-checkbox__inner{background-color:#edf2fc;border-color:#dcdfe6;cursor:not-allowed}.el-checkbox__input.is-disabled .el-checkbox__inner:after{cursor:not-allowed;border-color:#c0c4cc}.el-checkbox__input.is-disabled .el-checkbox__inner+.el-checkbox__label{cursor:not-allowed}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{background-color:#f2f6fc;border-color:#dcdfe6}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner:after{border-color:#c0c4cc}.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner{background-color:#f2f6fc;border-color:#dcdfe6}.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner:before{background-color:#c0c4cc;border-color:#c0c4cc}.el-checkbox__input.is-checked .el-checkbox__inner,.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#409eff;border-color:#409eff}.el-checkbox__input.is-disabled+span.el-checkbox__label{color:#c0c4cc;cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner:after{-webkit-transform:rotate(45deg) scaleY(1);transform:rotate(45deg) scaleY(1)}.el-checkbox__input.is-checked+.el-checkbox__label{color:#409eff}.el-checkbox__input.is-focus .el-checkbox__inner{border-color:#409eff}.el-checkbox__input.is-indeterminate .el-checkbox__inner:before{content:"";position:absolute;display:block;background-color:#fff;height:2px;-webkit-transform:scale(.5);transform:scale(.5);left:0;right:0;top:5px}.el-checkbox__input.is-indeterminate .el-checkbox__inner:after{display:none}.el-checkbox__inner{display:inline-block;position:relative;border:1px solid #dcdfe6;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box;width:14px;height:14px;background-color:#fff;z-index:1;-webkit-transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46)}.el-checkbox__inner:hover{border-color:#409eff}.el-checkbox__inner:after{-webkit-box-sizing:content-box;box-sizing:content-box;content:"";border:1px solid #fff;border-left:0;border-top:0;height:7px;left:4px;position:absolute;top:1px;-webkit-transform:rotate(45deg) scaleY(0);transform:rotate(45deg) scaleY(0);width:3px;-webkit-transition:-webkit-transform .15s ease-in .05s;transition:-webkit-transform .15s ease-in .05s;transition:transform .15s ease-in .05s;transition:transform .15s ease-in .05s,-webkit-transform .15s ease-in .05s;-webkit-transform-origin:center;transform-origin:center}.el-checkbox__original{opacity:0;outline:0;position:absolute;margin:0;width:0;height:0;z-index:-1}.el-checkbox-button,.el-checkbox-button__inner{display:inline-block;position:relative}.el-checkbox__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.el-checkbox:last-of-type{margin-right:0}.el-checkbox-button__inner{line-height:1;white-space:nowrap;vertical-align:middle;cursor:pointer;background:#fff;border:1px solid #dcdfe6;border-left:0;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);padding:12px 20px;font-size:14px;border-radius:0}.el-checkbox-button__inner.is-round{padding:12px 20px}.el-checkbox-button__inner:hover{color:#409eff}.el-checkbox-button__inner [class*=el-icon-]{line-height:.9}.el-radio,.el-radio__input{line-height:1;outline:0;white-space:nowrap}.el-checkbox-button__inner [class*=el-icon-]+span{margin-left:5px}.el-checkbox-button__original{opacity:0;outline:0;position:absolute;margin:0;z-index:-1}.el-radio,.el-radio__inner,.el-radio__input{position:relative;display:inline-block}.el-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#409eff;border-color:#409eff;-webkit-box-shadow:-1px 0 0 0 #8cc5ff;box-shadow:-1px 0 0 0 #8cc5ff}.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner{border-left-color:#409eff}.el-checkbox-button.is-disabled .el-checkbox-button__inner{color:#c0c4cc;cursor:not-allowed;background-image:none;background-color:#fff;border-color:#ebeef5;-webkit-box-shadow:none;box-shadow:none}.el-checkbox-button.is-disabled:first-child .el-checkbox-button__inner{border-left-color:#ebeef5}.el-checkbox-button:first-child .el-checkbox-button__inner{border-left:1px solid #dcdfe6;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.el-checkbox-button.is-focus .el-checkbox-button__inner{border-color:#409eff}.el-checkbox-button:last-child .el-checkbox-button__inner{border-radius:0 4px 4px 0}.el-checkbox-button--medium .el-checkbox-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.el-checkbox-button--medium .el-checkbox-button__inner.is-round{padding:10px 20px}.el-checkbox-button--small .el-checkbox-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.el-checkbox-button--small .el-checkbox-button__inner.is-round{padding:9px 15px}.el-checkbox-button--mini .el-checkbox-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.el-checkbox-button--mini .el-checkbox-button__inner.is-round{padding:7px 15px}.el-checkbox-group{font-size:0}.el-radio,.el-radio--medium.is-bordered .el-radio__label{font-size:14px}.el-radio{color:#606266;cursor:pointer;margin-right:30px}.el-cascader-node>.el-radio,.el-radio:last-child{margin-right:0}.el-radio.is-bordered{padding:12px 20px 0 10px;border-radius:4px;border:1px solid #dcdfe6;-webkit-box-sizing:border-box;box-sizing:border-box;height:40px}.el-radio.is-bordered.is-checked{border-color:#409eff}.el-radio.is-bordered.is-disabled{cursor:not-allowed;border-color:#ebeef5}.el-radio__input.is-disabled .el-radio__inner,.el-radio__input.is-disabled.is-checked .el-radio__inner{background-color:#f5f7fa;border-color:#e4e7ed}.el-radio.is-bordered+.el-radio.is-bordered{margin-left:10px}.el-radio--medium.is-bordered{padding:10px 20px 0 10px;border-radius:4px;height:36px}.el-radio--mini.is-bordered .el-radio__label,.el-radio--small.is-bordered .el-radio__label{font-size:12px}.el-radio--medium.is-bordered .el-radio__inner{height:14px;width:14px}.el-radio--small.is-bordered{padding:8px 15px 0 10px;border-radius:3px;height:32px}.el-radio--small.is-bordered .el-radio__inner{height:12px;width:12px}.el-radio--mini.is-bordered{padding:6px 15px 0 10px;border-radius:3px;height:28px}.el-radio--mini.is-bordered .el-radio__inner{height:12px;width:12px}.el-radio__input{cursor:pointer;vertical-align:middle}.el-radio__input.is-disabled .el-radio__inner{cursor:not-allowed}.el-radio__input.is-disabled .el-radio__inner:after{cursor:not-allowed;background-color:#f5f7fa}.el-radio__input.is-disabled .el-radio__inner+.el-radio__label{cursor:not-allowed}.el-radio__input.is-disabled.is-checked .el-radio__inner:after{background-color:#c0c4cc}.el-radio__input.is-disabled+span.el-radio__label{color:#c0c4cc;cursor:not-allowed}.el-radio__input.is-checked .el-radio__inner{border-color:#409eff;background:#409eff}.el-radio__input.is-checked .el-radio__inner:after{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}.el-radio__input.is-checked+.el-radio__label{color:#409eff}.el-radio__input.is-focus .el-radio__inner{border-color:#409eff}.el-radio__inner{border:1px solid #dcdfe6;border-radius:100%;width:14px;height:14px;background-color:#fff;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box}.el-radio__inner:hover{border-color:#409eff}.el-radio__inner:after{width:4px;height:4px;border-radius:100%;background-color:#fff;content:"";position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%) scale(0);transform:translate(-50%,-50%) scale(0);-webkit-transition:-webkit-transform .15s ease-in;transition:-webkit-transform .15s ease-in;transition:transform .15s ease-in;transition:transform .15s ease-in,-webkit-transform .15s ease-in}.el-radio__original{opacity:0;outline:0;position:absolute;z-index:-1;top:0;left:0;right:0;bottom:0;margin:0}.el-radio:focus:not(.is-focus):not(:active):not(.is-disabled) .el-radio__inner{-webkit-box-shadow:0 0 2px 2px #409eff;box-shadow:0 0 2px 2px #409eff}.el-radio__label{font-size:14px;padding-left:10px}.el-scrollbar{overflow:hidden;position:relative}.el-scrollbar:active>.el-scrollbar__bar,.el-scrollbar:focus>.el-scrollbar__bar,.el-scrollbar:hover>.el-scrollbar__bar{opacity:1;-webkit-transition:opacity .34s ease-out;transition:opacity .34s ease-out}.el-scrollbar__wrap{overflow:scroll;height:100%}.el-scrollbar__wrap--hidden-default::-webkit-scrollbar{width:0;height:0}.el-scrollbar__thumb{position:relative;display:block;width:0;height:0;cursor:pointer;border-radius:inherit;background-color:rgba(144,147,153,.3);-webkit-transition:background-color .3s;transition:background-color .3s}.el-scrollbar__thumb:hover{background-color:rgba(144,147,153,.5)}.el-scrollbar__bar{position:absolute;right:2px;bottom:2px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity .12s ease-out;transition:opacity .12s ease-out}.el-scrollbar__bar.is-vertical{width:6px;top:2px}.el-scrollbar__bar.is-vertical>div{width:100%}.el-scrollbar__bar.is-horizontal{height:6px;left:2px}.el-scrollbar__bar.is-horizontal>div{height:100%}.el-cascader-panel{display:-webkit-box;display:-ms-flexbox;display:flex;border-radius:4px;font-size:14px}.el-cascader-node,.el-drawer{display:-webkit-box;display:-ms-flexbox}.el-cascader-panel.is-bordered{border:1px solid #e4e7ed;border-radius:4px}.el-cascader-menu{min-width:180px;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;border-right:1px solid #e4e7ed}.el-cascader-menu:last-child{border-right:none}.el-cascader-menu:last-child .el-cascader-node{padding-right:20px}.el-cascader-menu__wrap{height:204px}.el-cascader-menu__list{position:relative;min-height:100%;margin:0;padding:6px 0;list-style:none;-webkit-box-sizing:border-box;box-sizing:border-box}.el-avatar,.el-drawer{-webkit-box-sizing:border-box;overflow:hidden}.el-cascader-menu__hover-zone{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none}.el-cascader-menu__empty-text{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);text-align:center;color:#c0c4cc}.el-cascader-node{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:0 30px 0 20px;height:34px;line-height:34px;outline:0}.el-cascader-node.is-selectable.in-active-path{color:#606266}.el-cascader-node.in-active-path,.el-cascader-node.is-active,.el-cascader-node.is-selectable.in-checked-path{color:#409eff;font-weight:700}.el-cascader-node:not(.is-disabled){cursor:pointer}.el-cascader-node:not(.is-disabled):focus,.el-cascader-node:not(.is-disabled):hover{background:#f5f7fa}.el-cascader-node.is-disabled{color:#c0c4cc;cursor:not-allowed}.el-cascader-node__prefix{position:absolute;left:10px}.el-cascader-node__postfix{position:absolute;right:10px}.el-cascader-node__label{-webkit-box-flex:1;-ms-flex:1;flex:1;padding:0 10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.el-cascader-node>.el-radio .el-radio__label{padding-left:0}.el-avatar{display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;color:#fff;background:#c0c4cc;width:40px;height:40px;line-height:40px;font-size:14px}.el-avatar>img{display:block;height:100%;vertical-align:middle}.el-avatar--circle{border-radius:50%}.el-avatar--square{border-radius:4px}.el-avatar--icon{font-size:18px}.el-avatar--large{width:40px;height:40px;line-height:40px}.el-avatar--medium{width:36px;height:36px;line-height:36px}.el-avatar--small{width:28px;height:28px;line-height:28px}.el-drawer.btt,.el-drawer.ttb,.el-drawer__container{left:0;right:0;width:100%}.el-drawer.ltr,.el-drawer.rtl,.el-drawer__container{top:0;bottom:0;height:100%}@-webkit-keyframes el-drawer-fade-in{0%{opacity:0}to{opacity:1}}@keyframes el-drawer-fade-in{0%{opacity:0}to{opacity:1}}@-webkit-keyframes rtl-drawer-in{0%{-webkit-transform:translate(100%);transform:translate(100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@keyframes rtl-drawer-in{0%{-webkit-transform:translate(100%);transform:translate(100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@-webkit-keyframes rtl-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translate(100%);transform:translate(100%)}}@keyframes rtl-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translate(100%);transform:translate(100%)}}@-webkit-keyframes ltr-drawer-in{0%{-webkit-transform:translate(-100%);transform:translate(-100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@keyframes ltr-drawer-in{0%{-webkit-transform:translate(-100%);transform:translate(-100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@-webkit-keyframes ltr-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translate(-100%);transform:translate(-100%)}}@keyframes ltr-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translate(-100%);transform:translate(-100%)}}@-webkit-keyframes ttb-drawer-in{0%{-webkit-transform:translateY(-100%);transform:translateY(-100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@keyframes ttb-drawer-in{0%{-webkit-transform:translateY(-100%);transform:translateY(-100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@-webkit-keyframes ttb-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@keyframes ttb-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@-webkit-keyframes btt-drawer-in{0%{-webkit-transform:translateY(100%);transform:translateY(100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@keyframes btt-drawer-in{0%{-webkit-transform:translateY(100%);transform:translateY(100%)}to{-webkit-transform:translate(0);transform:translate(0)}}@-webkit-keyframes btt-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translateY(100%);transform:translateY(100%)}}@keyframes btt-drawer-out{0%{-webkit-transform:translate(0);transform:translate(0)}to{-webkit-transform:translateY(100%);transform:translateY(100%)}}.el-drawer{position:absolute;-webkit-box-sizing:border-box;box-sizing:border-box;background-color:#fff;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-ms-flex-direction:column;flex-direction:column;-webkit-box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12)}.el-drawer.rtl{-webkit-animation:rtl-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;animation:rtl-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;right:0}.el-drawer__open .el-drawer.rtl{-webkit-animation:rtl-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s;animation:rtl-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s}.el-drawer.ltr{-webkit-animation:ltr-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;animation:ltr-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;left:0}.el-drawer__open .el-drawer.ltr{-webkit-animation:ltr-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s;animation:ltr-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s}.el-drawer.ttb{-webkit-animation:ttb-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;animation:ttb-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;top:0}.el-drawer__open .el-drawer.ttb{-webkit-animation:ttb-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s;animation:ttb-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s}.el-drawer.btt{-webkit-animation:btt-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;animation:btt-drawer-out 225ms cubic-bezier(0,0,.2,1) 0s;bottom:0}.el-drawer__open .el-drawer.btt{-webkit-animation:btt-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s;animation:btt-drawer-in 225ms cubic-bezier(0,0,.2,1) 0s}.el-drawer__header{-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#72767b;display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:32px;padding:20px 20px 0}.el-drawer__header>:first-child,.el-drawer__title{-webkit-box-flex:1;-ms-flex:1;flex:1}.el-drawer__title{margin:0;line-height:inherit;font-size:1rem}.el-drawer__close-btn{border:none;cursor:pointer;font-size:20px;color:inherit;background-color:transparent}.el-drawer__body{-webkit-box-flex:1;-ms-flex:1;flex:1}.el-drawer__body>*{-webkit-box-sizing:border-box;box-sizing:border-box}.el-drawer__container{position:relative}.el-drawer-fade-enter-active{-webkit-animation:el-drawer-fade-in 225ms cubic-bezier(0,0,.2,1) 0s;animation:el-drawer-fade-in 225ms cubic-bezier(0,0,.2,1) 0s}.el-drawer-fade-leave-active{animation:el-drawer-fade-in 225ms cubic-bezier(0,0,.2,1) 0s reverse} \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/fonts/element-icons.535877f5.woff" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/fonts/element-icons.535877f5.woff" new file mode 100644 index 0000000000000000000000000000000000000000..02b9a2539e425a7a8c244faba92527602be76212 Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/fonts/element-icons.535877f5.woff" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/fonts/element-icons.732389de.ttf" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/fonts/element-icons.732389de.ttf" new file mode 100644 index 0000000000000000000000000000000000000000..91b74de36778b0ff8958d37d07ce70fb3b26f50b Binary files /dev/null and "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/fonts/element-icons.732389de.ttf" differ diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/js/app.1966d06f.js" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/js/app.1966d06f.js" new file mode 100644 index 0000000000000000000000000000000000000000..32c891583272c37ab2ad66120f9212709597c019 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/js/app.1966d06f.js" @@ -0,0 +1 @@ +(function(e){function t(t){for(var o,s,i=t[0],l=t[1],c=t[2],d=0,f=[];d ").concat(o),type:"success"})}))},handleDelete:function(e,t){var n=this;this.axios.delete("/v1/todo/"+t).then((function(){n.tableData.splice(e,1),n.$message({showClose:!0,duration:1500,message:"删除待办事项成功",type:"success"})}))},handleAdd:function(){var e=this;""!=this.newTitle?(this.axios.post("/v1/todo",{title:this.newTitle}).then((function(){e.getTodoList(),e.$message({showClose:!0,duration:1500,message:"添加待办事项成功",type:"success"})})),this.newTitle=""):this.$message({showClose:!0,duration:1500,message:"title不能为空哦",type:"warning"})}}}),v=h,w=(n("ed30"),n("2877")),b=Object(w["a"])(v,f,p,!1,null,null,null),m=b.exports,g={name:"Index",components:{TodoList:m}},x=g,y=(n("8fc1"),Object(w["a"])(x,u,d,!1,null,null,null)),j=y.exports,_={name:"app",components:{Index:j}},O=_,T=(n("034f"),Object(w["a"])(O,l,c,!1,null,null,null)),P=T.exports,$=n("5c96"),k=n.n($);n("0fae");o["default"].use(k.a);var C=n("8c4f");o["default"].use(C["a"]);var D=[{path:"/",name:"index",component:j}],S=new C["a"]({routes:D}),E=S;o["default"].config.productionTip=!0,new o["default"]({router:E,render:function(e){return e(P)}}).$mount("#app")},"85ec":function(e,t,n){},"89d2":function(e,t,n){},"8fc1":function(e,t,n){"use strict";var o=n("9272"),r=n.n(o);r.a},9272:function(e,t,n){},ed30:function(e,t,n){"use strict";var o=n("89d2"),r=n.n(o);r.a}}); \ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/js/chunk-vendors.ddcb6f91.js" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/js/chunk-vendors.ddcb6f91.js" new file mode 100644 index 0000000000000000000000000000000000000000..0eaef8681e553bc6eb12237a6d045ce0ea5cb5e6 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/static/js/chunk-vendors.ddcb6f91.js" @@ -0,0 +1,34 @@ +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-vendors"],{"03d6":function(e,t,n){var i=n("9c0e"),r=n("6ca1"),o=n("39ad")(!1),a=n("5a94")("IE_PROTO");e.exports=function(e,t){var n,s=r(e),l=0,c=[];for(n in s)n!=a&&i(s,n)&&c.push(n);while(t.length>l)i(s,n=t[l++])&&(~o(c,n)||c.push(n));return c}},"051b":function(e,t,n){var i=n("1a14"),r=n("10db");e.exports=n("0bad")?function(e,t,n){return i.f(e,t,r(1,n))}:function(e,t,n){return e[t]=n,e}},"05f5":function(e,t,n){var i=n("7a41"),r=n("ef08").document,o=i(r)&&i(r.createElement);e.exports=function(e){return o?r.createElement(e):{}}},"06cf":function(e,t,n){var i=n("83ab"),r=n("d1e7"),o=n("5c6c"),a=n("fc6a"),s=n("c04e"),l=n("5135"),c=n("0cfb"),u=Object.getOwnPropertyDescriptor;t.f=i?u:function(e,t){if(e=a(e),t=s(t,!0),c)try{return u(e,t)}catch(n){}if(l(e,t))return o(!r.f.call(e,t),e[t])}},"072d":function(e,t,n){"use strict";var i=n("0bad"),r=n("9876"),o=n("fed5"),a=n("1917"),s=n("0983"),l=n("9fbb"),c=Object.assign;e.exports=!c||n("4b8b")((function(){var e={},t={},n=Symbol(),i="abcdefghijklmnopqrst";return e[n]=7,i.split("").forEach((function(e){t[e]=e})),7!=c({},e)[n]||Object.keys(c({},t)).join("")!=i}))?function(e,t){var n=s(e),c=arguments.length,u=1,d=o.f,h=a.f;while(c>u){var f,p=l(arguments[u++]),m=d?r(p).concat(d(p)):r(p),v=m.length,g=0;while(v>g)f=m[g++],i&&!h.call(p,f)||(n[f]=p[f])}return n}:c},"0983":function(e,t,n){var i=n("c901");e.exports=function(e){return Object(i(e))}},"0a06":function(e,t,n){"use strict";var i=n("2444"),r=n("c532"),o=n("f6b4"),a=n("5270");function s(e){this.defaults=e,this.interceptors={request:new o,response:new o}}s.prototype.request=function(e){"string"===typeof e&&(e=r.merge({url:arguments[0]},arguments[1])),e=r.merge(i,{method:"get"},this.defaults,e),e.method=e.method.toLowerCase();var t=[a,void 0],n=Promise.resolve(e);this.interceptors.request.forEach((function(e){t.unshift(e.fulfilled,e.rejected)})),this.interceptors.response.forEach((function(e){t.push(e.fulfilled,e.rejected)}));while(t.length)n=n.then(t.shift(),t.shift());return n},r.forEach(["delete","get","head","options"],(function(e){s.prototype[e]=function(t,n){return this.request(r.merge(n||{},{method:e,url:t}))}})),r.forEach(["post","put","patch"],(function(e){s.prototype[e]=function(t,n,i){return this.request(r.merge(i||{},{method:e,url:t,data:n}))}})),e.exports=s},"0ae2":function(e,t,n){var i=n("9876"),r=n("fed5"),o=n("1917");e.exports=function(e){var t=i(e),n=r.f;if(n){var a,s=n(e),l=o.f,c=0;while(s.length>c)l.call(e,a=s[c++])&&t.push(a)}return t}},"0b99":function(e,t,n){"use strict";var i=n("19fa")(!0);n("393a")(String,"String",(function(e){this._t=String(e),this._i=0}),(function(){var e,t=this._t,n=this._i;return n>=t.length?{value:void 0,done:!0}:(e=i(t,n),this._i+=e.length,{value:e,done:!1})}))},"0bad":function(e,t,n){e.exports=!n("4b8b")((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},"0cfb":function(e,t,n){var i=n("83ab"),r=n("d039"),o=n("cc12");e.exports=!i&&!r((function(){return 7!=Object.defineProperty(o("div"),"a",{get:function(){return 7}}).a}))},"0df6":function(e,t,n){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}},"0e15":function(e,t,n){var i=n("597f");e.exports=function(e,t,n){return void 0===n?i(e,t,!1):i(e,n,!1!==t)}},"0fae":function(e,t,n){},1098:function(e,t,n){"use strict";t.__esModule=!0;var i=n("17ed"),r=l(i),o=n("f893"),a=l(o),s="function"===typeof a.default&&"symbol"===typeof r.default?function(e){return typeof e}:function(e){return e&&"function"===typeof a.default&&e.constructor===a.default&&e!==a.default.prototype?"symbol":typeof e};function l(e){return e&&e.__esModule?e:{default:e}}t.default="function"===typeof a.default&&"symbol"===s(r.default)?function(e){return"undefined"===typeof e?"undefined":s(e)}:function(e){return e&&"function"===typeof a.default&&e.constructor===a.default&&e!==a.default.prototype?"symbol":"undefined"===typeof e?"undefined":s(e)}},"10db":function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},"12f2":function(e,t,n){"use strict";t.__esModule=!0,t.default=function(e){return{methods:{focus:function(){this.$refs[e].focus()}}}}},"14e9":function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=122)}({122:function(e,t,n){"use strict";n.r(t);var i=n(15),r=n(37),o=n.n(r),a=n(3),s=n(2),l={vertical:{offset:"offsetHeight",scroll:"scrollTop",scrollSize:"scrollHeight",size:"height",key:"vertical",axis:"Y",client:"clientY",direction:"top"},horizontal:{offset:"offsetWidth",scroll:"scrollLeft",scrollSize:"scrollWidth",size:"width",key:"horizontal",axis:"X",client:"clientX",direction:"left"}};function c(e){var t=e.move,n=e.size,i=e.bar,r={},o="translate"+i.axis+"("+t+"%)";return r[i.size]=n,r.transform=o,r.msTransform=o,r.webkitTransform=o,r}var u={name:"Bar",props:{vertical:Boolean,size:String,move:Number},computed:{bar:function(){return l[this.vertical?"vertical":"horizontal"]},wrap:function(){return this.$parent.wrap}},render:function(e){var t=this.size,n=this.move,i=this.bar;return e("div",{class:["el-scrollbar__bar","is-"+i.key],on:{mousedown:this.clickTrackHandler}},[e("div",{ref:"thumb",class:"el-scrollbar__thumb",on:{mousedown:this.clickThumbHandler},style:c({size:t,move:n,bar:i})})])},methods:{clickThumbHandler:function(e){e.ctrlKey||2===e.button||(this.startDrag(e),this[this.bar.axis]=e.currentTarget[this.bar.offset]-(e[this.bar.client]-e.currentTarget.getBoundingClientRect()[this.bar.direction]))},clickTrackHandler:function(e){var t=Math.abs(e.target.getBoundingClientRect()[this.bar.direction]-e[this.bar.client]),n=this.$refs.thumb[this.bar.offset]/2,i=100*(t-n)/this.$el[this.bar.offset];this.wrap[this.bar.scroll]=i*this.wrap[this.bar.scrollSize]/100},startDrag:function(e){e.stopImmediatePropagation(),this.cursorDown=!0,Object(s["on"])(document,"mousemove",this.mouseMoveDocumentHandler),Object(s["on"])(document,"mouseup",this.mouseUpDocumentHandler),document.onselectstart=function(){return!1}},mouseMoveDocumentHandler:function(e){if(!1!==this.cursorDown){var t=this[this.bar.axis];if(t){var n=-1*(this.$el.getBoundingClientRect()[this.bar.direction]-e[this.bar.client]),i=this.$refs.thumb[this.bar.offset]-t,r=100*(n-i)/this.$el[this.bar.offset];this.wrap[this.bar.scroll]=r*this.wrap[this.bar.scrollSize]/100}}},mouseUpDocumentHandler:function(e){this.cursorDown=!1,this[this.bar.axis]=0,Object(s["off"])(document,"mousemove",this.mouseMoveDocumentHandler),document.onselectstart=null}},destroyed:function(){Object(s["off"])(document,"mouseup",this.mouseUpDocumentHandler)}},d={name:"ElScrollbar",components:{Bar:u},props:{native:Boolean,wrapStyle:{},wrapClass:{},viewClass:{},viewStyle:{},noresize:Boolean,tag:{type:String,default:"div"}},data:function(){return{sizeWidth:"0",sizeHeight:"0",moveX:0,moveY:0}},computed:{wrap:function(){return this.$refs.wrap}},render:function(e){var t=o()(),n=this.wrapStyle;if(t){var i="-"+t+"px",r="margin-bottom: "+i+"; margin-right: "+i+";";Array.isArray(this.wrapStyle)?(n=Object(a["toObject"])(this.wrapStyle),n.marginRight=n.marginBottom=i):"string"===typeof this.wrapStyle?n+=r:n=r}var s=e(this.tag,{class:["el-scrollbar__view",this.viewClass],style:this.viewStyle,ref:"resize"},this.$slots.default),l=e("div",{ref:"wrap",style:n,on:{scroll:this.handleScroll},class:[this.wrapClass,"el-scrollbar__wrap",t?"":"el-scrollbar__wrap--hidden-default"]},[[s]]),c=void 0;return c=this.native?[e("div",{ref:"wrap",class:[this.wrapClass,"el-scrollbar__wrap"],style:n},[[s]])]:[l,e(u,{attrs:{move:this.moveX,size:this.sizeWidth}}),e(u,{attrs:{vertical:!0,move:this.moveY,size:this.sizeHeight}})],e("div",{class:"el-scrollbar"},c)},methods:{handleScroll:function(){var e=this.wrap;this.moveY=100*e.scrollTop/e.clientHeight,this.moveX=100*e.scrollLeft/e.clientWidth},update:function(){var e=void 0,t=void 0,n=this.wrap;n&&(e=100*n.clientHeight/n.scrollHeight,t=100*n.clientWidth/n.scrollWidth,this.sizeHeight=e<100?e+"%":"",this.sizeWidth=t<100?t+"%":"")}},mounted:function(){this.native||(this.$nextTick(this.update),!this.noresize&&Object(i["addResizeListener"])(this.$refs.resize,this.update))},beforeDestroy:function(){this.native||!this.noresize&&Object(i["removeResizeListener"])(this.$refs.resize,this.update)},install:function(e){e.component(d.name,d)}};t["default"]=d},15:function(e,t){e.exports=n("4010")},2:function(e,t){e.exports=n("5924")},3:function(e,t){e.exports=n("8122")},37:function(e,t){e.exports=n("e62d")}})},1609:function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},"17ed":function(e,t,n){e.exports={default:n("511f"),__esModule:!0}},1836:function(e,t,n){var i=n("6ca1"),r=n("6438").f,o={}.toString,a="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(e){try{return r(e)}catch(t){return a.slice()}};e.exports.f=function(e){return a&&"[object Window]"==o.call(e)?s(e):r(i(e))}},1917:function(e,t){t.f={}.propertyIsEnumerable},"19aa":function(e,t){e.exports=function(e,t,n){if(!(e instanceof t))throw TypeError("Incorrect "+(n?n+" ":"")+"invocation");return e}},"19fa":function(e,t,n){var i=n("fc5e"),r=n("c901");e.exports=function(e){return function(t,n){var o,a,s=String(r(t)),l=i(n),c=s.length;return l<0||l>=c?e?"":void 0:(o=s.charCodeAt(l),o<55296||o>56319||l+1===c||(a=s.charCodeAt(l+1))<56320||a>57343?e?s.charAt(l):o:e?s.slice(l,l+2):a-56320+(o-55296<<10)+65536)}}},"1a14":function(e,t,n){var i=n("77e9"),r=n("faf5"),o=n("3397"),a=Object.defineProperty;t.f=n("0bad")?Object.defineProperty:function(e,t,n){if(i(e),t=o(t,!0),i(n),r)try{return a(e,t,n)}catch(s){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},"1be4":function(e,t,n){var i=n("d066");e.exports=i("document","documentElement")},"1c0b":function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(String(e)+" is not a function");return e}},"1c7e":function(e,t,n){var i=n("b622"),r=i("iterator"),o=!1;try{var a=0,s={next:function(){return{done:!!a++}},return:function(){o=!0}};s[r]=function(){return this},Array.from(s,(function(){throw 2}))}catch(l){}e.exports=function(e,t){if(!t&&!o)return!1;var n=!1;try{var i={};i[r]=function(){return{next:function(){return{done:n=!0}}}},e(i)}catch(l){}return n}},"1d2b":function(e,t,n){"use strict";e.exports=function(e,t){return function(){for(var n=new Array(arguments.length),i=0;i=51||!i((function(){var t=[],n=t.constructor={};return n[a]=function(){return{foo:1}},1!==t[e](Boolean).foo}))}},2266:function(e,t,n){var i=n("825a"),r=n("e95a"),o=n("50c4"),a=n("f8c2"),s=n("35a1"),l=n("9bdd"),c=function(e,t){this.stopped=e,this.result=t},u=e.exports=function(e,t,n,u,d){var h,f,p,m,v,g,b,y=a(t,n,u?2:1);if(d)h=e;else{if(f=s(e),"function"!=typeof f)throw TypeError("Target is not iterable");if(r(f)){for(p=0,m=o(e.length);m>p;p++)if(v=u?y(i(b=e[p])[0],b[1]):y(e[p]),v&&v instanceof c)return v;return new c(!1)}h=f.call(e)}g=h.next;while(!(b=g.call(h)).done)if(v=l(h,y,b.value,u),"object"==typeof v&&v&&v instanceof c)return v;return new c(!1)};u.stop=function(e){return new c(!0,e)}},"23cb":function(e,t,n){var i=n("a691"),r=Math.max,o=Math.min;e.exports=function(e,t){var n=i(e);return n<0?r(n+t,0):o(n,t)}},"23e7":function(e,t,n){var i=n("da84"),r=n("06cf").f,o=n("9112"),a=n("6eeb"),s=n("ce4e"),l=n("e893"),c=n("94ca");e.exports=function(e,t){var n,u,d,h,f,p,m=e.target,v=e.global,g=e.stat;if(u=v?i:g?i[m]||s(m,{}):(i[m]||{}).prototype,u)for(d in t){if(f=t[d],e.noTargetGet?(p=r(u,d),h=p&&p.value):h=u[d],n=c(v?d:m+(g?".":"#")+d,e.forced),!n&&void 0!==h){if(typeof f===typeof h)continue;l(f,h)}(e.sham||h&&h.sham)&&o(f,"sham",!0),a(u,d,f,e)}}},"241c":function(e,t,n){var i=n("ca84"),r=n("7839"),o=r.concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return i(e,o)}},2444:function(e,t,n){"use strict";(function(t){var i=n("c532"),r=n("c8af"),o={"Content-Type":"application/x-www-form-urlencoded"};function a(e,t){!i.isUndefined(e)&&i.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}function s(){var e;return"undefined"!==typeof XMLHttpRequest?e=n("b50d"):"undefined"!==typeof t&&(e=n("b50d")),e}var l={adapter:s(),transformRequest:[function(e,t){return r(t,"Content-Type"),i.isFormData(e)||i.isArrayBuffer(e)||i.isBuffer(e)||i.isStream(e)||i.isFile(e)||i.isBlob(e)?e:i.isArrayBufferView(e)?e.buffer:i.isURLSearchParams(e)?(a(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):i.isObject(e)?(a(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"===typeof e)try{e=JSON.parse(e)}catch(t){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*"}}};i.forEach(["delete","get","head"],(function(e){l.headers[e]={}})),i.forEach(["post","put","patch"],(function(e){l.headers[e]=i.merge(o)})),e.exports=l}).call(this,n("4362"))},2626:function(e,t,n){"use strict";var i=n("d066"),r=n("9bf2"),o=n("b622"),a=n("83ab"),s=o("species");e.exports=function(e){var t=i(e),n=r.f;a&&t&&!t[s]&&n(t,s,{configurable:!0,get:function(){return this}})}},"26dd":function(e,t,n){"use strict";var i=n("6f4f"),r=n("10db"),o=n("92f0"),a={};n("051b")(a,n("cc15")("iterator"),(function(){return this})),e.exports=function(e,t,n){e.prototype=i(a,{next:r(1,n)}),o(e,t+" Iterator")}},2877:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},"299c":function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=129)}({129:function(e,t,n){"use strict";n.r(t);var i=n(5),r=n.n(i),o=n(16),a=n.n(o),s=n(2),l=n(3),c=n(7),u=n.n(c),d={name:"ElTooltip",mixins:[r.a],props:{openDelay:{type:Number,default:0},disabled:Boolean,manual:Boolean,effect:{type:String,default:"dark"},arrowOffset:{type:Number,default:0},popperClass:String,content:String,visibleArrow:{default:!0},transition:{type:String,default:"el-fade-in-linear"},popperOptions:{default:function(){return{boundariesPadding:10,gpuAcceleration:!1}}},enterable:{type:Boolean,default:!0},hideAfter:{type:Number,default:0},tabindex:{type:Number,default:0}},data:function(){return{tooltipId:"el-tooltip-"+Object(l["generateId"])(),timeoutPending:null,focusing:!1}},beforeCreate:function(){var e=this;this.$isServer||(this.popperVM=new u.a({data:{node:""},render:function(e){return this.node}}).$mount(),this.debounceClose=a()(200,(function(){return e.handleClosePopper()})))},render:function(e){var t=this;this.popperVM&&(this.popperVM.node=e("transition",{attrs:{name:this.transition},on:{afterLeave:this.doDestroy}},[e("div",{on:{mouseleave:function(){t.setExpectedState(!1),t.debounceClose()},mouseenter:function(){t.setExpectedState(!0)}},ref:"popper",attrs:{role:"tooltip",id:this.tooltipId,"aria-hidden":this.disabled||!this.showPopper?"true":"false"},directives:[{name:"show",value:!this.disabled&&this.showPopper}],class:["el-tooltip__popper","is-"+this.effect,this.popperClass]},[this.$slots.content||this.content])]));var n=this.getFirstElement();if(!n)return null;var i=n.data=n.data||{};return i.staticClass=this.addTooltipClass(i.staticClass),n},mounted:function(){var e=this;this.referenceElm=this.$el,1===this.$el.nodeType&&(this.$el.setAttribute("aria-describedby",this.tooltipId),this.$el.setAttribute("tabindex",this.tabindex),Object(s["on"])(this.referenceElm,"mouseenter",this.show),Object(s["on"])(this.referenceElm,"mouseleave",this.hide),Object(s["on"])(this.referenceElm,"focus",(function(){if(e.$slots.default&&e.$slots.default.length){var t=e.$slots.default[0].componentInstance;t&&t.focus?t.focus():e.handleFocus()}else e.handleFocus()})),Object(s["on"])(this.referenceElm,"blur",this.handleBlur),Object(s["on"])(this.referenceElm,"click",this.removeFocusing)),this.value&&this.popperVM&&this.popperVM.$nextTick((function(){e.value&&e.updatePopper()}))},watch:{focusing:function(e){e?Object(s["addClass"])(this.referenceElm,"focusing"):Object(s["removeClass"])(this.referenceElm,"focusing")}},methods:{show:function(){this.setExpectedState(!0),this.handleShowPopper()},hide:function(){this.setExpectedState(!1),this.debounceClose()},handleFocus:function(){this.focusing=!0,this.show()},handleBlur:function(){this.focusing=!1,this.hide()},removeFocusing:function(){this.focusing=!1},addTooltipClass:function(e){return e?"el-tooltip "+e.replace("el-tooltip",""):"el-tooltip"},handleShowPopper:function(){var e=this;this.expectedState&&!this.manual&&(clearTimeout(this.timeout),this.timeout=setTimeout((function(){e.showPopper=!0}),this.openDelay),this.hideAfter>0&&(this.timeoutPending=setTimeout((function(){e.showPopper=!1}),this.hideAfter)))},handleClosePopper:function(){this.enterable&&this.expectedState||this.manual||(clearTimeout(this.timeout),this.timeoutPending&&clearTimeout(this.timeoutPending),this.showPopper=!1,this.disabled&&this.doDestroy())},setExpectedState:function(e){!1===e&&clearTimeout(this.timeoutPending),this.expectedState=e},getFirstElement:function(){var e=this.$slots.default;if(!Array.isArray(e))return null;for(var t=null,n=0;nl&&(e.scrollTop=a-e.clientHeight)}else e.scrollTop=0}},"2b0e":function(e,t,n){"use strict";n.r(t),function(e){ +/*! + * Vue.js v2.6.10 + * (c) 2014-2019 Evan You + * Released under the MIT License. + */ +var n=Object.freeze({});function i(e){return void 0===e||null===e}function r(e){return void 0!==e&&null!==e}function o(e){return!0===e}function a(e){return!1===e}function s(e){return"string"===typeof e||"number"===typeof e||"symbol"===typeof e||"boolean"===typeof e}function l(e){return null!==e&&"object"===typeof e}var c=Object.prototype.toString;function u(e){return"[object Object]"===c.call(e)}function d(e){return"[object RegExp]"===c.call(e)}function h(e){var t=parseFloat(String(e));return t>=0&&Math.floor(t)===t&&isFinite(e)}function f(e){return r(e)&&"function"===typeof e.then&&"function"===typeof e.catch}function p(e){return null==e?"":Array.isArray(e)||u(e)&&e.toString===c?JSON.stringify(e,null,2):String(e)}function m(e){var t=parseFloat(e);return isNaN(t)?e:t}function v(e,t){for(var n=Object.create(null),i=e.split(","),r=0;r-1)return e.splice(n,1)}}var y=Object.prototype.hasOwnProperty;function _(e,t){return y.call(e,t)}function x(e){var t=Object.create(null);return function(n){var i=t[n];return i||(t[n]=e(n))}}var w=/-(\w)/g,C=x((function(e){return e.replace(w,(function(e,t){return t?t.toUpperCase():""}))})),k=x((function(e){return e.charAt(0).toUpperCase()+e.slice(1)})),S=/\B([A-Z])/g,O=x((function(e){return e.replace(S,"-$1").toLowerCase()}));function $(e,t){function n(n){var i=arguments.length;return i?i>1?e.apply(t,arguments):e.call(t,n):e.call(t)}return n._length=e.length,n}function D(e,t){return e.bind(t)}var E=Function.prototype.bind?D:$;function T(e,t){t=t||0;var n=e.length-t,i=new Array(n);while(n--)i[n]=e[n+t];return i}function P(e,t){for(var n in t)e[n]=t[n];return e}function M(e){for(var t={},n=0;n0,ne=Q&&Q.indexOf("edge/")>0,ie=(Q&&Q.indexOf("android"),Q&&/iphone|ipad|ipod|ios/.test(Q)||"ios"===J),re=(Q&&/chrome\/\d+/.test(Q),Q&&/phantomjs/.test(Q),Q&&Q.match(/firefox\/(\d+)/)),oe={}.watch,ae=!1;if(X)try{var se={};Object.defineProperty(se,"passive",{get:function(){ae=!0}}),window.addEventListener("test-passive",null,se)}catch(Ca){}var le=function(){return void 0===K&&(K=!X&&!Z&&"undefined"!==typeof e&&(e["process"]&&"server"===e["process"].env.VUE_ENV)),K},ce=X&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function ue(e){return"function"===typeof e&&/native code/.test(e.toString())}var de,he="undefined"!==typeof Symbol&&ue(Symbol)&&"undefined"!==typeof Reflect&&ue(Reflect.ownKeys);de="undefined"!==typeof Set&&ue(Set)?Set:function(){function e(){this.set=Object.create(null)}return e.prototype.has=function(e){return!0===this.set[e]},e.prototype.add=function(e){this.set[e]=!0},e.prototype.clear=function(){this.set=Object.create(null)},e}();var fe=I,pe=0,me=function(){this.id=pe++,this.subs=[]};me.prototype.addSub=function(e){this.subs.push(e)},me.prototype.removeSub=function(e){b(this.subs,e)},me.prototype.depend=function(){me.target&&me.target.addDep(this)},me.prototype.notify=function(){var e=this.subs.slice();for(var t=0,n=e.length;t-1)if(o&&!_(r,"default"))a=!1;else if(""===a||a===O(e)){var l=et(String,r.type);(l<0||s0&&(a=$t(a,(t||"")+"_"+n),Ot(a[0])&&Ot(c)&&(u[l]=we(c.text+a[0].text),a.shift()),u.push.apply(u,a)):s(a)?Ot(c)?u[l]=we(c.text+a):""!==a&&u.push(we(a)):Ot(a)&&Ot(c)?u[l]=we(c.text+a.text):(o(e._isVList)&&r(a.tag)&&i(a.key)&&r(t)&&(a.key="__vlist"+t+"_"+n+"__"),u.push(a)));return u}function Dt(e){var t=e.$options.provide;t&&(e._provided="function"===typeof t?t.call(e):t)}function Et(e){var t=Tt(e.$options.inject,e);t&&(Ee(!1),Object.keys(t).forEach((function(n){Ne(e,n,t[n])})),Ee(!0))}function Tt(e,t){if(e){for(var n=Object.create(null),i=he?Reflect.ownKeys(e):Object.keys(e),r=0;r0,a=e?!!e.$stable:!o,s=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(a&&i&&i!==n&&s===i.$key&&!o&&!i.$hasNormal)return i;for(var l in r={},e)e[l]&&"$"!==l[0]&&(r[l]=Nt(t,l,e[l]))}else r={};for(var c in t)c in r||(r[c]=jt(t,c));return e&&Object.isExtensible(e)&&(e._normalized=r),q(r,"$stable",a),q(r,"$key",s),q(r,"$hasNormal",o),r}function Nt(e,t,n){var i=function(){var e=arguments.length?n.apply(null,arguments):n({});return e=e&&"object"===typeof e&&!Array.isArray(e)?[e]:St(e),e&&(0===e.length||1===e.length&&e[0].isComment)?void 0:e};return n.proxy&&Object.defineProperty(e,t,{get:i,enumerable:!0,configurable:!0}),i}function jt(e,t){return function(){return e[t]}}function At(e,t){var n,i,o,a,s;if(Array.isArray(e)||"string"===typeof e)for(n=new Array(e.length),i=0,o=e.length;i1?T(n):n;for(var i=T(arguments,1),r='event handler for "'+e+'"',o=0,a=n.length;odocument.createEvent("Event").timeStamp&&(Kn=function(){return Gn.now()})}function Xn(){var e,t;for(Yn=Kn(),Wn=!0,zn.sort((function(e,t){return e.id-t.id})),qn=0;qnqn&&zn[n].id>e.id)n--;zn.splice(n+1,0,e)}else zn.push(e);Hn||(Hn=!0,pt(Xn))}}var ti=0,ni=function(e,t,n,i,r){this.vm=e,r&&(e._watcher=this),e._watchers.push(this),i?(this.deep=!!i.deep,this.user=!!i.user,this.lazy=!!i.lazy,this.sync=!!i.sync,this.before=i.before):this.deep=this.user=this.lazy=this.sync=!1,this.cb=n,this.id=++ti,this.active=!0,this.dirty=this.lazy,this.deps=[],this.newDeps=[],this.depIds=new de,this.newDepIds=new de,this.expression="","function"===typeof t?this.getter=t:(this.getter=Y(t),this.getter||(this.getter=I)),this.value=this.lazy?void 0:this.get()};ni.prototype.get=function(){var e;ge(this);var t=this.vm;try{e=this.getter.call(t,t)}catch(Ca){if(!this.user)throw Ca;tt(Ca,t,'getter for watcher "'+this.expression+'"')}finally{this.deep&&vt(e),be(),this.cleanupDeps()}return e},ni.prototype.addDep=function(e){var t=e.id;this.newDepIds.has(t)||(this.newDepIds.add(t),this.newDeps.push(e),this.depIds.has(t)||e.addSub(this))},ni.prototype.cleanupDeps=function(){var e=this.deps.length;while(e--){var t=this.deps[e];this.newDepIds.has(t.id)||t.removeSub(this)}var n=this.depIds;this.depIds=this.newDepIds,this.newDepIds=n,this.newDepIds.clear(),n=this.deps,this.deps=this.newDeps,this.newDeps=n,this.newDeps.length=0},ni.prototype.update=function(){this.lazy?this.dirty=!0:this.sync?this.run():ei(this)},ni.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||l(e)||this.deep){var t=this.value;if(this.value=e,this.user)try{this.cb.call(this.vm,e,t)}catch(Ca){tt(Ca,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,e,t)}}},ni.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},ni.prototype.depend=function(){var e=this.deps.length;while(e--)this.deps[e].depend()},ni.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||b(this.vm._watchers,this);var e=this.deps.length;while(e--)this.deps[e].removeSub(this);this.active=!1}};var ii={enumerable:!0,configurable:!0,get:I,set:I};function ri(e,t,n){ii.get=function(){return this[t][n]},ii.set=function(e){this[t][n]=e},Object.defineProperty(e,n,ii)}function oi(e){e._watchers=[];var t=e.$options;t.props&&ai(e,t.props),t.methods&&pi(e,t.methods),t.data?si(e):Ie(e._data={},!0),t.computed&&ui(e,t.computed),t.watch&&t.watch!==oe&&mi(e,t.watch)}function ai(e,t){var n=e.$options.propsData||{},i=e._props={},r=e.$options._propKeys=[],o=!e.$parent;o||Ee(!1);var a=function(o){r.push(o);var a=Xe(o,t,n,e);Ne(i,o,a),o in e||ri(e,"_props",o)};for(var s in t)a(s);Ee(!0)}function si(e){var t=e.$options.data;t=e._data="function"===typeof t?li(t,e):t||{},u(t)||(t={});var n=Object.keys(t),i=e.$options.props,r=(e.$options.methods,n.length);while(r--){var o=n[r];0,i&&_(i,o)||W(o)||ri(e,"_data",o)}Ie(t,!0)}function li(e,t){ge();try{return e.call(t,t)}catch(Ca){return tt(Ca,t,"data()"),{}}finally{be()}}var ci={lazy:!0};function ui(e,t){var n=e._computedWatchers=Object.create(null),i=le();for(var r in t){var o=t[r],a="function"===typeof o?o:o.get;0,i||(n[r]=new ni(e,a||I,I,ci)),r in e||di(e,r,o)}}function di(e,t,n){var i=!le();"function"===typeof n?(ii.get=i?hi(t):fi(n),ii.set=I):(ii.get=n.get?i&&!1!==n.cache?hi(t):fi(n.get):I,ii.set=n.set||I),Object.defineProperty(e,t,ii)}function hi(e){return function(){var t=this._computedWatchers&&this._computedWatchers[e];if(t)return t.dirty&&t.evaluate(),me.target&&t.depend(),t.value}}function fi(e){return function(){return e.call(this,this)}}function pi(e,t){e.$options.props;for(var n in t)e[n]="function"!==typeof t[n]?I:E(t[n],e)}function mi(e,t){for(var n in t){var i=t[n];if(Array.isArray(i))for(var r=0;r-1)return this;var n=T(arguments,1);return n.unshift(this),"function"===typeof e.install?e.install.apply(e,n):"function"===typeof e&&e.apply(null,n),t.push(e),this}}function Si(e){e.mixin=function(e){return this.options=Ke(this.options,e),this}}function Oi(e){e.cid=0;var t=1;e.extend=function(e){e=e||{};var n=this,i=n.cid,r=e._Ctor||(e._Ctor={});if(r[i])return r[i];var o=e.name||n.options.name;var a=function(e){this._init(e)};return a.prototype=Object.create(n.prototype),a.prototype.constructor=a,a.cid=t++,a.options=Ke(n.options,e),a["super"]=n,a.options.props&&$i(a),a.options.computed&&Di(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,z.forEach((function(e){a[e]=n[e]})),o&&(a.options.components[o]=a),a.superOptions=n.options,a.extendOptions=e,a.sealedOptions=P({},a.options),r[i]=a,a}}function $i(e){var t=e.options.props;for(var n in t)ri(e.prototype,"_props",n)}function Di(e){var t=e.options.computed;for(var n in t)di(e.prototype,n,t[n])}function Ei(e){z.forEach((function(t){e[t]=function(e,n){return n?("component"===t&&u(n)&&(n.name=n.name||e,n=this.options._base.extend(n)),"directive"===t&&"function"===typeof n&&(n={bind:n,update:n}),this.options[t+"s"][e]=n,n):this.options[t+"s"][e]}}))}function Ti(e){return e&&(e.Ctor.options.name||e.tag)}function Pi(e,t){return Array.isArray(e)?e.indexOf(t)>-1:"string"===typeof e?e.split(",").indexOf(t)>-1:!!d(e)&&e.test(t)}function Mi(e,t){var n=e.cache,i=e.keys,r=e._vnode;for(var o in n){var a=n[o];if(a){var s=Ti(a.componentOptions);s&&!t(s)&&Ii(n,o,i,r)}}}function Ii(e,t,n,i){var r=e[t];!r||i&&r.tag===i.tag||r.componentInstance.$destroy(),e[t]=null,b(n,t)}yi(Ci),gi(Ci),En(Ci),In(Ci),bn(Ci);var Ni=[String,RegExp,Array],ji={name:"keep-alive",abstract:!0,props:{include:Ni,exclude:Ni,max:[String,Number]},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var e in this.cache)Ii(this.cache,e,this.keys)},mounted:function(){var e=this;this.$watch("include",(function(t){Mi(e,(function(e){return Pi(t,e)}))})),this.$watch("exclude",(function(t){Mi(e,(function(e){return!Pi(t,e)}))}))},render:function(){var e=this.$slots.default,t=Cn(e),n=t&&t.componentOptions;if(n){var i=Ti(n),r=this,o=r.include,a=r.exclude;if(o&&(!i||!Pi(o,i))||a&&i&&Pi(a,i))return t;var s=this,l=s.cache,c=s.keys,u=null==t.key?n.Ctor.cid+(n.tag?"::"+n.tag:""):t.key;l[u]?(t.componentInstance=l[u].componentInstance,b(c,u),c.push(u)):(l[u]=t,c.push(u),this.max&&c.length>parseInt(this.max)&&Ii(l,c[0],c,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}},Ai={KeepAlive:ji};function Fi(e){var t={get:function(){return R}};Object.defineProperty(e,"config",t),e.util={warn:fe,extend:P,mergeOptions:Ke,defineReactive:Ne},e.set=je,e.delete=Ae,e.nextTick=pt,e.observable=function(e){return Ie(e),e},e.options=Object.create(null),z.forEach((function(t){e.options[t+"s"]=Object.create(null)})),e.options._base=e,P(e.options.components,Ai),ki(e),Si(e),Oi(e),Ei(e)}Fi(Ci),Object.defineProperty(Ci.prototype,"$isServer",{get:le}),Object.defineProperty(Ci.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Ci,"FunctionalRenderContext",{value:Zt}),Ci.version="2.6.10";var Li=v("style,class"),Vi=v("input,textarea,option,select,progress"),zi=function(e,t,n){return"value"===n&&Vi(e)&&"button"!==t||"selected"===n&&"option"===e||"checked"===n&&"input"===e||"muted"===n&&"video"===e},Bi=v("contenteditable,draggable,spellcheck"),Ri=v("events,caret,typing,plaintext-only"),Hi=function(e,t){return Ki(t)||"false"===t?"false":"contenteditable"===e&&Ri(t)?t:"true"},Wi=v("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),qi="http://www.w3.org/1999/xlink",Ui=function(e){return":"===e.charAt(5)&&"xlink"===e.slice(0,5)},Yi=function(e){return Ui(e)?e.slice(6,e.length):""},Ki=function(e){return null==e||!1===e};function Gi(e){var t=e.data,n=e,i=e;while(r(i.componentInstance))i=i.componentInstance._vnode,i&&i.data&&(t=Xi(i.data,t));while(r(n=n.parent))n&&n.data&&(t=Xi(t,n.data));return Zi(t.staticClass,t.class)}function Xi(e,t){return{staticClass:Ji(e.staticClass,t.staticClass),class:r(e.class)?[e.class,t.class]:t.class}}function Zi(e,t){return r(e)||r(t)?Ji(e,Qi(t)):""}function Ji(e,t){return e?t?e+" "+t:e:t||""}function Qi(e){return Array.isArray(e)?er(e):l(e)?tr(e):"string"===typeof e?e:""}function er(e){for(var t,n="",i=0,o=e.length;i-1?sr[e]=t.constructor===window.HTMLUnknownElement||t.constructor===window.HTMLElement:sr[e]=/HTMLUnknownElement/.test(t.toString())}var cr=v("text,number,password,search,email,tel,url");function ur(e){if("string"===typeof e){var t=document.querySelector(e);return t||document.createElement("div")}return e}function dr(e,t){var n=document.createElement(e);return"select"!==e?n:(t.data&&t.data.attrs&&void 0!==t.data.attrs.multiple&&n.setAttribute("multiple","multiple"),n)}function hr(e,t){return document.createElementNS(nr[e],t)}function fr(e){return document.createTextNode(e)}function pr(e){return document.createComment(e)}function mr(e,t,n){e.insertBefore(t,n)}function vr(e,t){e.removeChild(t)}function gr(e,t){e.appendChild(t)}function br(e){return e.parentNode}function yr(e){return e.nextSibling}function _r(e){return e.tagName}function xr(e,t){e.textContent=t}function wr(e,t){e.setAttribute(t,"")}var Cr=Object.freeze({createElement:dr,createElementNS:hr,createTextNode:fr,createComment:pr,insertBefore:mr,removeChild:vr,appendChild:gr,parentNode:br,nextSibling:yr,tagName:_r,setTextContent:xr,setStyleScope:wr}),kr={create:function(e,t){Sr(t)},update:function(e,t){e.data.ref!==t.data.ref&&(Sr(e,!0),Sr(t))},destroy:function(e){Sr(e,!0)}};function Sr(e,t){var n=e.data.ref;if(r(n)){var i=e.context,o=e.componentInstance||e.elm,a=i.$refs;t?Array.isArray(a[n])?b(a[n],o):a[n]===o&&(a[n]=void 0):e.data.refInFor?Array.isArray(a[n])?a[n].indexOf(o)<0&&a[n].push(o):a[n]=[o]:a[n]=o}}var Or=new ye("",{},[]),$r=["create","activate","update","remove","destroy"];function Dr(e,t){return e.key===t.key&&(e.tag===t.tag&&e.isComment===t.isComment&&r(e.data)===r(t.data)&&Er(e,t)||o(e.isAsyncPlaceholder)&&e.asyncFactory===t.asyncFactory&&i(t.asyncFactory.error))}function Er(e,t){if("input"!==e.tag)return!0;var n,i=r(n=e.data)&&r(n=n.attrs)&&n.type,o=r(n=t.data)&&r(n=n.attrs)&&n.type;return i===o||cr(i)&&cr(o)}function Tr(e,t,n){var i,o,a={};for(i=t;i<=n;++i)o=e[i].key,r(o)&&(a[o]=i);return a}function Pr(e){var t,n,a={},l=e.modules,c=e.nodeOps;for(t=0;t<$r.length;++t)for(a[$r[t]]=[],n=0;nm?(d=i(n[b+1])?null:n[b+1].elm,C(e,d,n,p,b,o)):p>b&&S(e,t,h,m)}function D(e,t,n,i){for(var o=n;o-1?Rr(e,t,n):Wi(t)?Ki(n)?e.removeAttribute(t):(n="allowfullscreen"===t&&"EMBED"===e.tagName?"true":t,e.setAttribute(t,n)):Bi(t)?e.setAttribute(t,Hi(t,n)):Ui(t)?Ki(n)?e.removeAttributeNS(qi,Yi(t)):e.setAttributeNS(qi,t,n):Rr(e,t,n)}function Rr(e,t,n){if(Ki(n))e.removeAttribute(t);else{if(ee&&!te&&"TEXTAREA"===e.tagName&&"placeholder"===t&&""!==n&&!e.__ieph){var i=function(t){t.stopImmediatePropagation(),e.removeEventListener("input",i)};e.addEventListener("input",i),e.__ieph=!0}e.setAttribute(t,n)}}var Hr={create:zr,update:zr};function Wr(e,t){var n=t.elm,o=t.data,a=e.data;if(!(i(o.staticClass)&&i(o.class)&&(i(a)||i(a.staticClass)&&i(a.class)))){var s=Gi(t),l=n._transitionClasses;r(l)&&(s=Ji(s,Qi(l))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}var qr,Ur={create:Wr,update:Wr},Yr="__r",Kr="__c";function Gr(e){if(r(e[Yr])){var t=ee?"change":"input";e[t]=[].concat(e[Yr],e[t]||[]),delete e[Yr]}r(e[Kr])&&(e.change=[].concat(e[Kr],e.change||[]),delete e[Kr])}function Xr(e,t,n){var i=qr;return function r(){var o=t.apply(null,arguments);null!==o&&Qr(e,r,n,i)}}var Zr=at&&!(re&&Number(re[1])<=53);function Jr(e,t,n,i){if(Zr){var r=Yn,o=t;t=o._wrapper=function(e){if(e.target===e.currentTarget||e.timeStamp>=r||e.timeStamp<=0||e.target.ownerDocument!==document)return o.apply(this,arguments)}}qr.addEventListener(e,t,ae?{capture:n,passive:i}:n)}function Qr(e,t,n,i){(i||qr).removeEventListener(e,t._wrapper||t,n)}function eo(e,t){if(!i(e.data.on)||!i(t.data.on)){var n=t.data.on||{},r=e.data.on||{};qr=t.elm,Gr(n),_t(n,r,Jr,Qr,Xr,t.context),qr=void 0}}var to,no={create:eo,update:eo};function io(e,t){if(!i(e.data.domProps)||!i(t.data.domProps)){var n,o,a=t.elm,s=e.data.domProps||{},l=t.data.domProps||{};for(n in r(l.__ob__)&&(l=t.data.domProps=P({},l)),s)n in l||(a[n]="");for(n in l){if(o=l[n],"textContent"===n||"innerHTML"===n){if(t.children&&(t.children.length=0),o===s[n])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===n&&"PROGRESS"!==a.tagName){a._value=o;var c=i(o)?"":String(o);ro(a,c)&&(a.value=c)}else if("innerHTML"===n&&rr(a.tagName)&&i(a.innerHTML)){to=to||document.createElement("div"),to.innerHTML=""+o+"";var u=to.firstChild;while(a.firstChild)a.removeChild(a.firstChild);while(u.firstChild)a.appendChild(u.firstChild)}else if(o!==s[n])try{a[n]=o}catch(Ca){}}}}function ro(e,t){return!e.composing&&("OPTION"===e.tagName||oo(e,t)||ao(e,t))}function oo(e,t){var n=!0;try{n=document.activeElement!==e}catch(Ca){}return n&&e.value!==t}function ao(e,t){var n=e.value,i=e._vModifiers;if(r(i)){if(i.number)return m(n)!==m(t);if(i.trim)return n.trim()!==t.trim()}return n!==t}var so={create:io,update:io},lo=x((function(e){var t={},n=/;(?![^(]*\))/g,i=/:(.+)/;return e.split(n).forEach((function(e){if(e){var n=e.split(i);n.length>1&&(t[n[0].trim()]=n[1].trim())}})),t}));function co(e){var t=uo(e.style);return e.staticStyle?P(e.staticStyle,t):t}function uo(e){return Array.isArray(e)?M(e):"string"===typeof e?lo(e):e}function ho(e,t){var n,i={};if(t){var r=e;while(r.componentInstance)r=r.componentInstance._vnode,r&&r.data&&(n=co(r.data))&&P(i,n)}(n=co(e.data))&&P(i,n);var o=e;while(o=o.parent)o.data&&(n=co(o.data))&&P(i,n);return i}var fo,po=/^--/,mo=/\s*!important$/,vo=function(e,t,n){if(po.test(t))e.style.setProperty(t,n);else if(mo.test(n))e.style.setProperty(O(t),n.replace(mo,""),"important");else{var i=bo(t);if(Array.isArray(n))for(var r=0,o=n.length;r-1?t.split(xo).forEach((function(t){return e.classList.add(t)})):e.classList.add(t);else{var n=" "+(e.getAttribute("class")||"")+" ";n.indexOf(" "+t+" ")<0&&e.setAttribute("class",(n+t).trim())}}function Co(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(xo).forEach((function(t){return e.classList.remove(t)})):e.classList.remove(t),e.classList.length||e.removeAttribute("class");else{var n=" "+(e.getAttribute("class")||"")+" ",i=" "+t+" ";while(n.indexOf(i)>=0)n=n.replace(i," ");n=n.trim(),n?e.setAttribute("class",n):e.removeAttribute("class")}}function ko(e){if(e){if("object"===typeof e){var t={};return!1!==e.css&&P(t,So(e.name||"v")),P(t,e),t}return"string"===typeof e?So(e):void 0}}var So=x((function(e){return{enterClass:e+"-enter",enterToClass:e+"-enter-to",enterActiveClass:e+"-enter-active",leaveClass:e+"-leave",leaveToClass:e+"-leave-to",leaveActiveClass:e+"-leave-active"}})),Oo=X&&!te,$o="transition",Do="animation",Eo="transition",To="transitionend",Po="animation",Mo="animationend";Oo&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(Eo="WebkitTransition",To="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(Po="WebkitAnimation",Mo="webkitAnimationEnd"));var Io=X?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(e){return e()};function No(e){Io((function(){Io(e)}))}function jo(e,t){var n=e._transitionClasses||(e._transitionClasses=[]);n.indexOf(t)<0&&(n.push(t),wo(e,t))}function Ao(e,t){e._transitionClasses&&b(e._transitionClasses,t),Co(e,t)}function Fo(e,t,n){var i=Vo(e,t),r=i.type,o=i.timeout,a=i.propCount;if(!r)return n();var s=r===$o?To:Mo,l=0,c=function(){e.removeEventListener(s,u),n()},u=function(t){t.target===e&&++l>=a&&c()};setTimeout((function(){l0&&(n=$o,u=a,d=o.length):t===Do?c>0&&(n=Do,u=c,d=l.length):(u=Math.max(a,c),n=u>0?a>c?$o:Do:null,d=n?n===$o?o.length:l.length:0);var h=n===$o&&Lo.test(i[Eo+"Property"]);return{type:n,timeout:u,propCount:d,hasTransform:h}}function zo(e,t){while(e.length1}function Uo(e,t){!0!==t.data.show&&Ro(t)}var Yo=X?{create:Uo,activate:Uo,remove:function(e,t){!0!==e.data.show?Ho(e,t):t()}}:{},Ko=[Hr,Ur,no,so,_o,Yo],Go=Ko.concat(Vr),Xo=Pr({nodeOps:Cr,modules:Go});te&&document.addEventListener("selectionchange",(function(){var e=document.activeElement;e&&e.vmodel&&ra(e,"input")}));var Zo={inserted:function(e,t,n,i){"select"===n.tag?(i.elm&&!i.elm._vOptions?xt(n,"postpatch",(function(){Zo.componentUpdated(e,t,n)})):Jo(e,t,n.context),e._vOptions=[].map.call(e.options,ta)):("textarea"===n.tag||cr(e.type))&&(e._vModifiers=t.modifiers,t.modifiers.lazy||(e.addEventListener("compositionstart",na),e.addEventListener("compositionend",ia),e.addEventListener("change",ia),te&&(e.vmodel=!0)))},componentUpdated:function(e,t,n){if("select"===n.tag){Jo(e,t,n.context);var i=e._vOptions,r=e._vOptions=[].map.call(e.options,ta);if(r.some((function(e,t){return!A(e,i[t])}))){var o=e.multiple?t.value.some((function(e){return ea(e,r)})):t.value!==t.oldValue&&ea(t.value,r);o&&ra(e,"change")}}}};function Jo(e,t,n){Qo(e,t,n),(ee||ne)&&setTimeout((function(){Qo(e,t,n)}),0)}function Qo(e,t,n){var i=t.value,r=e.multiple;if(!r||Array.isArray(i)){for(var o,a,s=0,l=e.options.length;s-1,a.selected!==o&&(a.selected=o);else if(A(ta(a),i))return void(e.selectedIndex!==s&&(e.selectedIndex=s));r||(e.selectedIndex=-1)}}function ea(e,t){return t.every((function(t){return!A(t,e)}))}function ta(e){return"_value"in e?e._value:e.value}function na(e){e.target.composing=!0}function ia(e){e.target.composing&&(e.target.composing=!1,ra(e.target,"input"))}function ra(e,t){var n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)}function oa(e){return!e.componentInstance||e.data&&e.data.transition?e:oa(e.componentInstance._vnode)}var aa={bind:function(e,t,n){var i=t.value;n=oa(n);var r=n.data&&n.data.transition,o=e.__vOriginalDisplay="none"===e.style.display?"":e.style.display;i&&r?(n.data.show=!0,Ro(n,(function(){e.style.display=o}))):e.style.display=i?o:"none"},update:function(e,t,n){var i=t.value,r=t.oldValue;if(!i!==!r){n=oa(n);var o=n.data&&n.data.transition;o?(n.data.show=!0,i?Ro(n,(function(){e.style.display=e.__vOriginalDisplay})):Ho(n,(function(){e.style.display="none"}))):e.style.display=i?e.__vOriginalDisplay:"none"}},unbind:function(e,t,n,i,r){r||(e.style.display=e.__vOriginalDisplay)}},sa={model:Zo,show:aa},la={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function ca(e){var t=e&&e.componentOptions;return t&&t.Ctor.options.abstract?ca(Cn(t.children)):e}function ua(e){var t={},n=e.$options;for(var i in n.propsData)t[i]=e[i];var r=n._parentListeners;for(var o in r)t[C(o)]=r[o];return t}function da(e,t){if(/\d-keep-alive$/.test(t.tag))return e("keep-alive",{props:t.componentOptions.propsData})}function ha(e){while(e=e.parent)if(e.data.transition)return!0}function fa(e,t){return t.key===e.key&&t.tag===e.tag}var pa=function(e){return e.tag||wn(e)},ma=function(e){return"show"===e.name},va={name:"transition",props:la,abstract:!0,render:function(e){var t=this,n=this.$slots.default;if(n&&(n=n.filter(pa),n.length)){0;var i=this.mode;0;var r=n[0];if(ha(this.$vnode))return r;var o=ca(r);if(!o)return r;if(this._leaving)return da(e,r);var a="__transition-"+this._uid+"-";o.key=null==o.key?o.isComment?a+"comment":a+o.tag:s(o.key)?0===String(o.key).indexOf(a)?o.key:a+o.key:o.key;var l=(o.data||(o.data={})).transition=ua(this),c=this._vnode,u=ca(c);if(o.data.directives&&o.data.directives.some(ma)&&(o.data.show=!0),u&&u.data&&!fa(o,u)&&!wn(u)&&(!u.componentInstance||!u.componentInstance._vnode.isComment)){var d=u.data.transition=P({},l);if("out-in"===i)return this._leaving=!0,xt(d,"afterLeave",(function(){t._leaving=!1,t.$forceUpdate()})),da(e,r);if("in-out"===i){if(wn(o))return c;var h,f=function(){h()};xt(l,"afterEnter",f),xt(l,"enterCancelled",f),xt(d,"delayLeave",(function(e){h=e}))}}return r}}},ga=P({tag:String,moveClass:String},la);delete ga.mode;var ba={props:ga,beforeMount:function(){var e=this,t=this._update;this._update=function(n,i){var r=Pn(e);e.__patch__(e._vnode,e.kept,!1,!0),e._vnode=e.kept,r(),t.call(e,n,i)}},render:function(e){for(var t=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),i=this.prevChildren=this.children,r=this.$slots.default||[],o=this.children=[],a=ua(this),s=0;sn)t.push(arguments[n++]);return _[++y]=function(){("function"==typeof e?e:Function(e)).apply(void 0,t)},i(y),y},m=function(e){delete _[e]},"process"==l(v)?i=function(e){v.nextTick(C(e))}:b&&b.now?i=function(e){b.now(C(e))}:g&&!/(iphone|ipod|ipad).*applewebkit/i.test(h)?(r=new g,o=r.port2,r.port1.onmessage=k,i=c(o.postMessage,o,1)):!a.addEventListener||"function"!=typeof postMessage||a.importScripts||s(S)?i=x in d("script")?function(e){u.appendChild(d("script"))[x]=function(){u.removeChild(this),w(e)}}:function(e){setTimeout(C(e),0)}:(i=S,a.addEventListener("message",k,!1))),e.exports={set:p,clear:m}},"2d83":function(e,t,n){"use strict";var i=n("387f");e.exports=function(e,t,n,r,o){var a=new Error(e);return i(a,t,n,r,o)}},"2e67":function(e,t,n){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},"2f9a":function(e,t){e.exports=function(){}},"301c":function(e,t,n){n("e198")("asyncIterator")},"30b5":function(e,t,n){"use strict";var i=n("c532");function r(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}e.exports=function(e,t,n){if(!t)return e;var o;if(n)o=n(t);else if(i.isURLSearchParams(t))o=t.toString();else{var a=[];i.forEach(t,(function(e,t){null!==e&&"undefined"!==typeof e&&(i.isArray(e)?t+="[]":e=[e],i.forEach(e,(function(e){i.isDate(e)?e=e.toISOString():i.isObject(e)&&(e=JSON.stringify(e)),a.push(r(t)+"="+r(e))})))})),o=a.join("&")}return o&&(e+=(-1===e.indexOf("?")?"?":"&")+o),e}},3397:function(e,t,n){var i=n("7a41");e.exports=function(e,t){if(!i(e))return e;var n,r;if(t&&"function"==typeof(n=e.toString)&&!i(r=n.call(e)))return r;if("function"==typeof(n=e.valueOf)&&!i(r=n.call(e)))return r;if(!t&&"function"==typeof(n=e.toString)&&!i(r=n.call(e)))return r;throw TypeError("Can't convert object to primitive value")}},"35a1":function(e,t,n){var i=n("f5df"),r=n("3f8c"),o=n("b622"),a=o("iterator");e.exports=function(e){if(void 0!=e)return e[a]||e["@@iterator"]||r[i(e)]}},"37e8":function(e,t,n){var i=n("83ab"),r=n("9bf2"),o=n("825a"),a=n("df75");e.exports=i?Object.defineProperties:function(e,t){o(e);var n,i=a(t),s=i.length,l=0;while(s>l)r.f(e,n=i[l++],t[n]);return e}},"387f":function(e,t,n){"use strict";e.exports=function(e,t,n,i,r){return e.config=t,n&&(e.code=n),e.request=i,e.response=r,e}},3934:function(e,t,n){"use strict";var i=n("c532");e.exports=i.isStandardBrowserEnv()?function(){var e,t=/(msie|trident)/i.test(navigator.userAgent),n=document.createElement("a");function r(e){var i=e;return t&&(n.setAttribute("href",i),i=n.href),n.setAttribute("href",i),{href:n.href,protocol:n.protocol?n.protocol.replace(/:$/,""):"",host:n.host,search:n.search?n.search.replace(/^\?/,""):"",hash:n.hash?n.hash.replace(/^#/,""):"",hostname:n.hostname,port:n.port,pathname:"/"===n.pathname.charAt(0)?n.pathname:"/"+n.pathname}}return e=r(window.location.href),function(t){var n=i.isString(t)?r(t):t;return n.protocol===e.protocol&&n.host===e.host}}():function(){return function(){return!0}}()},"393a":function(e,t,n){"use strict";var i=n("e444"),r=n("512c"),o=n("ba01"),a=n("051b"),s=n("8a0d"),l=n("26dd"),c=n("92f0"),u=n("ce7a"),d=n("cc15")("iterator"),h=!([].keys&&"next"in[].keys()),f="@@iterator",p="keys",m="values",v=function(){return this};e.exports=function(e,t,n,g,b,y,_){l(n,t,g);var x,w,C,k=function(e){if(!h&&e in D)return D[e];switch(e){case p:return function(){return new n(this,e)};case m:return function(){return new n(this,e)}}return function(){return new n(this,e)}},S=t+" Iterator",O=b==m,$=!1,D=e.prototype,E=D[d]||D[f]||b&&D[b],T=E||k(b),P=b?O?k("entries"):T:void 0,M="Array"==t&&D.entries||E;if(M&&(C=u(M.call(new e)),C!==Object.prototype&&C.next&&(c(C,S,!0),i||"function"==typeof C[d]||a(C,d,v))),O&&E&&E.name!==m&&($=!0,T=function(){return E.call(this)}),i&&!_||!h&&!$&&D[d]||a(D,d,T),s[t]=T,s[S]=v,b)if(x={values:O?T:k(m),keys:y?T:k(p),entries:P},_)for(w in x)w in D||o(D,w,x[w]);else r(r.P+r.F*(h||$),t,x);return x}},"39ad":function(e,t,n){var i=n("6ca1"),r=n("d16a"),o=n("9d11");e.exports=function(e){return function(t,n,a){var s,l=i(t),c=r(l.length),u=o(a,c);if(e&&n!=n){while(c>u)if(s=l[u++],s!=s)return!0}else for(;c>u;u++)if((e||u in l)&&l[u]===n)return e||u||0;return!e&&-1}}},"3bbe":function(e,t,n){var i=n("861d");e.exports=function(e){if(!i(e)&&null!==e)throw TypeError("Can't set "+String(e)+" as a prototype");return e}},"3c4e":function(e,t,n){"use strict";var i=function(e){return r(e)&&!o(e)};function r(e){return!!e&&"object"===typeof e}function o(e){var t=Object.prototype.toString.call(e);return"[object RegExp]"===t||"[object Date]"===t||l(e)}var a="function"===typeof Symbol&&Symbol.for,s=a?Symbol.for("react.element"):60103;function l(e){return e.$$typeof===s}function c(e){return Array.isArray(e)?[]:{}}function u(e,t){var n=t&&!0===t.clone;return n&&i(e)?f(c(e),e,t):e}function d(e,t,n){var r=e.slice();return t.forEach((function(t,o){"undefined"===typeof r[o]?r[o]=u(t,n):i(t)?r[o]=f(e[o],t,n):-1===e.indexOf(t)&&r.push(u(t,n))})),r}function h(e,t,n){var r={};return i(e)&&Object.keys(e).forEach((function(t){r[t]=u(e[t],n)})),Object.keys(t).forEach((function(o){i(t[o])&&e[o]?r[o]=f(e[o],t[o],n):r[o]=u(t[o],n)})),r}function f(e,t,n){var i=Array.isArray(t),r=Array.isArray(e),o=n||{arrayMerge:d},a=i===r;if(a){if(i){var s=o.arrayMerge||d;return s(e,t,n)}return h(e,t,n)}return u(t,n)}f.all=function(e,t){if(!Array.isArray(e)||e.length<2)throw new Error("first argument should be an array with at least two elements");return e.reduce((function(e,n){return f(e,n,t)}))};var p=f;e.exports=p},"3f6b":function(e,t,n){e.exports={default:n("b9c7"),__esModule:!0}},"3f8c":function(e,t){e.exports={}},4010:function(e,t,n){"use strict";t.__esModule=!0,t.removeResizeListener=t.addResizeListener=void 0;var i=n("6dd8"),r=o(i);function o(e){return e&&e.__esModule?e:{default:e}}var a="undefined"===typeof window,s=function(e){var t=e,n=Array.isArray(t),i=0;for(t=n?t:t[Symbol.iterator]();;){var r;if(n){if(i>=t.length)break;r=t[i++]}else{if(i=t.next(),i.done)break;r=i.value}var o=r,a=o.target.__resizeListeners__||[];a.length&&a.forEach((function(e){e()}))}};t.addResizeListener=function(e,t){a||(e.__resizeListeners__||(e.__resizeListeners__=[],e.__ro__=new r.default(s),e.__ro__.observe(e)),e.__resizeListeners__.push(t))},t.removeResizeListener=function(e,t){e&&e.__resizeListeners__&&(e.__resizeListeners__.splice(e.__resizeListeners__.indexOf(t),1),e.__resizeListeners__.length||e.__ro__.disconnect())}},"417f":function(e,t,n){"use strict";t.__esModule=!0;var i=n("2b0e"),r=a(i),o=n("5924");function a(e){return e&&e.__esModule?e:{default:e}}var s=[],l="@@clickoutsideContext",c=void 0,u=0;function d(e,t,n){return function(){var i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};!(n&&n.context&&i.target&&r.target)||e.contains(i.target)||e.contains(r.target)||e===i.target||n.context.popperElm&&(n.context.popperElm.contains(i.target)||n.context.popperElm.contains(r.target))||(t.expression&&e[l].methodName&&n.context[e[l].methodName]?n.context[e[l].methodName]():e[l].bindingFn&&e[l].bindingFn())}}!r.default.prototype.$isServer&&(0,o.on)(document,"mousedown",(function(e){return c=e})),!r.default.prototype.$isServer&&(0,o.on)(document,"mouseup",(function(e){s.forEach((function(t){return t[l].documentHandler(e,c)}))})),t.default={bind:function(e,t,n){s.push(e);var i=u++;e[l]={id:i,documentHandler:d(e,t,n),methodName:t.expression,bindingFn:t.value}},update:function(e,t,n){e[l].documentHandler=d(e,t,n),e[l].methodName=t.expression,e[l].bindingFn=t.value},unbind:function(e){for(var t=s.length,n=0;n\n \n '}else n||(this.hoverTimer=setTimeout(this.clearHoverZone,this.panel.config.hoverThreshold))},clearHoverZone:function(){var e=this.$refs.hoverZone;e&&(e.innerHTML="")},renderEmptyText:function(e){return e("div",{class:"el-cascader-menu__empty-text"},[this.t("el.cascader.noData")])},renderNodeList:function(e){var t=this.menuId,n=this.panel.isHoverMenu,i={on:{}};n&&(i.on.expand=this.handleExpand);var r=this.nodes.map((function(n,r){var o=n.hasChildren;return e("cascader-node",l()([{key:n.uid,attrs:{node:n,"node-id":t+"-"+r,"aria-haspopup":o,"aria-owns":o?t:null}},i]))}));return[].concat(r,[n?e("svg",{ref:"hoverZone",class:"el-cascader-menu__hover-zone"}):null])}},render:function(e){var t=this.isEmpty,n=this.menuId,i={nativeOn:{}};return this.panel.isHoverMenu&&(i.nativeOn.mousemove=this.handleMouseMove),e("el-scrollbar",l()([{attrs:{tag:"ul",role:"menu",id:n,"wrap-class":"el-cascader-menu__wrap","view-class":{"el-cascader-menu__list":!0,"is-empty":t}},class:"el-cascader-menu"},i]),[t?this.renderEmptyText(e):this.renderNodeList(e)])}},$=O,D=Object(y["a"])($,x,w,!1,null,null,null);D.options.__file="packages/cascader-panel/src/cascader-menu.vue";var E=D.exports,T=n(21),P=function(){function e(e,t){for(var n=0;n1?t-1:0),i=1;i1?i-1:0),o=1;o0},e.prototype.syncCheckState=function(e){var t=this.getValueByOption(),n=this.isSameNode(e,t);this.doCheck(n)},e.prototype.doCheck=function(e){this.checked!==e&&(this.config.checkStrictly?this.checked=e:(this.broadcast("check",e),this.setCheckState(e),this.emit("check")))},P(e,[{key:"isDisabled",get:function(){var e=this.data,t=this.parent,n=this.config,i=n.disabled,r=n.checkStrictly;return e[i]||!r&&t&&t.isDisabled}},{key:"isLeaf",get:function(){var e=this.data,t=this.loaded,n=this.hasChildren,i=this.children,r=this.config,o=r.lazy,a=r.leaf;if(o){var s=Object(T["isDef"])(e[a])?e[a]:!!t&&!i.length;return this.hasChildren=!s,s}return!n}}]),e}(),j=N;function A(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var F=function e(t,n){return t.reduce((function(t,i){return i.isLeaf?t.push(i):(!n&&t.push(i),t=t.concat(e(i.children,n))),t}),[])},L=function(){function e(t,n){A(this,e),this.config=n,this.initNodes(t)}return e.prototype.initNodes=function(e){var t=this;e=Object(m["coerceTruthyValueToArray"])(e),this.nodes=e.map((function(e){return new j(e,t.config)})),this.flattedNodes=this.getFlattedNodes(!1,!1),this.leafNodes=this.getFlattedNodes(!0,!1)},e.prototype.appendNode=function(e,t){var n=new j(e,this.config,t),i=t?t.children:this.nodes;i.push(n)},e.prototype.appendNodes=function(e,t){var n=this;e=Object(m["coerceTruthyValueToArray"])(e),e.forEach((function(e){return n.appendNode(e,t)}))},e.prototype.getNodes=function(){return this.nodes},e.prototype.getFlattedNodes=function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=e?this.leafNodes:this.flattedNodes;return t?n:F(this.nodes,e)},e.prototype.getNodeByValue=function(e){if(e){var t=this.getFlattedNodes(!1,!this.config.lazy).filter((function(t){return Object(m["valueEquals"])(t.path,e)||t.value===e}));return t&&t.length?t[0]:null}return null},e}(),V=L,z=n(9),B=n.n(z),R=n(39),H=n.n(R),W=n(31),q=n.n(W),U=Object.assign||function(e){for(var t=1;t0){var l=n.store.getNodeByValue(o);l.data[s]||n.lazyLoad(l,(function(){n.handleExpand(l)})),n.loadCount===n.checkedValue.length&&n.$parent.computePresentText()}}t&&t(i)};i.lazyLoad(e,r)},calculateMultiCheckedValue:function(){this.checkedValue=this.getCheckedNodes(this.leafOnly).map((function(e){return e.getValueByOption()}))},scrollIntoView:function(){if(!this.$isServer){var e=this.$refs.menu||[];e.forEach((function(e){var t=e.$el;if(t){var n=t.querySelector(".el-scrollbar__wrap"),i=t.querySelector(".el-cascader-node.is-active")||t.querySelector(".el-cascader-node.in-active-path");q()(n,i)}}))}},getNodeByValue:function(e){return this.store.getNodeByValue(e)},getFlattedNodes:function(e){var t=!this.config.lazy;return this.store.getFlattedNodes(e,t)},getCheckedNodes:function(e){var t=this.checkedValue,n=this.multiple;if(n){var i=this.getFlattedNodes(e);return i.filter((function(e){return e.checked}))}return Object(m["isEmpty"])(t)?[]:[this.getNodeByValue(t)]},clearCheckedNodes:function(){var e=this.config,t=this.leafOnly,n=e.multiple,i=e.emitPath;n?(this.getCheckedNodes(t).filter((function(e){return!e.isDisabled})).forEach((function(e){return e.doCheck(!1)})),this.calculateMultiCheckedValue()):this.checkedValue=i?[]:null}}},te=ee,ne=Object(y["a"])(te,i,r,!1,null,null,null);ne.options.__file="packages/cascader-panel/src/cascader-panel.vue";var ie=ne.exports;ie.install=function(e){e.component(ie.name,ie)};t["default"]=ie},6:function(e,t){e.exports=n("6b7c")},9:function(e,t){e.exports=n("7f4d")}})},4840:function(e,t,n){var i=n("825a"),r=n("1c0b"),o=n("b622"),a=o("species");e.exports=function(e,t){var n,o=i(e).constructor;return void 0===o||void 0==(n=i(o)[a])?t:r(n)}},4897:function(e,t,n){"use strict";t.__esModule=!0,t.i18n=t.use=t.t=void 0;var i=n("f0d9"),r=d(i),o=n("2b0e"),a=d(o),s=n("3c4e"),l=d(s),c=n("9d7e"),u=d(c);function d(e){return e&&e.__esModule?e:{default:e}}var h=(0,u.default)(a.default),f=r.default,p=!1,m=function(){var e=Object.getPrototypeOf(this||a.default).$t;if("function"===typeof e&&a.default.locale)return p||(p=!0,a.default.locale(a.default.config.lang,(0,l.default)(f,a.default.locale(a.default.config.lang)||{},{clone:!0}))),e.apply(this,arguments)},v=t.t=function(e,t){var n=m.apply(this,arguments);if(null!==n&&void 0!==n)return n;for(var i=e.split("."),r=f,o=0,a=i.length;o0){var i=t[t.length-1];if(i.id===e){if(i.modalClass){var r=i.modalClass.trim().split(/\s+/);r.forEach((function(e){return(0,o.removeClass)(n,e)}))}t.pop(),t.length>0&&(n.style.zIndex=t[t.length-1].zIndex)}else for(var a=t.length-1;a>=0;a--)if(t[a].id===e){t.splice(a,1);break}}0===t.length&&(this.modalFade&&(0,o.addClass)(n,"v-modal-leave"),setTimeout((function(){0===t.length&&(n.parentNode&&n.parentNode.removeChild(n),n.style.display="none",h.modalDom=void 0),(0,o.removeClass)(n,"v-modal-leave")}),200))}};Object.defineProperty(h,"zIndex",{configurable:!0,get:function(){return l||(c=c||(r.default.prototype.$ELEMENT||{}).zIndex||2e3,l=!0),c},set:function(e){c=e}});var f=function(){if(!r.default.prototype.$isServer&&h.modalStack.length>0){var e=h.modalStack[h.modalStack.length-1];if(!e)return;var t=h.getInstance(e.id);return t}};r.default.prototype.$isServer||window.addEventListener("keydown",(function(e){if(27===e.keyCode){var t=f();t&&t.closeOnPressEscape&&(t.handleClose?t.handleClose():t.handleAction?t.handleAction("cancel"):t.close())}})),t.default=h},"4b8b":function(e,t){e.exports=function(e){try{return!!e()}catch(t){return!0}}},"4d20":function(e,t,n){var i=n("1917"),r=n("10db"),o=n("6ca1"),a=n("3397"),s=n("9c0e"),l=n("faf5"),c=Object.getOwnPropertyDescriptor;t.f=n("0bad")?c:function(e,t){if(e=o(e),t=a(t,!0),l)try{return c(e,t)}catch(n){}if(s(e,t))return r(!i.f.call(e,t),e[t])}},"4d64":function(e,t,n){var i=n("fc6a"),r=n("50c4"),o=n("23cb"),a=function(e){return function(t,n,a){var s,l=i(t),c=r(l.length),u=o(a,c);if(e&&n!=n){while(c>u)if(s=l[u++],s!=s)return!0}else for(;c>u;u++)if((e||u in l)&&l[u]===n)return e||u||0;return!e&&-1}};e.exports={includes:a(!0),indexOf:a(!1)}},"4d88":function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},"4e4b":function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=60)}([function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},,,function(e,t){e.exports=n("8122")},function(e,t){e.exports=n("d010")},function(e,t){e.exports=n("e974")},function(e,t){e.exports=n("6b7c")},,,,,function(e,t){e.exports=n("f3ad")},function(e,t){e.exports=n("417f")},function(e,t){e.exports=n("14e9")},,function(e,t){e.exports=n("4010")},function(e,t){e.exports=n("0e15")},,,,function(e,t){e.exports=n("4897")},function(e,t){e.exports=n("d397")},function(e,t){e.exports=n("12f2")},,,,,,,,,function(e,t){e.exports=n("2a5e")},,function(e,t,n){"use strict";var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-select-dropdown__item",class:{selected:e.itemSelected,"is-disabled":e.disabled||e.groupDisabled||e.limitReached,hover:e.hover},on:{mouseenter:e.hoverItem,click:function(t){return t.stopPropagation(),e.selectOptionClick(t)}}},[e._t("default",[n("span",[e._v(e._s(e.currentLabel))])])],2)},r=[];i._withStripped=!0;var o=n(4),a=n.n(o),s=n(3),l="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c={mixins:[a.a],name:"ElOption",componentName:"ElOption",inject:["select"],props:{value:{required:!0},label:[String,Number],created:Boolean,disabled:{type:Boolean,default:!1}},data:function(){return{index:-1,groupDisabled:!1,visible:!0,hitState:!1,hover:!1}},computed:{isObject:function(){return"[object object]"===Object.prototype.toString.call(this.value).toLowerCase()},currentLabel:function(){return this.label||(this.isObject?"":this.value)},currentValue:function(){return this.value||this.label||""},itemSelected:function(){return this.select.multiple?this.contains(this.select.value,this.value):this.isEqual(this.value,this.select.value)},limitReached:function(){return!!this.select.multiple&&(!this.itemSelected&&(this.select.value||[]).length>=this.select.multipleLimit&&this.select.multipleLimit>0)}},watch:{currentLabel:function(){this.created||this.select.remote||this.dispatch("ElSelect","setSelected")},value:function(e,t){var n=this.select,i=n.remote,r=n.valueKey;if(!this.created&&!i){if(r&&"object"===("undefined"===typeof e?"undefined":l(e))&&"object"===("undefined"===typeof t?"undefined":l(t))&&e[r]===t[r])return;this.dispatch("ElSelect","setSelected")}}},methods:{isEqual:function(e,t){if(this.isObject){var n=this.select.valueKey;return Object(s["getValueByPath"])(e,n)===Object(s["getValueByPath"])(t,n)}return e===t},contains:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1];if(this.isObject){var n=this.select.valueKey;return e&&e.some((function(e){return Object(s["getValueByPath"])(e,n)===Object(s["getValueByPath"])(t,n)}))}return e&&e.indexOf(t)>-1},handleGroupDisabled:function(e){this.groupDisabled=e},hoverItem:function(){this.disabled||this.groupDisabled||(this.select.hoverIndex=this.select.options.indexOf(this))},selectOptionClick:function(){!0!==this.disabled&&!0!==this.groupDisabled&&this.dispatch("ElSelect","handleOptionClick",[this,!0])},queryChange:function(e){this.visible=new RegExp(Object(s["escapeRegexpString"])(e),"i").test(this.currentLabel)||this.created,this.visible||this.select.filteredOptionsCount--}},created:function(){this.select.options.push(this),this.select.cachedOptions.push(this),this.select.optionsCount++,this.select.filteredOptionsCount++,this.$on("queryChange",this.queryChange),this.$on("handleGroupDisabled",this.handleGroupDisabled)},beforeDestroy:function(){var e=this.select.cachedOptions.indexOf(this);e>-1&&this.select.cachedOptions.splice(e,1),this.select.onOptionDestroy(this.select.options.indexOf(this))}},u=c,d=n(0),h=Object(d["a"])(u,i,r,!1,null,null,null);h.options.__file="packages/select/src/option.vue";t["a"]=h.exports},,,function(e,t){e.exports=n("8bbc")},,,,,,,,,,,,,,,,,,,,,,,,function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleClose,expression:"handleClose"}],staticClass:"el-select",class:[e.selectSize?"el-select--"+e.selectSize:""],on:{click:function(t){return t.stopPropagation(),e.toggleMenu(t)}}},[e.multiple?n("div",{ref:"tags",staticClass:"el-select__tags",style:{"max-width":e.inputWidth-32+"px",width:"100%"}},[e.collapseTags&&e.selected.length?n("span",[n("el-tag",{attrs:{closable:!e.selectDisabled,size:e.collapseTagSize,hit:e.selected[0].hitState,type:"info","disable-transitions":""},on:{close:function(t){e.deleteTag(t,e.selected[0])}}},[n("span",{staticClass:"el-select__tags-text"},[e._v(e._s(e.selected[0].currentLabel))])]),e.selected.length>1?n("el-tag",{attrs:{closable:!1,size:e.collapseTagSize,type:"info","disable-transitions":""}},[n("span",{staticClass:"el-select__tags-text"},[e._v("+ "+e._s(e.selected.length-1))])]):e._e()],1):e._e(),e.collapseTags?e._e():n("transition-group",{on:{"after-leave":e.resetInputHeight}},e._l(e.selected,(function(t){return n("el-tag",{key:e.getValueKey(t),attrs:{closable:!e.selectDisabled,size:e.collapseTagSize,hit:t.hitState,type:"info","disable-transitions":""},on:{close:function(n){e.deleteTag(n,t)}}},[n("span",{staticClass:"el-select__tags-text"},[e._v(e._s(t.currentLabel))])])})),1),e.filterable?n("input",{directives:[{name:"model",rawName:"v-model",value:e.query,expression:"query"}],ref:"input",staticClass:"el-select__input",class:[e.selectSize?"is-"+e.selectSize:""],style:{"flex-grow":"1",width:e.inputLength/(e.inputWidth-32)+"%","max-width":e.inputWidth-42+"px"},attrs:{type:"text",disabled:e.selectDisabled,autocomplete:e.autoComplete||e.autocomplete},domProps:{value:e.query},on:{focus:e.handleFocus,blur:function(t){e.softFocus=!1},keyup:e.managePlaceholder,keydown:[e.resetInputState,function(t){if(!("button"in t)&&e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"]))return null;t.preventDefault(),e.navigateOptions("next")},function(t){if(!("button"in t)&&e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"]))return null;t.preventDefault(),e.navigateOptions("prev")},function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?(t.preventDefault(),e.selectOption(t)):null},function(t){if(!("button"in t)&&e._k(t.keyCode,"esc",27,t.key,["Esc","Escape"]))return null;t.stopPropagation(),t.preventDefault(),e.visible=!1},function(t){return"button"in t||!e._k(t.keyCode,"delete",[8,46],t.key,["Backspace","Delete","Del"])?e.deletePrevTag(t):null},function(t){if(!("button"in t)&&e._k(t.keyCode,"tab",9,t.key,"Tab"))return null;e.visible=!1}],compositionstart:e.handleComposition,compositionupdate:e.handleComposition,compositionend:e.handleComposition,input:[function(t){t.target.composing||(e.query=t.target.value)},e.debouncedQueryChange]}}):e._e()],1):e._e(),n("el-input",{ref:"reference",class:{"is-focus":e.visible},attrs:{type:"text",placeholder:e.currentPlaceholder,name:e.name,id:e.id,autocomplete:e.autoComplete||e.autocomplete,size:e.selectSize,disabled:e.selectDisabled,readonly:e.readonly,"validate-event":!1,tabindex:e.multiple&&e.filterable?"-1":null},on:{focus:e.handleFocus,blur:e.handleBlur},nativeOn:{keyup:function(t){return e.debouncedOnInputChange(t)},keydown:[function(t){if(!("button"in t)&&e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"]))return null;t.stopPropagation(),t.preventDefault(),e.navigateOptions("next")},function(t){if(!("button"in t)&&e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"]))return null;t.stopPropagation(),t.preventDefault(),e.navigateOptions("prev")},function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?(t.preventDefault(),e.selectOption(t)):null},function(t){if(!("button"in t)&&e._k(t.keyCode,"esc",27,t.key,["Esc","Escape"]))return null;t.stopPropagation(),t.preventDefault(),e.visible=!1},function(t){if(!("button"in t)&&e._k(t.keyCode,"tab",9,t.key,"Tab"))return null;e.visible=!1}],paste:function(t){return e.debouncedOnInputChange(t)},mouseenter:function(t){e.inputHovering=!0},mouseleave:function(t){e.inputHovering=!1}},model:{value:e.selectedLabel,callback:function(t){e.selectedLabel=t},expression:"selectedLabel"}},[e.$slots.prefix?n("template",{slot:"prefix"},[e._t("prefix")],2):e._e(),n("template",{slot:"suffix"},[n("i",{directives:[{name:"show",rawName:"v-show",value:!e.showClose,expression:"!showClose"}],class:["el-select__caret","el-input__icon","el-icon-"+e.iconClass]}),e.showClose?n("i",{staticClass:"el-select__caret el-input__icon el-icon-circle-close",on:{click:e.handleClearClick}}):e._e()])],2),n("transition",{attrs:{name:"el-zoom-in-top"},on:{"before-enter":e.handleMenuEnter,"after-leave":e.doDestroy}},[n("el-select-menu",{directives:[{name:"show",rawName:"v-show",value:e.visible&&!1!==e.emptyText,expression:"visible && emptyText !== false"}],ref:"popper",attrs:{"append-to-body":e.popperAppendToBody}},[n("el-scrollbar",{directives:[{name:"show",rawName:"v-show",value:e.options.length>0&&!e.loading,expression:"options.length > 0 && !loading"}],ref:"scrollbar",class:{"is-empty":!e.allowCreate&&e.query&&0===e.filteredOptionsCount},attrs:{tag:"ul","wrap-class":"el-select-dropdown__wrap","view-class":"el-select-dropdown__list"}},[e.showNewOption?n("el-option",{attrs:{value:e.query,created:""}}):e._e(),e._t("default")],2),e.emptyText&&(!e.allowCreate||e.loading||e.allowCreate&&0===e.options.length)?[e.$slots.empty?e._t("empty"):n("p",{staticClass:"el-select-dropdown__empty"},[e._v("\n "+e._s(e.emptyText)+"\n ")])]:e._e()],2)],1)],1)},r=[];i._withStripped=!0;var o=n(4),a=n.n(o),s=n(22),l=n.n(s),c=n(6),u=n.n(c),d=n(11),h=n.n(d),f=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-select-dropdown el-popper",class:[{"is-multiple":e.$parent.multiple},e.popperClass],style:{minWidth:e.minWidth}},[e._t("default")],2)},p=[];f._withStripped=!0;var m=n(5),v=n.n(m),g={name:"ElSelectDropdown",componentName:"ElSelectDropdown",mixins:[v.a],props:{placement:{default:"bottom-start"},boundariesPadding:{default:0},popperOptions:{default:function(){return{gpuAcceleration:!1}}},visibleArrow:{default:!0},appendToBody:{type:Boolean,default:!0}},data:function(){return{minWidth:""}},computed:{popperClass:function(){return this.$parent.popperClass}},watch:{"$parent.inputWidth":function(){this.minWidth=this.$parent.$el.getBoundingClientRect().width+"px"}},mounted:function(){var e=this;this.referenceElm=this.$parent.$refs.reference.$el,this.$parent.popperElm=this.popperElm=this.$el,this.$on("updatePopper",(function(){e.$parent.visible&&e.updatePopper()})),this.$on("destroyPopper",this.destroyPopper)}},b=g,y=n(0),_=Object(y["a"])(b,f,p,!1,null,null,null);_.options.__file="packages/select/src/select-dropdown.vue";var x=_.exports,w=n(33),C=n(36),k=n.n(C),S=n(13),O=n.n(S),$=n(16),D=n.n($),E=n(12),T=n.n(E),P=n(15),M=n(20),I=n(31),N=n.n(I),j=n(3),A={data:function(){return{hoverOption:-1}},computed:{optionsAllDisabled:function(){return this.options.filter((function(e){return e.visible})).every((function(e){return e.disabled}))}},watch:{hoverIndex:function(e){var t=this;"number"===typeof e&&e>-1&&(this.hoverOption=this.options[e]||{}),this.options.forEach((function(e){e.hover=t.hoverOption===e}))}},methods:{navigateOptions:function(e){var t=this;if(this.visible){if(0!==this.options.length&&0!==this.filteredOptionsCount&&!this.optionsAllDisabled){"next"===e?(this.hoverIndex++,this.hoverIndex===this.options.length&&(this.hoverIndex=0)):"prev"===e&&(this.hoverIndex--,this.hoverIndex<0&&(this.hoverIndex=this.options.length-1));var n=this.options[this.hoverIndex];!0!==n.disabled&&!0!==n.groupDisabled&&n.visible||this.navigateOptions(e),this.$nextTick((function(){return t.scrollToOption(t.hoverOption)}))}}else this.visible=!0}}},F=n(21),L={mixins:[a.a,u.a,l()("reference"),A],name:"ElSelect",componentName:"ElSelect",inject:{elForm:{default:""},elFormItem:{default:""}},provide:function(){return{select:this}},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},readonly:function(){return!this.filterable||this.multiple||!Object(j["isIE"])()&&!Object(j["isEdge"])()&&!this.visible},showClose:function(){var e=this.multiple?Array.isArray(this.value)&&this.value.length>0:void 0!==this.value&&null!==this.value&&""!==this.value,t=this.clearable&&!this.selectDisabled&&this.inputHovering&&e;return t},iconClass:function(){return this.remote&&this.filterable?"":this.visible?"arrow-up is-reverse":"arrow-up"},debounce:function(){return this.remote?300:0},emptyText:function(){return this.loading?this.loadingText||this.t("el.select.loading"):(!this.remote||""!==this.query||0!==this.options.length)&&(this.filterable&&this.query&&this.options.length>0&&0===this.filteredOptionsCount?this.noMatchText||this.t("el.select.noMatch"):0===this.options.length?this.noDataText||this.t("el.select.noData"):null)},showNewOption:function(){var e=this,t=this.options.filter((function(e){return!e.created})).some((function(t){return t.currentLabel===e.query}));return this.filterable&&this.allowCreate&&""!==this.query&&!t},selectSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},selectDisabled:function(){return this.disabled||(this.elForm||{}).disabled},collapseTagSize:function(){return["small","mini"].indexOf(this.selectSize)>-1?"mini":"small"}},components:{ElInput:h.a,ElSelectMenu:x,ElOption:w["a"],ElTag:k.a,ElScrollbar:O.a},directives:{Clickoutside:T.a},props:{name:String,id:String,value:{required:!0},autocomplete:{type:String,default:"off"},autoComplete:{type:String,validator:function(e){return!0}},automaticDropdown:Boolean,size:String,disabled:Boolean,clearable:Boolean,filterable:Boolean,allowCreate:Boolean,loading:Boolean,popperClass:String,remote:Boolean,loadingText:String,noMatchText:String,noDataText:String,remoteMethod:Function,filterMethod:Function,multiple:Boolean,multipleLimit:{type:Number,default:0},placeholder:{type:String,default:function(){return Object(M["t"])("el.select.placeholder")}},defaultFirstOption:Boolean,reserveKeyword:Boolean,valueKey:{type:String,default:"value"},collapseTags:Boolean,popperAppendToBody:{type:Boolean,default:!0}},data:function(){return{options:[],cachedOptions:[],createdLabel:null,createdSelected:!1,selected:this.multiple?[]:{},inputLength:20,inputWidth:0,initialInputHeight:0,cachedPlaceHolder:"",optionsCount:0,filteredOptionsCount:0,visible:!1,softFocus:!1,selectedLabel:"",hoverIndex:-1,query:"",previousQuery:null,inputHovering:!1,currentPlaceholder:"",menuVisibleOnFocus:!1,isOnComposition:!1,isSilentBlur:!1}},watch:{selectDisabled:function(){var e=this;this.$nextTick((function(){e.resetInputHeight()}))},placeholder:function(e){this.cachedPlaceHolder=this.currentPlaceholder=e},value:function(e,t){this.multiple&&(this.resetInputHeight(),e&&e.length>0||this.$refs.input&&""!==this.query?this.currentPlaceholder="":this.currentPlaceholder=this.cachedPlaceHolder,this.filterable&&!this.reserveKeyword&&(this.query="",this.handleQueryChange(this.query))),this.setSelected(),this.filterable&&!this.multiple&&(this.inputLength=20),Object(j["valueEquals"])(e,t)||this.dispatch("ElFormItem","el.form.change",e)},visible:function(e){var t=this;e?(this.broadcast("ElSelectDropdown","updatePopper"),this.filterable&&(this.query=this.remote?"":this.selectedLabel,this.handleQueryChange(this.query),this.multiple?this.$refs.input.focus():(this.remote||(this.broadcast("ElOption","queryChange",""),this.broadcast("ElOptionGroup","queryChange")),this.selectedLabel&&(this.currentPlaceholder=this.selectedLabel,this.selectedLabel="")))):(this.broadcast("ElSelectDropdown","destroyPopper"),this.$refs.input&&this.$refs.input.blur(),this.query="",this.previousQuery=null,this.selectedLabel="",this.inputLength=20,this.menuVisibleOnFocus=!1,this.resetHoverIndex(),this.$nextTick((function(){t.$refs.input&&""===t.$refs.input.value&&0===t.selected.length&&(t.currentPlaceholder=t.cachedPlaceHolder)})),this.multiple||(this.selected&&(this.filterable&&this.allowCreate&&this.createdSelected&&this.createdLabel?this.selectedLabel=this.createdLabel:this.selectedLabel=this.selected.currentLabel,this.filterable&&(this.query=this.selectedLabel)),this.filterable&&(this.currentPlaceholder=this.cachedPlaceHolder))),this.$emit("visible-change",e)},options:function(){var e=this;if(!this.$isServer){this.$nextTick((function(){e.broadcast("ElSelectDropdown","updatePopper")})),this.multiple&&this.resetInputHeight();var t=this.$el.querySelectorAll("input");-1===[].indexOf.call(t,document.activeElement)&&this.setSelected(),this.defaultFirstOption&&(this.filterable||this.remote)&&this.filteredOptionsCount&&this.checkDefaultFirstOption()}}},methods:{handleComposition:function(e){var t=this,n=e.target.value;if("compositionend"===e.type)this.isOnComposition=!1,this.$nextTick((function(e){return t.handleQueryChange(n)}));else{var i=n[n.length-1]||"";this.isOnComposition=!Object(F["isKorean"])(i)}},handleQueryChange:function(e){var t=this;this.previousQuery===e||this.isOnComposition||(null!==this.previousQuery||"function"!==typeof this.filterMethod&&"function"!==typeof this.remoteMethod?(this.previousQuery=e,this.$nextTick((function(){t.visible&&t.broadcast("ElSelectDropdown","updatePopper")})),this.hoverIndex=-1,this.multiple&&this.filterable&&this.$nextTick((function(){var e=15*t.$refs.input.value.length+20;t.inputLength=t.collapseTags?Math.min(50,e):e,t.managePlaceholder(),t.resetInputHeight()})),this.remote&&"function"===typeof this.remoteMethod?(this.hoverIndex=-1,this.remoteMethod(e)):"function"===typeof this.filterMethod?(this.filterMethod(e),this.broadcast("ElOptionGroup","queryChange")):(this.filteredOptionsCount=this.optionsCount,this.broadcast("ElOption","queryChange",e),this.broadcast("ElOptionGroup","queryChange")),this.defaultFirstOption&&(this.filterable||this.remote)&&this.filteredOptionsCount&&this.checkDefaultFirstOption()):this.previousQuery=e)},scrollToOption:function(e){var t=Array.isArray(e)&&e[0]?e[0].$el:e.$el;if(this.$refs.popper&&t){var n=this.$refs.popper.$el.querySelector(".el-select-dropdown__wrap");N()(n,t)}this.$refs.scrollbar&&this.$refs.scrollbar.handleScroll()},handleMenuEnter:function(){var e=this;this.$nextTick((function(){return e.scrollToOption(e.selected)}))},emitChange:function(e){Object(j["valueEquals"])(this.value,e)||this.$emit("change",e)},getOption:function(e){for(var t=void 0,n="[object object]"===Object.prototype.toString.call(e).toLowerCase(),i="[object null]"===Object.prototype.toString.call(e).toLowerCase(),r="[object undefined]"===Object.prototype.toString.call(e).toLowerCase(),o=this.cachedOptions.length-1;o>=0;o--){var a=this.cachedOptions[o],s=n?Object(j["getValueByPath"])(a.value,this.valueKey)===Object(j["getValueByPath"])(e,this.valueKey):a.value===e;if(s){t=a;break}}if(t)return t;var l=n||i||r?"":e,c={value:e,currentLabel:l};return this.multiple&&(c.hitState=!1),c},setSelected:function(){var e=this;if(!this.multiple){var t=this.getOption(this.value);return t.created?(this.createdLabel=t.currentLabel,this.createdSelected=!0):this.createdSelected=!1,this.selectedLabel=t.currentLabel,this.selected=t,void(this.filterable&&(this.query=this.selectedLabel))}var n=[];Array.isArray(this.value)&&this.value.forEach((function(t){n.push(e.getOption(t))})),this.selected=n,this.$nextTick((function(){e.resetInputHeight()}))},handleFocus:function(e){this.softFocus?this.softFocus=!1:((this.automaticDropdown||this.filterable)&&(this.visible=!0,this.filterable&&(this.menuVisibleOnFocus=!0)),this.$emit("focus",e))},blur:function(){this.visible=!1,this.$refs.reference.blur()},handleBlur:function(e){var t=this;setTimeout((function(){t.isSilentBlur?t.isSilentBlur=!1:t.$emit("blur",e)}),50),this.softFocus=!1},handleClearClick:function(e){this.deleteSelected(e)},doDestroy:function(){this.$refs.popper&&this.$refs.popper.doDestroy()},handleClose:function(){this.visible=!1},toggleLastOptionHitState:function(e){if(Array.isArray(this.selected)){var t=this.selected[this.selected.length-1];if(t)return!0===e||!1===e?(t.hitState=e,e):(t.hitState=!t.hitState,t.hitState)}},deletePrevTag:function(e){if(e.target.value.length<=0&&!this.toggleLastOptionHitState()){var t=this.value.slice();t.pop(),this.$emit("input",t),this.emitChange(t)}},managePlaceholder:function(){""!==this.currentPlaceholder&&(this.currentPlaceholder=this.$refs.input.value?"":this.cachedPlaceHolder)},resetInputState:function(e){8!==e.keyCode&&this.toggleLastOptionHitState(!1),this.inputLength=15*this.$refs.input.value.length+20,this.resetInputHeight()},resetInputHeight:function(){var e=this;this.collapseTags&&!this.filterable||this.$nextTick((function(){if(e.$refs.reference){var t=e.$refs.reference.$el.childNodes,n=[].filter.call(t,(function(e){return"INPUT"===e.tagName}))[0],i=e.$refs.tags,r=e.initialInputHeight||40;n.style.height=0===e.selected.length?r+"px":Math.max(i?i.clientHeight+(i.clientHeight>r?6:0):0,r)+"px",e.visible&&!1!==e.emptyText&&e.broadcast("ElSelectDropdown","updatePopper")}}))},resetHoverIndex:function(){var e=this;setTimeout((function(){e.multiple?e.selected.length>0?e.hoverIndex=Math.min.apply(null,e.selected.map((function(t){return e.options.indexOf(t)}))):e.hoverIndex=-1:e.hoverIndex=e.options.indexOf(e.selected)}),300)},handleOptionSelect:function(e,t){var n=this;if(this.multiple){var i=(this.value||[]).slice(),r=this.getValueIndex(i,e.value);r>-1?i.splice(r,1):(this.multipleLimit<=0||i.length0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1],n="[object object]"===Object.prototype.toString.call(t).toLowerCase();if(n){var i=this.valueKey,r=-1;return e.some((function(e,n){return Object(j["getValueByPath"])(e,i)===Object(j["getValueByPath"])(t,i)&&(r=n,!0)})),r}return e.indexOf(t)},toggleMenu:function(){this.selectDisabled||(this.menuVisibleOnFocus?this.menuVisibleOnFocus=!1:this.visible=!this.visible,this.visible&&(this.$refs.input||this.$refs.reference).focus())},selectOption:function(){this.visible?this.options[this.hoverIndex]&&this.handleOptionSelect(this.options[this.hoverIndex]):this.toggleMenu()},deleteSelected:function(e){e.stopPropagation();var t=this.multiple?[]:"";this.$emit("input",t),this.emitChange(t),this.visible=!1,this.$emit("clear")},deleteTag:function(e,t){var n=this.selected.indexOf(t);if(n>-1&&!this.selectDisabled){var i=this.value.slice();i.splice(n,1),this.$emit("input",i),this.emitChange(i),this.$emit("remove-tag",t.value)}e.stopPropagation()},onInputChange:function(){this.filterable&&this.query!==this.selectedLabel&&(this.query=this.selectedLabel,this.handleQueryChange(this.query))},onOptionDestroy:function(e){e>-1&&(this.optionsCount--,this.filteredOptionsCount--,this.options.splice(e,1))},resetInputWidth:function(){this.inputWidth=this.$refs.reference.$el.getBoundingClientRect().width},handleResize:function(){this.resetInputWidth(),this.multiple&&this.resetInputHeight()},checkDefaultFirstOption:function(){this.hoverIndex=-1;for(var e=!1,t=this.options.length-1;t>=0;t--)if(this.options[t].created){e=!0,this.hoverIndex=t;break}if(!e)for(var n=0;n!==this.options.length;++n){var i=this.options[n];if(this.query){if(!i.disabled&&!i.groupDisabled&&i.visible){this.hoverIndex=n;break}}else if(i.itemSelected){this.hoverIndex=n;break}}},getValueKey:function(e){return"[object object]"!==Object.prototype.toString.call(e.value).toLowerCase()?e.value:Object(j["getValueByPath"])(e.value,this.valueKey)}},created:function(){var e=this;this.cachedPlaceHolder=this.currentPlaceholder=this.placeholder,this.multiple&&!Array.isArray(this.value)&&this.$emit("input",[]),!this.multiple&&Array.isArray(this.value)&&this.$emit("input",""),this.debouncedOnInputChange=D()(this.debounce,(function(){e.onInputChange()})),this.debouncedQueryChange=D()(this.debounce,(function(t){e.handleQueryChange(t.target.value)})),this.$on("handleOptionClick",this.handleOptionSelect),this.$on("setSelected",this.setSelected)},mounted:function(){var e=this;this.multiple&&Array.isArray(this.value)&&this.value.length>0&&(this.currentPlaceholder=""),Object(P["addResizeListener"])(this.$el,this.handleResize);var t=this.$refs.reference;if(t&&t.$el){var n={medium:36,small:32,mini:28},i=t.$el.querySelector("input");this.initialInputHeight=i.getBoundingClientRect().height||n[this.selectSize]}this.remote&&this.multiple&&this.resetInputHeight(),this.$nextTick((function(){t&&t.$el&&(e.inputWidth=t.$el.getBoundingClientRect().width)})),this.setSelected()},beforeDestroy:function(){this.$el&&this.handleResize&&Object(P["removeResizeListener"])(this.$el,this.handleResize)}},V=L,z=Object(y["a"])(V,i,r,!1,null,null,null);z.options.__file="packages/select/src/select.vue";var B=z.exports;B.install=function(e){e.component(B.name,B)};t["default"]=B}])},"4e71":function(e,t,n){n("e198")("observable")},"4ebc":function(e,t,n){var i=n("4d88");e.exports=Array.isArray||function(e){return"Array"==i(e)}},"50c4":function(e,t,n){var i=n("a691"),r=Math.min;e.exports=function(e){return e>0?r(i(e),9007199254740991):0}},"511f":function(e,t,n){n("0b99"),n("658f"),e.exports=n("fcd4").f("iterator")},5128:function(e,t,n){"use strict";t.__esModule=!0,t.PopupManager=void 0;var i=n("2b0e"),r=h(i),o=n("7f4d"),a=h(o),s=n("4b26"),l=h(s),c=n("e62d"),u=h(c),d=n("5924");function h(e){return e&&e.__esModule?e:{default:e}}var f=1,p=void 0;t.default={props:{visible:{type:Boolean,default:!1},openDelay:{},closeDelay:{},zIndex:{},modal:{type:Boolean,default:!1},modalFade:{type:Boolean,default:!0},modalClass:{},modalAppendToBody:{type:Boolean,default:!1},lockScroll:{type:Boolean,default:!0},closeOnPressEscape:{type:Boolean,default:!1},closeOnClickModal:{type:Boolean,default:!1}},beforeMount:function(){this._popupId="popup-"+f++,l.default.register(this._popupId,this)},beforeDestroy:function(){l.default.deregister(this._popupId),l.default.closeModal(this._popupId),this.restoreBodyStyle()},data:function(){return{opened:!1,bodyPaddingRight:null,computedBodyPaddingRight:0,withoutHiddenClass:!0,rendered:!1}},watch:{visible:function(e){var t=this;if(e){if(this._opening)return;this.rendered?this.open():(this.rendered=!0,r.default.nextTick((function(){t.open()})))}else this.close()}},methods:{open:function(e){var t=this;this.rendered||(this.rendered=!0);var n=(0,a.default)({},this.$props||this,e);this._closeTimer&&(clearTimeout(this._closeTimer),this._closeTimer=null),clearTimeout(this._openTimer);var i=Number(n.openDelay);i>0?this._openTimer=setTimeout((function(){t._openTimer=null,t.doOpen(n)}),i):this.doOpen(n)},doOpen:function(e){if(!this.$isServer&&(!this.willOpen||this.willOpen())&&!this.opened){this._opening=!0;var t=this.$el,n=e.modal,i=e.zIndex;if(i&&(l.default.zIndex=i),n&&(this._closing&&(l.default.closeModal(this._popupId),this._closing=!1),l.default.openModal(this._popupId,l.default.nextZIndex(),this.modalAppendToBody?void 0:t,e.modalClass,e.modalFade),e.lockScroll)){this.withoutHiddenClass=!(0,d.hasClass)(document.body,"el-popup-parent--hidden"),this.withoutHiddenClass&&(this.bodyPaddingRight=document.body.style.paddingRight,this.computedBodyPaddingRight=parseInt((0,d.getStyle)(document.body,"paddingRight"),10)),p=(0,u.default)();var r=document.documentElement.clientHeight0&&(r||"scroll"===o)&&this.withoutHiddenClass&&(document.body.style.paddingRight=this.computedBodyPaddingRight+p+"px"),(0,d.addClass)(document.body,"el-popup-parent--hidden")}"static"===getComputedStyle(t).position&&(t.style.position="absolute"),t.style.zIndex=l.default.nextZIndex(),this.opened=!0,this.onOpen&&this.onOpen(),this.doAfterOpen()}},doAfterOpen:function(){this._opening=!1},close:function(){var e=this;if(!this.willClose||this.willClose()){null!==this._openTimer&&(clearTimeout(this._openTimer),this._openTimer=null),clearTimeout(this._closeTimer);var t=Number(this.closeDelay);t>0?this._closeTimer=setTimeout((function(){e._closeTimer=null,e.doClose()}),t):this.doClose()}},doClose:function(){this._closing=!0,this.onClose&&this.onClose(),this.lockScroll&&setTimeout(this.restoreBodyStyle,200),this.opened=!1,this.doAfterClose()},doAfterClose:function(){l.default.closeModal(this._popupId),this._closing=!1},restoreBodyStyle:function(){this.modal&&this.withoutHiddenClass&&(document.body.style.paddingRight=this.bodyPaddingRight,(0,d.removeClass)(document.body,"el-popup-parent--hidden")),this.withoutHiddenClass=!0}}},t.PopupManager=l.default},"512c":function(e,t,n){var i=n("ef08"),r=n("5524"),o=n("9c0c"),a=n("051b"),s=n("9c0e"),l="prototype",c=function(e,t,n){var u,d,h,f=e&c.F,p=e&c.G,m=e&c.S,v=e&c.P,g=e&c.B,b=e&c.W,y=p?r:r[t]||(r[t]={}),_=y[l],x=p?i:m?i[t]:(i[t]||{})[l];for(u in p&&(n=t),n)d=!f&&x&&void 0!==x[u],d&&s(y,u)||(h=d?x[u]:n[u],y[u]=p&&"function"!=typeof x[u]?n[u]:g&&d?o(h,i):b&&x[u]==h?function(e){var t=function(t,n,i){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,i)}return e.apply(this,arguments)};return t[l]=e[l],t}(h):v&&"function"==typeof h?o(Function.call,h):h,v&&((y.virtual||(y.virtual={}))[u]=h,e&c.R&&_&&!_[u]&&a(_,u,h)))};c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,e.exports=c},5135:function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},5270:function(e,t,n){"use strict";var i=n("c532"),r=n("c401"),o=n("2e67"),a=n("2444"),s=n("d925"),l=n("e683");function c(e){e.cancelToken&&e.cancelToken.throwIfRequested()}e.exports=function(e){c(e),e.baseURL&&!s(e.url)&&(e.url=l(e.baseURL,e.url)),e.headers=e.headers||{},e.data=r(e.data,e.headers,e.transformRequest),e.headers=i.merge(e.headers.common||{},e.headers[e.method]||{},e.headers||{}),i.forEach(["delete","get","head","post","put","patch","common"],(function(t){delete e.headers[t]}));var t=e.adapter||a.adapter;return t(e).then((function(t){return c(e),t.data=r(t.data,t.headers,e.transformResponse),t}),(function(t){return o(t)||(c(e),t&&t.response&&(t.response.data=r(t.response.data,t.response.headers,e.transformResponse))),Promise.reject(t)}))}},5488:function(e,t,n){"use strict";t.__esModule=!0;var i=n("5924");function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=function(){function e(){r(this,e)}return e.prototype.beforeEnter=function(e){(0,i.addClass)(e,"collapse-transition"),e.dataset||(e.dataset={}),e.dataset.oldPaddingTop=e.style.paddingTop,e.dataset.oldPaddingBottom=e.style.paddingBottom,e.style.height="0",e.style.paddingTop=0,e.style.paddingBottom=0},e.prototype.enter=function(e){e.dataset.oldOverflow=e.style.overflow,0!==e.scrollHeight?(e.style.height=e.scrollHeight+"px",e.style.paddingTop=e.dataset.oldPaddingTop,e.style.paddingBottom=e.dataset.oldPaddingBottom):(e.style.height="",e.style.paddingTop=e.dataset.oldPaddingTop,e.style.paddingBottom=e.dataset.oldPaddingBottom),e.style.overflow="hidden"},e.prototype.afterEnter=function(e){(0,i.removeClass)(e,"collapse-transition"),e.style.height="",e.style.overflow=e.dataset.oldOverflow},e.prototype.beforeLeave=function(e){e.dataset||(e.dataset={}),e.dataset.oldPaddingTop=e.style.paddingTop,e.dataset.oldPaddingBottom=e.style.paddingBottom,e.dataset.oldOverflow=e.style.overflow,e.style.height=e.scrollHeight+"px",e.style.overflow="hidden"},e.prototype.leave=function(e){0!==e.scrollHeight&&((0,i.addClass)(e,"collapse-transition"),e.style.height=0,e.style.paddingTop=0,e.style.paddingBottom=0)},e.prototype.afterLeave=function(e){(0,i.removeClass)(e,"collapse-transition"),e.style.height="",e.style.overflow=e.dataset.oldOverflow,e.style.paddingTop=e.dataset.oldPaddingTop,e.style.paddingBottom=e.dataset.oldPaddingBottom},e}();t.default={name:"ElCollapseTransition",functional:!0,render:function(e,t){var n=t.children,i={on:new o};return e("transition",i,n)}}},5524:function(e,t){var n=e.exports={version:"2.6.10"};"number"==typeof __e&&(__e=n)},5692:function(e,t,n){var i=n("c430"),r=n("c6cd");(e.exports=function(e,t){return r[e]||(r[e]=void 0!==t?t:{})})("versions",[]).push({version:"3.3.5",mode:i?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},"56ef":function(e,t,n){var i=n("d066"),r=n("241c"),o=n("7418"),a=n("825a");e.exports=i("Reflect","ownKeys")||function(e){var t=r.f(a(e)),n=o.f;return n?t.concat(n(e)):t}},5924:function(e,t,n){"use strict";t.__esModule=!0,t.isInContainer=t.getScrollContainer=t.isScroll=t.getStyle=t.once=t.off=t.on=void 0;var i="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};t.hasClass=m,t.addClass=v,t.removeClass=g,t.setStyle=y;var r=n("2b0e"),o=a(r);function a(e){return e&&e.__esModule?e:{default:e}}var s=o.default.prototype.$isServer,l=/([\:\-\_]+(.))/g,c=/^moz([A-Z])/,u=s?0:Number(document.documentMode),d=function(e){return(e||"").replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g,"")},h=function(e){return e.replace(l,(function(e,t,n,i){return i?n.toUpperCase():n})).replace(c,"Moz$1")},f=t.on=function(){return!s&&document.addEventListener?function(e,t,n){e&&t&&n&&e.addEventListener(t,n,!1)}:function(e,t,n){e&&t&&n&&e.attachEvent("on"+t,n)}}(),p=t.off=function(){return!s&&document.removeEventListener?function(e,t,n){e&&t&&e.removeEventListener(t,n,!1)}:function(e,t,n){e&&t&&e.detachEvent("on"+t,n)}}();t.once=function(e,t,n){var i=function i(){n&&n.apply(this,arguments),p(e,t,i)};f(e,t,i)};function m(e,t){if(!e||!t)return!1;if(-1!==t.indexOf(" "))throw new Error("className should not contain space.");return e.classList?e.classList.contains(t):(" "+e.className+" ").indexOf(" "+t+" ")>-1}function v(e,t){if(e){for(var n=e.className,i=(t||"").split(" "),r=0,o=i.length;ri.top&&n.right>i.left&&n.lefte?c():!0!==t&&(r=setTimeout(i?u:c,void 0===i?e-s:e))}return("boolean"!==typeof t&&(i=n,n=t,t=void 0),a)}},"5a94":function(e,t,n){var i=n("b367")("keys"),r=n("8b1a");e.exports=function(e){return i[e]||(i[e]=r(e))}},"5c6c":function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},"5c96":function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=44)}([function(e,t){e.exports=n("d940")},function(e,t){e.exports=n("5924")},function(e,t){e.exports=n("8122")},function(e,t){e.exports=n("d010")},function(e,t){e.exports=n("6b7c")},function(e,t){e.exports=n("e974")},function(e,t){e.exports=n("2b0e")},function(e,t){e.exports=n("7f4d")},function(e,t){e.exports=n("2bb5")},function(e,t){e.exports=n("f3ad")},function(e,t){e.exports=n("417f")},function(e,t){e.exports=n("4010")},function(e,t){e.exports=n("5128")},function(e,t){e.exports=n("0e15")},function(e,t){e.exports=n("dcdc")},function(e,t){e.exports=n("4897")},function(e,t){e.exports=n("14e9")},function(e,t){e.exports=n("eedf")},function(e,t){e.exports=n("a742")},function(e,t){e.exports=n("d397")},function(e,t){e.exports=n("d7d1")},function(e,t){e.exports=n("5488")},function(e,t){e.exports=n("12f2")},function(e,t){e.exports=n("41f8")},function(e,t){e.exports=n("92fa")},function(e,t){e.exports=n("597f")},function(e,t){e.exports=n("299c")},function(e,t){e.exports=n("2a5e")},function(e,t){e.exports=n("8bbc")},function(e,t){e.exports=n("e62d")},function(e,t){e.exports=n("7fc1")},function(e,t){e.exports=n("c56a")},function(e,t){e.exports=n("c284")},function(e,t){e.exports=n("e452")},function(e,t){e.exports=n("9619")},function(e,t){e.exports=n("4e4b")},function(e,t){e.exports=n("e772")},function(e,t){e.exports=n("845f")},function(e,t){e.exports=n("c098")},function(e,t){e.exports=n("722f")},function(e,t){e.exports=n("a15e")},function(e,t){e.exports=n("e450")},function(e,t){e.exports=n("4726")},function(e,t){e.exports=n("f494")},function(e,t,n){e.exports=n(45)},function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("ul",{staticClass:"el-pager",on:{click:e.onPagerClick}},[e.pageCount>0?n("li",{staticClass:"number",class:{active:1===e.currentPage,disabled:e.disabled}},[e._v("1")]):e._e(),e.showPrevMore?n("li",{staticClass:"el-icon more btn-quickprev",class:[e.quickprevIconClass,{disabled:e.disabled}],on:{mouseenter:function(t){e.onMouseenter("left")},mouseleave:function(t){e.quickprevIconClass="el-icon-more"}}}):e._e(),e._l(e.pagers,(function(t){return n("li",{key:t,staticClass:"number",class:{active:e.currentPage===t,disabled:e.disabled}},[e._v(e._s(t))])})),e.showNextMore?n("li",{staticClass:"el-icon more btn-quicknext",class:[e.quicknextIconClass,{disabled:e.disabled}],on:{mouseenter:function(t){e.onMouseenter("right")},mouseleave:function(t){e.quicknextIconClass="el-icon-more"}}}):e._e(),e.pageCount>1?n("li",{staticClass:"number",class:{active:e.currentPage===e.pageCount,disabled:e.disabled}},[e._v(e._s(e.pageCount))]):e._e()],2)},r=[];i._withStripped=!0;var o={name:"ElPager",props:{currentPage:Number,pageCount:Number,pagerCount:Number,disabled:Boolean},watch:{showPrevMore:function(e){e||(this.quickprevIconClass="el-icon-more")},showNextMore:function(e){e||(this.quicknextIconClass="el-icon-more")}},methods:{onPagerClick:function(e){var t=e.target;if("UL"!==t.tagName&&!this.disabled){var n=Number(e.target.textContent),i=this.pageCount,r=this.currentPage,o=this.pagerCount-2;-1!==t.className.indexOf("more")&&(-1!==t.className.indexOf("quickprev")?n=r-o:-1!==t.className.indexOf("quicknext")&&(n=r+o)),isNaN(n)||(n<1&&(n=1),n>i&&(n=i)),n!==r&&this.$emit("change",n)}},onMouseenter:function(e){this.disabled||("left"===e?this.quickprevIconClass="el-icon-d-arrow-left":this.quicknextIconClass="el-icon-d-arrow-right")}},computed:{pagers:function(){var e=this.pagerCount,t=(e-1)/2,n=Number(this.currentPage),i=Number(this.pageCount),r=!1,o=!1;i>e&&(n>e-t&&(r=!0),n4&&e<22&&e%2===1},default:7},currentPage:{type:Number,default:1},layout:{default:"prev, pager, next, jumper, ->, total"},pageSizes:{type:Array,default:function(){return[10,20,30,40,50,100]}},popperClass:String,prevText:String,nextText:String,background:Boolean,disabled:Boolean,hideOnSinglePage:Boolean},data:function(){return{internalCurrentPage:1,internalPageSize:0,lastEmittedPage:-1,userChangePageSize:!1}},render:function(e){var t=this.layout;if(!t)return null;if(this.hideOnSinglePage&&(!this.internalPageCount||1===this.internalPageCount))return null;var n=e("div",{class:["el-pagination",{"is-background":this.background,"el-pagination--small":this.small}]}),i={prev:e("prev"),jumper:e("jumper"),pager:e("pager",{attrs:{currentPage:this.internalCurrentPage,pageCount:this.internalPageCount,pagerCount:this.pagerCount,disabled:this.disabled},on:{change:this.handleCurrentChange}}),next:e("next"),sizes:e("sizes",{attrs:{pageSizes:this.pageSizes}}),slot:e("slot",[this.$slots.default?this.$slots.default:""]),total:e("total")},r=t.split(",").map((function(e){return e.trim()})),o=e("div",{class:"el-pagination__rightwrapper"}),a=!1;return n.children=n.children||[],o.children=o.children||[],r.forEach((function(e){"->"!==e?a?o.children.push(i[e]):n.children.push(i[e]):a=!0})),a&&n.children.unshift(o),n},components:{Prev:{render:function(e){return e("button",{attrs:{type:"button",disabled:this.$parent.disabled||this.$parent.internalCurrentPage<=1},class:"btn-prev",on:{click:this.$parent.prev}},[this.$parent.prevText?e("span",[this.$parent.prevText]):e("i",{class:"el-icon el-icon-arrow-left"})])}},Next:{render:function(e){return e("button",{attrs:{type:"button",disabled:this.$parent.disabled||this.$parent.internalCurrentPage===this.$parent.internalPageCount||0===this.$parent.internalPageCount},class:"btn-next",on:{click:this.$parent.next}},[this.$parent.nextText?e("span",[this.$parent.nextText]):e("i",{class:"el-icon el-icon-arrow-right"})])}},Sizes:{mixins:[g.a],props:{pageSizes:Array},watch:{pageSizes:{immediate:!0,handler:function(e,t){Object(b["valueEquals"])(e,t)||Array.isArray(e)&&(this.$parent.internalPageSize=e.indexOf(this.$parent.pageSize)>-1?this.$parent.pageSize:this.pageSizes[0])}}},render:function(e){var t=this;return e("span",{class:"el-pagination__sizes"},[e("el-select",{attrs:{value:this.$parent.internalPageSize,popperClass:this.$parent.popperClass||"",size:"mini",disabled:this.$parent.disabled},on:{input:this.handleChange}},[this.pageSizes.map((function(n){return e("el-option",{attrs:{value:n,label:n+t.t("el.pagination.pagesize")}})}))])])},components:{ElSelect:d.a,ElOption:f.a},methods:{handleChange:function(e){e!==this.$parent.internalPageSize&&(this.$parent.internalPageSize=e=parseInt(e,10),this.$parent.userChangePageSize=!0,this.$parent.$emit("update:pageSize",e),this.$parent.$emit("size-change",e))}}},Jumper:{mixins:[g.a],components:{ElInput:m.a},data:function(){return{userInput:null}},watch:{"$parent.internalCurrentPage":function(){this.userInput=null}},methods:{handleKeyup:function(e){var t=e.keyCode,n=e.target;13===t&&this.handleChange(n.value)},handleInput:function(e){this.userInput=e},handleChange:function(e){this.$parent.internalCurrentPage=this.$parent.getValidCurrentPage(e),this.$parent.emitChange(),this.userInput=null}},render:function(e){return e("span",{class:"el-pagination__jump"},[this.t("el.pagination.goto"),e("el-input",{class:"el-pagination__editor is-in-pagination",attrs:{min:1,max:this.$parent.internalPageCount,value:null!==this.userInput?this.userInput:this.$parent.internalCurrentPage,type:"number",disabled:this.$parent.disabled},nativeOn:{keyup:this.handleKeyup},on:{input:this.handleInput,change:this.handleChange}}),this.t("el.pagination.pageClassifier")])}},Total:{mixins:[g.a],render:function(e){return"number"===typeof this.$parent.total?e("span",{class:"el-pagination__total"},[this.t("el.pagination.total",{total:this.$parent.total})]):""}},Pager:c},methods:{handleCurrentChange:function(e){this.internalCurrentPage=this.getValidCurrentPage(e),this.userChangePageSize=!0,this.emitChange()},prev:function(){if(!this.disabled){var e=this.internalCurrentPage-1;this.internalCurrentPage=this.getValidCurrentPage(e),this.$emit("prev-click",this.internalCurrentPage),this.emitChange()}},next:function(){if(!this.disabled){var e=this.internalCurrentPage+1;this.internalCurrentPage=this.getValidCurrentPage(e),this.$emit("next-click",this.internalCurrentPage),this.emitChange()}},getValidCurrentPage:function(e){e=parseInt(e,10);var t="number"===typeof this.internalPageCount,n=void 0;return t?e<1?n=1:e>this.internalPageCount&&(n=this.internalPageCount):(isNaN(e)||e<1)&&(n=1),void 0===n&&isNaN(e)?n=1:0===n&&(n=1),void 0===n?e:n},emitChange:function(){var e=this;this.$nextTick((function(){(e.internalCurrentPage!==e.lastEmittedPage||e.userChangePageSize)&&(e.$emit("current-change",e.internalCurrentPage),e.lastEmittedPage=e.internalCurrentPage,e.userChangePageSize=!1)}))}},computed:{internalPageCount:function(){return"number"===typeof this.total?Math.max(1,Math.ceil(this.total/this.internalPageSize)):"number"===typeof this.pageCount?Math.max(1,this.pageCount):null}},watch:{currentPage:{immediate:!0,handler:function(e){this.internalCurrentPage=this.getValidCurrentPage(e)}},pageSize:{immediate:!0,handler:function(e){this.internalPageSize=isNaN(e)?10:e}},internalCurrentPage:{immediate:!0,handler:function(e){this.$emit("update:currentPage",e),this.lastEmittedPage=-1}},internalPageCount:function(e){var t=this.internalCurrentPage;e>0&&0===t?this.internalCurrentPage=1:t>e&&(this.internalCurrentPage=0===e?1:e,this.userChangePageSize&&this.emitChange()),this.userChangePageSize=!1}},install:function(e){e.component(y.name,y)}},_=y,x=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"dialog-fade"},on:{"after-enter":e.afterEnter,"after-leave":e.afterLeave}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-dialog__wrapper",on:{click:function(t){return t.target!==t.currentTarget?null:e.handleWrapperClick(t)}}},[n("div",{key:e.key,ref:"dialog",class:["el-dialog",{"is-fullscreen":e.fullscreen,"el-dialog--center":e.center},e.customClass],style:e.style,attrs:{role:"dialog","aria-modal":"true","aria-label":e.title||"dialog"}},[n("div",{staticClass:"el-dialog__header"},[e._t("title",[n("span",{staticClass:"el-dialog__title"},[e._v(e._s(e.title))])]),e.showClose?n("button",{staticClass:"el-dialog__headerbtn",attrs:{type:"button","aria-label":"Close"},on:{click:e.handleClose}},[n("i",{staticClass:"el-dialog__close el-icon el-icon-close"})]):e._e()],2),e.rendered?n("div",{staticClass:"el-dialog__body"},[e._t("default")],2):e._e(),e.$slots.footer?n("div",{staticClass:"el-dialog__footer"},[e._t("footer")],2):e._e()])])])},w=[];x._withStripped=!0;var C=n(12),k=n.n(C),S=n(8),O=n.n(S),$=n(3),D=n.n($),E={name:"ElDialog",mixins:[k.a,D.a,O.a],props:{title:{type:String,default:""},modal:{type:Boolean,default:!0},modalAppendToBody:{type:Boolean,default:!0},appendToBody:{type:Boolean,default:!1},lockScroll:{type:Boolean,default:!0},closeOnClickModal:{type:Boolean,default:!0},closeOnPressEscape:{type:Boolean,default:!0},showClose:{type:Boolean,default:!0},width:String,fullscreen:Boolean,customClass:{type:String,default:""},top:{type:String,default:"15vh"},beforeClose:Function,center:{type:Boolean,default:!1},destroyOnClose:Boolean},data:function(){return{closed:!1,key:0}},watch:{visible:function(e){var t=this;e?(this.closed=!1,this.$emit("open"),this.$el.addEventListener("scroll",this.updatePopper),this.$nextTick((function(){t.$refs.dialog.scrollTop=0})),this.appendToBody&&document.body.appendChild(this.$el)):(this.$el.removeEventListener("scroll",this.updatePopper),this.closed||this.$emit("close"),this.destroyOnClose&&this.$nextTick((function(){t.key++})))}},computed:{style:function(){var e={};return this.fullscreen||(e.marginTop=this.top,this.width&&(e.width=this.width)),e}},methods:{getMigratingConfig:function(){return{props:{size:"size is removed."}}},handleWrapperClick:function(){this.closeOnClickModal&&this.handleClose()},handleClose:function(){"function"===typeof this.beforeClose?this.beforeClose(this.hide):this.hide()},hide:function(e){!1!==e&&(this.$emit("update:visible",!1),this.$emit("close"),this.closed=!0)},updatePopper:function(){this.broadcast("ElSelectDropdown","updatePopper"),this.broadcast("ElDropdownMenu","updatePopper")},afterEnter:function(){this.$emit("opened")},afterLeave:function(){this.$emit("closed")}},mounted:function(){this.visible&&(this.rendered=!0,this.open(),this.appendToBody&&document.body.appendChild(this.$el))},destroyed:function(){this.appendToBody&&this.$el&&this.$el.parentNode&&this.$el.parentNode.removeChild(this.$el)}},T=E,P=s(T,x,w,!1,null,null,null);P.options.__file="packages/dialog/src/component.vue";var M=P.exports;M.install=function(e){e.component(M.name,M)};var I=M,N=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.close,expression:"close"}],staticClass:"el-autocomplete",attrs:{"aria-haspopup":"listbox",role:"combobox","aria-expanded":e.suggestionVisible,"aria-owns":e.id}},[n("el-input",e._b({ref:"input",on:{input:e.handleChange,focus:e.handleFocus,blur:e.handleBlur,clear:e.handleClear},nativeOn:{keydown:[function(t){if(!("button"in t)&&e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"]))return null;t.preventDefault(),e.highlight(e.highlightedIndex-1)},function(t){if(!("button"in t)&&e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"]))return null;t.preventDefault(),e.highlight(e.highlightedIndex+1)},function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.handleKeyEnter(t):null},function(t){return"button"in t||!e._k(t.keyCode,"tab",9,t.key,"Tab")?e.close(t):null}]}},"el-input",[e.$props,e.$attrs],!1),[e.$slots.prepend?n("template",{slot:"prepend"},[e._t("prepend")],2):e._e(),e.$slots.append?n("template",{slot:"append"},[e._t("append")],2):e._e(),e.$slots.prefix?n("template",{slot:"prefix"},[e._t("prefix")],2):e._e(),e.$slots.suffix?n("template",{slot:"suffix"},[e._t("suffix")],2):e._e()],2),n("el-autocomplete-suggestions",{ref:"suggestions",class:[e.popperClass?e.popperClass:""],attrs:{"visible-arrow":"","popper-options":e.popperOptions,"append-to-body":e.popperAppendToBody,placement:e.placement,id:e.id}},e._l(e.suggestions,(function(t,i){return n("li",{key:i,class:{highlighted:e.highlightedIndex===i},attrs:{id:e.id+"-item-"+i,role:"option","aria-selected":e.highlightedIndex===i},on:{click:function(n){e.select(t)}}},[e._t("default",[e._v("\n "+e._s(t[e.valueKey])+"\n ")],{item:t})],2)})),0)],1)},j=[];N._withStripped=!0;var A=n(13),F=n.n(A),L=n(10),V=n.n(L),z=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":e.doDestroy}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.showPopper,expression:"showPopper"}],staticClass:"el-autocomplete-suggestion el-popper",class:{"is-loading":!e.parent.hideLoading&&e.parent.loading},style:{width:e.dropdownWidth},attrs:{role:"region"}},[n("el-scrollbar",{attrs:{tag:"ul","wrap-class":"el-autocomplete-suggestion__wrap","view-class":"el-autocomplete-suggestion__list"}},[!e.parent.hideLoading&&e.parent.loading?n("li",[n("i",{staticClass:"el-icon-loading"})]):e._t("default")],2)],1)])},B=[];z._withStripped=!0;var R=n(5),H=n.n(R),W=n(16),q=n.n(W),U={components:{ElScrollbar:q.a},mixins:[H.a,D.a],componentName:"ElAutocompleteSuggestions",data:function(){return{parent:this.$parent,dropdownWidth:""}},props:{options:{default:function(){return{gpuAcceleration:!1}}},id:String},methods:{select:function(e){this.dispatch("ElAutocomplete","item-click",e)}},updated:function(){var e=this;this.$nextTick((function(t){e.popperJS&&e.updatePopper()}))},mounted:function(){this.$parent.popperElm=this.popperElm=this.$el,this.referenceElm=this.$parent.$refs.input.$refs.input,this.referenceList=this.$el.querySelector(".el-autocomplete-suggestion__list"),this.referenceList.setAttribute("role","listbox"),this.referenceList.setAttribute("id",this.id)},created:function(){var e=this;this.$on("visible",(function(t,n){e.dropdownWidth=n+"px",e.showPopper=t}))}},Y=U,K=s(Y,z,B,!1,null,null,null);K.options.__file="packages/autocomplete/src/autocomplete-suggestions.vue";var G=K.exports,X=n(22),Z=n.n(X),J={name:"ElAutocomplete",mixins:[D.a,Z()("input"),O.a],inheritAttrs:!1,componentName:"ElAutocomplete",components:{ElInput:m.a,ElAutocompleteSuggestions:G},directives:{Clickoutside:V.a},props:{valueKey:{type:String,default:"value"},popperClass:String,popperOptions:Object,placeholder:String,clearable:{type:Boolean,default:!1},disabled:Boolean,name:String,size:String,value:String,maxlength:Number,minlength:Number,autofocus:Boolean,fetchSuggestions:Function,triggerOnFocus:{type:Boolean,default:!0},customItem:String,selectWhenUnmatched:{type:Boolean,default:!1},prefixIcon:String,suffixIcon:String,label:String,debounce:{type:Number,default:300},placement:{type:String,default:"bottom-start"},hideLoading:Boolean,popperAppendToBody:{type:Boolean,default:!0},highlightFirstItem:{type:Boolean,default:!1}},data:function(){return{activated:!1,suggestions:[],loading:!1,highlightedIndex:-1,suggestionDisabled:!1}},computed:{suggestionVisible:function(){var e=this.suggestions,t=Array.isArray(e)&&e.length>0;return(t||this.loading)&&this.activated},id:function(){return"el-autocomplete-"+Object(b["generateId"])()}},watch:{suggestionVisible:function(e){var t=this.getInput();t&&this.broadcast("ElAutocompleteSuggestions","visible",[e,t.offsetWidth])}},methods:{getMigratingConfig:function(){return{props:{"custom-item":"custom-item is removed, use scoped slot instead.",props:"props is removed, use value-key instead."}}},getData:function(e){var t=this;this.suggestionDisabled||(this.loading=!0,this.fetchSuggestions(e,(function(e){t.loading=!1,t.suggestionDisabled||(Array.isArray(e)?(t.suggestions=e,t.highlightedIndex=t.highlightFirstItem?0:-1):console.error("[Element Error][Autocomplete]autocomplete suggestions must be an array"))})))},handleChange:function(e){if(this.$emit("input",e),this.suggestionDisabled=!1,!this.triggerOnFocus&&!e)return this.suggestionDisabled=!0,void(this.suggestions=[]);this.debouncedGetData(e)},handleFocus:function(e){this.activated=!0,this.$emit("focus",e),this.triggerOnFocus&&this.debouncedGetData(this.value)},handleBlur:function(e){this.$emit("blur",e)},handleClear:function(){this.activated=!1,this.$emit("clear")},close:function(e){this.activated=!1},handleKeyEnter:function(e){var t=this;this.suggestionVisible&&this.highlightedIndex>=0&&this.highlightedIndex=this.suggestions.length&&(e=this.suggestions.length-1);var t=this.$refs.suggestions.$el.querySelector(".el-autocomplete-suggestion__wrap"),n=t.querySelectorAll(".el-autocomplete-suggestion__list li"),i=n[e],r=t.scrollTop,o=i.offsetTop;o+i.scrollHeight>r+t.clientHeight&&(t.scrollTop+=i.scrollHeight),o=0&&this.resetTabindex(this.triggerElm),clearTimeout(this.timeout),this.timeout=setTimeout((function(){e.visible=!1}),"click"===this.trigger?0:this.hideTimeout))},handleClick:function(){this.triggerElm.disabled||(this.visible?this.hide():this.show())},handleTriggerKeyDown:function(e){var t=e.keyCode;[38,40].indexOf(t)>-1?(this.removeTabindex(),this.resetTabindex(this.menuItems[0]),this.menuItems[0].focus(),e.preventDefault(),e.stopPropagation()):13===t?this.handleClick():[9,27].indexOf(t)>-1&&this.hide()},handleItemKeyDown:function(e){var t=e.keyCode,n=e.target,i=this.menuItemsArray.indexOf(n),r=this.menuItemsArray.length-1,o=void 0;[38,40].indexOf(t)>-1?(o=38===t?0!==i?i-1:0:i-1&&(this.hide(),this.triggerElmFocus())},resetTabindex:function(e){this.removeTabindex(),e.setAttribute("tabindex","0")},removeTabindex:function(){this.triggerElm.setAttribute("tabindex","-1"),this.menuItemsArray.forEach((function(e){e.setAttribute("tabindex","-1")}))},initAria:function(){this.dropdownElm.setAttribute("id",this.listId),this.triggerElm.setAttribute("aria-haspopup","list"),this.triggerElm.setAttribute("aria-controls",this.listId),this.splitButton||(this.triggerElm.setAttribute("role","button"),this.triggerElm.setAttribute("tabindex",this.tabindex),this.triggerElm.setAttribute("class",(this.triggerElm.getAttribute("class")||"")+" el-dropdown-selfdefine"))},initEvent:function(){var e=this,t=this.trigger,n=this.show,i=this.hide,r=this.handleClick,o=this.splitButton,a=this.handleTriggerKeyDown,s=this.handleItemKeyDown;this.triggerElm=o?this.$refs.trigger.$el:this.$slots.default[0].elm;var l=this.dropdownElm;this.triggerElm.addEventListener("keydown",a),l.addEventListener("keydown",s,!0),o||(this.triggerElm.addEventListener("focus",(function(){e.focusing=!0})),this.triggerElm.addEventListener("blur",(function(){e.focusing=!1})),this.triggerElm.addEventListener("click",(function(){e.focusing=!1}))),"hover"===t?(this.triggerElm.addEventListener("mouseenter",n),this.triggerElm.addEventListener("mouseleave",i),l.addEventListener("mouseenter",n),l.addEventListener("mouseleave",i)):"click"===t&&this.triggerElm.addEventListener("click",r)},handleMenuItemClick:function(e,t){this.hideOnClick&&(this.visible=!1),this.$emit("command",e,t)},triggerElmFocus:function(){this.triggerElm.focus&&this.triggerElm.focus()},initDomOperation:function(){this.dropdownElm=this.popperElm,this.menuItems=this.dropdownElm.querySelectorAll("[tabindex='-1']"),this.menuItemsArray=[].slice.call(this.menuItems),this.initEvent(),this.initAria()}},render:function(e){var t=this,n=this.hide,i=this.splitButton,r=this.type,o=this.dropdownSize,a=function(e){t.$emit("click",e),n()},s=i?e("el-button-group",[e("el-button",{attrs:{type:r,size:o},nativeOn:{click:a}},[this.$slots.default]),e("el-button",{ref:"trigger",attrs:{type:r,size:o},class:"el-dropdown__caret-button"},[e("i",{class:"el-dropdown__icon el-icon-arrow-down"})])]):this.$slots.default;return e("div",{class:"el-dropdown",directives:[{name:"clickoutside",value:n}]},[s,this.$slots.dropdown])}},ue=ce,de=s(ue,ne,ie,!1,null,null,null);de.options.__file="packages/dropdown/src/dropdown.vue";var he=de.exports;he.install=function(e){e.component(he.name,he)};var fe=he,pe=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":e.doDestroy}},[n("ul",{directives:[{name:"show",rawName:"v-show",value:e.showPopper,expression:"showPopper"}],staticClass:"el-dropdown-menu el-popper",class:[e.size&&"el-dropdown-menu--"+e.size]},[e._t("default")],2)])},me=[];pe._withStripped=!0;var ve={name:"ElDropdownMenu",componentName:"ElDropdownMenu",mixins:[H.a],props:{visibleArrow:{type:Boolean,default:!0},arrowOffset:{type:Number,default:0}},data:function(){return{size:this.dropdown.dropdownSize}},inject:["dropdown"],created:function(){var e=this;this.$on("updatePopper",(function(){e.showPopper&&e.updatePopper()})),this.$on("visible",(function(t){e.showPopper=t}))},mounted:function(){this.dropdown.popperElm=this.popperElm=this.$el,this.referenceElm=this.dropdown.$el,this.dropdown.initDomOperation()},watch:{"dropdown.placement":{immediate:!0,handler:function(e){this.currentPlacement=e}}}},ge=ve,be=s(ge,pe,me,!1,null,null,null);be.options.__file="packages/dropdown/src/dropdown-menu.vue";var ye=be.exports;ye.install=function(e){e.component(ye.name,ye)};var _e=ye,xe=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{staticClass:"el-dropdown-menu__item",class:{"is-disabled":e.disabled,"el-dropdown-menu__item--divided":e.divided},attrs:{"aria-disabled":e.disabled,tabindex:e.disabled?null:-1},on:{click:e.handleClick}},[e.icon?n("i",{class:e.icon}):e._e(),e._t("default")],2)},we=[];xe._withStripped=!0;var Ce={name:"ElDropdownItem",mixins:[D.a],props:{command:{},disabled:Boolean,divided:Boolean,icon:String},methods:{handleClick:function(e){this.dispatch("ElDropdown","menu-item-click",[this.command,this])}}},ke=Ce,Se=s(ke,xe,we,!1,null,null,null);Se.options.__file="packages/dropdown/src/dropdown-item.vue";var Oe=Se.exports;Oe.install=function(e){e.component(Oe.name,Oe)};var $e=Oe,De=De||{};De.Utils=De.Utils||{},De.Utils.focusFirstDescendant=function(e){for(var t=0;t=0;t--){var n=e.childNodes[t];if(De.Utils.attemptFocus(n)||De.Utils.focusLastDescendant(n))return!0}return!1},De.Utils.attemptFocus=function(e){if(!De.Utils.isFocusable(e))return!1;De.Utils.IgnoreUtilFocusChanges=!0;try{e.focus()}catch(t){}return De.Utils.IgnoreUtilFocusChanges=!1,document.activeElement===e},De.Utils.isFocusable=function(e){if(e.tabIndex>0||0===e.tabIndex&&null!==e.getAttribute("tabIndex"))return!0;if(e.disabled)return!1;switch(e.nodeName){case"A":return!!e.href&&"ignore"!==e.rel;case"INPUT":return"hidden"!==e.type&&"file"!==e.type;case"BUTTON":case"SELECT":case"TEXTAREA":return!0;default:return!1}},De.Utils.triggerEvent=function(e,t){var n=void 0;n=/^mouse|click/.test(t)?"MouseEvents":/^key/.test(t)?"KeyboardEvent":"HTMLEvents";for(var i=document.createEvent(n),r=arguments.length,o=Array(r>2?r-2:0),a=2;a=0;t--)e.splice(t,0,e[t]);e=e.join("")}return/^[0-9a-fA-F]{6}$/.test(e)?{red:parseInt(e.slice(0,2),16),green:parseInt(e.slice(2,4),16),blue:parseInt(e.slice(4,6),16)}:{red:255,green:255,blue:255}},mixColor:function(e,t){var n=this.getColorChannels(e),i=n.red,r=n.green,o=n.blue;return t>0?(i*=1-t,r*=1-t,o*=1-t):(i+=(255-i)*t,r+=(255-r)*t,o+=(255-o)*t),"rgb("+Math.round(i)+", "+Math.round(r)+", "+Math.round(o)+")"},addItem:function(e){this.$set(this.items,e.index,e)},removeItem:function(e){delete this.items[e.index]},addSubmenu:function(e){this.$set(this.submenus,e.index,e)},removeSubmenu:function(e){delete this.submenus[e.index]},openMenu:function(e,t){var n=this.openedMenus;-1===n.indexOf(e)&&(this.uniqueOpened&&(this.openedMenus=n.filter((function(e){return-1!==t.indexOf(e)}))),this.openedMenus.push(e))},closeMenu:function(e){var t=this.openedMenus.indexOf(e);-1!==t&&this.openedMenus.splice(t,1)},handleSubmenuClick:function(e){var t=e.index,n=e.indexPath,i=-1!==this.openedMenus.indexOf(t);i?(this.closeMenu(t),this.$emit("close",t,n)):(this.openMenu(t,n),this.$emit("open",t,n))},handleItemClick:function(e){var t=this,n=e.index,i=e.indexPath,r=this.activeIndex,o=null!==e.index;o&&(this.activeIndex=e.index),this.$emit("select",n,i,e),("horizontal"===this.mode||this.collapse)&&(this.openedMenus=[]),this.router&&o&&this.routeToItem(e,(function(e){t.activeIndex=r,e&&console.error(e)}))},initOpenedMenu:function(){var e=this,t=this.activeIndex,n=this.items[t];if(n&&"horizontal"!==this.mode&&!this.collapse){var i=n.indexPath;i.forEach((function(t){var n=e.submenus[t];n&&e.openMenu(t,n.indexPath)}))}},routeToItem:function(e,t){var n=e.route||e.index;try{this.$router.push(n,(function(){}),t)}catch(i){console.error(i)}},open:function(e){var t=this,n=this.submenus[e.toString()].indexPath;n.forEach((function(e){return t.openMenu(e,n)}))},close:function(e){this.closeMenu(e)}},mounted:function(){this.initOpenedMenu(),this.$on("item-click",this.handleItemClick),this.$on("submenu-click",this.handleSubmenuClick),"horizontal"===this.mode&&new Fe(this.$el),this.$watch("items",this.updateActiveIndex)}},ze=Ve,Be=s(ze,je,Ae,!1,null,null,null);Be.options.__file="packages/menu/src/menu.vue";var Re=Be.exports;Re.install=function(e){e.component(Re.name,Re)};var He,We,qe=Re,Ue=n(21),Ye=n.n(Ue),Ke={inject:["rootMenu"],computed:{indexPath:function(){var e=[this.index],t=this.$parent;while("ElMenu"!==t.$options.componentName)t.index&&e.unshift(t.index),t=t.$parent;return e},parentMenu:function(){var e=this.$parent;while(e&&-1===["ElMenu","ElSubmenu"].indexOf(e.$options.componentName))e=e.$parent;return e},paddingStyle:function(){if("vertical"!==this.rootMenu.mode)return{};var e=20,t=this.$parent;if(this.rootMenu.collapse)e=20;else while(t&&"ElMenu"!==t.$options.componentName)"ElSubmenu"===t.$options.componentName&&(e+=20),t=t.$parent;return{paddingLeft:e+"px"}}}},Ge={props:{transformOrigin:{type:[Boolean,String],default:!1},offset:H.a.props.offset,boundariesPadding:H.a.props.boundariesPadding,popperOptions:H.a.props.popperOptions},data:H.a.data,methods:H.a.methods,beforeDestroy:H.a.beforeDestroy,deactivated:H.a.deactivated},Xe={name:"ElSubmenu",componentName:"ElSubmenu",mixins:[Ke,D.a,Ge],components:{ElCollapseTransition:Ye.a},props:{index:{type:String,required:!0},showTimeout:{type:Number,default:300},hideTimeout:{type:Number,default:300},popperClass:String,disabled:Boolean,popperAppendToBody:{type:Boolean,default:void 0}},data:function(){return{popperJS:null,timeout:null,items:{},submenus:{},mouseInChild:!1}},watch:{opened:function(e){var t=this;this.isMenuPopup&&this.$nextTick((function(e){t.updatePopper()}))}},computed:{appendToBody:function(){return void 0===this.popperAppendToBody?this.isFirstLevel:this.popperAppendToBody},menuTransitionName:function(){return this.rootMenu.collapse?"el-zoom-in-left":"el-zoom-in-top"},opened:function(){return this.rootMenu.openedMenus.indexOf(this.index)>-1},active:function(){var e=!1,t=this.submenus,n=this.items;return Object.keys(n).forEach((function(t){n[t].active&&(e=!0)})),Object.keys(t).forEach((function(n){t[n].active&&(e=!0)})),e},hoverBackground:function(){return this.rootMenu.hoverBackground},backgroundColor:function(){return this.rootMenu.backgroundColor||""},activeTextColor:function(){return this.rootMenu.activeTextColor||""},textColor:function(){return this.rootMenu.textColor||""},mode:function(){return this.rootMenu.mode},isMenuPopup:function(){return this.rootMenu.isMenuPopup},titleStyle:function(){return"horizontal"!==this.mode?{color:this.textColor}:{borderBottomColor:this.active?this.rootMenu.activeTextColor?this.activeTextColor:"":"transparent",color:this.active?this.activeTextColor:this.textColor}},isFirstLevel:function(){var e=!0,t=this.$parent;while(t&&t!==this.rootMenu){if(["ElSubmenu","ElMenuItemGroup"].indexOf(t.$options.componentName)>-1){e=!1;break}t=t.$parent}return e}},methods:{handleCollapseToggle:function(e){e?this.initPopper():this.doDestroy()},addItem:function(e){this.$set(this.items,e.index,e)},removeItem:function(e){delete this.items[e.index]},addSubmenu:function(e){this.$set(this.submenus,e.index,e)},removeSubmenu:function(e){delete this.submenus[e.index]},handleClick:function(){var e=this.rootMenu,t=this.disabled;"hover"===e.menuTrigger&&"horizontal"===e.mode||e.collapse&&"vertical"===e.mode||t||this.dispatch("ElMenu","submenu-click",this)},handleMouseenter:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.showTimeout;if("ActiveXObject"in window||"focus"!==e.type||e.relatedTarget){var i=this.rootMenu,r=this.disabled;"click"===i.menuTrigger&&"horizontal"===i.mode||!i.collapse&&"vertical"===i.mode||r||(this.dispatch("ElSubmenu","mouse-enter-child"),clearTimeout(this.timeout),this.timeout=setTimeout((function(){t.rootMenu.openMenu(t.index,t.indexPath)}),n),this.appendToBody&&this.$parent.$el.dispatchEvent(new MouseEvent("mouseenter")))}},handleMouseleave:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],n=this.rootMenu;"click"===n.menuTrigger&&"horizontal"===n.mode||!n.collapse&&"vertical"===n.mode||(this.dispatch("ElSubmenu","mouse-leave-child"),clearTimeout(this.timeout),this.timeout=setTimeout((function(){!e.mouseInChild&&e.rootMenu.closeMenu(e.index)}),this.hideTimeout),this.appendToBody&&t&&"ElSubmenu"===this.$parent.$options.name&&this.$parent.handleMouseleave(!0))},handleTitleMouseenter:function(){if("horizontal"!==this.mode||this.rootMenu.backgroundColor){var e=this.$refs["submenu-title"];e&&(e.style.backgroundColor=this.rootMenu.hoverBackground)}},handleTitleMouseleave:function(){if("horizontal"!==this.mode||this.rootMenu.backgroundColor){var e=this.$refs["submenu-title"];e&&(e.style.backgroundColor=this.rootMenu.backgroundColor||"")}},updatePlacement:function(){this.currentPlacement="horizontal"===this.mode&&this.isFirstLevel?"bottom-start":"right-start"},initPopper:function(){this.referenceElm=this.$el,this.popperElm=this.$refs.menu,this.updatePlacement()}},created:function(){var e=this;this.$on("toggle-collapse",this.handleCollapseToggle),this.$on("mouse-enter-child",(function(){e.mouseInChild=!0,clearTimeout(e.timeout)})),this.$on("mouse-leave-child",(function(){e.mouseInChild=!1,clearTimeout(e.timeout)}))},mounted:function(){this.parentMenu.addSubmenu(this),this.rootMenu.addSubmenu(this),this.initPopper()},beforeDestroy:function(){this.parentMenu.removeSubmenu(this),this.rootMenu.removeSubmenu(this)},render:function(e){var t=this,n=this.active,i=this.opened,r=this.paddingStyle,o=this.titleStyle,a=this.backgroundColor,s=this.rootMenu,l=this.currentPlacement,c=this.menuTransitionName,u=this.mode,d=this.disabled,h=this.popperClass,f=this.$slots,p=this.isFirstLevel,m=e("transition",{attrs:{name:c}},[e("div",{ref:"menu",directives:[{name:"show",value:i}],class:["el-menu--"+u,h],on:{mouseenter:function(e){return t.handleMouseenter(e,100)},mouseleave:function(){return t.handleMouseleave(!0)},focus:function(e){return t.handleMouseenter(e,100)}}},[e("ul",{attrs:{role:"menu"},class:["el-menu el-menu--popup","el-menu--popup-"+l],style:{backgroundColor:s.backgroundColor||""}},[f.default])])]),v=e("el-collapse-transition",[e("ul",{attrs:{role:"menu"},class:"el-menu el-menu--inline",directives:[{name:"show",value:i}],style:{backgroundColor:s.backgroundColor||""}},[f.default])]),g="horizontal"===s.mode&&p||"vertical"===s.mode&&!s.collapse?"el-icon-arrow-down":"el-icon-arrow-right";return e("li",{class:{"el-submenu":!0,"is-active":n,"is-opened":i,"is-disabled":d},attrs:{role:"menuitem","aria-haspopup":"true","aria-expanded":i},on:{mouseenter:this.handleMouseenter,mouseleave:function(){return t.handleMouseleave(!1)},focus:this.handleMouseenter}},[e("div",{class:"el-submenu__title",ref:"submenu-title",on:{click:this.handleClick,mouseenter:this.handleTitleMouseenter,mouseleave:this.handleTitleMouseleave},style:[r,o,{backgroundColor:a}]},[f.title,e("i",{class:["el-submenu__icon-arrow",g]})]),this.isMenuPopup?m:v])}},Ze=Xe,Je=s(Ze,He,We,!1,null,null,null);Je.options.__file="packages/menu/src/submenu.vue";var Qe=Je.exports;Qe.install=function(e){e.component(Qe.name,Qe)};var et=Qe,tt=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{staticClass:"el-menu-item",class:{"is-active":e.active,"is-disabled":e.disabled},style:[e.paddingStyle,e.itemStyle,{backgroundColor:e.backgroundColor}],attrs:{role:"menuitem",tabindex:"-1"},on:{click:e.handleClick,mouseenter:e.onMouseEnter,focus:e.onMouseEnter,blur:e.onMouseLeave,mouseleave:e.onMouseLeave}},["ElMenu"===e.parentMenu.$options.componentName&&e.rootMenu.collapse&&e.$slots.title?n("el-tooltip",{attrs:{effect:"dark",placement:"right"}},[n("div",{attrs:{slot:"content"},slot:"content"},[e._t("title")],2),n("div",{staticStyle:{position:"absolute",left:"0",top:"0",height:"100%",width:"100%",display:"inline-block","box-sizing":"border-box",padding:"0 20px"}},[e._t("default")],2)]):[e._t("default"),e._t("title")]],2)},nt=[];tt._withStripped=!0;var it=n(26),rt=n.n(it),ot={name:"ElMenuItem",componentName:"ElMenuItem",mixins:[Ke,D.a],components:{ElTooltip:rt.a},props:{index:{default:null,validator:function(e){return"string"===typeof e||null===e}},route:[String,Object],disabled:Boolean},computed:{active:function(){return this.index===this.rootMenu.activeIndex},hoverBackground:function(){return this.rootMenu.hoverBackground},backgroundColor:function(){return this.rootMenu.backgroundColor||""},activeTextColor:function(){return this.rootMenu.activeTextColor||""},textColor:function(){return this.rootMenu.textColor||""},mode:function(){return this.rootMenu.mode},itemStyle:function(){var e={color:this.active?this.activeTextColor:this.textColor};return"horizontal"!==this.mode||this.isNested||(e.borderBottomColor=this.active?this.rootMenu.activeTextColor?this.activeTextColor:"":"transparent"),e},isNested:function(){return this.parentMenu!==this.rootMenu}},methods:{onMouseEnter:function(){("horizontal"!==this.mode||this.rootMenu.backgroundColor)&&(this.$el.style.backgroundColor=this.hoverBackground)},onMouseLeave:function(){("horizontal"!==this.mode||this.rootMenu.backgroundColor)&&(this.$el.style.backgroundColor=this.backgroundColor)},handleClick:function(){this.disabled||(this.dispatch("ElMenu","item-click",this),this.$emit("click",this))}},mounted:function(){this.parentMenu.addItem(this),this.rootMenu.addItem(this)},beforeDestroy:function(){this.parentMenu.removeItem(this),this.rootMenu.removeItem(this)}},at=ot,st=s(at,tt,nt,!1,null,null,null);st.options.__file="packages/menu/src/menu-item.vue";var lt=st.exports;lt.install=function(e){e.component(lt.name,lt)};var ct=lt,ut=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{staticClass:"el-menu-item-group"},[n("div",{staticClass:"el-menu-item-group__title",style:{paddingLeft:e.levelPadding+"px"}},[e.$slots.title?e._t("title"):[e._v(e._s(e.title))]],2),n("ul",[e._t("default")],2)])},dt=[];ut._withStripped=!0;var ht={name:"ElMenuItemGroup",componentName:"ElMenuItemGroup",inject:["rootMenu"],props:{title:{type:String}},data:function(){return{paddingLeft:20}},computed:{levelPadding:function(){var e=20,t=this.$parent;if(this.rootMenu.collapse)return 20;while(t&&"ElMenu"!==t.$options.componentName)"ElSubmenu"===t.$options.componentName&&(e+=20),t=t.$parent;return e}}},ft=ht,pt=s(ft,ut,dt,!1,null,null,null);pt.options.__file="packages/menu/src/menu-item-group.vue";var mt=pt.exports;mt.install=function(e){e.component(mt.name,mt)};var vt=mt,gt=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:["textarea"===e.type?"el-textarea":"el-input",e.inputSize?"el-input--"+e.inputSize:"",{"is-disabled":e.inputDisabled,"is-exceed":e.inputExceed,"el-input-group":e.$slots.prepend||e.$slots.append,"el-input-group--append":e.$slots.append,"el-input-group--prepend":e.$slots.prepend,"el-input--prefix":e.$slots.prefix||e.prefixIcon,"el-input--suffix":e.$slots.suffix||e.suffixIcon||e.clearable||e.showPassword}],on:{mouseenter:function(t){e.hovering=!0},mouseleave:function(t){e.hovering=!1}}},["textarea"!==e.type?[e.$slots.prepend?n("div",{staticClass:"el-input-group__prepend"},[e._t("prepend")],2):e._e(),"textarea"!==e.type?n("input",e._b({ref:"input",staticClass:"el-input__inner",attrs:{tabindex:e.tabindex,type:e.showPassword?e.passwordVisible?"text":"password":e.type,disabled:e.inputDisabled,readonly:e.readonly,autocomplete:e.autoComplete||e.autocomplete,"aria-label":e.label},on:{compositionstart:e.handleCompositionStart,compositionupdate:e.handleCompositionUpdate,compositionend:e.handleCompositionEnd,input:e.handleInput,focus:e.handleFocus,blur:e.handleBlur,change:e.handleChange}},"input",e.$attrs,!1)):e._e(),e.$slots.prefix||e.prefixIcon?n("span",{staticClass:"el-input__prefix"},[e._t("prefix"),e.prefixIcon?n("i",{staticClass:"el-input__icon",class:e.prefixIcon}):e._e()],2):e._e(),e.getSuffixVisible()?n("span",{staticClass:"el-input__suffix"},[n("span",{staticClass:"el-input__suffix-inner"},[e.showClear&&e.showPwdVisible&&e.isWordLimitVisible?e._e():[e._t("suffix"),e.suffixIcon?n("i",{staticClass:"el-input__icon",class:e.suffixIcon}):e._e()],e.showClear?n("i",{staticClass:"el-input__icon el-icon-circle-close el-input__clear",on:{mousedown:function(e){e.preventDefault()},click:e.clear}}):e._e(),e.showPwdVisible?n("i",{staticClass:"el-input__icon el-icon-view el-input__clear",on:{click:e.handlePasswordVisible}}):e._e(),e.isWordLimitVisible?n("span",{staticClass:"el-input__count"},[n("span",{staticClass:"el-input__count-inner"},[e._v("\n "+e._s(e.textLength)+"/"+e._s(e.upperLimit)+"\n ")])]):e._e()],2),e.validateState?n("i",{staticClass:"el-input__icon",class:["el-input__validateIcon",e.validateIcon]}):e._e()]):e._e(),e.$slots.append?n("div",{staticClass:"el-input-group__append"},[e._t("append")],2):e._e()]:n("textarea",e._b({ref:"textarea",staticClass:"el-textarea__inner",style:e.textareaStyle,attrs:{tabindex:e.tabindex,disabled:e.inputDisabled,readonly:e.readonly,autocomplete:e.autoComplete||e.autocomplete,"aria-label":e.label},on:{compositionstart:e.handleCompositionStart,compositionupdate:e.handleCompositionUpdate,compositionend:e.handleCompositionEnd,input:e.handleInput,focus:e.handleFocus,blur:e.handleBlur,change:e.handleChange}},"textarea",e.$attrs,!1)),e.isWordLimitVisible&&"textarea"===e.type?n("span",{staticClass:"el-input__count"},[e._v(e._s(e.textLength)+"/"+e._s(e.upperLimit))]):e._e()],2)},bt=[];gt._withStripped=!0;var yt=void 0,_t="\n height:0 !important;\n visibility:hidden !important;\n overflow:hidden !important;\n position:absolute !important;\n z-index:-1000 !important;\n top:0 !important;\n right:0 !important\n",xt=["letter-spacing","line-height","padding-top","padding-bottom","font-family","font-weight","font-size","text-rendering","text-transform","width","text-indent","padding-left","padding-right","border-width","box-sizing"];function wt(e){var t=window.getComputedStyle(e),n=t.getPropertyValue("box-sizing"),i=parseFloat(t.getPropertyValue("padding-bottom"))+parseFloat(t.getPropertyValue("padding-top")),r=parseFloat(t.getPropertyValue("border-bottom-width"))+parseFloat(t.getPropertyValue("border-top-width")),o=xt.map((function(e){return e+":"+t.getPropertyValue(e)})).join(";");return{contextStyle:o,paddingSize:i,borderSize:r,boxSizing:n}}function Ct(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;yt||(yt=document.createElement("textarea"),document.body.appendChild(yt));var i=wt(e),r=i.paddingSize,o=i.borderSize,a=i.boxSizing,s=i.contextStyle;yt.setAttribute("style",s+";"+_t),yt.value=e.value||e.placeholder||"";var l=yt.scrollHeight,c={};"border-box"===a?l+=o:"content-box"===a&&(l-=r),yt.value="";var u=yt.scrollHeight-r;if(null!==t){var d=u*t;"border-box"===a&&(d=d+r+o),l=Math.max(d,l),c.minHeight=d+"px"}if(null!==n){var h=u*n;"border-box"===a&&(h=h+r+o),l=Math.min(h,l)}return c.height=l+"px",yt.parentNode&&yt.parentNode.removeChild(yt),yt=null,c}var kt=n(7),St=n.n(kt),Ot=n(19),$t={name:"ElInput",componentName:"ElInput",mixins:[D.a,O.a],inheritAttrs:!1,inject:{elForm:{default:""},elFormItem:{default:""}},data:function(){return{textareaCalcStyle:{},hovering:!1,focused:!1,isComposing:!1,passwordVisible:!1}},props:{value:[String,Number],size:String,resize:String,form:String,disabled:Boolean,readonly:Boolean,type:{type:String,default:"text"},autosize:{type:[Boolean,Object],default:!1},autocomplete:{type:String,default:"off"},autoComplete:{type:String,validator:function(e){return!0}},validateEvent:{type:Boolean,default:!0},suffixIcon:String,prefixIcon:String,label:String,clearable:{type:Boolean,default:!1},showPassword:{type:Boolean,default:!1},showWordLimit:{type:Boolean,default:!1},tabindex:String},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},validateState:function(){return this.elFormItem?this.elFormItem.validateState:""},needStatusIcon:function(){return!!this.elForm&&this.elForm.statusIcon},validateIcon:function(){return{validating:"el-icon-loading",success:"el-icon-circle-check",error:"el-icon-circle-close"}[this.validateState]},textareaStyle:function(){return St()({},this.textareaCalcStyle,{resize:this.resize})},inputSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},inputDisabled:function(){return this.disabled||(this.elForm||{}).disabled},nativeInputValue:function(){return null===this.value||void 0===this.value?"":String(this.value)},showClear:function(){return this.clearable&&!this.inputDisabled&&!this.readonly&&this.nativeInputValue&&(this.focused||this.hovering)},showPwdVisible:function(){return this.showPassword&&!this.inputDisabled&&!this.readonly&&(!!this.nativeInputValue||this.focused)},isWordLimitVisible:function(){return this.showWordLimit&&this.$attrs.maxlength&&("text"===this.type||"textarea"===this.type)&&!this.inputDisabled&&!this.readonly&&!this.showPassword},upperLimit:function(){return this.$attrs.maxlength},textLength:function(){return"number"===typeof this.value?String(this.value).length:(this.value||"").length},inputExceed:function(){return this.isWordLimitVisible&&this.textLength>this.upperLimit}},watch:{value:function(e){this.$nextTick(this.resizeTextarea),this.validateEvent&&this.dispatch("ElFormItem","el.form.change",[e])},nativeInputValue:function(){this.setNativeInputValue()},type:function(){var e=this;this.$nextTick((function(){e.setNativeInputValue(),e.resizeTextarea(),e.updateIconOffset()}))}},methods:{focus:function(){this.getInput().focus()},blur:function(){this.getInput().blur()},getMigratingConfig:function(){return{props:{icon:"icon is removed, use suffix-icon / prefix-icon instead.","on-icon-click":"on-icon-click is removed."},events:{click:"click is removed."}}},handleBlur:function(e){this.focused=!1,this.$emit("blur",e),this.validateEvent&&this.dispatch("ElFormItem","el.form.blur",[this.value])},select:function(){this.getInput().select()},resizeTextarea:function(){if(!this.$isServer){var e=this.autosize,t=this.type;if("textarea"===t)if(e){var n=e.minRows,i=e.maxRows;this.textareaCalcStyle=Ct(this.$refs.textarea,n,i)}else this.textareaCalcStyle={minHeight:Ct(this.$refs.textarea).minHeight}}},setNativeInputValue:function(){var e=this.getInput();e&&e.value!==this.nativeInputValue&&(e.value=this.nativeInputValue)},handleFocus:function(e){this.focused=!0,this.$emit("focus",e)},handleCompositionStart:function(){this.isComposing=!0},handleCompositionUpdate:function(e){var t=e.target.value,n=t[t.length-1]||"";this.isComposing=!Object(Ot["isKorean"])(n)},handleCompositionEnd:function(e){this.isComposing&&(this.isComposing=!1,this.handleInput(e))},handleInput:function(e){this.isComposing||e.target.value!==this.nativeInputValue&&(this.$emit("input",e.target.value),this.$nextTick(this.setNativeInputValue))},handleChange:function(e){this.$emit("change",e.target.value)},calcIconOffset:function(e){var t=[].slice.call(this.$el.querySelectorAll(".el-input__"+e)||[]);if(t.length){for(var n=null,i=0;i=0&&e===parseInt(e,10)}}},data:function(){return{currentValue:0,userInput:null}},watch:{value:{immediate:!0,handler:function(e){var t=void 0===e?e:Number(e);if(void 0!==t){if(isNaN(t))return;if(this.stepStrictly){var n=this.getPrecision(this.step),i=Math.pow(10,n);t=Math.round(t/this.step)*i*this.step/i}void 0!==this.precision&&(t=this.toPrecision(t,this.precision))}t>=this.max&&(t=this.max),t<=this.min&&(t=this.min),this.currentValue=t,this.userInput=null,this.$emit("input",t)}}},computed:{minDisabled:function(){return this._decrease(this.value,this.step)this.max},numPrecision:function(){var e=this.value,t=this.step,n=this.getPrecision,i=this.precision,r=n(t);return void 0!==i?(r>i&&console.warn("[Element Warn][InputNumber]precision should not be less than the decimal places of step"),i):Math.max(n(e),r)},controlsAtRight:function(){return this.controls&&"right"===this.controlsPosition},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},inputNumberSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},inputNumberDisabled:function(){return this.disabled||(this.elForm||{}).disabled},displayValue:function(){if(null!==this.userInput)return this.userInput;var e=this.currentValue;if("number"===typeof e){if(this.stepStrictly){var t=this.getPrecision(this.step),n=Math.pow(10,t);e=Math.round(e/this.step)*n*this.step/n}void 0!==this.precision&&(e=e.toFixed(this.precision))}return e}},methods:{toPrecision:function(e,t){return void 0===t&&(t=this.numPrecision),parseFloat(Math.round(e*Math.pow(10,t))/Math.pow(10,t))},getPrecision:function(e){if(void 0===e)return 0;var t=e.toString(),n=t.indexOf("."),i=0;return-1!==n&&(i=t.length-n-1),i},_increase:function(e,t){if("number"!==typeof e&&void 0!==e)return this.currentValue;var n=Math.pow(10,this.numPrecision);return this.toPrecision((n*e+n*t)/n)},_decrease:function(e,t){if("number"!==typeof e&&void 0!==e)return this.currentValue;var n=Math.pow(10,this.numPrecision);return this.toPrecision((n*e-n*t)/n)},increase:function(){if(!this.inputNumberDisabled&&!this.maxDisabled){var e=this.value||0,t=this._increase(e,this.step);this.setCurrentValue(t)}},decrease:function(){if(!this.inputNumberDisabled&&!this.minDisabled){var e=this.value||0,t=this._decrease(e,this.step);this.setCurrentValue(t)}},handleBlur:function(e){this.$emit("blur",e)},handleFocus:function(e){this.$emit("focus",e)},setCurrentValue:function(e){var t=this.currentValue;"number"===typeof e&&void 0!==this.precision&&(e=this.toPrecision(e,this.precision)),e>=this.max&&(e=this.max),e<=this.min&&(e=this.min),t!==e&&(this.userInput=null,this.$emit("input",e),this.$emit("change",e,t),this.currentValue=e)},handleInput:function(e){this.userInput=e},handleInputChange:function(e){var t=""===e?void 0:Number(e);isNaN(t)&&""!==e||this.setCurrentValue(t),this.userInput=null},select:function(){this.$refs.input.select()}},mounted:function(){var e=this.$refs.input.$refs.input;e.setAttribute("role","spinbutton"),e.setAttribute("aria-valuemax",this.max),e.setAttribute("aria-valuemin",this.min),e.setAttribute("aria-valuenow",this.currentValue),e.setAttribute("aria-disabled",this.inputNumberDisabled)},updated:function(){if(this.$refs&&this.$refs.input){var e=this.$refs.input.$refs.input;e.setAttribute("aria-valuenow",this.currentValue)}}},At=jt,Ft=s(At,Mt,It,!1,null,null,null);Ft.options.__file="packages/input-number/src/input-number.vue";var Lt=Ft.exports;Lt.install=function(e){e.component(Lt.name,Lt)};var Vt=Lt,zt=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("label",{staticClass:"el-radio",class:[e.border&&e.radioSize?"el-radio--"+e.radioSize:"",{"is-disabled":e.isDisabled},{"is-focus":e.focus},{"is-bordered":e.border},{"is-checked":e.model===e.label}],attrs:{role:"radio","aria-checked":e.model===e.label,"aria-disabled":e.isDisabled,tabindex:e.tabIndex},on:{keydown:function(t){if(!("button"in t)&&e._k(t.keyCode,"space",32,t.key,[" ","Spacebar"]))return null;t.stopPropagation(),t.preventDefault(),e.model=e.isDisabled?e.model:e.label}}},[n("span",{staticClass:"el-radio__input",class:{"is-disabled":e.isDisabled,"is-checked":e.model===e.label}},[n("span",{staticClass:"el-radio__inner"}),n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],ref:"radio",staticClass:"el-radio__original",attrs:{type:"radio","aria-hidden":"true",name:e.name,disabled:e.isDisabled,tabindex:"-1"},domProps:{value:e.label,checked:e._q(e.model,e.label)},on:{focus:function(t){e.focus=!0},blur:function(t){e.focus=!1},change:[function(t){e.model=e.label},e.handleChange]}})]),n("span",{staticClass:"el-radio__label",on:{keydown:function(e){e.stopPropagation()}}},[e._t("default"),e.$slots.default?e._e():[e._v(e._s(e.label))]],2)])},Bt=[];zt._withStripped=!0;var Rt={name:"ElRadio",mixins:[D.a],inject:{elForm:{default:""},elFormItem:{default:""}},componentName:"ElRadio",props:{value:{},label:{},disabled:Boolean,name:String,border:Boolean,size:String},data:function(){return{focus:!1}},computed:{isGroup:function(){var e=this.$parent;while(e){if("ElRadioGroup"===e.$options.componentName)return this._radioGroup=e,!0;e=e.$parent}return!1},model:{get:function(){return this.isGroup?this._radioGroup.value:this.value},set:function(e){this.isGroup?this.dispatch("ElRadioGroup","input",[e]):this.$emit("input",e),this.$refs.radio&&(this.$refs.radio.checked=this.model===this.label)}},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},radioSize:function(){var e=this.size||this._elFormItemSize||(this.$ELEMENT||{}).size;return this.isGroup&&this._radioGroup.radioGroupSize||e},isDisabled:function(){return this.isGroup?this._radioGroup.disabled||this.disabled||(this.elForm||{}).disabled:this.disabled||(this.elForm||{}).disabled},tabIndex:function(){return this.isDisabled||this.isGroup&&this.model!==this.label?-1:0}},methods:{handleChange:function(){var e=this;this.$nextTick((function(){e.$emit("change",e.model),e.isGroup&&e.dispatch("ElRadioGroup","handleChange",e.model)}))}}},Ht=Rt,Wt=s(Ht,zt,Bt,!1,null,null,null);Wt.options.__file="packages/radio/src/radio.vue";var qt=Wt.exports;qt.install=function(e){e.component(qt.name,qt)};var Ut=qt,Yt=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n(e._elTag,{tag:"component",staticClass:"el-radio-group",attrs:{role:"radiogroup"},on:{keydown:e.handleKeydown}},[e._t("default")],2)},Kt=[];Yt._withStripped=!0;var Gt=Object.freeze({LEFT:37,UP:38,RIGHT:39,DOWN:40}),Xt={name:"ElRadioGroup",componentName:"ElRadioGroup",inject:{elFormItem:{default:""}},mixins:[D.a],props:{value:{},size:String,fill:String,textColor:String,disabled:Boolean},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},_elTag:function(){return(this.$vnode.data||{}).tag||"div"},radioGroupSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size}},created:function(){var e=this;this.$on("handleChange",(function(t){e.$emit("change",t)}))},mounted:function(){var e=this.$el.querySelectorAll("[type=radio]"),t=this.$el.querySelectorAll("[role=radio]")[0];![].some.call(e,(function(e){return e.checked}))&&t&&(t.tabIndex=0)},methods:{handleKeydown:function(e){var t=e.target,n="INPUT"===t.nodeName?"[type=radio]":"[role=radio]",i=this.$el.querySelectorAll(n),r=i.length,o=[].indexOf.call(i,t),a=this.$el.querySelectorAll("[role=radio]");switch(e.keyCode){case Gt.LEFT:case Gt.UP:e.stopPropagation(),e.preventDefault(),0===o?(a[r-1].click(),a[r-1].focus()):(a[o-1].click(),a[o-1].focus());break;case Gt.RIGHT:case Gt.DOWN:o===r-1?(e.stopPropagation(),e.preventDefault(),a[0].click(),a[0].focus()):(a[o+1].click(),a[o+1].focus());break;default:break}}},watch:{value:function(e){this.dispatch("ElFormItem","el.form.change",[this.value])}}},Zt=Xt,Jt=s(Zt,Yt,Kt,!1,null,null,null);Jt.options.__file="packages/radio/src/radio-group.vue";var Qt=Jt.exports;Qt.install=function(e){e.component(Qt.name,Qt)};var en=Qt,tn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("label",{staticClass:"el-radio-button",class:[e.size?"el-radio-button--"+e.size:"",{"is-active":e.value===e.label},{"is-disabled":e.isDisabled},{"is-focus":e.focus}],attrs:{role:"radio","aria-checked":e.value===e.label,"aria-disabled":e.isDisabled,tabindex:e.tabIndex},on:{keydown:function(t){if(!("button"in t)&&e._k(t.keyCode,"space",32,t.key,[" ","Spacebar"]))return null;t.stopPropagation(),t.preventDefault(),e.value=e.isDisabled?e.value:e.label}}},[n("input",{directives:[{name:"model",rawName:"v-model",value:e.value,expression:"value"}],staticClass:"el-radio-button__orig-radio",attrs:{type:"radio",name:e.name,disabled:e.isDisabled,tabindex:"-1"},domProps:{value:e.label,checked:e._q(e.value,e.label)},on:{change:[function(t){e.value=e.label},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}}),n("span",{staticClass:"el-radio-button__inner",style:e.value===e.label?e.activeStyle:null,on:{keydown:function(e){e.stopPropagation()}}},[e._t("default"),e.$slots.default?e._e():[e._v(e._s(e.label))]],2)])},nn=[];tn._withStripped=!0;var rn={name:"ElRadioButton",mixins:[D.a],inject:{elForm:{default:""},elFormItem:{default:""}},props:{label:{},disabled:Boolean,name:String},data:function(){return{focus:!1}},computed:{value:{get:function(){return this._radioGroup.value},set:function(e){this._radioGroup.$emit("input",e)}},_radioGroup:function(){var e=this.$parent;while(e){if("ElRadioGroup"===e.$options.componentName)return e;e=e.$parent}return!1},activeStyle:function(){return{backgroundColor:this._radioGroup.fill||"",borderColor:this._radioGroup.fill||"",boxShadow:this._radioGroup.fill?"-1px 0 0 0 "+this._radioGroup.fill:"",color:this._radioGroup.textColor||""}},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},size:function(){return this._radioGroup.radioGroupSize||this._elFormItemSize||(this.$ELEMENT||{}).size},isDisabled:function(){return this.disabled||this._radioGroup.disabled||(this.elForm||{}).disabled},tabIndex:function(){return this.isDisabled||this._radioGroup&&this.value!==this.label?-1:0}},methods:{handleChange:function(){var e=this;this.$nextTick((function(){e.dispatch("ElRadioGroup","handleChange",e.value)}))}}},on=rn,an=s(on,tn,nn,!1,null,null,null);an.options.__file="packages/radio/src/radio-button.vue";var sn=an.exports;sn.install=function(e){e.component(sn.name,sn)};var ln=sn,cn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("label",{staticClass:"el-checkbox",class:[e.border&&e.checkboxSize?"el-checkbox--"+e.checkboxSize:"",{"is-disabled":e.isDisabled},{"is-bordered":e.border},{"is-checked":e.isChecked}],attrs:{id:e.id}},[n("span",{staticClass:"el-checkbox__input",class:{"is-disabled":e.isDisabled,"is-checked":e.isChecked,"is-indeterminate":e.indeterminate,"is-focus":e.focus},attrs:{tabindex:!!e.indeterminate&&0,role:!!e.indeterminate&&"checkbox","aria-checked":!!e.indeterminate&&"mixed"}},[n("span",{staticClass:"el-checkbox__inner"}),e.trueLabel||e.falseLabel?n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],staticClass:"el-checkbox__original",attrs:{type:"checkbox","aria-hidden":e.indeterminate?"true":"false",name:e.name,disabled:e.isDisabled,"true-value":e.trueLabel,"false-value":e.falseLabel},domProps:{checked:Array.isArray(e.model)?e._i(e.model,null)>-1:e._q(e.model,e.trueLabel)},on:{change:[function(t){var n=e.model,i=t.target,r=i.checked?e.trueLabel:e.falseLabel;if(Array.isArray(n)){var o=null,a=e._i(n,o);i.checked?a<0&&(e.model=n.concat([o])):a>-1&&(e.model=n.slice(0,a).concat(n.slice(a+1)))}else e.model=r},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}}):n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],staticClass:"el-checkbox__original",attrs:{type:"checkbox","aria-hidden":e.indeterminate?"true":"false",disabled:e.isDisabled,name:e.name},domProps:{value:e.label,checked:Array.isArray(e.model)?e._i(e.model,e.label)>-1:e.model},on:{change:[function(t){var n=e.model,i=t.target,r=!!i.checked;if(Array.isArray(n)){var o=e.label,a=e._i(n,o);i.checked?a<0&&(e.model=n.concat([o])):a>-1&&(e.model=n.slice(0,a).concat(n.slice(a+1)))}else e.model=r},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}})]),e.$slots.default||e.label?n("span",{staticClass:"el-checkbox__label"},[e._t("default"),e.$slots.default?e._e():[e._v(e._s(e.label))]],2):e._e()])},un=[];cn._withStripped=!0;var dn={name:"ElCheckbox",mixins:[D.a],inject:{elForm:{default:""},elFormItem:{default:""}},componentName:"ElCheckbox",data:function(){return{selfModel:!1,focus:!1,isLimitExceeded:!1}},computed:{model:{get:function(){return this.isGroup?this.store:void 0!==this.value?this.value:this.selfModel},set:function(e){this.isGroup?(this.isLimitExceeded=!1,void 0!==this._checkboxGroup.min&&e.lengththis._checkboxGroup.max&&(this.isLimitExceeded=!0),!1===this.isLimitExceeded&&this.dispatch("ElCheckboxGroup","input",[e])):(this.$emit("input",e),this.selfModel=e)}},isChecked:function(){return"[object Boolean]"==={}.toString.call(this.model)?this.model:Array.isArray(this.model)?this.model.indexOf(this.label)>-1:null!==this.model&&void 0!==this.model?this.model===this.trueLabel:void 0},isGroup:function(){var e=this.$parent;while(e){if("ElCheckboxGroup"===e.$options.componentName)return this._checkboxGroup=e,!0;e=e.$parent}return!1},store:function(){return this._checkboxGroup?this._checkboxGroup.value:this.value},isLimitDisabled:function(){var e=this._checkboxGroup,t=e.max,n=e.min;return!(!t&&!n)&&this.model.length>=t&&!this.isChecked||this.model.length<=n&&this.isChecked},isDisabled:function(){return this.isGroup?this._checkboxGroup.disabled||this.disabled||(this.elForm||{}).disabled||this.isLimitDisabled:this.disabled||(this.elForm||{}).disabled},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},checkboxSize:function(){var e=this.size||this._elFormItemSize||(this.$ELEMENT||{}).size;return this.isGroup&&this._checkboxGroup.checkboxGroupSize||e}},props:{value:{},label:{},indeterminate:Boolean,disabled:Boolean,checked:Boolean,name:String,trueLabel:[String,Number],falseLabel:[String,Number],id:String,controls:String,border:Boolean,size:String},methods:{addToStore:function(){Array.isArray(this.model)&&-1===this.model.indexOf(this.label)?this.model.push(this.label):this.model=this.trueLabel||!0},handleChange:function(e){var t=this;if(!this.isLimitExceeded){var n=void 0;n=e.target.checked?void 0===this.trueLabel||this.trueLabel:void 0!==this.falseLabel&&this.falseLabel,this.$emit("change",n,e),this.$nextTick((function(){t.isGroup&&t.dispatch("ElCheckboxGroup","change",[t._checkboxGroup.value])}))}}},created:function(){this.checked&&this.addToStore()},mounted:function(){this.indeterminate&&this.$el.setAttribute("aria-controls",this.controls)},watch:{value:function(e){this.dispatch("ElFormItem","el.form.change",e)}}},hn=dn,fn=s(hn,cn,un,!1,null,null,null);fn.options.__file="packages/checkbox/src/checkbox.vue";var pn=fn.exports;pn.install=function(e){e.component(pn.name,pn)};var mn=pn,vn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("label",{staticClass:"el-checkbox-button",class:[e.size?"el-checkbox-button--"+e.size:"",{"is-disabled":e.isDisabled},{"is-checked":e.isChecked},{"is-focus":e.focus}],attrs:{role:"checkbox","aria-checked":e.isChecked,"aria-disabled":e.isDisabled}},[e.trueLabel||e.falseLabel?n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],staticClass:"el-checkbox-button__original",attrs:{type:"checkbox",name:e.name,disabled:e.isDisabled,"true-value":e.trueLabel,"false-value":e.falseLabel},domProps:{checked:Array.isArray(e.model)?e._i(e.model,null)>-1:e._q(e.model,e.trueLabel)},on:{change:[function(t){var n=e.model,i=t.target,r=i.checked?e.trueLabel:e.falseLabel;if(Array.isArray(n)){var o=null,a=e._i(n,o);i.checked?a<0&&(e.model=n.concat([o])):a>-1&&(e.model=n.slice(0,a).concat(n.slice(a+1)))}else e.model=r},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}}):n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],staticClass:"el-checkbox-button__original",attrs:{type:"checkbox",name:e.name,disabled:e.isDisabled},domProps:{value:e.label,checked:Array.isArray(e.model)?e._i(e.model,e.label)>-1:e.model},on:{change:[function(t){var n=e.model,i=t.target,r=!!i.checked;if(Array.isArray(n)){var o=e.label,a=e._i(n,o);i.checked?a<0&&(e.model=n.concat([o])):a>-1&&(e.model=n.slice(0,a).concat(n.slice(a+1)))}else e.model=r},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}}),e.$slots.default||e.label?n("span",{staticClass:"el-checkbox-button__inner",style:e.isChecked?e.activeStyle:null},[e._t("default",[e._v(e._s(e.label))])],2):e._e()])},gn=[];vn._withStripped=!0;var bn={name:"ElCheckboxButton",mixins:[D.a],inject:{elForm:{default:""},elFormItem:{default:""}},data:function(){return{selfModel:!1,focus:!1,isLimitExceeded:!1}},props:{value:{},label:{},disabled:Boolean,checked:Boolean,name:String,trueLabel:[String,Number],falseLabel:[String,Number]},computed:{model:{get:function(){return this._checkboxGroup?this.store:void 0!==this.value?this.value:this.selfModel},set:function(e){this._checkboxGroup?(this.isLimitExceeded=!1,void 0!==this._checkboxGroup.min&&e.lengththis._checkboxGroup.max&&(this.isLimitExceeded=!0),!1===this.isLimitExceeded&&this.dispatch("ElCheckboxGroup","input",[e])):void 0!==this.value?this.$emit("input",e):this.selfModel=e}},isChecked:function(){return"[object Boolean]"==={}.toString.call(this.model)?this.model:Array.isArray(this.model)?this.model.indexOf(this.label)>-1:null!==this.model&&void 0!==this.model?this.model===this.trueLabel:void 0},_checkboxGroup:function(){var e=this.$parent;while(e){if("ElCheckboxGroup"===e.$options.componentName)return e;e=e.$parent}return!1},store:function(){return this._checkboxGroup?this._checkboxGroup.value:this.value},activeStyle:function(){return{backgroundColor:this._checkboxGroup.fill||"",borderColor:this._checkboxGroup.fill||"",color:this._checkboxGroup.textColor||"","box-shadow":"-1px 0 0 0 "+this._checkboxGroup.fill}},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},size:function(){return this._checkboxGroup.checkboxGroupSize||this._elFormItemSize||(this.$ELEMENT||{}).size},isLimitDisabled:function(){var e=this._checkboxGroup,t=e.max,n=e.min;return!(!t&&!n)&&this.model.length>=t&&!this.isChecked||this.model.length<=n&&this.isChecked},isDisabled:function(){return this._checkboxGroup?this._checkboxGroup.disabled||this.disabled||(this.elForm||{}).disabled||this.isLimitDisabled:this.disabled||(this.elForm||{}).disabled}},methods:{addToStore:function(){Array.isArray(this.model)&&-1===this.model.indexOf(this.label)?this.model.push(this.label):this.model=this.trueLabel||!0},handleChange:function(e){var t=this;if(!this.isLimitExceeded){var n=void 0;n=e.target.checked?void 0===this.trueLabel||this.trueLabel:void 0!==this.falseLabel&&this.falseLabel,this.$emit("change",n,e),this.$nextTick((function(){t._checkboxGroup&&t.dispatch("ElCheckboxGroup","change",[t._checkboxGroup.value])}))}}},created:function(){this.checked&&this.addToStore()}},yn=bn,_n=s(yn,vn,gn,!1,null,null,null);_n.options.__file="packages/checkbox/src/checkbox-button.vue";var xn=_n.exports;xn.install=function(e){e.component(xn.name,xn)};var wn=xn,Cn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-checkbox-group",attrs:{role:"group","aria-label":"checkbox-group"}},[e._t("default")],2)},kn=[];Cn._withStripped=!0;var Sn={name:"ElCheckboxGroup",componentName:"ElCheckboxGroup",mixins:[D.a],inject:{elFormItem:{default:""}},props:{value:{},disabled:Boolean,min:Number,max:Number,size:String,fill:String,textColor:String},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},checkboxGroupSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size}},watch:{value:function(e){this.dispatch("ElFormItem","el.form.change",[e])}}},On=Sn,$n=s(On,Cn,kn,!1,null,null,null);$n.options.__file="packages/checkbox/src/checkbox-group.vue";var Dn=$n.exports;Dn.install=function(e){e.component(Dn.name,Dn)};var En=Dn,Tn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-switch",class:{"is-disabled":e.switchDisabled,"is-checked":e.checked},attrs:{role:"switch","aria-checked":e.checked,"aria-disabled":e.switchDisabled},on:{click:function(t){return t.preventDefault(),e.switchValue(t)}}},[n("input",{ref:"input",staticClass:"el-switch__input",attrs:{type:"checkbox",id:e.id,name:e.name,"true-value":e.activeValue,"false-value":e.inactiveValue,disabled:e.switchDisabled},on:{change:e.handleChange,keydown:function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.switchValue(t):null}}}),e.inactiveIconClass||e.inactiveText?n("span",{class:["el-switch__label","el-switch__label--left",e.checked?"":"is-active"]},[e.inactiveIconClass?n("i",{class:[e.inactiveIconClass]}):e._e(),!e.inactiveIconClass&&e.inactiveText?n("span",{attrs:{"aria-hidden":e.checked}},[e._v(e._s(e.inactiveText))]):e._e()]):e._e(),n("span",{ref:"core",staticClass:"el-switch__core",style:{width:e.coreWidth+"px"}}),e.activeIconClass||e.activeText?n("span",{class:["el-switch__label","el-switch__label--right",e.checked?"is-active":""]},[e.activeIconClass?n("i",{class:[e.activeIconClass]}):e._e(),!e.activeIconClass&&e.activeText?n("span",{attrs:{"aria-hidden":!e.checked}},[e._v(e._s(e.activeText))]):e._e()]):e._e()])},Pn=[];Tn._withStripped=!0;var Mn={name:"ElSwitch",mixins:[Z()("input"),O.a,D.a],inject:{elForm:{default:""}},props:{value:{type:[Boolean,String,Number],default:!1},disabled:{type:Boolean,default:!1},width:{type:Number,default:40},activeIconClass:{type:String,default:""},inactiveIconClass:{type:String,default:""},activeText:String,inactiveText:String,activeColor:{type:String,default:""},inactiveColor:{type:String,default:""},activeValue:{type:[Boolean,String,Number],default:!0},inactiveValue:{type:[Boolean,String,Number],default:!1},name:{type:String,default:""},validateEvent:{type:Boolean,default:!0},id:String},data:function(){return{coreWidth:this.width}},created:function(){~[this.activeValue,this.inactiveValue].indexOf(this.value)||this.$emit("input",this.inactiveValue)},computed:{checked:function(){return this.value===this.activeValue},switchDisabled:function(){return this.disabled||(this.elForm||{}).disabled}},watch:{checked:function(){this.$refs.input.checked=this.checked,(this.activeColor||this.inactiveColor)&&this.setBackgroundColor(),this.validateEvent&&this.dispatch("ElFormItem","el.form.change",[this.value])}},methods:{handleChange:function(e){var t=this,n=this.checked?this.inactiveValue:this.activeValue;this.$emit("input",n),this.$emit("change",n),this.$nextTick((function(){t.$refs.input.checked=t.checked}))},setBackgroundColor:function(){var e=this.checked?this.activeColor:this.inactiveColor;this.$refs.core.style.borderColor=e,this.$refs.core.style.backgroundColor=e},switchValue:function(){!this.switchDisabled&&this.handleChange()},getMigratingConfig:function(){return{props:{"on-color":"on-color is renamed to active-color.","off-color":"off-color is renamed to inactive-color.","on-text":"on-text is renamed to active-text.","off-text":"off-text is renamed to inactive-text.","on-value":"on-value is renamed to active-value.","off-value":"off-value is renamed to inactive-value.","on-icon-class":"on-icon-class is renamed to active-icon-class.","off-icon-class":"off-icon-class is renamed to inactive-icon-class."}}}},mounted:function(){this.coreWidth=this.width||40,(this.activeColor||this.inactiveColor)&&this.setBackgroundColor(),this.$refs.input.checked=this.checked}},In=Mn,Nn=s(In,Tn,Pn,!1,null,null,null);Nn.options.__file="packages/switch/src/component.vue";var jn=Nn.exports;jn.install=function(e){e.component(jn.name,jn)};var An=jn,Fn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleClose,expression:"handleClose"}],staticClass:"el-select",class:[e.selectSize?"el-select--"+e.selectSize:""],on:{click:function(t){return t.stopPropagation(),e.toggleMenu(t)}}},[e.multiple?n("div",{ref:"tags",staticClass:"el-select__tags",style:{"max-width":e.inputWidth-32+"px",width:"100%"}},[e.collapseTags&&e.selected.length?n("span",[n("el-tag",{attrs:{closable:!e.selectDisabled,size:e.collapseTagSize,hit:e.selected[0].hitState,type:"info","disable-transitions":""},on:{close:function(t){e.deleteTag(t,e.selected[0])}}},[n("span",{staticClass:"el-select__tags-text"},[e._v(e._s(e.selected[0].currentLabel))])]),e.selected.length>1?n("el-tag",{attrs:{closable:!1,size:e.collapseTagSize,type:"info","disable-transitions":""}},[n("span",{staticClass:"el-select__tags-text"},[e._v("+ "+e._s(e.selected.length-1))])]):e._e()],1):e._e(),e.collapseTags?e._e():n("transition-group",{on:{"after-leave":e.resetInputHeight}},e._l(e.selected,(function(t){return n("el-tag",{key:e.getValueKey(t),attrs:{closable:!e.selectDisabled,size:e.collapseTagSize,hit:t.hitState,type:"info","disable-transitions":""},on:{close:function(n){e.deleteTag(n,t)}}},[n("span",{staticClass:"el-select__tags-text"},[e._v(e._s(t.currentLabel))])])})),1),e.filterable?n("input",{directives:[{name:"model",rawName:"v-model",value:e.query,expression:"query"}],ref:"input",staticClass:"el-select__input",class:[e.selectSize?"is-"+e.selectSize:""],style:{"flex-grow":"1",width:e.inputLength/(e.inputWidth-32)+"%","max-width":e.inputWidth-42+"px"},attrs:{type:"text",disabled:e.selectDisabled,autocomplete:e.autoComplete||e.autocomplete},domProps:{value:e.query},on:{focus:e.handleFocus,blur:function(t){e.softFocus=!1},keyup:e.managePlaceholder,keydown:[e.resetInputState,function(t){if(!("button"in t)&&e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"]))return null;t.preventDefault(),e.navigateOptions("next")},function(t){if(!("button"in t)&&e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"]))return null;t.preventDefault(),e.navigateOptions("prev")},function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?(t.preventDefault(),e.selectOption(t)):null},function(t){if(!("button"in t)&&e._k(t.keyCode,"esc",27,t.key,["Esc","Escape"]))return null;t.stopPropagation(),t.preventDefault(),e.visible=!1},function(t){return"button"in t||!e._k(t.keyCode,"delete",[8,46],t.key,["Backspace","Delete","Del"])?e.deletePrevTag(t):null},function(t){if(!("button"in t)&&e._k(t.keyCode,"tab",9,t.key,"Tab"))return null;e.visible=!1}],compositionstart:e.handleComposition,compositionupdate:e.handleComposition,compositionend:e.handleComposition,input:[function(t){t.target.composing||(e.query=t.target.value)},e.debouncedQueryChange]}}):e._e()],1):e._e(),n("el-input",{ref:"reference",class:{"is-focus":e.visible},attrs:{type:"text",placeholder:e.currentPlaceholder,name:e.name,id:e.id,autocomplete:e.autoComplete||e.autocomplete,size:e.selectSize,disabled:e.selectDisabled,readonly:e.readonly,"validate-event":!1,tabindex:e.multiple&&e.filterable?"-1":null},on:{focus:e.handleFocus,blur:e.handleBlur},nativeOn:{keyup:function(t){return e.debouncedOnInputChange(t)},keydown:[function(t){if(!("button"in t)&&e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"]))return null;t.stopPropagation(),t.preventDefault(),e.navigateOptions("next")},function(t){if(!("button"in t)&&e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"]))return null;t.stopPropagation(),t.preventDefault(),e.navigateOptions("prev")},function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?(t.preventDefault(),e.selectOption(t)):null},function(t){if(!("button"in t)&&e._k(t.keyCode,"esc",27,t.key,["Esc","Escape"]))return null;t.stopPropagation(),t.preventDefault(),e.visible=!1},function(t){if(!("button"in t)&&e._k(t.keyCode,"tab",9,t.key,"Tab"))return null;e.visible=!1}],paste:function(t){return e.debouncedOnInputChange(t)},mouseenter:function(t){e.inputHovering=!0},mouseleave:function(t){e.inputHovering=!1}},model:{value:e.selectedLabel,callback:function(t){e.selectedLabel=t},expression:"selectedLabel"}},[e.$slots.prefix?n("template",{slot:"prefix"},[e._t("prefix")],2):e._e(),n("template",{slot:"suffix"},[n("i",{directives:[{name:"show",rawName:"v-show",value:!e.showClose,expression:"!showClose"}],class:["el-select__caret","el-input__icon","el-icon-"+e.iconClass]}),e.showClose?n("i",{staticClass:"el-select__caret el-input__icon el-icon-circle-close",on:{click:e.handleClearClick}}):e._e()])],2),n("transition",{attrs:{name:"el-zoom-in-top"},on:{"before-enter":e.handleMenuEnter,"after-leave":e.doDestroy}},[n("el-select-menu",{directives:[{name:"show",rawName:"v-show",value:e.visible&&!1!==e.emptyText,expression:"visible && emptyText !== false"}],ref:"popper",attrs:{"append-to-body":e.popperAppendToBody}},[n("el-scrollbar",{directives:[{name:"show",rawName:"v-show",value:e.options.length>0&&!e.loading,expression:"options.length > 0 && !loading"}],ref:"scrollbar",class:{"is-empty":!e.allowCreate&&e.query&&0===e.filteredOptionsCount},attrs:{tag:"ul","wrap-class":"el-select-dropdown__wrap","view-class":"el-select-dropdown__list"}},[e.showNewOption?n("el-option",{attrs:{value:e.query,created:""}}):e._e(),e._t("default")],2),e.emptyText&&(!e.allowCreate||e.loading||e.allowCreate&&0===e.options.length)?[e.$slots.empty?e._t("empty"):n("p",{staticClass:"el-select-dropdown__empty"},[e._v("\n "+e._s(e.emptyText)+"\n ")])]:e._e()],2)],1)],1)},Ln=[];Fn._withStripped=!0;var Vn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-select-dropdown el-popper",class:[{"is-multiple":e.$parent.multiple},e.popperClass],style:{minWidth:e.minWidth}},[e._t("default")],2)},zn=[];Vn._withStripped=!0;var Bn={name:"ElSelectDropdown",componentName:"ElSelectDropdown",mixins:[H.a],props:{placement:{default:"bottom-start"},boundariesPadding:{default:0},popperOptions:{default:function(){return{gpuAcceleration:!1}}},visibleArrow:{default:!0},appendToBody:{type:Boolean,default:!0}},data:function(){return{minWidth:""}},computed:{popperClass:function(){return this.$parent.popperClass}},watch:{"$parent.inputWidth":function(){this.minWidth=this.$parent.$el.getBoundingClientRect().width+"px"}},mounted:function(){var e=this;this.referenceElm=this.$parent.$refs.reference.$el,this.$parent.popperElm=this.popperElm=this.$el,this.$on("updatePopper",(function(){e.$parent.visible&&e.updatePopper()})),this.$on("destroyPopper",this.destroyPopper)}},Rn=Bn,Hn=s(Rn,Vn,zn,!1,null,null,null);Hn.options.__file="packages/select/src/select-dropdown.vue";var Wn=Hn.exports,qn=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-select-dropdown__item",class:{selected:e.itemSelected,"is-disabled":e.disabled||e.groupDisabled||e.limitReached,hover:e.hover},on:{mouseenter:e.hoverItem,click:function(t){return t.stopPropagation(),e.selectOptionClick(t)}}},[e._t("default",[n("span",[e._v(e._s(e.currentLabel))])])],2)},Un=[];qn._withStripped=!0;var Yn="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Kn={mixins:[D.a],name:"ElOption",componentName:"ElOption",inject:["select"],props:{value:{required:!0},label:[String,Number],created:Boolean,disabled:{type:Boolean,default:!1}},data:function(){return{index:-1,groupDisabled:!1,visible:!0,hitState:!1,hover:!1}},computed:{isObject:function(){return"[object object]"===Object.prototype.toString.call(this.value).toLowerCase()},currentLabel:function(){return this.label||(this.isObject?"":this.value)},currentValue:function(){return this.value||this.label||""},itemSelected:function(){return this.select.multiple?this.contains(this.select.value,this.value):this.isEqual(this.value,this.select.value)},limitReached:function(){return!!this.select.multiple&&(!this.itemSelected&&(this.select.value||[]).length>=this.select.multipleLimit&&this.select.multipleLimit>0)}},watch:{currentLabel:function(){this.created||this.select.remote||this.dispatch("ElSelect","setSelected")},value:function(e,t){var n=this.select,i=n.remote,r=n.valueKey;if(!this.created&&!i){if(r&&"object"===("undefined"===typeof e?"undefined":Yn(e))&&"object"===("undefined"===typeof t?"undefined":Yn(t))&&e[r]===t[r])return;this.dispatch("ElSelect","setSelected")}}},methods:{isEqual:function(e,t){if(this.isObject){var n=this.select.valueKey;return Object(b["getValueByPath"])(e,n)===Object(b["getValueByPath"])(t,n)}return e===t},contains:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1];if(this.isObject){var n=this.select.valueKey;return e&&e.some((function(e){return Object(b["getValueByPath"])(e,n)===Object(b["getValueByPath"])(t,n)}))}return e&&e.indexOf(t)>-1},handleGroupDisabled:function(e){this.groupDisabled=e},hoverItem:function(){this.disabled||this.groupDisabled||(this.select.hoverIndex=this.select.options.indexOf(this))},selectOptionClick:function(){!0!==this.disabled&&!0!==this.groupDisabled&&this.dispatch("ElSelect","handleOptionClick",[this,!0])},queryChange:function(e){this.visible=new RegExp(Object(b["escapeRegexpString"])(e),"i").test(this.currentLabel)||this.created,this.visible||this.select.filteredOptionsCount--}},created:function(){this.select.options.push(this),this.select.cachedOptions.push(this),this.select.optionsCount++,this.select.filteredOptionsCount++,this.$on("queryChange",this.queryChange),this.$on("handleGroupDisabled",this.handleGroupDisabled)},beforeDestroy:function(){var e=this.select.cachedOptions.indexOf(this);e>-1&&this.select.cachedOptions.splice(e,1),this.select.onOptionDestroy(this.select.options.indexOf(this))}},Gn=Kn,Xn=s(Gn,qn,Un,!1,null,null,null);Xn.options.__file="packages/select/src/option.vue";var Zn=Xn.exports,Jn=n(28),Qn=n.n(Jn),ei=n(11),ti=n(15),ni=n.n(ti),ii=n(27),ri=n.n(ii),oi={data:function(){return{hoverOption:-1}},computed:{optionsAllDisabled:function(){return this.options.filter((function(e){return e.visible})).every((function(e){return e.disabled}))}},watch:{hoverIndex:function(e){var t=this;"number"===typeof e&&e>-1&&(this.hoverOption=this.options[e]||{}),this.options.forEach((function(e){e.hover=t.hoverOption===e}))}},methods:{navigateOptions:function(e){var t=this;if(this.visible){if(0!==this.options.length&&0!==this.filteredOptionsCount&&!this.optionsAllDisabled){"next"===e?(this.hoverIndex++,this.hoverIndex===this.options.length&&(this.hoverIndex=0)):"prev"===e&&(this.hoverIndex--,this.hoverIndex<0&&(this.hoverIndex=this.options.length-1));var n=this.options[this.hoverIndex];!0!==n.disabled&&!0!==n.groupDisabled&&n.visible||this.navigateOptions(e),this.$nextTick((function(){return t.scrollToOption(t.hoverOption)}))}}else this.visible=!0}}},ai={mixins:[D.a,g.a,Z()("reference"),oi],name:"ElSelect",componentName:"ElSelect",inject:{elForm:{default:""},elFormItem:{default:""}},provide:function(){return{select:this}},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},readonly:function(){return!this.filterable||this.multiple||!Object(b["isIE"])()&&!Object(b["isEdge"])()&&!this.visible},showClose:function(){var e=this.multiple?Array.isArray(this.value)&&this.value.length>0:void 0!==this.value&&null!==this.value&&""!==this.value,t=this.clearable&&!this.selectDisabled&&this.inputHovering&&e;return t},iconClass:function(){return this.remote&&this.filterable?"":this.visible?"arrow-up is-reverse":"arrow-up"},debounce:function(){return this.remote?300:0},emptyText:function(){return this.loading?this.loadingText||this.t("el.select.loading"):(!this.remote||""!==this.query||0!==this.options.length)&&(this.filterable&&this.query&&this.options.length>0&&0===this.filteredOptionsCount?this.noMatchText||this.t("el.select.noMatch"):0===this.options.length?this.noDataText||this.t("el.select.noData"):null)},showNewOption:function(){var e=this,t=this.options.filter((function(e){return!e.created})).some((function(t){return t.currentLabel===e.query}));return this.filterable&&this.allowCreate&&""!==this.query&&!t},selectSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},selectDisabled:function(){return this.disabled||(this.elForm||{}).disabled},collapseTagSize:function(){return["small","mini"].indexOf(this.selectSize)>-1?"mini":"small"}},components:{ElInput:m.a,ElSelectMenu:Wn,ElOption:Zn,ElTag:Qn.a,ElScrollbar:q.a},directives:{Clickoutside:V.a},props:{name:String,id:String,value:{required:!0},autocomplete:{type:String,default:"off"},autoComplete:{type:String,validator:function(e){return!0}},automaticDropdown:Boolean,size:String,disabled:Boolean,clearable:Boolean,filterable:Boolean,allowCreate:Boolean,loading:Boolean,popperClass:String,remote:Boolean,loadingText:String,noMatchText:String,noDataText:String,remoteMethod:Function,filterMethod:Function,multiple:Boolean,multipleLimit:{type:Number,default:0},placeholder:{type:String,default:function(){return Object(ti["t"])("el.select.placeholder")}},defaultFirstOption:Boolean,reserveKeyword:Boolean,valueKey:{type:String,default:"value"},collapseTags:Boolean,popperAppendToBody:{type:Boolean,default:!0}},data:function(){return{options:[],cachedOptions:[],createdLabel:null,createdSelected:!1,selected:this.multiple?[]:{},inputLength:20,inputWidth:0,initialInputHeight:0,cachedPlaceHolder:"",optionsCount:0,filteredOptionsCount:0,visible:!1,softFocus:!1,selectedLabel:"",hoverIndex:-1,query:"",previousQuery:null,inputHovering:!1,currentPlaceholder:"",menuVisibleOnFocus:!1,isOnComposition:!1,isSilentBlur:!1}},watch:{selectDisabled:function(){var e=this;this.$nextTick((function(){e.resetInputHeight()}))},placeholder:function(e){this.cachedPlaceHolder=this.currentPlaceholder=e},value:function(e,t){this.multiple&&(this.resetInputHeight(),e&&e.length>0||this.$refs.input&&""!==this.query?this.currentPlaceholder="":this.currentPlaceholder=this.cachedPlaceHolder,this.filterable&&!this.reserveKeyword&&(this.query="",this.handleQueryChange(this.query))),this.setSelected(),this.filterable&&!this.multiple&&(this.inputLength=20),Object(b["valueEquals"])(e,t)||this.dispatch("ElFormItem","el.form.change",e)},visible:function(e){var t=this;e?(this.broadcast("ElSelectDropdown","updatePopper"),this.filterable&&(this.query=this.remote?"":this.selectedLabel,this.handleQueryChange(this.query),this.multiple?this.$refs.input.focus():(this.remote||(this.broadcast("ElOption","queryChange",""),this.broadcast("ElOptionGroup","queryChange")),this.selectedLabel&&(this.currentPlaceholder=this.selectedLabel,this.selectedLabel="")))):(this.broadcast("ElSelectDropdown","destroyPopper"),this.$refs.input&&this.$refs.input.blur(),this.query="",this.previousQuery=null,this.selectedLabel="",this.inputLength=20,this.menuVisibleOnFocus=!1,this.resetHoverIndex(),this.$nextTick((function(){t.$refs.input&&""===t.$refs.input.value&&0===t.selected.length&&(t.currentPlaceholder=t.cachedPlaceHolder)})),this.multiple||(this.selected&&(this.filterable&&this.allowCreate&&this.createdSelected&&this.createdLabel?this.selectedLabel=this.createdLabel:this.selectedLabel=this.selected.currentLabel,this.filterable&&(this.query=this.selectedLabel)),this.filterable&&(this.currentPlaceholder=this.cachedPlaceHolder))),this.$emit("visible-change",e)},options:function(){var e=this;if(!this.$isServer){this.$nextTick((function(){e.broadcast("ElSelectDropdown","updatePopper")})),this.multiple&&this.resetInputHeight();var t=this.$el.querySelectorAll("input");-1===[].indexOf.call(t,document.activeElement)&&this.setSelected(),this.defaultFirstOption&&(this.filterable||this.remote)&&this.filteredOptionsCount&&this.checkDefaultFirstOption()}}},methods:{handleComposition:function(e){var t=this,n=e.target.value;if("compositionend"===e.type)this.isOnComposition=!1,this.$nextTick((function(e){return t.handleQueryChange(n)}));else{var i=n[n.length-1]||"";this.isOnComposition=!Object(Ot["isKorean"])(i)}},handleQueryChange:function(e){var t=this;this.previousQuery===e||this.isOnComposition||(null!==this.previousQuery||"function"!==typeof this.filterMethod&&"function"!==typeof this.remoteMethod?(this.previousQuery=e,this.$nextTick((function(){t.visible&&t.broadcast("ElSelectDropdown","updatePopper")})),this.hoverIndex=-1,this.multiple&&this.filterable&&this.$nextTick((function(){var e=15*t.$refs.input.value.length+20;t.inputLength=t.collapseTags?Math.min(50,e):e,t.managePlaceholder(),t.resetInputHeight()})),this.remote&&"function"===typeof this.remoteMethod?(this.hoverIndex=-1,this.remoteMethod(e)):"function"===typeof this.filterMethod?(this.filterMethod(e),this.broadcast("ElOptionGroup","queryChange")):(this.filteredOptionsCount=this.optionsCount,this.broadcast("ElOption","queryChange",e),this.broadcast("ElOptionGroup","queryChange")),this.defaultFirstOption&&(this.filterable||this.remote)&&this.filteredOptionsCount&&this.checkDefaultFirstOption()):this.previousQuery=e)},scrollToOption:function(e){var t=Array.isArray(e)&&e[0]?e[0].$el:e.$el;if(this.$refs.popper&&t){var n=this.$refs.popper.$el.querySelector(".el-select-dropdown__wrap");ri()(n,t)}this.$refs.scrollbar&&this.$refs.scrollbar.handleScroll()},handleMenuEnter:function(){var e=this;this.$nextTick((function(){return e.scrollToOption(e.selected)}))},emitChange:function(e){Object(b["valueEquals"])(this.value,e)||this.$emit("change",e)},getOption:function(e){for(var t=void 0,n="[object object]"===Object.prototype.toString.call(e).toLowerCase(),i="[object null]"===Object.prototype.toString.call(e).toLowerCase(),r="[object undefined]"===Object.prototype.toString.call(e).toLowerCase(),o=this.cachedOptions.length-1;o>=0;o--){var a=this.cachedOptions[o],s=n?Object(b["getValueByPath"])(a.value,this.valueKey)===Object(b["getValueByPath"])(e,this.valueKey):a.value===e;if(s){t=a;break}}if(t)return t;var l=n||i||r?"":e,c={value:e,currentLabel:l};return this.multiple&&(c.hitState=!1),c},setSelected:function(){var e=this;if(!this.multiple){var t=this.getOption(this.value);return t.created?(this.createdLabel=t.currentLabel,this.createdSelected=!0):this.createdSelected=!1,this.selectedLabel=t.currentLabel,this.selected=t,void(this.filterable&&(this.query=this.selectedLabel))}var n=[];Array.isArray(this.value)&&this.value.forEach((function(t){n.push(e.getOption(t))})),this.selected=n,this.$nextTick((function(){e.resetInputHeight()}))},handleFocus:function(e){this.softFocus?this.softFocus=!1:((this.automaticDropdown||this.filterable)&&(this.visible=!0,this.filterable&&(this.menuVisibleOnFocus=!0)),this.$emit("focus",e))},blur:function(){this.visible=!1,this.$refs.reference.blur()},handleBlur:function(e){var t=this;setTimeout((function(){t.isSilentBlur?t.isSilentBlur=!1:t.$emit("blur",e)}),50),this.softFocus=!1},handleClearClick:function(e){this.deleteSelected(e)},doDestroy:function(){this.$refs.popper&&this.$refs.popper.doDestroy()},handleClose:function(){this.visible=!1},toggleLastOptionHitState:function(e){if(Array.isArray(this.selected)){var t=this.selected[this.selected.length-1];if(t)return!0===e||!1===e?(t.hitState=e,e):(t.hitState=!t.hitState,t.hitState)}},deletePrevTag:function(e){if(e.target.value.length<=0&&!this.toggleLastOptionHitState()){var t=this.value.slice();t.pop(),this.$emit("input",t),this.emitChange(t)}},managePlaceholder:function(){""!==this.currentPlaceholder&&(this.currentPlaceholder=this.$refs.input.value?"":this.cachedPlaceHolder)},resetInputState:function(e){8!==e.keyCode&&this.toggleLastOptionHitState(!1),this.inputLength=15*this.$refs.input.value.length+20,this.resetInputHeight()},resetInputHeight:function(){var e=this;this.collapseTags&&!this.filterable||this.$nextTick((function(){if(e.$refs.reference){var t=e.$refs.reference.$el.childNodes,n=[].filter.call(t,(function(e){return"INPUT"===e.tagName}))[0],i=e.$refs.tags,r=e.initialInputHeight||40;n.style.height=0===e.selected.length?r+"px":Math.max(i?i.clientHeight+(i.clientHeight>r?6:0):0,r)+"px",e.visible&&!1!==e.emptyText&&e.broadcast("ElSelectDropdown","updatePopper")}}))},resetHoverIndex:function(){var e=this;setTimeout((function(){e.multiple?e.selected.length>0?e.hoverIndex=Math.min.apply(null,e.selected.map((function(t){return e.options.indexOf(t)}))):e.hoverIndex=-1:e.hoverIndex=e.options.indexOf(e.selected)}),300)},handleOptionSelect:function(e,t){var n=this;if(this.multiple){var i=(this.value||[]).slice(),r=this.getValueIndex(i,e.value);r>-1?i.splice(r,1):(this.multipleLimit<=0||i.length0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1],n="[object object]"===Object.prototype.toString.call(t).toLowerCase();if(n){var i=this.valueKey,r=-1;return e.some((function(e,n){return Object(b["getValueByPath"])(e,i)===Object(b["getValueByPath"])(t,i)&&(r=n,!0)})),r}return e.indexOf(t)},toggleMenu:function(){this.selectDisabled||(this.menuVisibleOnFocus?this.menuVisibleOnFocus=!1:this.visible=!this.visible,this.visible&&(this.$refs.input||this.$refs.reference).focus())},selectOption:function(){this.visible?this.options[this.hoverIndex]&&this.handleOptionSelect(this.options[this.hoverIndex]):this.toggleMenu()},deleteSelected:function(e){e.stopPropagation();var t=this.multiple?[]:"";this.$emit("input",t),this.emitChange(t),this.visible=!1,this.$emit("clear")},deleteTag:function(e,t){var n=this.selected.indexOf(t);if(n>-1&&!this.selectDisabled){var i=this.value.slice();i.splice(n,1),this.$emit("input",i),this.emitChange(i),this.$emit("remove-tag",t.value)}e.stopPropagation()},onInputChange:function(){this.filterable&&this.query!==this.selectedLabel&&(this.query=this.selectedLabel,this.handleQueryChange(this.query))},onOptionDestroy:function(e){e>-1&&(this.optionsCount--,this.filteredOptionsCount--,this.options.splice(e,1))},resetInputWidth:function(){this.inputWidth=this.$refs.reference.$el.getBoundingClientRect().width},handleResize:function(){this.resetInputWidth(),this.multiple&&this.resetInputHeight()},checkDefaultFirstOption:function(){this.hoverIndex=-1;for(var e=!1,t=this.options.length-1;t>=0;t--)if(this.options[t].created){e=!0,this.hoverIndex=t;break}if(!e)for(var n=0;n!==this.options.length;++n){var i=this.options[n];if(this.query){if(!i.disabled&&!i.groupDisabled&&i.visible){this.hoverIndex=n;break}}else if(i.itemSelected){this.hoverIndex=n;break}}},getValueKey:function(e){return"[object object]"!==Object.prototype.toString.call(e.value).toLowerCase()?e.value:Object(b["getValueByPath"])(e.value,this.valueKey)}},created:function(){var e=this;this.cachedPlaceHolder=this.currentPlaceholder=this.placeholder,this.multiple&&!Array.isArray(this.value)&&this.$emit("input",[]),!this.multiple&&Array.isArray(this.value)&&this.$emit("input",""),this.debouncedOnInputChange=F()(this.debounce,(function(){e.onInputChange()})),this.debouncedQueryChange=F()(this.debounce,(function(t){e.handleQueryChange(t.target.value)})),this.$on("handleOptionClick",this.handleOptionSelect),this.$on("setSelected",this.setSelected)},mounted:function(){var e=this;this.multiple&&Array.isArray(this.value)&&this.value.length>0&&(this.currentPlaceholder=""),Object(ei["addResizeListener"])(this.$el,this.handleResize);var t=this.$refs.reference;if(t&&t.$el){var n={medium:36,small:32,mini:28},i=t.$el.querySelector("input");this.initialInputHeight=i.getBoundingClientRect().height||n[this.selectSize]}this.remote&&this.multiple&&this.resetInputHeight(),this.$nextTick((function(){t&&t.$el&&(e.inputWidth=t.$el.getBoundingClientRect().width)})),this.setSelected()},beforeDestroy:function(){this.$el&&this.handleResize&&Object(ei["removeResizeListener"])(this.$el,this.handleResize)}},si=ai,li=s(si,Fn,Ln,!1,null,null,null);li.options.__file="packages/select/src/select.vue";var ci=li.exports;ci.install=function(e){e.component(ci.name,ci)};var ui=ci;Zn.install=function(e){e.component(Zn.name,Zn)};var di=Zn,hi=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("ul",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-select-group__wrap"},[n("li",{staticClass:"el-select-group__title"},[e._v(e._s(e.label))]),n("li",[n("ul",{staticClass:"el-select-group"},[e._t("default")],2)])])},fi=[];hi._withStripped=!0;var pi={mixins:[D.a],name:"ElOptionGroup",componentName:"ElOptionGroup",props:{label:String,disabled:{type:Boolean,default:!1}},data:function(){return{visible:!0}},watch:{disabled:function(e){this.broadcast("ElOption","handleGroupDisabled",e)}},methods:{queryChange:function(){this.visible=this.$children&&Array.isArray(this.$children)&&this.$children.some((function(e){return!0===e.visible}))}},created:function(){this.$on("queryChange",this.queryChange)},mounted:function(){this.disabled&&this.broadcast("ElOption","handleGroupDisabled",this.disabled)}},mi=pi,vi=s(mi,hi,fi,!1,null,null,null);vi.options.__file="packages/select/src/option-group.vue";var gi=vi.exports;gi.install=function(e){e.component(gi.name,gi)};var bi=gi,yi=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("button",{staticClass:"el-button",class:[e.type?"el-button--"+e.type:"",e.buttonSize?"el-button--"+e.buttonSize:"",{"is-disabled":e.buttonDisabled,"is-loading":e.loading,"is-plain":e.plain,"is-round":e.round,"is-circle":e.circle}],attrs:{disabled:e.buttonDisabled||e.loading,autofocus:e.autofocus,type:e.nativeType},on:{click:e.handleClick}},[e.loading?n("i",{staticClass:"el-icon-loading"}):e._e(),e.icon&&!e.loading?n("i",{class:e.icon}):e._e(),e.$slots.default?n("span",[e._t("default")],2):e._e()])},_i=[];yi._withStripped=!0;var xi={name:"ElButton",inject:{elForm:{default:""},elFormItem:{default:""}},props:{type:{type:String,default:"default"},size:String,icon:{type:String,default:""},nativeType:{type:String,default:"button"},loading:Boolean,disabled:Boolean,plain:Boolean,autofocus:Boolean,round:Boolean,circle:Boolean},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},buttonSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},buttonDisabled:function(){return this.disabled||(this.elForm||{}).disabled}},methods:{handleClick:function(e){this.$emit("click",e)}}},wi=xi,Ci=s(wi,yi,_i,!1,null,null,null);Ci.options.__file="packages/button/src/button.vue";var ki=Ci.exports;ki.install=function(e){e.component(ki.name,ki)};var Si=ki,Oi=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-button-group"},[e._t("default")],2)},$i=[];Oi._withStripped=!0;var Di={name:"ElButtonGroup"},Ei=Di,Ti=s(Ei,Oi,$i,!1,null,null,null);Ti.options.__file="packages/button/src/button-group.vue";var Pi=Ti.exports;Pi.install=function(e){e.component(Pi.name,Pi)};var Mi=Pi,Ii=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-table",class:[{"el-table--fit":e.fit,"el-table--striped":e.stripe,"el-table--border":e.border||e.isGroup,"el-table--hidden":e.isHidden,"el-table--group":e.isGroup,"el-table--fluid-height":e.maxHeight,"el-table--scrollable-x":e.layout.scrollX,"el-table--scrollable-y":e.layout.scrollY,"el-table--enable-row-hover":!e.store.states.isComplex,"el-table--enable-row-transition":0!==(e.store.states.data||[]).length&&(e.store.states.data||[]).length<100},e.tableSize?"el-table--"+e.tableSize:""],on:{mouseleave:function(t){e.handleMouseLeave(t)}}},[n("div",{ref:"hiddenColumns",staticClass:"hidden-columns"},[e._t("default")],2),e.showHeader?n("div",{directives:[{name:"mousewheel",rawName:"v-mousewheel",value:e.handleHeaderFooterMousewheel,expression:"handleHeaderFooterMousewheel"}],ref:"headerWrapper",staticClass:"el-table__header-wrapper"},[n("table-header",{ref:"tableHeader",style:{width:e.layout.bodyWidth?e.layout.bodyWidth+"px":""},attrs:{store:e.store,border:e.border,"default-sort":e.defaultSort}})],1):e._e(),n("div",{ref:"bodyWrapper",staticClass:"el-table__body-wrapper",class:[e.layout.scrollX?"is-scrolling-"+e.scrollPosition:"is-scrolling-none"],style:[e.bodyHeight]},[n("table-body",{style:{width:e.bodyWidth},attrs:{context:e.context,store:e.store,stripe:e.stripe,"row-class-name":e.rowClassName,"row-style":e.rowStyle,highlight:e.highlightCurrentRow}}),e.data&&0!==e.data.length?e._e():n("div",{ref:"emptyBlock",staticClass:"el-table__empty-block",style:e.emptyBlockStyle},[n("span",{staticClass:"el-table__empty-text"},[e._t("empty",[e._v(e._s(e.emptyText||e.t("el.table.emptyText")))])],2)]),e.$slots.append?n("div",{ref:"appendWrapper",staticClass:"el-table__append-wrapper"},[e._t("append")],2):e._e()],1),e.showSummary?n("div",{directives:[{name:"show",rawName:"v-show",value:e.data&&e.data.length>0,expression:"data && data.length > 0"},{name:"mousewheel",rawName:"v-mousewheel",value:e.handleHeaderFooterMousewheel,expression:"handleHeaderFooterMousewheel"}],ref:"footerWrapper",staticClass:"el-table__footer-wrapper"},[n("table-footer",{style:{width:e.layout.bodyWidth?e.layout.bodyWidth+"px":""},attrs:{store:e.store,border:e.border,"sum-text":e.sumText||e.t("el.table.sumText"),"summary-method":e.summaryMethod,"default-sort":e.defaultSort}})],1):e._e(),e.fixedColumns.length>0?n("div",{directives:[{name:"mousewheel",rawName:"v-mousewheel",value:e.handleFixedMousewheel,expression:"handleFixedMousewheel"}],ref:"fixedWrapper",staticClass:"el-table__fixed",style:[{width:e.layout.fixedWidth?e.layout.fixedWidth+"px":""},e.fixedHeight]},[e.showHeader?n("div",{ref:"fixedHeaderWrapper",staticClass:"el-table__fixed-header-wrapper"},[n("table-header",{ref:"fixedTableHeader",style:{width:e.bodyWidth},attrs:{fixed:"left",border:e.border,store:e.store}})],1):e._e(),n("div",{ref:"fixedBodyWrapper",staticClass:"el-table__fixed-body-wrapper",style:[{top:e.layout.headerHeight+"px"},e.fixedBodyHeight]},[n("table-body",{style:{width:e.bodyWidth},attrs:{fixed:"left",store:e.store,stripe:e.stripe,highlight:e.highlightCurrentRow,"row-class-name":e.rowClassName,"row-style":e.rowStyle}}),e.$slots.append?n("div",{staticClass:"el-table__append-gutter",style:{height:e.layout.appendHeight+"px"}}):e._e()],1),e.showSummary?n("div",{directives:[{name:"show",rawName:"v-show",value:e.data&&e.data.length>0,expression:"data && data.length > 0"}],ref:"fixedFooterWrapper",staticClass:"el-table__fixed-footer-wrapper"},[n("table-footer",{style:{width:e.bodyWidth},attrs:{fixed:"left",border:e.border,"sum-text":e.sumText||e.t("el.table.sumText"),"summary-method":e.summaryMethod,store:e.store}})],1):e._e()]):e._e(),e.rightFixedColumns.length>0?n("div",{directives:[{name:"mousewheel",rawName:"v-mousewheel",value:e.handleFixedMousewheel,expression:"handleFixedMousewheel"}],ref:"rightFixedWrapper",staticClass:"el-table__fixed-right",style:[{width:e.layout.rightFixedWidth?e.layout.rightFixedWidth+"px":"",right:e.layout.scrollY?(e.border?e.layout.gutterWidth:e.layout.gutterWidth||0)+"px":""},e.fixedHeight]},[e.showHeader?n("div",{ref:"rightFixedHeaderWrapper",staticClass:"el-table__fixed-header-wrapper"},[n("table-header",{ref:"rightFixedTableHeader",style:{width:e.bodyWidth},attrs:{fixed:"right",border:e.border,store:e.store}})],1):e._e(),n("div",{ref:"rightFixedBodyWrapper",staticClass:"el-table__fixed-body-wrapper",style:[{top:e.layout.headerHeight+"px"},e.fixedBodyHeight]},[n("table-body",{style:{width:e.bodyWidth},attrs:{fixed:"right",store:e.store,stripe:e.stripe,"row-class-name":e.rowClassName,"row-style":e.rowStyle,highlight:e.highlightCurrentRow}}),e.$slots.append?n("div",{staticClass:"el-table__append-gutter",style:{height:e.layout.appendHeight+"px"}}):e._e()],1),e.showSummary?n("div",{directives:[{name:"show",rawName:"v-show",value:e.data&&e.data.length>0,expression:"data && data.length > 0"}],ref:"rightFixedFooterWrapper",staticClass:"el-table__fixed-footer-wrapper"},[n("table-footer",{style:{width:e.bodyWidth},attrs:{fixed:"right",border:e.border,"sum-text":e.sumText||e.t("el.table.sumText"),"summary-method":e.summaryMethod,store:e.store}})],1):e._e()]):e._e(),e.rightFixedColumns.length>0?n("div",{ref:"rightFixedPatch",staticClass:"el-table__fixed-right-patch",style:{width:e.layout.scrollY?e.layout.gutterWidth+"px":"0",height:e.layout.headerHeight+"px"}}):e._e(),n("div",{directives:[{name:"show",rawName:"v-show",value:e.resizeProxyVisible,expression:"resizeProxyVisible"}],ref:"resizeProxy",staticClass:"el-table__column-resize-proxy"})])},Ni=[];Ii._withStripped=!0;var ji=n(14),Ai=n.n(ji),Fi=n(34),Li=n(38),Vi=n.n(Li),zi="undefined"!==typeof navigator&&navigator.userAgent.toLowerCase().indexOf("firefox")>-1,Bi=function(e,t){e&&e.addEventListener&&e.addEventListener(zi?"DOMMouseScroll":"mousewheel",(function(e){var n=Vi()(e);t&&t.apply(this,[e,n])}))},Ri={bind:function(e,t){Bi(e,t.value)}},Hi=n(6),Wi=n.n(Hi),qi="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ui=function(e){var t=e.target;while(t&&"HTML"!==t.tagName.toUpperCase()){if("TD"===t.tagName.toUpperCase())return t;t=t.parentNode}return null},Yi=function(e){return null!==e&&"object"===("undefined"===typeof e?"undefined":qi(e))},Ki=function(e,t,n,i,r){if(!t&&!i&&(!r||Array.isArray(r)&&!r.length))return e;n="string"===typeof n?"descending"===n?-1:1:n&&n<0?-1:1;var o=i?null:function(n,i){return r?(Array.isArray(r)||(r=[r]),r.map((function(t){return"string"===typeof t?Object(b["getValueByPath"])(n,t):t(n,i,e)}))):("$key"!==t&&Yi(n)&&"$value"in n&&(n=n.$value),[Yi(n)?Object(b["getValueByPath"])(n,t):n])},a=function(e,t){if(i)return i(e.value,t.value);for(var n=0,r=e.key.length;nt.key[n])return 1}return 0};return e.map((function(e,t){return{value:e,index:t,key:o?o(e,t):null}})).sort((function(e,t){var i=a(e,t);return i||(i=e.index-t.index),i*n})).map((function(e){return e.value}))},Gi=function(e,t){var n=null;return e.columns.forEach((function(e){e.id===t&&(n=e)})),n},Xi=function(e,t){for(var n=null,i=0;i2&&void 0!==arguments[2]?arguments[2]:"children",i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"hasChildren",r=function(e){return!(Array.isArray(e)&&e.length)};function o(e,a,s){t(e,a,s),a.forEach((function(e){if(e[i])t(e,null,s+1);else{var a=e[n];r(a)||o(e,a,s+1)}}))}e.forEach((function(e){if(e[i])t(e,null,0);else{var a=e[n];r(a)||o(e,a,0)}}))}var lr={data:function(){return{states:{defaultExpandAll:!1,expandRows:[]}}},methods:{updateExpandRows:function(){var e=this.states,t=e.data,n=void 0===t?[]:t,i=e.rowKey,r=e.defaultExpandAll,o=e.expandRows;if(r)this.states.expandRows=n.slice();else if(i){var a=Qi(o,i);this.states.expandRows=n.reduce((function(e,t){var n=Ji(t,i),r=a[n];return r&&e.push(t),e}),[])}else this.states.expandRows=[]},toggleRowExpansion:function(e,t){var n=ar(this.states.expandRows,e,t);n&&(this.table.$emit("expand-change",e,this.states.expandRows.slice()),this.scheduleLayout())},setExpandRowKeys:function(e){this.assertRowKey();var t=this.states,n=t.data,i=t.rowKey,r=Qi(n,i);this.states.expandRows=e.reduce((function(e,t){var n=r[t];return n&&e.push(n.row),e}),[])},isRowExpanded:function(e){var t=this.states,n=t.expandRows,i=void 0===n?[]:n,r=t.rowKey;if(r){var o=Qi(i,r);return!!o[Ji(e,r)]}return-1!==i.indexOf(e)}}},cr={data:function(){return{states:{_currentRowKey:null,currentRow:null}}},methods:{setCurrentRowKey:function(e){this.assertRowKey(),this.states._currentRowKey=e,this.setCurrentRowByKey(e)},restoreCurrentRowKey:function(){this.states._currentRowKey=null},setCurrentRowByKey:function(e){var t=this.states,n=t.data,i=void 0===n?[]:n,r=t.rowKey,o=null;r&&(o=Object(b["arrayFind"])(i,(function(t){return Ji(t,r)===e}))),t.currentRow=o},updateCurrentRow:function(e){var t=this.states,n=this.table,i=t.currentRow;if(e&&e!==i)return t.currentRow=e,void n.$emit("current-change",e,i);!e&&i&&(t.currentRow=null,n.$emit("current-change",null,i))},updateCurrentRowData:function(){var e=this.states,t=this.table,n=e.rowKey,i=e._currentRowKey,r=e.data||[],o=e.currentRow;if(-1===r.indexOf(o)&&o){if(n){var a=Ji(o,n);this.setCurrentRowByKey(a)}else e.currentRow=null;null===e.currentRow&&t.$emit("current-change",null,o)}else i&&(this.setCurrentRowByKey(i),this.restoreCurrentRowKey())}}},ur=Object.assign||function(e){for(var t=1;t0&&t[0]&&"selection"===t[0].type&&!t[0].fixed&&(t[0].fixed=!0,e.fixedColumns.unshift(t[0]));var n=t.filter((function(e){return!e.fixed}));e.originColumns=[].concat(e.fixedColumns).concat(n).concat(e.rightFixedColumns);var i=fr(n),r=fr(e.fixedColumns),o=fr(e.rightFixedColumns);e.leafColumnsLength=i.length,e.fixedLeafColumnsLength=r.length,e.rightFixedLeafColumnsLength=o.length,e.columns=[].concat(r).concat(i).concat(o),e.isComplex=e.fixedColumns.length>0||e.rightFixedColumns.length>0},scheduleLayout:function(e){e&&this.updateColumns(),this.table.debouncedUpdateLayout()},isSelected:function(e){var t=this.states.selection,n=void 0===t?[]:t;return n.indexOf(e)>-1},clearSelection:function(){var e=this.states;e.isAllSelected=!1;var t=e.selection;t.length&&(e.selection=[],this.table.$emit("selection-change",[]))},cleanSelection:function(){var e=this.states,t=e.data,n=e.rowKey,i=e.selection,r=void 0;if(n){r=[];var o=Qi(i,n),a=Qi(t,n);for(var s in o)o.hasOwnProperty(s)&&!a[s]&&r.push(o[s].row)}else r=i.filter((function(e){return-1===t.indexOf(e)}));if(r.length){var l=i.filter((function(e){return-1===r.indexOf(e)}));e.selection=l,this.table.$emit("selection-change",l.slice())}},toggleRowSelection:function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],i=ar(this.states.selection,e,t);if(i){var r=(this.states.selection||[]).slice();n&&this.table.$emit("select",r,e),this.table.$emit("selection-change",r)}},_toggleAllSelection:function(){var e=this.states,t=e.data,n=void 0===t?[]:t,i=e.selection,r=e.selectOnIndeterminate?!e.isAllSelected:!(e.isAllSelected||i.length);e.isAllSelected=r;var o=!1;n.forEach((function(t,n){e.selectable?e.selectable.call(null,t,n)&&ar(i,t,r)&&(o=!0):ar(i,t,r)&&(o=!0)})),o&&this.table.$emit("selection-change",i?i.slice():[]),this.table.$emit("select-all",i)},updateSelectionByRowKey:function(){var e=this.states,t=e.selection,n=e.rowKey,i=e.data,r=Qi(t,n);i.forEach((function(e){var i=Ji(e,n),o=r[i];o&&(t[o.index]=e)}))},updateAllSelected:function(){var e=this.states,t=e.selection,n=e.rowKey,i=e.selectable,r=e.data||[];if(0!==r.length){var o=void 0;n&&(o=Qi(t,n));for(var a=function(e){return o?!!o[Ji(e,n)]:-1!==t.indexOf(e)},s=!0,l=0,c=0,u=r.length;c1?n-1:0),r=1;r1&&void 0!==arguments[1]?arguments[1]:{};if(!e)throw new Error("Table is required.");var n=new mr;return n.table=e,n.toggleAllSelection=F()(10,n._toggleAllSelection),Object.keys(t).forEach((function(e){n.states[e]=t[e]})),n}function gr(e){var t={};return Object.keys(e).forEach((function(n){var i=e[n],r=void 0;"string"===typeof i?r=function(){return this.store.states[i]}:"function"===typeof i?r=function(){return i.call(this,this.store.states)}:console.error("invalid value type"),r&&(t[n]=r)})),t}var br=n(29),yr=n.n(br);function _r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var xr=function(){function e(t){for(var n in _r(this,e),this.observers=[],this.table=null,this.store=null,this.columns=null,this.fit=!0,this.showHeader=!0,this.height=null,this.scrollX=!1,this.scrollY=!1,this.bodyWidth=null,this.fixedWidth=null,this.rightFixedWidth=null,this.tableHeight=null,this.headerHeight=44,this.appendHeight=0,this.footerHeight=44,this.viewportHeight=null,this.bodyHeight=null,this.fixedBodyHeight=null,this.gutterWidth=yr()(),t)t.hasOwnProperty(n)&&(this[n]=t[n]);if(!this.table)throw new Error("table is required for Table Layout");if(!this.store)throw new Error("store is required for Table Layout")}return e.prototype.updateScrollY=function(){var e=this.height;if(null===e)return!1;var t=this.table.bodyWrapper;if(this.table.$el&&t){var n=t.querySelector(".el-table__body"),i=this.scrollY,r=n.offsetHeight>this.bodyHeight;return this.scrollY=r,i!==r}return!1},e.prototype.setHeight=function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"height";if(!Wi.a.prototype.$isServer){var i=this.table.$el;if(e=rr(e),this.height=e,!i&&(e||0===e))return Wi.a.nextTick((function(){return t.setHeight(e,n)}));"number"===typeof e?(i.style[n]=e+"px",this.updateElsHeight()):"string"===typeof e&&(i.style[n]=e,this.updateElsHeight())}},e.prototype.setMaxHeight=function(e){this.setHeight(e,"max-height")},e.prototype.getFlattenColumns=function(){var e=[],t=this.table.columns;return t.forEach((function(t){t.isColumnGroup?e.push.apply(e,t.columns):e.push(t)})),e},e.prototype.updateElsHeight=function(){var e=this;if(!this.table.$ready)return Wi.a.nextTick((function(){return e.updateElsHeight()}));var t=this.table.$refs,n=t.headerWrapper,i=t.appendWrapper,r=t.footerWrapper;if(this.appendHeight=i?i.offsetHeight:0,!this.showHeader||n){var o=n.querySelector(".el-table__header tr"),a=this.headerDisplayNone(o),s=this.headerHeight=this.showHeader?n.offsetHeight:0;if(this.showHeader&&!a&&n.offsetWidth>0&&(this.table.columns||[]).length>0&&s<2)return Wi.a.nextTick((function(){return e.updateElsHeight()}));var l=this.tableHeight=this.table.$el.clientHeight,c=this.footerHeight=r?r.offsetHeight:0;null!==this.height&&(this.bodyHeight=l-s-c+(r?1:0)),this.fixedBodyHeight=this.scrollX?this.bodyHeight-this.gutterWidth:this.bodyHeight;var u=!this.table.data||0===this.table.data.length;this.viewportHeight=this.scrollX?l-(u?0:this.gutterWidth):l,this.updateScrollY(),this.notifyObservers("scrollable")}},e.prototype.headerDisplayNone=function(e){var t=e;while("DIV"!==t.tagName){if("none"===getComputedStyle(t).display)return!0;t=t.parentElement}return!1},e.prototype.updateColumnsWidth=function(){if(!Wi.a.prototype.$isServer){var e=this.fit,t=this.table.$el.clientWidth,n=0,i=this.getFlattenColumns(),r=i.filter((function(e){return"number"!==typeof e.width}));if(i.forEach((function(e){"number"===typeof e.width&&e.realWidth&&(e.realWidth=null)})),r.length>0&&e){i.forEach((function(e){n+=e.width||e.minWidth||80}));var o=this.scrollY?this.gutterWidth:0;if(n<=t-o){this.scrollX=!1;var a=t-o-n;if(1===r.length)r[0].realWidth=(r[0].minWidth||80)+a;else{var s=r.reduce((function(e,t){return e+(t.minWidth||80)}),0),l=a/s,c=0;r.forEach((function(e,t){if(0!==t){var n=Math.floor((e.minWidth||80)*l);c+=n,e.realWidth=(e.minWidth||80)+n}})),r[0].realWidth=(r[0].minWidth||80)+a-c}}else this.scrollX=!0,r.forEach((function(e){e.realWidth=e.minWidth}));this.bodyWidth=Math.max(n,t),this.table.resizeState.width=this.bodyWidth}else i.forEach((function(e){e.width||e.minWidth?e.realWidth=e.width||e.minWidth:e.realWidth=80,n+=e.realWidth})),this.scrollX=n>t,this.bodyWidth=n;var u=this.store.states.fixedColumns;if(u.length>0){var d=0;u.forEach((function(e){d+=e.realWidth||e.width})),this.fixedWidth=d}var h=this.store.states.rightFixedColumns;if(h.length>0){var f=0;h.forEach((function(e){f+=e.realWidth||e.width})),this.rightFixedWidth=f}this.notifyObservers("columns")}},e.prototype.addObserver=function(e){this.observers.push(e)},e.prototype.removeObserver=function(e){var t=this.observers.indexOf(e);-1!==t&&this.observers.splice(t,1)},e.prototype.notifyObservers=function(e){var t=this,n=this.observers;n.forEach((function(n){switch(e){case"columns":n.onColumnsChange(t);break;case"scrollable":n.onScrollableChange(t);break;default:throw new Error("Table Layout don't have event "+e+".")}}))},e}(),wr=xr,Cr={created:function(){this.tableLayout.addObserver(this)},destroyed:function(){this.tableLayout.removeObserver(this)},computed:{tableLayout:function(){var e=this.layout;if(!e&&this.table&&(e=this.table.layout),!e)throw new Error("Can not find table layout.");return e}},mounted:function(){this.onColumnsChange(this.tableLayout),this.onScrollableChange(this.tableLayout)},updated:function(){this.__updated__||(this.onColumnsChange(this.tableLayout),this.onScrollableChange(this.tableLayout),this.__updated__=!0)},methods:{onColumnsChange:function(){var e=this.$el.querySelectorAll("colgroup > col");if(e.length){var t=this.tableLayout.getFlattenColumns(),n={};t.forEach((function(e){n[e.id]=e}));for(var i=0,r=e.length;i col[name=gutter]"),n=0,i=t.length;n=this.leftFixedLeafCount:"right"===this.fixed?e=this.columnsCount-this.rightFixedLeafCount},getSpan:function(e,t,n,i){var r=1,o=1,a=this.table.spanMethod;if("function"===typeof a){var s=a({row:e,column:t,rowIndex:n,columnIndex:i});Array.isArray(s)?(r=s[0],o=s[1]):"object"===("undefined"===typeof s?"undefined":kr(s))&&(r=s.rowspan,o=s.colspan)}return{rowspan:r,colspan:o}},getRowStyle:function(e,t){var n=this.table.rowStyle;return"function"===typeof n?n.call(null,{row:e,rowIndex:t}):n||null},getRowClass:function(e,t){var n=["el-table__row"];this.table.highlightCurrentRow&&e===this.store.states.currentRow&&n.push("current-row"),this.stripe&&t%2===1&&n.push("el-table__row--striped");var i=this.table.rowClassName;return"string"===typeof i?n.push(i):"function"===typeof i&&n.push(i.call(null,{row:e,rowIndex:t})),this.store.states.expandRows.indexOf(e)>-1&&n.push("expanded"),n},getCellStyle:function(e,t,n,i){var r=this.table.cellStyle;return"function"===typeof r?r.call(null,{rowIndex:e,columnIndex:t,row:n,column:i}):r},getCellClass:function(e,t,n,i){var r=[i.id,i.align,i.className];this.isColumnHidden(t)&&r.push("is-hidden");var o=this.table.cellClassName;return"string"===typeof o?r.push(o):"function"===typeof o&&r.push(o.call(null,{rowIndex:e,columnIndex:t,row:n,column:i})),r.join(" ")},getColspanRealWidth:function(e,t,n){if(t<1)return e[n].realWidth;var i=e.map((function(e){var t=e.realWidth;return t})).slice(n,n+t);return i.reduce((function(e,t){return e+t}),-1)},handleCellMouseEnter:function(e,t){var n=this.table,i=Ui(e);if(i){var r=Zi(n,i),o=n.hoverState={cell:i,column:r,row:t};n.$emit("cell-mouse-enter",o.row,o.column,o.cell,e)}var a=e.target.querySelector(".cell");if(Object(Le["hasClass"])(a,"el-tooltip")&&a.childNodes.length){var s=document.createRange();s.setStart(a,0),s.setEnd(a,a.childNodes.length);var l=s.getBoundingClientRect().width,c=(parseInt(Object(Le["getStyle"])(a,"paddingLeft"),10)||0)+(parseInt(Object(Le["getStyle"])(a,"paddingRight"),10)||0);if((l+c>a.offsetWidth||a.scrollWidth>a.offsetWidth)&&this.$refs.tooltip){var u=this.$refs.tooltip;this.tooltipContent=i.innerText||i.textContent,u.referenceElm=i,u.$refs.popper&&(u.$refs.popper.style.display="none"),u.doDestroy(),u.setExpectedState(!0),this.activateTooltip(u)}}},handleCellMouseLeave:function(e){var t=this.$refs.tooltip;t&&(t.setExpectedState(!1),t.handleClosePopper());var n=Ui(e);if(n){var i=this.table.hoverState||{};this.table.$emit("cell-mouse-leave",i.row,i.column,i.cell,e)}},handleMouseEnter:F()(30,(function(e){this.store.commit("setHoverRow",e)})),handleMouseLeave:F()(30,(function(){this.store.commit("setHoverRow",null)})),handleContextMenu:function(e,t){this.handleEvent(e,t,"contextmenu")},handleDoubleClick:function(e,t){this.handleEvent(e,t,"dblclick")},handleClick:function(e,t){this.store.commit("setCurrentRow",t),this.handleEvent(e,t,"click")},handleEvent:function(e,t,n){var i=this.table,r=Ui(e),o=void 0;r&&(o=Zi(i,r),o&&i.$emit("cell-"+n,t,o,r,e)),i.$emit("row-"+n,t,o,e)},rowRender:function(e,t,n){var i=this,r=this.$createElement,o=this.treeIndent,a=this.columns,s=this.firstDefaultColumnIndex,l=a.map((function(e,t){return i.isColumnHidden(t)})),c=this.getRowClass(e,t),u=!0;return n&&(c.push("el-table__row--level-"+n.level),u=n.display),r("tr",{directives:[{name:"show",value:u}],style:this.getRowStyle(e,t),class:c,key:this.getKeyOfRow(e,t),on:{dblclick:function(t){return i.handleDoubleClick(t,e)},click:function(t){return i.handleClick(t,e)},contextmenu:function(t){return i.handleContextMenu(t,e)},mouseenter:function(e){return i.handleMouseEnter(t)},mouseleave:this.handleMouseLeave}},[a.map((function(c,u){var d=i.getSpan(e,c,t,u),h=d.rowspan,f=d.colspan;if(!h||!f)return null;var p=Sr({},c);p.realWidth=i.getColspanRealWidth(a,f,u);var m={store:i.store,_self:i.context||i.table.$vnode.context,column:p,row:e,$index:t};return u===s&&n&&(m.treeNode={indent:n.level*o,level:n.level},"boolean"===typeof n.expanded&&(m.treeNode.expanded=n.expanded,"loading"in n&&(m.treeNode.loading=n.loading),"noLazyChildren"in n&&(m.treeNode.noLazyChildren=n.noLazyChildren))),r("td",{style:i.getCellStyle(t,u,e,c),class:i.getCellClass(t,u,e,c),attrs:{rowspan:h,colspan:f},on:{mouseenter:function(t){return i.handleCellMouseEnter(t,e)},mouseleave:i.handleCellMouseLeave}},[c.renderCell.call(i._renderProxy,i.$createElement,m,l[u])])}))])},wrappedRowRender:function(e,t){var n=this,i=this.$createElement,r=this.store,o=r.isRowExpanded,a=r.assertRowKey,s=r.states,l=s.treeData,c=s.lazyTreeNodeMap,u=s.childrenColumnName,d=s.rowKey;if(this.hasExpandColumn&&o(e)){var h=this.table.renderExpanded,f=this.rowRender(e,t);return h?[[f,i("tr",{key:"expanded-row__"+f.key},[i("td",{attrs:{colspan:this.columnsCount},class:"el-table__expanded-cell"},[h(this.$createElement,{row:e,$index:t,store:this.store})])])]]:(console.error("[Element Error]renderExpanded is required."),f)}if(Object.keys(l).length){a();var p=Ji(e,d),m=l[p],v=null;m&&(v={expanded:m.expanded,level:m.level,display:!0},"boolean"===typeof m.lazy&&("boolean"===typeof m.loaded&&m.loaded&&(v.noLazyChildren=!(m.children&&m.children.length)),v.loading=m.loading));var g=[this.rowRender(e,t,v)];if(m){var b=0,y=function e(i,r){i&&i.length&&r&&i.forEach((function(i){var o={display:r.display&&r.expanded,level:r.level+1},a=Ji(i,d);if(void 0===a||null===a)throw new Error("for nested data item, row-key is required.");if(m=Sr({},l[a]),m&&(o.expanded=m.expanded,m.level=m.level||o.level,m.display=!(!m.expanded||!o.display),"boolean"===typeof m.lazy&&("boolean"===typeof m.loaded&&m.loaded&&(o.noLazyChildren=!(m.children&&m.children.length)),o.loading=m.loading)),b++,g.push(n.rowRender(i,t+b,o)),m){var s=c[a]||i[u];e(s,m)}}))};m.display=!0;var _=c[p]||e[u];y(_,m)}return g}return this.rowRender(e,t)}}},$r=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"}},[e.multiple?n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleOutsideClick,expression:"handleOutsideClick"},{name:"show",rawName:"v-show",value:e.showPopper,expression:"showPopper"}],staticClass:"el-table-filter"},[n("div",{staticClass:"el-table-filter__content"},[n("el-scrollbar",{attrs:{"wrap-class":"el-table-filter__wrap"}},[n("el-checkbox-group",{staticClass:"el-table-filter__checkbox-group",model:{value:e.filteredValue,callback:function(t){e.filteredValue=t},expression:"filteredValue"}},e._l(e.filters,(function(t){return n("el-checkbox",{key:t.value,attrs:{label:t.value}},[e._v(e._s(t.text))])})),1)],1)],1),n("div",{staticClass:"el-table-filter__bottom"},[n("button",{class:{"is-disabled":0===e.filteredValue.length},attrs:{disabled:0===e.filteredValue.length},on:{click:e.handleConfirm}},[e._v(e._s(e.t("el.table.confirmFilter")))]),n("button",{on:{click:e.handleReset}},[e._v(e._s(e.t("el.table.resetFilter")))])])]):n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleOutsideClick,expression:"handleOutsideClick"},{name:"show",rawName:"v-show",value:e.showPopper,expression:"showPopper"}],staticClass:"el-table-filter"},[n("ul",{staticClass:"el-table-filter__list"},[n("li",{staticClass:"el-table-filter__list-item",class:{"is-active":void 0===e.filterValue||null===e.filterValue},on:{click:function(t){e.handleSelect(null)}}},[e._v(e._s(e.t("el.table.clearFilter")))]),e._l(e.filters,(function(t){return n("li",{key:t.value,staticClass:"el-table-filter__list-item",class:{"is-active":e.isActive(t)},attrs:{label:t.value},on:{click:function(n){e.handleSelect(t.value)}}},[e._v(e._s(t.text))])}))],2)])])},Dr=[];$r._withStripped=!0;var Er=[];!Wi.a.prototype.$isServer&&document.addEventListener("click",(function(e){Er.forEach((function(t){var n=e.target;t&&t.$el&&(n===t.$el||t.$el.contains(n)||t.handleOutsideClick&&t.handleOutsideClick(e))}))}));var Tr={open:function(e){e&&Er.push(e)},close:function(e){var t=Er.indexOf(e);-1!==t&&Er.splice(e,1)}},Pr=n(30),Mr=n.n(Pr),Ir={name:"ElTableFilterPanel",mixins:[H.a,g.a],directives:{Clickoutside:V.a},components:{ElCheckbox:Ai.a,ElCheckboxGroup:Mr.a,ElScrollbar:q.a},props:{placement:{type:String,default:"bottom-end"}},methods:{isActive:function(e){return e.value===this.filterValue},handleOutsideClick:function(){var e=this;setTimeout((function(){e.showPopper=!1}),16)},handleConfirm:function(){this.confirmFilter(this.filteredValue),this.handleOutsideClick()},handleReset:function(){this.filteredValue=[],this.confirmFilter(this.filteredValue),this.handleOutsideClick()},handleSelect:function(e){this.filterValue=e,"undefined"!==typeof e&&null!==e?this.confirmFilter(this.filteredValue):this.confirmFilter([]),this.handleOutsideClick()},confirmFilter:function(e){this.table.store.commit("filterChange",{column:this.column,values:e}),this.table.store.updateAllSelected()}},data:function(){return{table:null,cell:null,column:null}},computed:{filters:function(){return this.column&&this.column.filters},filterValue:{get:function(){return(this.column.filteredValue||[])[0]},set:function(e){this.filteredValue&&("undefined"!==typeof e&&null!==e?this.filteredValue.splice(0,1,e):this.filteredValue.splice(0,1))}},filteredValue:{get:function(){return this.column&&this.column.filteredValue||[]},set:function(e){this.column&&(this.column.filteredValue=e)}},multiple:function(){return!this.column||this.column.filterMultiple}},mounted:function(){var e=this;this.popperElm=this.$el,this.referenceElm=this.cell,this.table.bodyWrapper.addEventListener("scroll",(function(){e.updatePopper()})),this.$watch("showPopper",(function(t){e.column&&(e.column.filterOpened=t),t?Tr.open(e):Tr.close(e)}))},watch:{showPopper:function(e){!0===e&&parseInt(this.popperJS._popper.style.zIndex,10)1;return r&&(this.$parent.isGroup=!0),e("table",{class:"el-table__header",attrs:{cellspacing:"0",cellpadding:"0",border:"0"}},[e("colgroup",[this.columns.map((function(t){return e("col",{attrs:{name:t.id},key:t.id})})),this.hasGutter?e("col",{attrs:{name:"gutter"}}):""]),e("thead",{class:[{"is-group":r,"has-gutter":this.hasGutter}]},[this._l(i,(function(n,i){return e("tr",{style:t.getHeaderRowStyle(i),class:t.getHeaderRowClass(i)},[n.map((function(r,o){return e("th",{attrs:{colspan:r.colSpan,rowspan:r.rowSpan},on:{mousemove:function(e){return t.handleMouseMove(e,r)},mouseout:t.handleMouseOut,mousedown:function(e){return t.handleMouseDown(e,r)},click:function(e){return t.handleHeaderClick(e,r)},contextmenu:function(e){return t.handleHeaderContextMenu(e,r)}},style:t.getHeaderCellStyle(i,o,n,r),class:t.getHeaderCellClass(i,o,n,r),key:r.id},[e("div",{class:["cell",r.filteredValue&&r.filteredValue.length>0?"highlight":"",r.labelClassName]},[r.renderHeader?r.renderHeader.call(t._renderProxy,e,{column:r,$index:o,store:t.store,_self:t.$parent.$vnode.context}):r.label,r.sortable?e("span",{class:"caret-wrapper",on:{click:function(e){return t.handleSortClick(e,r)}}},[e("i",{class:"sort-caret ascending",on:{click:function(e){return t.handleSortClick(e,r,"ascending")}}}),e("i",{class:"sort-caret descending",on:{click:function(e){return t.handleSortClick(e,r,"descending")}}})]):"",r.filterable?e("span",{class:"el-table__column-filter-trigger",on:{click:function(e){return t.handleFilterClick(e,r)}}},[e("i",{class:["el-icon-arrow-down",r.filterOpened?"el-icon-arrow-up":""]})]):""])])})),t.hasGutter?e("th",{class:"gutter"}):""])}))])])},props:{fixed:String,store:{required:!0},border:Boolean,defaultSort:{type:Object,default:function(){return{prop:"",order:""}}}},components:{ElCheckbox:Ai.a},computed:Fr({table:function(){return this.$parent},hasGutter:function(){return!this.fixed&&this.tableLayout.gutterWidth}},gr({columns:"columns",isAllSelected:"isAllSelected",leftFixedLeafCount:"fixedLeafColumnsLength",rightFixedLeafCount:"rightFixedLeafColumnsLength",columnsCount:function(e){return e.columns.length},leftFixedCount:function(e){return e.fixedColumns.length},rightFixedCount:function(e){return e.rightFixedColumns.length}})),created:function(){this.filterPanels={}},mounted:function(){var e=this;this.$nextTick((function(){var t=e.defaultSort,n=t.prop,i=t.order,r=!0;e.store.commit("sort",{prop:n,order:i,init:r})}))},beforeDestroy:function(){var e=this.filterPanels;for(var t in e)e.hasOwnProperty(t)&&e[t]&&e[t].$destroy(!0)},methods:{isCellHidden:function(e,t){for(var n=0,i=0;i=this.leftFixedLeafCount:"right"===this.fixed?n=this.columnsCount-this.rightFixedLeafCount},getHeaderRowStyle:function(e){var t=this.table.headerRowStyle;return"function"===typeof t?t.call(null,{rowIndex:e}):t},getHeaderRowClass:function(e){var t=[],n=this.table.headerRowClassName;return"string"===typeof n?t.push(n):"function"===typeof n&&t.push(n.call(null,{rowIndex:e})),t.join(" ")},getHeaderCellStyle:function(e,t,n,i){var r=this.table.headerCellStyle;return"function"===typeof r?r.call(null,{rowIndex:e,columnIndex:t,row:n,column:i}):r},getHeaderCellClass:function(e,t,n,i){var r=[i.id,i.order,i.headerAlign,i.className,i.labelClassName];0===e&&this.isCellHidden(t,n)&&r.push("is-hidden"),i.children||r.push("is-leaf"),i.sortable&&r.push("is-sortable");var o=this.table.headerCellClassName;return"string"===typeof o?r.push(o):"function"===typeof o&&r.push(o.call(null,{rowIndex:e,columnIndex:t,row:n,column:i})),r.join(" ")},toggleAllSelection:function(e){e.stopPropagation(),this.store.commit("toggleAllSelection")},handleFilterClick:function(e,t){e.stopPropagation();var n=e.target,i="TH"===n.tagName?n:n.parentNode;if(!Object(Le["hasClass"])(i,"noclick")){i=i.querySelector(".el-table__column-filter-trigger")||i;var r=this.$parent,o=this.filterPanels[t.id];o&&t.filterOpened?o.showPopper=!1:(o||(o=new Wi.a(Ar),this.filterPanels[t.id]=o,t.filterPlacement&&(o.placement=t.filterPlacement),o.table=r,o.cell=i,o.column=t,!this.$isServer&&o.$mount(document.createElement("div"))),setTimeout((function(){o.showPopper=!0}),16))}},handleHeaderClick:function(e,t){!t.filters&&t.sortable?this.handleSortClick(e,t):t.filterable&&!t.sortable&&this.handleFilterClick(e,t),this.$parent.$emit("header-click",t,e)},handleHeaderContextMenu:function(e,t){this.$parent.$emit("header-contextmenu",t,e)},handleMouseDown:function(e,t){var n=this;if(!this.$isServer&&!(t.children&&t.children.length>0)&&this.draggingColumn&&this.border){this.dragging=!0,this.$parent.resizeProxyVisible=!0;var i=this.$parent,r=i.$el,o=r.getBoundingClientRect().left,a=this.$el.querySelector("th."+t.id),s=a.getBoundingClientRect(),l=s.left-o+30;Object(Le["addClass"])(a,"noclick"),this.dragState={startMouseLeft:e.clientX,startLeft:s.right-o,startColumnLeft:s.left-o,tableLeft:o};var c=i.$refs.resizeProxy;c.style.left=this.dragState.startLeft+"px",document.onselectstart=function(){return!1},document.ondragstart=function(){return!1};var u=function(e){var t=e.clientX-n.dragState.startMouseLeft,i=n.dragState.startLeft+t;c.style.left=Math.max(l,i)+"px"},d=function r(){if(n.dragging){var o=n.dragState,s=o.startColumnLeft,l=o.startLeft,d=parseInt(c.style.left,10),h=d-s;t.width=t.realWidth=h,i.$emit("header-dragend",t.width,l-s,t,e),n.store.scheduleLayout(),document.body.style.cursor="",n.dragging=!1,n.draggingColumn=null,n.dragState={},i.resizeProxyVisible=!1}document.removeEventListener("mousemove",u),document.removeEventListener("mouseup",r),document.onselectstart=null,document.ondragstart=null,setTimeout((function(){Object(Le["removeClass"])(a,"noclick")}),0)};document.addEventListener("mousemove",u),document.addEventListener("mouseup",d)}},handleMouseMove:function(e,t){if(!(t.children&&t.children.length>0)){var n=e.target;while(n&&"TH"!==n.tagName)n=n.parentNode;if(t&&t.resizable&&!this.dragging&&this.border){var i=n.getBoundingClientRect(),r=document.body.style;i.width>12&&i.right-e.pageX<8?(r.cursor="col-resize",Object(Le["hasClass"])(n,"is-sortable")&&(n.style.cursor="col-resize"),this.draggingColumn=t):this.dragging||(r.cursor="",Object(Le["hasClass"])(n,"is-sortable")&&(n.style.cursor="pointer"),this.draggingColumn=null)}}},handleMouseOut:function(){this.$isServer||(document.body.style.cursor="")},toggleOrder:function(e){var t=e.order,n=e.sortOrders;if(""===t)return n[0];var i=n.indexOf(t||null);return n[i>n.length-2?0:i+1]},handleSortClick:function(e,t,n){e.stopPropagation();var i=t.order===n?null:n||this.toggleOrder(t),r=e.target;while(r&&"TH"!==r.tagName)r=r.parentNode;if(r&&"TH"===r.tagName&&Object(Le["hasClass"])(r,"noclick"))Object(Le["removeClass"])(r,"noclick");else if(t.sortable){var o=this.store.states,a=o.sortProp,s=void 0,l=o.sortingColumn;(l!==t||l===t&&null===l.order)&&(l&&(l.order=null),o.sortingColumn=t,a=t.property),s=t.order=i||null,o.sortProp=a,o.sortOrder=s,this.store.commit("changeSortCondition")}}},data:function(){return{draggingColumn:null,dragging:!1,dragState:{}}}},Br=Object.assign||function(e){for(var t=1;t=this.leftFixedLeafCount;if("right"===this.fixed){for(var i=0,r=0;r=this.columnsCount-this.rightFixedCount)},getRowClasses:function(e,t){var n=[e.id,e.align,e.labelClassName];return e.className&&n.push(e.className),this.isCellHidden(t,this.columns,e)&&n.push("is-hidden"),e.children||n.push("is-leaf"),n}}},Hr=Object.assign||function(e){for(var t=1;t0){var i=n.scrollTop;t.pixelY<0&&0!==i&&e.preventDefault(),t.pixelY>0&&n.scrollHeight-n.clientHeight>i&&e.preventDefault(),n.scrollTop+=Math.ceil(t.pixelY/5)}else n.scrollLeft+=Math.ceil(t.pixelX/5)},handleHeaderFooterMousewheel:function(e,t){var n=t.pixelX,i=t.pixelY;Math.abs(n)>=Math.abs(i)&&(this.bodyWrapper.scrollLeft+=t.pixelX/5)},syncPostion:Object(Fi["throttle"])(20,(function(){var e=this.bodyWrapper,t=e.scrollLeft,n=e.scrollTop,i=e.offsetWidth,r=e.scrollWidth,o=this.$refs,a=o.headerWrapper,s=o.footerWrapper,l=o.fixedBodyWrapper,c=o.rightFixedBodyWrapper;a&&(a.scrollLeft=t),s&&(s.scrollLeft=t),l&&(l.scrollTop=n),c&&(c.scrollTop=n);var u=r-i-1;this.scrollPosition=t>=u?"right":0===t?"left":"middle"})),bindEvents:function(){this.bodyWrapper.addEventListener("scroll",this.syncPostion,{passive:!0}),this.fit&&Object(ei["addResizeListener"])(this.$el,this.resizeListener)},unbindEvents:function(){this.bodyWrapper.removeEventListener("scroll",this.syncPostion,{passive:!0}),this.fit&&Object(ei["removeResizeListener"])(this.$el,this.resizeListener)},resizeListener:function(){if(this.$ready){var e=!1,t=this.$el,n=this.resizeState,i=n.width,r=n.height,o=t.offsetWidth;i!==o&&(e=!0);var a=t.offsetHeight;(this.height||this.shouldUpdateHeight)&&r!==a&&(e=!0),e&&(this.resizeState.width=o,this.resizeState.height=a,this.doLayout())}},doLayout:function(){this.shouldUpdateHeight&&this.layout.updateElsHeight(),this.layout.updateColumnsWidth()},sort:function(e,t){this.store.commit("sort",{prop:e,order:t})},toggleAllSelection:function(){this.store.commit("toggleAllSelection")}},computed:Hr({tableSize:function(){return this.size||(this.$ELEMENT||{}).size},bodyWrapper:function(){return this.$refs.bodyWrapper},shouldUpdateHeight:function(){return this.height||this.maxHeight||this.fixedColumns.length>0||this.rightFixedColumns.length>0},bodyWidth:function(){var e=this.layout,t=e.bodyWidth,n=e.scrollY,i=e.gutterWidth;return t?t-(n?i:0)+"px":""},bodyHeight:function(){var e=this.layout,t=e.headerHeight,n=void 0===t?0:t,i=e.bodyHeight,r=e.footerHeight,o=void 0===r?0:r;if(this.height)return{height:i?i+"px":""};if(this.maxHeight){var a=rr(this.maxHeight);if("number"===typeof a)return{"max-height":a-o-(this.showHeader?n:0)+"px"}}return{}},fixedBodyHeight:function(){if(this.height)return{height:this.layout.fixedBodyHeight?this.layout.fixedBodyHeight+"px":""};if(this.maxHeight){var e=rr(this.maxHeight);if("number"===typeof e)return e=this.layout.scrollX?e-this.layout.gutterWidth:e,this.showHeader&&(e-=this.layout.headerHeight),e-=this.layout.footerHeight,{"max-height":e+"px"}}return{}},fixedHeight:function(){return this.maxHeight?this.showSummary?{bottom:0}:{bottom:this.layout.scrollX&&this.data.length?this.layout.gutterWidth+"px":""}:this.showSummary?{height:this.layout.tableHeight?this.layout.tableHeight+"px":""}:{height:this.layout.viewportHeight?this.layout.viewportHeight+"px":""}},emptyBlockStyle:function(){if(this.data&&this.data.length)return null;var e="100%";return this.layout.appendHeight&&(e="calc(100% - "+this.layout.appendHeight+"px)"),{width:this.bodyWidth,height:e}}},gr({selection:"selection",columns:"columns",tableData:"data",fixedColumns:"fixedColumns",rightFixedColumns:"rightFixedColumns"})),watch:{height:{immediate:!0,handler:function(e){this.layout.setHeight(e)}},maxHeight:{immediate:!0,handler:function(e){this.layout.setMaxHeight(e)}},currentRowKey:{immediate:!0,handler:function(e){this.rowKey&&this.store.setCurrentRowKey(e)}},data:{immediate:!0,handler:function(e){this.store.commit("setData",e)}},expandRowKeys:{immediate:!0,handler:function(e){e&&this.store.setExpandRowKeysAdapter(e)}}},created:function(){var e=this;this.tableId="el-table_"+Wr++,this.debouncedUpdateLayout=Object(Fi["debounce"])(50,(function(){return e.doLayout()}))},mounted:function(){var e=this;this.bindEvents(),this.store.updateColumns(),this.doLayout(),this.resizeState={width:this.$el.offsetWidth,height:this.$el.offsetHeight},this.store.states.columns.forEach((function(t){t.filteredValue&&t.filteredValue.length&&e.store.commit("filterChange",{column:t,values:t.filteredValue,silent:!0})})),this.$ready=!0},destroyed:function(){this.unbindEvents()},data:function(){var e=this.treeProps,t=e.hasChildren,n=void 0===t?"hasChildren":t,i=e.children,r=void 0===i?"children":i;this.store=vr(this,{rowKey:this.rowKey,defaultExpandAll:this.defaultExpandAll,selectOnIndeterminate:this.selectOnIndeterminate,indent:this.indent,lazy:this.lazy,lazyColumnIdentifier:n,childrenColumnName:r});var o=new wr({store:this.store,table:this,fit:this.fit,showHeader:this.showHeader});return{layout:o,isHidden:!1,renderExpanded:null,resizeProxyVisible:!1,resizeState:{width:null,height:null},isGroup:!1,scrollPosition:"left"}}},Ur=qr,Yr=s(Ur,Ii,Ni,!1,null,null,null);Yr.options.__file="packages/table/src/table.vue";var Kr=Yr.exports;Kr.install=function(e){e.component(Kr.name,Kr)};var Gr=Kr,Xr={default:{order:""},selection:{width:48,minWidth:48,realWidth:48,order:"",className:"el-table-column--selection"},expand:{width:48,minWidth:48,realWidth:48,order:""},index:{width:48,minWidth:48,realWidth:48,order:""}},Zr={selection:{renderHeader:function(e,t){var n=t.store;return e("el-checkbox",{attrs:{disabled:n.states.data&&0===n.states.data.length,indeterminate:n.states.selection.length>0&&!this.isAllSelected,value:this.isAllSelected},nativeOn:{click:this.toggleAllSelection}})},renderCell:function(e,t){var n=t.row,i=t.column,r=t.store,o=t.$index;return e("el-checkbox",{nativeOn:{click:function(e){return e.stopPropagation()}},attrs:{value:r.isSelected(n),disabled:!!i.selectable&&!i.selectable.call(null,n,o)},on:{input:function(){r.commit("rowSelectedChanged",n)}}})},sortable:!1,resizable:!1},index:{renderHeader:function(e,t){var n=t.column;return n.label||"#"},renderCell:function(e,t){var n=t.$index,i=t.column,r=n+1,o=i.index;return"number"===typeof o?r=n+o:"function"===typeof o&&(r=o(n)),e("div",[r])},sortable:!1},expand:{renderHeader:function(e,t){var n=t.column;return n.label||""},renderCell:function(e,t){var n=t.row,i=t.store,r=["el-table__expand-icon"];i.states.expandRows.indexOf(n)>-1&&r.push("el-table__expand-icon--expanded");var o=function(e){e.stopPropagation(),i.toggleRowExpansion(n)};return e("div",{class:r,on:{click:o}},[e("i",{class:"el-icon el-icon-arrow-right"})])},sortable:!1,resizable:!1,className:"el-table__expand-column"}};function Jr(e,t){var n=t.row,i=t.column,r=t.$index,o=i.property,a=o&&Object(b["getPropByPath"])(n,o).v;return i&&i.formatter?i.formatter(n,i,a,r):a}function Qr(e,t){var n=t.row,i=t.treeNode,r=t.store;if(!i)return null;var o=[],a=function(e){e.stopPropagation(),r.loadOrToggle(n)};if(i.indent&&o.push(e("span",{class:"el-table__indent",style:{"padding-left":i.indent+"px"}})),"boolean"!==typeof i.expanded||i.noLazyChildren)o.push(e("span",{class:"el-table__placeholder"}));else{var s=["el-table__expand-icon",i.expanded?"el-table__expand-icon--expanded":""],l=["el-icon-arrow-right"];i.loading&&(l=["el-icon-loading"]),o.push(e("div",{class:s,on:{click:a}},[e("i",{class:l})]))}return o}var eo=Object.assign||function(e){for(var t=1;t-1}))}}},data:function(){return{isSubColumn:!1,columns:[]}},computed:{owner:function(){var e=this.$parent;while(e&&!e.tableId)e=e.$parent;return e},columnOrTableParent:function(){var e=this.$parent;while(e&&!e.tableId&&!e.columnId)e=e.$parent;return e},realWidth:function(){return nr(this.width)},realMinWidth:function(){return ir(this.minWidth)},realAlign:function(){return this.align?"is-"+this.align:null},realHeaderAlign:function(){return this.headerAlign?"is-"+this.headerAlign:this.realAlign}},methods:{getPropsData:function(){for(var e=this,t=arguments.length,n=Array(t),i=0;i3&&void 0!==arguments[3]?arguments[3]:"-";if(!e)return null;var r=(mo[n]||mo["default"]).parser,o=t||lo[n];return r(e,o,i)},bo=function(e,t,n){if(!e)return null;var i=(mo[n]||mo["default"]).formatter,r=t||lo[n];return i(e,r)},yo=function(e,t){var n=function(e,t){var n=e instanceof Date,i=t instanceof Date;return n&&i?e.getTime()===t.getTime():!n&&!i&&e===t},i=e instanceof Array,r=t instanceof Array;return i&&r?e.length===t.length&&e.every((function(e,i){return n(e,t[i])})):!i&&!r&&n(e,t)},_o=function(e){return"string"===typeof e||e instanceof String},xo=function(e){return null===e||void 0===e||_o(e)||Array.isArray(e)&&2===e.length&&e.every(_o)},wo={mixins:[D.a,so],inject:{elForm:{default:""},elFormItem:{default:""}},props:{size:String,format:String,valueFormat:String,readonly:Boolean,placeholder:String,startPlaceholder:String,endPlaceholder:String,prefixIcon:String,clearIcon:{type:String,default:"el-icon-circle-close"},name:{default:"",validator:xo},disabled:Boolean,clearable:{type:Boolean,default:!0},id:{default:"",validator:xo},popperClass:String,editable:{type:Boolean,default:!0},align:{type:String,default:"left"},value:{},defaultValue:{},defaultTime:{},rangeSeparator:{default:"-"},pickerOptions:{},unlinkPanels:Boolean,validateEvent:{type:Boolean,default:!0}},components:{ElInput:m.a},directives:{Clickoutside:V.a},data:function(){return{pickerVisible:!1,showClose:!1,userInput:null,valueOnOpen:null,unwatchPickerOptions:null}},watch:{pickerVisible:function(e){this.readonly||this.pickerDisabled||(e?(this.showPicker(),this.valueOnOpen=Array.isArray(this.value)?[].concat(this.value):this.value):(this.hidePicker(),this.emitChange(this.value),this.userInput=null,this.validateEvent&&this.dispatch("ElFormItem","el.form.blur"),this.$emit("blur",this),this.blur()))},parsedValue:{immediate:!0,handler:function(e){this.picker&&(this.picker.value=e)}},defaultValue:function(e){this.picker&&(this.picker.defaultValue=e)},value:function(e,t){yo(e,t)||this.pickerVisible||!this.validateEvent||this.dispatch("ElFormItem","el.form.change",e)}},computed:{ranged:function(){return this.type.indexOf("range")>-1},reference:function(){var e=this.$refs.reference;return e.$el||e},refInput:function(){return this.reference?[].slice.call(this.reference.querySelectorAll("input")):[]},valueIsEmpty:function(){var e=this.value;if(Array.isArray(e)){for(var t=0,n=e.length;t0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];e.userInput=null,e.pickerVisible=e.picker.visible=n,e.emitInput(t),e.picker.resetView&&e.picker.resetView()})),this.picker.$on("select-range",(function(t,n,i){0!==e.refInput.length&&(i&&"min"!==i?"max"===i&&(e.refInput[1].setSelectionRange(t,n),e.refInput[1].focus()):(e.refInput[0].setSelectionRange(t,n),e.refInput[0].focus()))}))},unmountPicker:function(){this.picker&&(this.picker.$destroy(),this.picker.$off(),"function"===typeof this.unwatchPickerOptions&&this.unwatchPickerOptions(),this.picker.$el.parentNode.removeChild(this.picker.$el))},emitChange:function(e){yo(e,this.valueOnOpen)||(this.$emit("change",e),this.valueOnOpen=e,this.validateEvent&&this.dispatch("ElFormItem","el.form.change",e))},emitInput:function(e){var t=this.formatToValue(e);yo(this.value,t)||this.$emit("input",t)},isValidValue:function(e){return this.picker||this.mountPicker(),!this.picker.isValidValue||e&&this.picker.isValidValue(e)}}},Co=wo,ko=s(Co,ro,oo,!1,null,null,null);ko.options.__file="packages/date-picker/src/picker.vue";var So=ko.exports,Oo=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-enter":e.handleEnter,"after-leave":e.handleLeave}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-picker-panel el-date-picker el-popper",class:[{"has-sidebar":e.$slots.sidebar||e.shortcuts,"has-time":e.showTime},e.popperClass]},[n("div",{staticClass:"el-picker-panel__body-wrapper"},[e._t("sidebar"),e.shortcuts?n("div",{staticClass:"el-picker-panel__sidebar"},e._l(e.shortcuts,(function(t,i){return n("button",{key:i,staticClass:"el-picker-panel__shortcut",attrs:{type:"button"},on:{click:function(n){e.handleShortcutClick(t)}}},[e._v(e._s(t.text))])})),0):e._e(),n("div",{staticClass:"el-picker-panel__body"},[e.showTime?n("div",{staticClass:"el-date-picker__time-header"},[n("span",{staticClass:"el-date-picker__editor-wrap"},[n("el-input",{attrs:{placeholder:e.t("el.datepicker.selectDate"),value:e.visibleDate,size:"small"},on:{input:function(t){return e.userInputDate=t},change:e.handleVisibleDateChange}})],1),n("span",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleTimePickClose,expression:"handleTimePickClose"}],staticClass:"el-date-picker__editor-wrap"},[n("el-input",{ref:"input",attrs:{placeholder:e.t("el.datepicker.selectTime"),value:e.visibleTime,size:"small"},on:{focus:function(t){e.timePickerVisible=!0},input:function(t){return e.userInputTime=t},change:e.handleVisibleTimeChange}}),n("time-picker",{ref:"timepicker",attrs:{"time-arrow-control":e.arrowControl,visible:e.timePickerVisible},on:{pick:e.handleTimePick,mounted:e.proxyTimePickerDataProperties}})],1)]):e._e(),n("div",{directives:[{name:"show",rawName:"v-show",value:"time"!==e.currentView,expression:"currentView !== 'time'"}],staticClass:"el-date-picker__header",class:{"el-date-picker__header--bordered":"year"===e.currentView||"month"===e.currentView}},[n("button",{staticClass:"el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-d-arrow-left",attrs:{type:"button","aria-label":e.t("el.datepicker.prevYear")},on:{click:e.prevYear}}),n("button",{directives:[{name:"show",rawName:"v-show",value:"date"===e.currentView,expression:"currentView === 'date'"}],staticClass:"el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-arrow-left",attrs:{type:"button","aria-label":e.t("el.datepicker.prevMonth")},on:{click:e.prevMonth}}),n("span",{staticClass:"el-date-picker__header-label",attrs:{role:"button"},on:{click:e.showYearPicker}},[e._v(e._s(e.yearLabel))]),n("span",{directives:[{name:"show",rawName:"v-show",value:"date"===e.currentView,expression:"currentView === 'date'"}],staticClass:"el-date-picker__header-label",class:{active:"month"===e.currentView},attrs:{role:"button"},on:{click:e.showMonthPicker}},[e._v(e._s(e.t("el.datepicker.month"+(e.month+1))))]),n("button",{staticClass:"el-picker-panel__icon-btn el-date-picker__next-btn el-icon-d-arrow-right",attrs:{type:"button","aria-label":e.t("el.datepicker.nextYear")},on:{click:e.nextYear}}),n("button",{directives:[{name:"show",rawName:"v-show",value:"date"===e.currentView,expression:"currentView === 'date'"}],staticClass:"el-picker-panel__icon-btn el-date-picker__next-btn el-icon-arrow-right",attrs:{type:"button","aria-label":e.t("el.datepicker.nextMonth")},on:{click:e.nextMonth}})]),n("div",{staticClass:"el-picker-panel__content"},[n("date-table",{directives:[{name:"show",rawName:"v-show",value:"date"===e.currentView,expression:"currentView === 'date'"}],attrs:{"selection-mode":e.selectionMode,"first-day-of-week":e.firstDayOfWeek,value:e.value,"default-value":e.defaultValue?new Date(e.defaultValue):null,date:e.date,"cell-class-name":e.cellClassName,"disabled-date":e.disabledDate},on:{pick:e.handleDatePick}}),n("year-table",{directives:[{name:"show",rawName:"v-show",value:"year"===e.currentView,expression:"currentView === 'year'"}],attrs:{value:e.value,"default-value":e.defaultValue?new Date(e.defaultValue):null,date:e.date,"disabled-date":e.disabledDate},on:{pick:e.handleYearPick}}),n("month-table",{directives:[{name:"show",rawName:"v-show",value:"month"===e.currentView,expression:"currentView === 'month'"}],attrs:{value:e.value,"default-value":e.defaultValue?new Date(e.defaultValue):null,date:e.date,"disabled-date":e.disabledDate},on:{pick:e.handleMonthPick}})],1)])],2),n("div",{directives:[{name:"show",rawName:"v-show",value:e.footerVisible&&"date"===e.currentView,expression:"footerVisible && currentView === 'date'"}],staticClass:"el-picker-panel__footer"},[n("el-button",{directives:[{name:"show",rawName:"v-show",value:"dates"!==e.selectionMode,expression:"selectionMode !== 'dates'"}],staticClass:"el-picker-panel__link-btn",attrs:{size:"mini",type:"text"},on:{click:e.changeToNow}},[e._v("\n "+e._s(e.t("el.datepicker.now"))+"\n ")]),n("el-button",{staticClass:"el-picker-panel__link-btn",attrs:{plain:"",size:"mini"},on:{click:e.confirm}},[e._v("\n "+e._s(e.t("el.datepicker.confirm"))+"\n ")])],1)])])},$o=[];Oo._withStripped=!0;var Do=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":function(t){e.$emit("dodestroy")}}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-time-panel el-popper",class:e.popperClass},[n("div",{staticClass:"el-time-panel__content",class:{"has-seconds":e.showSeconds}},[n("time-spinner",{ref:"spinner",attrs:{"arrow-control":e.useArrow,"show-seconds":e.showSeconds,"am-pm-mode":e.amPmMode,date:e.date},on:{change:e.handleChange,"select-range":e.setSelectionRange}})],1),n("div",{staticClass:"el-time-panel__footer"},[n("button",{staticClass:"el-time-panel__btn cancel",attrs:{type:"button"},on:{click:e.handleCancel}},[e._v(e._s(e.t("el.datepicker.cancel")))]),n("button",{staticClass:"el-time-panel__btn",class:{confirm:!e.disabled},attrs:{type:"button"},on:{click:function(t){e.handleConfirm()}}},[e._v(e._s(e.t("el.datepicker.confirm")))])])])])},Eo=[];Do._withStripped=!0;var To=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-time-spinner",class:{"has-seconds":e.showSeconds}},[e.arrowControl?e._e():[n("el-scrollbar",{ref:"hours",staticClass:"el-time-spinner__wrapper",attrs:{"wrap-style":"max-height: inherit;","view-class":"el-time-spinner__list",noresize:"",tag:"ul"},nativeOn:{mouseenter:function(t){e.emitSelectRange("hours")},mousemove:function(t){e.adjustCurrentSpinner("hours")}}},e._l(e.hoursList,(function(t,i){return n("li",{key:i,staticClass:"el-time-spinner__item",class:{active:i===e.hours,disabled:t},on:{click:function(n){e.handleClick("hours",{value:i,disabled:t})}}},[e._v(e._s(("0"+(e.amPmMode?i%12||12:i)).slice(-2))+e._s(e.amPm(i)))])})),0),n("el-scrollbar",{ref:"minutes",staticClass:"el-time-spinner__wrapper",attrs:{"wrap-style":"max-height: inherit;","view-class":"el-time-spinner__list",noresize:"",tag:"ul"},nativeOn:{mouseenter:function(t){e.emitSelectRange("minutes")},mousemove:function(t){e.adjustCurrentSpinner("minutes")}}},e._l(e.minutesList,(function(t,i){return n("li",{key:i,staticClass:"el-time-spinner__item",class:{active:i===e.minutes,disabled:!t},on:{click:function(t){e.handleClick("minutes",{value:i,disabled:!1})}}},[e._v(e._s(("0"+i).slice(-2)))])})),0),n("el-scrollbar",{directives:[{name:"show",rawName:"v-show",value:e.showSeconds,expression:"showSeconds"}],ref:"seconds",staticClass:"el-time-spinner__wrapper",attrs:{"wrap-style":"max-height: inherit;","view-class":"el-time-spinner__list",noresize:"",tag:"ul"},nativeOn:{mouseenter:function(t){e.emitSelectRange("seconds")},mousemove:function(t){e.adjustCurrentSpinner("seconds")}}},e._l(60,(function(t,i){return n("li",{key:i,staticClass:"el-time-spinner__item",class:{active:i===e.seconds},on:{click:function(t){e.handleClick("seconds",{value:i,disabled:!1})}}},[e._v(e._s(("0"+i).slice(-2)))])})),0)],e.arrowControl?[n("div",{staticClass:"el-time-spinner__wrapper is-arrow",on:{mouseenter:function(t){e.emitSelectRange("hours")}}},[n("i",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.decrease,expression:"decrease"}],staticClass:"el-time-spinner__arrow el-icon-arrow-up"}),n("i",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.increase,expression:"increase"}],staticClass:"el-time-spinner__arrow el-icon-arrow-down"}),n("ul",{ref:"hours",staticClass:"el-time-spinner__list"},e._l(e.arrowHourList,(function(t,i){return n("li",{key:i,staticClass:"el-time-spinner__item",class:{active:t===e.hours,disabled:e.hoursList[t]}},[e._v(e._s(void 0===t?"":("0"+(e.amPmMode?t%12||12:t)).slice(-2)+e.amPm(t)))])})),0)]),n("div",{staticClass:"el-time-spinner__wrapper is-arrow",on:{mouseenter:function(t){e.emitSelectRange("minutes")}}},[n("i",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.decrease,expression:"decrease"}],staticClass:"el-time-spinner__arrow el-icon-arrow-up"}),n("i",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.increase,expression:"increase"}],staticClass:"el-time-spinner__arrow el-icon-arrow-down"}),n("ul",{ref:"minutes",staticClass:"el-time-spinner__list"},e._l(e.arrowMinuteList,(function(t,i){return n("li",{key:i,staticClass:"el-time-spinner__item",class:{active:t===e.minutes}},[e._v("\n "+e._s(void 0===t?"":("0"+t).slice(-2))+"\n ")])})),0)]),e.showSeconds?n("div",{staticClass:"el-time-spinner__wrapper is-arrow",on:{mouseenter:function(t){e.emitSelectRange("seconds")}}},[n("i",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.decrease,expression:"decrease"}],staticClass:"el-time-spinner__arrow el-icon-arrow-up"}),n("i",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.increase,expression:"increase"}],staticClass:"el-time-spinner__arrow el-icon-arrow-down"}),n("ul",{ref:"seconds",staticClass:"el-time-spinner__list"},e._l(e.arrowSecondList,(function(t,i){return n("li",{key:i,staticClass:"el-time-spinner__item",class:{active:t===e.seconds}},[e._v("\n "+e._s(void 0===t?"":("0"+t).slice(-2))+"\n ")])})),0)]):e._e()]:e._e()],2)},Po=[];To._withStripped=!0;var Mo={components:{ElScrollbar:q.a},directives:{repeatClick:Nt},props:{date:{},defaultValue:{},showSeconds:{type:Boolean,default:!0},arrowControl:Boolean,amPmMode:{type:String,default:""}},computed:{hours:function(){return this.date.getHours()},minutes:function(){return this.date.getMinutes()},seconds:function(){return this.date.getSeconds()},hoursList:function(){return Object(ao["getRangeHours"])(this.selectableRange)},minutesList:function(){return Object(ao["getRangeMinutes"])(this.selectableRange,this.hours)},arrowHourList:function(){var e=this.hours;return[e>0?e-1:void 0,e,e<23?e+1:void 0]},arrowMinuteList:function(){var e=this.minutes;return[e>0?e-1:void 0,e,e<59?e+1:void 0]},arrowSecondList:function(){var e=this.seconds;return[e>0?e-1:void 0,e,e<59?e+1:void 0]}},data:function(){return{selectableRange:[],currentScrollbar:null}},mounted:function(){var e=this;this.$nextTick((function(){!e.arrowControl&&e.bindScrollEvent()}))},methods:{increase:function(){this.scrollDown(1)},decrease:function(){this.scrollDown(-1)},modifyDateField:function(e,t){switch(e){case"hours":this.$emit("change",Object(ao["modifyTime"])(this.date,t,this.minutes,this.seconds));break;case"minutes":this.$emit("change",Object(ao["modifyTime"])(this.date,this.hours,t,this.seconds));break;case"seconds":this.$emit("change",Object(ao["modifyTime"])(this.date,this.hours,this.minutes,t));break}},handleClick:function(e,t){var n=t.value,i=t.disabled;i||(this.modifyDateField(e,n),this.emitSelectRange(e),this.adjustSpinner(e,n))},emitSelectRange:function(e){"hours"===e?this.$emit("select-range",0,2):"minutes"===e?this.$emit("select-range",3,5):"seconds"===e&&this.$emit("select-range",6,8),this.currentScrollbar=e},bindScrollEvent:function(){var e=this,t=function(t){e.$refs[t].wrap.onscroll=function(n){e.handleScroll(t,n)}};t("hours"),t("minutes"),t("seconds")},handleScroll:function(e){var t=Math.min(Math.round((this.$refs[e].wrap.scrollTop-(.5*this.scrollBarHeight(e)-10)/this.typeItemHeight(e)+3)/this.typeItemHeight(e)),"hours"===e?23:59);this.modifyDateField(e,t)},adjustSpinners:function(){this.adjustSpinner("hours",this.hours),this.adjustSpinner("minutes",this.minutes),this.adjustSpinner("seconds",this.seconds)},adjustCurrentSpinner:function(e){this.adjustSpinner(e,this[e])},adjustSpinner:function(e,t){if(!this.arrowControl){var n=this.$refs[e].wrap;n&&(n.scrollTop=Math.max(0,t*this.typeItemHeight(e)))}},scrollDown:function(e){this.currentScrollbar||this.emitSelectRange("hours");var t=this.currentScrollbar,n=this.hoursList,i=this[t];if("hours"===this.currentScrollbar){var r=Math.abs(e);e=e>0?1:-1;var o=n.length;while(o--&&r)i=(i+e+n.length)%n.length,n[i]||r--;if(n[i])return}else i=(i+e+60)%60;this.modifyDateField(t,i),this.adjustSpinner(t,i)},amPm:function(e){var t="a"===this.amPmMode.toLowerCase();if(!t)return"";var n="A"===this.amPmMode,i=e<12?" am":" pm";return n&&(i=i.toUpperCase()),i},typeItemHeight:function(e){return this.$refs[e].$el.querySelector("li").offsetHeight},scrollBarHeight:function(e){return this.$refs[e].$el.offsetHeight}}},Io=Mo,No=s(Io,To,Po,!1,null,null,null);No.options.__file="packages/date-picker/src/basic/time-spinner.vue";var jo=No.exports,Ao={mixins:[g.a],components:{TimeSpinner:jo},props:{visible:Boolean,timeArrowControl:Boolean},watch:{visible:function(e){var t=this;e?(this.oldValue=this.value,this.$nextTick((function(){return t.$refs.spinner.emitSelectRange("hours")}))):this.needInitAdjust=!0},value:function(e){var t=this,n=void 0;e instanceof Date?n=Object(ao["limitTimeRange"])(e,this.selectableRange,this.format):e||(n=this.defaultValue?new Date(this.defaultValue):new Date),this.date=n,this.visible&&this.needInitAdjust&&(this.$nextTick((function(e){return t.adjustSpinners()})),this.needInitAdjust=!1)},selectableRange:function(e){this.$refs.spinner.selectableRange=e},defaultValue:function(e){Object(ao["isDate"])(this.value)||(this.date=e?new Date(e):new Date)}},data:function(){return{popperClass:"",format:"HH:mm:ss",value:"",defaultValue:null,date:new Date,oldValue:new Date,selectableRange:[],selectionRange:[0,2],disabled:!1,arrowControl:!1,needInitAdjust:!0}},computed:{showSeconds:function(){return-1!==(this.format||"").indexOf("ss")},useArrow:function(){return this.arrowControl||this.timeArrowControl||!1},amPmMode:function(){return-1!==(this.format||"").indexOf("A")?"A":-1!==(this.format||"").indexOf("a")?"a":""}},methods:{handleCancel:function(){this.$emit("pick",this.oldValue,!1)},handleChange:function(e){this.visible&&(this.date=Object(ao["clearMilliseconds"])(e),this.isValidValue(this.date)&&this.$emit("pick",this.date,!0))},setSelectionRange:function(e,t){this.$emit("select-range",e,t),this.selectionRange=[e,t]},handleConfirm:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=arguments[1];if(!t){var n=Object(ao["clearMilliseconds"])(Object(ao["limitTimeRange"])(this.date,this.selectableRange,this.format));this.$emit("pick",n,e,t)}},handleKeydown:function(e){var t=e.keyCode,n={38:-1,40:1,37:-1,39:1};if(37===t||39===t){var i=n[t];return this.changeSelectionRange(i),void e.preventDefault()}if(38===t||40===t){var r=n[t];return this.$refs.spinner.scrollDown(r),void e.preventDefault()}},isValidValue:function(e){return Object(ao["timeWithinRange"])(e,this.selectableRange,this.format)},adjustSpinners:function(){return this.$refs.spinner.adjustSpinners()},changeSelectionRange:function(e){var t=[0,3].concat(this.showSeconds?[6]:[]),n=["hours","minutes"].concat(this.showSeconds?["seconds"]:[]),i=t.indexOf(this.selectionRange[0]),r=(i+e+t.length)%t.length;this.$refs.spinner.emitSelectRange(n[r])}},mounted:function(){var e=this;this.$nextTick((function(){return e.handleConfirm(!0,!0)})),this.$emit("mounted")}},Fo=Ao,Lo=s(Fo,Do,Eo,!1,null,null,null);Lo.options.__file="packages/date-picker/src/panel/time.vue";var Vo=Lo.exports,zo=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("table",{staticClass:"el-year-table",on:{click:e.handleYearTableClick}},[n("tbody",[n("tr",[n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+0)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+1)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+1))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+2)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+2))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+3)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+3))])])]),n("tr",[n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+4)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+4))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+5)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+5))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+6)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+6))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+7)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+7))])])]),n("tr",[n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+8)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+8))])]),n("td",{staticClass:"available",class:e.getCellStyle(e.startYear+9)},[n("a",{staticClass:"cell"},[e._v(e._s(e.startYear+9))])]),n("td"),n("td")])])])},Bo=[];zo._withStripped=!0;var Ro=function(e){var t=Object(ao["getDayCountOfYear"])(e),n=new Date(e,0,1);return Object(ao["range"])(t).map((function(e){return Object(ao["nextDate"])(n,e)}))},Ho={props:{disabledDate:{},value:{},defaultValue:{validator:function(e){return null===e||e instanceof Date&&Object(ao["isDate"])(e)}},date:{}},computed:{startYear:function(){return 10*Math.floor(this.date.getFullYear()/10)}},methods:{getCellStyle:function(e){var t={},n=new Date;return t.disabled="function"===typeof this.disabledDate&&Ro(e).every(this.disabledDate),t.current=Object(b["arrayFindIndex"])(Object(b["coerceTruthyValueToArray"])(this.value),(function(t){return t.getFullYear()===e}))>=0,t.today=n.getFullYear()===e,t.default=this.defaultValue&&this.defaultValue.getFullYear()===e,t},handleYearTableClick:function(e){var t=e.target;if("A"===t.tagName){if(Object(Le["hasClass"])(t.parentNode,"disabled"))return;var n=t.textContent||t.innerText;this.$emit("pick",Number(n))}}}},Wo=Ho,qo=s(Wo,zo,Bo,!1,null,null,null);qo.options.__file="packages/date-picker/src/basic/year-table.vue";var Uo=qo.exports,Yo=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("table",{staticClass:"el-month-table",on:{click:e.handleMonthTableClick,mousemove:e.handleMouseMove}},[n("tbody",e._l(e.rows,(function(t,i){return n("tr",{key:i},e._l(t,(function(t,i){return n("td",{key:i,class:e.getCellStyle(t)},[n("div",[n("a",{staticClass:"cell"},[e._v(e._s(e.t("el.datepicker.months."+e.months[t.text])))])])])})),0)})),0)])},Ko=[];Yo._withStripped=!0;var Go=function(e,t){var n=Object(ao["getDayCountOfMonth"])(e,t),i=new Date(e,t,1);return Object(ao["range"])(n).map((function(e){return Object(ao["nextDate"])(i,e)}))},Xo=function(e){return new Date(e.getFullYear(),e.getMonth())},Zo=function(e){return"number"===typeof e||"string"===typeof e?Xo(new Date(e)).getTime():e instanceof Date?Xo(e).getTime():NaN},Jo={props:{disabledDate:{},value:{},selectionMode:{default:"month"},minDate:{},maxDate:{},defaultValue:{validator:function(e){return null===e||Object(ao["isDate"])(e)||Array.isArray(e)&&e.every(ao["isDate"])}},date:{},rangeState:{default:function(){return{endDate:null,selecting:!1}}}},mixins:[g.a],watch:{"rangeState.endDate":function(e){this.markRange(this.minDate,e)},minDate:function(e,t){Zo(e)!==Zo(t)&&this.markRange(this.minDate,this.maxDate)},maxDate:function(e,t){Zo(e)!==Zo(t)&&this.markRange(this.minDate,this.maxDate)}},data:function(){return{months:["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"],tableRows:[[],[],[]],lastRow:null,lastColumn:null}},methods:{cellMatchesDate:function(e,t){var n=new Date(t);return this.date.getFullYear()===n.getFullYear()&&Number(e.text)===n.getMonth()},getCellStyle:function(e){var t=this,n={},i=this.date.getFullYear(),r=new Date,o=e.text,a=this.defaultValue?Array.isArray(this.defaultValue)?this.defaultValue:[this.defaultValue]:[];return n.disabled="function"===typeof this.disabledDate&&Go(i,o).every(this.disabledDate),n.current=Object(b["arrayFindIndex"])(Object(b["coerceTruthyValueToArray"])(this.value),(function(e){return e.getFullYear()===i&&e.getMonth()===o}))>=0,n.today=r.getFullYear()===i&&r.getMonth()===o,n.default=a.some((function(n){return t.cellMatchesDate(e,n)})),e.inRange&&(n["in-range"]=!0,e.start&&(n["start-date"]=!0),e.end&&(n["end-date"]=!0)),n},getMonthOfCell:function(e){var t=this.date.getFullYear();return new Date(t,e,1)},markRange:function(e,t){e=Zo(e),t=Zo(t)||e;var n=[Math.min(e,t),Math.max(e,t)];e=n[0],t=n[1];for(var i=this.rows,r=0,o=i.length;r=e&&d<=t,c.start=e&&d===e,c.end=t&&d===t}},handleMouseMove:function(e){if(this.rangeState.selecting){var t=e.target;if("A"===t.tagName&&(t=t.parentNode.parentNode),"DIV"===t.tagName&&(t=t.parentNode),"TD"===t.tagName){var n=t.parentNode.rowIndex,i=t.cellIndex;this.rows[n][i].disabled||n===this.lastRow&&i===this.lastColumn||(this.lastRow=n,this.lastColumn=i,this.$emit("changerange",{minDate:this.minDate,maxDate:this.maxDate,rangeState:{selecting:!0,endDate:this.getMonthOfCell(4*n+i)}}))}}},handleMonthTableClick:function(e){var t=e.target;if("A"===t.tagName&&(t=t.parentNode.parentNode),"DIV"===t.tagName&&(t=t.parentNode),"TD"===t.tagName&&!Object(Le["hasClass"])(t,"disabled")){var n=t.cellIndex,i=t.parentNode.rowIndex,r=4*i+n,o=this.getMonthOfCell(r);"range"===this.selectionMode?this.rangeState.selecting?(o>=this.minDate?this.$emit("pick",{minDate:this.minDate,maxDate:o}):this.$emit("pick",{minDate:o,maxDate:this.minDate}),this.rangeState.selecting=!1):(this.$emit("pick",{minDate:o,maxDate:null}),this.rangeState.selecting=!0):this.$emit("pick",r)}}},computed:{rows:function(){for(var e=this,t=this.tableRows,n=this.disabledDate,i=[],r=Zo(new Date),o=0;o<3;o++)for(var a=t[o],s=function(t){var s=a[t];s||(s={row:o,column:t,type:"normal",inRange:!1,start:!1,end:!1}),s.type="normal";var l=4*o+t,c=new Date(e.date.getFullYear(),l).getTime();s.inRange=c>=Zo(e.minDate)&&c<=Zo(e.maxDate),s.start=e.minDate&&c===Zo(e.minDate),s.end=e.maxDate&&c===Zo(e.maxDate);var u=c===r;u&&(s.type="today"),s.text=l;var d=new Date(c);s.disabled="function"===typeof n&&n(d),s.selected=Object(b["arrayFind"])(i,(function(e){return e.getTime()===d.getTime()})),e.$set(a,t,s)},l=0;l<4;l++)s(l);return t}}},Qo=Jo,ea=s(Qo,Yo,Ko,!1,null,null,null);ea.options.__file="packages/date-picker/src/basic/month-table.vue";var ta=ea.exports,na=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("table",{staticClass:"el-date-table",class:{"is-week-mode":"week"===e.selectionMode},attrs:{cellspacing:"0",cellpadding:"0"},on:{click:e.handleClick,mousemove:e.handleMouseMove}},[n("tbody",[n("tr",[e.showWeekNumber?n("th",[e._v(e._s(e.t("el.datepicker.week")))]):e._e(),e._l(e.WEEKS,(function(t,i){return n("th",{key:i},[e._v(e._s(e.t("el.datepicker.weeks."+t)))])}))],2),e._l(e.rows,(function(t,i){return n("tr",{key:i,staticClass:"el-date-table__row",class:{current:e.isWeekActive(t[1])}},e._l(t,(function(t,i){return n("td",{key:i,class:e.getCellClasses(t)},[n("div",[n("span",[e._v("\n "+e._s(t.text)+"\n ")])])])})),0)}))],2)])},ia=[];na._withStripped=!0;var ra=["sun","mon","tue","wed","thu","fri","sat"],oa=function(e){return"number"===typeof e||"string"===typeof e?Object(ao["clearTime"])(new Date(e)).getTime():e instanceof Date?Object(ao["clearTime"])(e).getTime():NaN},aa=function(e,t){var n="function"===typeof t?Object(b["arrayFindIndex"])(e,t):e.indexOf(t);return n>=0?[].concat(e.slice(0,n),e.slice(n+1)):e},sa={mixins:[g.a],props:{firstDayOfWeek:{default:7,type:Number,validator:function(e){return e>=1&&e<=7}},value:{},defaultValue:{validator:function(e){return null===e||Object(ao["isDate"])(e)||Array.isArray(e)&&e.every(ao["isDate"])}},date:{},selectionMode:{default:"day"},showWeekNumber:{type:Boolean,default:!1},disabledDate:{},cellClassName:{},minDate:{},maxDate:{},rangeState:{default:function(){return{endDate:null,selecting:!1}}}},computed:{offsetDay:function(){var e=this.firstDayOfWeek;return e>3?7-e:-e},WEEKS:function(){var e=this.firstDayOfWeek;return ra.concat(ra).slice(e,e+7)},year:function(){return this.date.getFullYear()},month:function(){return this.date.getMonth()},startDate:function(){return Object(ao["getStartDateOfMonth"])(this.year,this.month)},rows:function(){var e=this,t=new Date(this.year,this.month,1),n=Object(ao["getFirstDayOfMonth"])(t),i=Object(ao["getDayCountOfMonth"])(t.getFullYear(),t.getMonth()),r=Object(ao["getDayCountOfMonth"])(t.getFullYear(),0===t.getMonth()?11:t.getMonth()-1);n=0===n?7:n;for(var o=this.offsetDay,a=this.tableRows,s=1,l=this.startDate,c=this.disabledDate,u=this.cellClassName,d="dates"===this.selectionMode?Object(b["coerceTruthyValueToArray"])(this.value):[],h=oa(new Date),f=0;f<6;f++){var p=a[f];this.showWeekNumber&&(p[0]||(p[0]={type:"week",text:Object(ao["getWeekNumber"])(Object(ao["nextDate"])(l,7*f+1))}));for(var m=function(t){var a=p[e.showWeekNumber?t+1:t];a||(a={row:f,column:t,type:"normal",inRange:!1,start:!1,end:!1}),a.type="normal";var m=7*f+t,v=Object(ao["nextDate"])(l,m-o).getTime();a.inRange=v>=oa(e.minDate)&&v<=oa(e.maxDate),a.start=e.minDate&&v===oa(e.minDate),a.end=e.maxDate&&v===oa(e.maxDate);var g=v===h;if(g&&(a.type="today"),f>=0&&f<=1){var y=n+o<0?7+n+o:n+o;t+7*f>=y?a.text=s++:(a.text=r-(y-t%7)+1+7*f,a.type="prev-month")}else s<=i?a.text=s++:(a.text=s++-i,a.type="next-month");var _=new Date(v);a.disabled="function"===typeof c&&c(_),a.selected=Object(b["arrayFind"])(d,(function(e){return e.getTime()===_.getTime()})),a.customClass="function"===typeof u&&u(_),e.$set(p,e.showWeekNumber?t+1:t,a)},v=0;v<7;v++)m(v);if("week"===this.selectionMode){var g=this.showWeekNumber?1:0,y=this.showWeekNumber?7:6,_=this.isWeekActive(p[g+1]);p[g].inRange=_,p[g].start=_,p[y].inRange=_,p[y].end=_}}return a}},watch:{"rangeState.endDate":function(e){this.markRange(this.minDate,e)},minDate:function(e,t){oa(e)!==oa(t)&&this.markRange(this.minDate,this.maxDate)},maxDate:function(e,t){oa(e)!==oa(t)&&this.markRange(this.minDate,this.maxDate)}},data:function(){return{tableRows:[[],[],[],[],[],[]],lastRow:null,lastColumn:null}},methods:{cellMatchesDate:function(e,t){var n=new Date(t);return this.year===n.getFullYear()&&this.month===n.getMonth()&&Number(e.text)===n.getDate()},getCellClasses:function(e){var t=this,n=this.selectionMode,i=this.defaultValue?Array.isArray(this.defaultValue)?this.defaultValue:[this.defaultValue]:[],r=[];return"normal"!==e.type&&"today"!==e.type||e.disabled?r.push(e.type):(r.push("available"),"today"===e.type&&r.push("today")),"normal"===e.type&&i.some((function(n){return t.cellMatchesDate(e,n)}))&&r.push("default"),"day"!==n||"normal"!==e.type&&"today"!==e.type||!this.cellMatchesDate(e,this.value)||r.push("current"),!e.inRange||"normal"!==e.type&&"today"!==e.type&&"week"!==this.selectionMode||(r.push("in-range"),e.start&&r.push("start-date"),e.end&&r.push("end-date")),e.disabled&&r.push("disabled"),e.selected&&r.push("selected"),e.customClass&&r.push(e.customClass),r.join(" ")},getDateOfCell:function(e,t){var n=7*e+(t-(this.showWeekNumber?1:0))-this.offsetDay;return Object(ao["nextDate"])(this.startDate,n)},isWeekActive:function(e){if("week"!==this.selectionMode)return!1;var t=new Date(this.year,this.month,1),n=t.getFullYear(),i=t.getMonth();if("prev-month"===e.type&&(t.setMonth(0===i?11:i-1),t.setFullYear(0===i?n-1:n)),"next-month"===e.type&&(t.setMonth(11===i?0:i+1),t.setFullYear(11===i?n+1:n)),t.setDate(parseInt(e.text,10)),Object(ao["isDate"])(this.value)){var r=(this.value.getDay()-this.firstDayOfWeek+7)%7-1,o=Object(ao["prevDate"])(this.value,r);return o.getTime()===t.getTime()}return!1},markRange:function(e,t){e=oa(e),t=oa(t)||e;var n=[Math.min(e,t),Math.max(e,t)];e=n[0],t=n[1];for(var i=this.startDate,r=this.rows,o=0,a=r.length;o=e&&h<=t,u.start=e&&h===e,u.end=t&&h===t}},handleMouseMove:function(e){if(this.rangeState.selecting){var t=e.target;if("SPAN"===t.tagName&&(t=t.parentNode.parentNode),"DIV"===t.tagName&&(t=t.parentNode),"TD"===t.tagName){var n=t.parentNode.rowIndex-1,i=t.cellIndex;this.rows[n][i].disabled||n===this.lastRow&&i===this.lastColumn||(this.lastRow=n,this.lastColumn=i,this.$emit("changerange",{minDate:this.minDate,maxDate:this.maxDate,rangeState:{selecting:!0,endDate:this.getDateOfCell(n,i)}}))}}},handleClick:function(e){var t=e.target;if("SPAN"===t.tagName&&(t=t.parentNode.parentNode),"DIV"===t.tagName&&(t=t.parentNode),"TD"===t.tagName){var n=t.parentNode.rowIndex-1,i="week"===this.selectionMode?1:t.cellIndex,r=this.rows[n][i];if(!r.disabled&&"week"!==r.type){var o=this.getDateOfCell(n,i);if("range"===this.selectionMode)this.rangeState.selecting?(o>=this.minDate?this.$emit("pick",{minDate:this.minDate,maxDate:o}):this.$emit("pick",{minDate:o,maxDate:this.minDate}),this.rangeState.selecting=!1):(this.$emit("pick",{minDate:o,maxDate:null}),this.rangeState.selecting=!0);else if("day"===this.selectionMode)this.$emit("pick",o);else if("week"===this.selectionMode){var a=Object(ao["getWeekNumber"])(o),s=o.getFullYear()+"w"+a;this.$emit("pick",{year:o.getFullYear(),week:a,value:s,date:o})}else if("dates"===this.selectionMode){var l=this.value||[],c=r.selected?aa(l,(function(e){return e.getTime()===o.getTime()})):[].concat(l,[o]);this.$emit("pick",c)}}}}}},la=sa,ca=s(la,na,ia,!1,null,null,null);ca.options.__file="packages/date-picker/src/basic/date-table.vue";var ua=ca.exports,da={mixins:[g.a],directives:{Clickoutside:V.a},watch:{showTime:function(e){var t=this;e&&this.$nextTick((function(e){var n=t.$refs.input.$el;n&&(t.pickerWidth=n.getBoundingClientRect().width+10)}))},value:function(e){"dates"===this.selectionMode&&this.value||(Object(ao["isDate"])(e)?this.date=new Date(e):this.date=this.getDefaultValue())},defaultValue:function(e){Object(ao["isDate"])(this.value)||(this.date=e?new Date(e):new Date)},timePickerVisible:function(e){var t=this;e&&this.$nextTick((function(){return t.$refs.timepicker.adjustSpinners()}))},selectionMode:function(e){"month"===e?"year"===this.currentView&&"month"===this.currentView||(this.currentView="month"):"dates"===e&&(this.currentView="date")}},methods:{proxyTimePickerDataProperties:function(){var e=this,t=function(t){e.$refs.timepicker.format=t},n=function(t){e.$refs.timepicker.value=t},i=function(t){e.$refs.timepicker.date=t},r=function(t){e.$refs.timepicker.selectableRange=t};this.$watch("value",n),this.$watch("date",i),this.$watch("selectableRange",r),t(this.timeFormat),n(this.value),i(this.date),r(this.selectableRange)},handleClear:function(){this.date=this.getDefaultValue(),this.$emit("pick",null)},emit:function(e){for(var t=this,n=arguments.length,i=Array(n>1?n-1:0),r=1;r0)||Object(ao["timeWithinRange"])(e,this.selectableRange,this.format||"HH:mm:ss")}},components:{TimePicker:Vo,YearTable:Uo,MonthTable:ta,DateTable:ua,ElInput:m.a,ElButton:ae.a},data:function(){return{popperClass:"",date:new Date,value:"",defaultValue:null,defaultTime:null,showTime:!1,selectionMode:"day",shortcuts:"",visible:!1,currentView:"date",disabledDate:"",cellClassName:"",selectableRange:[],firstDayOfWeek:7,showWeekNumber:!1,timePickerVisible:!1,format:"",arrowControl:!1,userInputDate:null,userInputTime:null}},computed:{year:function(){return this.date.getFullYear()},month:function(){return this.date.getMonth()},week:function(){return Object(ao["getWeekNumber"])(this.date)},monthDate:function(){return this.date.getDate()},footerVisible:function(){return this.showTime||"dates"===this.selectionMode},visibleTime:function(){return null!==this.userInputTime?this.userInputTime:Object(ao["formatDate"])(this.value||this.defaultValue,this.timeFormat)},visibleDate:function(){return null!==this.userInputDate?this.userInputDate:Object(ao["formatDate"])(this.value||this.defaultValue,this.dateFormat)},yearLabel:function(){var e=this.t("el.datepicker.year");if("year"===this.currentView){var t=10*Math.floor(this.year/10);return e?t+" "+e+" - "+(t+9)+" "+e:t+" - "+(t+9)}return this.year+" "+e},timeFormat:function(){return this.format?Object(ao["extractTimeFormat"])(this.format):"HH:mm:ss"},dateFormat:function(){return this.format?Object(ao["extractDateFormat"])(this.format):"yyyy-MM-dd"}}},ha=da,fa=s(ha,Oo,$o,!1,null,null,null);fa.options.__file="packages/date-picker/src/panel/date.vue";var pa=fa.exports,ma=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":function(t){e.$emit("dodestroy")}}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-picker-panel el-date-range-picker el-popper",class:[{"has-sidebar":e.$slots.sidebar||e.shortcuts,"has-time":e.showTime},e.popperClass]},[n("div",{staticClass:"el-picker-panel__body-wrapper"},[e._t("sidebar"),e.shortcuts?n("div",{staticClass:"el-picker-panel__sidebar"},e._l(e.shortcuts,(function(t,i){return n("button",{key:i,staticClass:"el-picker-panel__shortcut",attrs:{type:"button"},on:{click:function(n){e.handleShortcutClick(t)}}},[e._v(e._s(t.text))])})),0):e._e(),n("div",{staticClass:"el-picker-panel__body"},[e.showTime?n("div",{staticClass:"el-date-range-picker__time-header"},[n("span",{staticClass:"el-date-range-picker__editors-wrap"},[n("span",{staticClass:"el-date-range-picker__time-picker-wrap"},[n("el-input",{ref:"minInput",staticClass:"el-date-range-picker__editor",attrs:{size:"small",disabled:e.rangeState.selecting,placeholder:e.t("el.datepicker.startDate"),value:e.minVisibleDate},on:{input:function(t){return e.handleDateInput(t,"min")},change:function(t){return e.handleDateChange(t,"min")}}})],1),n("span",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleMinTimeClose,expression:"handleMinTimeClose"}],staticClass:"el-date-range-picker__time-picker-wrap"},[n("el-input",{staticClass:"el-date-range-picker__editor",attrs:{size:"small",disabled:e.rangeState.selecting,placeholder:e.t("el.datepicker.startTime"),value:e.minVisibleTime},on:{focus:function(t){e.minTimePickerVisible=!0},input:function(t){return e.handleTimeInput(t,"min")},change:function(t){return e.handleTimeChange(t,"min")}}}),n("time-picker",{ref:"minTimePicker",attrs:{"time-arrow-control":e.arrowControl,visible:e.minTimePickerVisible},on:{pick:e.handleMinTimePick,mounted:function(t){e.$refs.minTimePicker.format=e.timeFormat}}})],1)]),n("span",{staticClass:"el-icon-arrow-right"}),n("span",{staticClass:"el-date-range-picker__editors-wrap is-right"},[n("span",{staticClass:"el-date-range-picker__time-picker-wrap"},[n("el-input",{staticClass:"el-date-range-picker__editor",attrs:{size:"small",disabled:e.rangeState.selecting,placeholder:e.t("el.datepicker.endDate"),value:e.maxVisibleDate,readonly:!e.minDate},on:{input:function(t){return e.handleDateInput(t,"max")},change:function(t){return e.handleDateChange(t,"max")}}})],1),n("span",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.handleMaxTimeClose,expression:"handleMaxTimeClose"}],staticClass:"el-date-range-picker__time-picker-wrap"},[n("el-input",{staticClass:"el-date-range-picker__editor",attrs:{size:"small",disabled:e.rangeState.selecting,placeholder:e.t("el.datepicker.endTime"),value:e.maxVisibleTime,readonly:!e.minDate},on:{focus:function(t){e.minDate&&(e.maxTimePickerVisible=!0)},input:function(t){return e.handleTimeInput(t,"max")},change:function(t){return e.handleTimeChange(t,"max")}}}),n("time-picker",{ref:"maxTimePicker",attrs:{"time-arrow-control":e.arrowControl,visible:e.maxTimePickerVisible},on:{pick:e.handleMaxTimePick,mounted:function(t){e.$refs.maxTimePicker.format=e.timeFormat}}})],1)])]):e._e(),n("div",{staticClass:"el-picker-panel__content el-date-range-picker__content is-left"},[n("div",{staticClass:"el-date-range-picker__header"},[n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-left",attrs:{type:"button"},on:{click:e.leftPrevYear}}),n("button",{staticClass:"el-picker-panel__icon-btn el-icon-arrow-left",attrs:{type:"button"},on:{click:e.leftPrevMonth}}),e.unlinkPanels?n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-right",class:{"is-disabled":!e.enableYearArrow},attrs:{type:"button",disabled:!e.enableYearArrow},on:{click:e.leftNextYear}}):e._e(),e.unlinkPanels?n("button",{staticClass:"el-picker-panel__icon-btn el-icon-arrow-right",class:{"is-disabled":!e.enableMonthArrow},attrs:{type:"button",disabled:!e.enableMonthArrow},on:{click:e.leftNextMonth}}):e._e(),n("div",[e._v(e._s(e.leftLabel))])]),n("date-table",{attrs:{"selection-mode":"range",date:e.leftDate,"default-value":e.defaultValue,"min-date":e.minDate,"max-date":e.maxDate,"range-state":e.rangeState,"disabled-date":e.disabledDate,"cell-class-name":e.cellClassName,"first-day-of-week":e.firstDayOfWeek},on:{changerange:e.handleChangeRange,pick:e.handleRangePick}})],1),n("div",{staticClass:"el-picker-panel__content el-date-range-picker__content is-right"},[n("div",{staticClass:"el-date-range-picker__header"},[e.unlinkPanels?n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-left",class:{"is-disabled":!e.enableYearArrow},attrs:{type:"button",disabled:!e.enableYearArrow},on:{click:e.rightPrevYear}}):e._e(),e.unlinkPanels?n("button",{staticClass:"el-picker-panel__icon-btn el-icon-arrow-left",class:{"is-disabled":!e.enableMonthArrow},attrs:{type:"button",disabled:!e.enableMonthArrow},on:{click:e.rightPrevMonth}}):e._e(),n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-right",attrs:{type:"button"},on:{click:e.rightNextYear}}),n("button",{staticClass:"el-picker-panel__icon-btn el-icon-arrow-right",attrs:{type:"button"},on:{click:e.rightNextMonth}}),n("div",[e._v(e._s(e.rightLabel))])]),n("date-table",{attrs:{"selection-mode":"range",date:e.rightDate,"default-value":e.defaultValue,"min-date":e.minDate,"max-date":e.maxDate,"range-state":e.rangeState,"disabled-date":e.disabledDate,"cell-class-name":e.cellClassName,"first-day-of-week":e.firstDayOfWeek},on:{changerange:e.handleChangeRange,pick:e.handleRangePick}})],1)])],2),e.showTime?n("div",{staticClass:"el-picker-panel__footer"},[n("el-button",{staticClass:"el-picker-panel__link-btn",attrs:{size:"mini",type:"text"},on:{click:e.handleClear}},[e._v("\n "+e._s(e.t("el.datepicker.clear"))+"\n ")]),n("el-button",{staticClass:"el-picker-panel__link-btn",attrs:{plain:"",size:"mini",disabled:e.btnDisabled},on:{click:function(t){e.handleConfirm(!1)}}},[e._v("\n "+e._s(e.t("el.datepicker.confirm"))+"\n ")])],1):e._e()])])},va=[];ma._withStripped=!0;var ga=function(e){return Array.isArray(e)?[new Date(e[0]),new Date(e[1])]:e?[new Date(e),Object(ao["nextDate"])(new Date(e),1)]:[new Date,Object(ao["nextDate"])(new Date,1)]},ba={mixins:[g.a],directives:{Clickoutside:V.a},computed:{btnDisabled:function(){return!(this.minDate&&this.maxDate&&!this.selecting&&this.isValidValue([this.minDate,this.maxDate]))},leftLabel:function(){return this.leftDate.getFullYear()+" "+this.t("el.datepicker.year")+" "+this.t("el.datepicker.month"+(this.leftDate.getMonth()+1))},rightLabel:function(){return this.rightDate.getFullYear()+" "+this.t("el.datepicker.year")+" "+this.t("el.datepicker.month"+(this.rightDate.getMonth()+1))},leftYear:function(){return this.leftDate.getFullYear()},leftMonth:function(){return this.leftDate.getMonth()},leftMonthDate:function(){return this.leftDate.getDate()},rightYear:function(){return this.rightDate.getFullYear()},rightMonth:function(){return this.rightDate.getMonth()},rightMonthDate:function(){return this.rightDate.getDate()},minVisibleDate:function(){return null!==this.dateUserInput.min?this.dateUserInput.min:this.minDate?Object(ao["formatDate"])(this.minDate,this.dateFormat):""},maxVisibleDate:function(){return null!==this.dateUserInput.max?this.dateUserInput.max:this.maxDate||this.minDate?Object(ao["formatDate"])(this.maxDate||this.minDate,this.dateFormat):""},minVisibleTime:function(){return null!==this.timeUserInput.min?this.timeUserInput.min:this.minDate?Object(ao["formatDate"])(this.minDate,this.timeFormat):""},maxVisibleTime:function(){return null!==this.timeUserInput.max?this.timeUserInput.max:this.maxDate||this.minDate?Object(ao["formatDate"])(this.maxDate||this.minDate,this.timeFormat):""},timeFormat:function(){return this.format?Object(ao["extractTimeFormat"])(this.format):"HH:mm:ss"},dateFormat:function(){return this.format?Object(ao["extractDateFormat"])(this.format):"yyyy-MM-dd"},enableMonthArrow:function(){var e=(this.leftMonth+1)%12,t=this.leftMonth+1>=12?1:0;return this.unlinkPanels&&new Date(this.leftYear+t,e)=12}},data:function(){return{popperClass:"",value:[],defaultValue:null,defaultTime:null,minDate:"",maxDate:"",leftDate:new Date,rightDate:Object(ao["nextMonth"])(new Date),rangeState:{endDate:null,selecting:!1,row:null,column:null},showTime:!1,shortcuts:"",visible:"",disabledDate:"",cellClassName:"",firstDayOfWeek:7,minTimePickerVisible:!1,maxTimePickerVisible:!1,format:"",arrowControl:!1,unlinkPanels:!1,dateUserInput:{min:null,max:null},timeUserInput:{min:null,max:null}}},watch:{minDate:function(e){var t=this;this.dateUserInput.min=null,this.timeUserInput.min=null,this.$nextTick((function(){if(t.$refs.maxTimePicker&&t.maxDate&&t.maxDatethis.maxDate&&(this.maxDate=this.minDate)):(this.maxDate=Object(ao["modifyDate"])(this.maxDate,n.getFullYear(),n.getMonth(),n.getDate()),this.maxDatethis.maxDate&&(this.maxDate=this.minDate),this.$refs.minTimePicker.value=this.minDate,this.minTimePickerVisible=!1):(this.maxDate=Object(ao["modifyTime"])(this.maxDate,n.getHours(),n.getMinutes(),n.getSeconds()),this.maxDate1&&void 0!==arguments[1])||arguments[1],i=this.defaultTime||[],r=Object(ao["modifyWithTimeString"])(e.minDate,i[0]),o=Object(ao["modifyWithTimeString"])(e.maxDate,i[1]);this.maxDate===o&&this.minDate===r||(this.onPick&&this.onPick(e),this.maxDate=o,this.minDate=r,setTimeout((function(){t.maxDate=o,t.minDate=r}),10),n&&!this.showTime&&this.handleConfirm())},handleShortcutClick:function(e){e.onClick&&e.onClick(this)},handleMinTimePick:function(e,t,n){this.minDate=this.minDate||new Date,e&&(this.minDate=Object(ao["modifyTime"])(this.minDate,e.getHours(),e.getMinutes(),e.getSeconds())),n||(this.minTimePickerVisible=t),(!this.maxDate||this.maxDate&&this.maxDate.getTime()this.maxDate.getTime()&&(this.minDate=new Date(this.maxDate))},handleMaxTimeClose:function(){this.maxTimePickerVisible=!1},leftPrevYear:function(){this.leftDate=Object(ao["prevYear"])(this.leftDate),this.unlinkPanels||(this.rightDate=Object(ao["nextMonth"])(this.leftDate))},leftPrevMonth:function(){this.leftDate=Object(ao["prevMonth"])(this.leftDate),this.unlinkPanels||(this.rightDate=Object(ao["nextMonth"])(this.leftDate))},rightNextYear:function(){this.unlinkPanels?this.rightDate=Object(ao["nextYear"])(this.rightDate):(this.leftDate=Object(ao["nextYear"])(this.leftDate),this.rightDate=Object(ao["nextMonth"])(this.leftDate))},rightNextMonth:function(){this.unlinkPanels?this.rightDate=Object(ao["nextMonth"])(this.rightDate):(this.leftDate=Object(ao["nextMonth"])(this.leftDate),this.rightDate=Object(ao["nextMonth"])(this.leftDate))},leftNextYear:function(){this.leftDate=Object(ao["nextYear"])(this.leftDate)},leftNextMonth:function(){this.leftDate=Object(ao["nextMonth"])(this.leftDate)},rightPrevYear:function(){this.rightDate=Object(ao["prevYear"])(this.rightDate)},rightPrevMonth:function(){this.rightDate=Object(ao["prevMonth"])(this.rightDate)},handleConfirm:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.isValidValue([this.minDate,this.maxDate])&&this.$emit("pick",[this.minDate,this.maxDate],e)},isValidValue:function(e){return Array.isArray(e)&&e&&e[0]&&e[1]&&Object(ao["isDate"])(e[0])&&Object(ao["isDate"])(e[1])&&e[0].getTime()<=e[1].getTime()&&("function"!==typeof this.disabledDate||!this.disabledDate(e[0])&&!this.disabledDate(e[1]))},resetView:function(){this.minDate=this.value&&Object(ao["isDate"])(this.value[0])?new Date(this.value[0]):null,this.maxDate=this.value&&Object(ao["isDate"])(this.value[0])?new Date(this.value[1]):null}},components:{TimePicker:Vo,DateTable:ua,ElInput:m.a,ElButton:ae.a}},ya=ba,_a=s(ya,ma,va,!1,null,null,null);_a.options.__file="packages/date-picker/src/panel/date-range.vue";var xa=_a.exports,wa=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":function(t){e.$emit("dodestroy")}}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-picker-panel el-date-range-picker el-popper",class:[{"has-sidebar":e.$slots.sidebar||e.shortcuts},e.popperClass]},[n("div",{staticClass:"el-picker-panel__body-wrapper"},[e._t("sidebar"),e.shortcuts?n("div",{staticClass:"el-picker-panel__sidebar"},e._l(e.shortcuts,(function(t,i){return n("button",{key:i,staticClass:"el-picker-panel__shortcut",attrs:{type:"button"},on:{click:function(n){e.handleShortcutClick(t)}}},[e._v(e._s(t.text))])})),0):e._e(),n("div",{staticClass:"el-picker-panel__body"},[n("div",{staticClass:"el-picker-panel__content el-date-range-picker__content is-left"},[n("div",{staticClass:"el-date-range-picker__header"},[n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-left",attrs:{type:"button"},on:{click:e.leftPrevYear}}),e.unlinkPanels?n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-right",class:{"is-disabled":!e.enableYearArrow},attrs:{type:"button",disabled:!e.enableYearArrow},on:{click:e.leftNextYear}}):e._e(),n("div",[e._v(e._s(e.leftLabel))])]),n("month-table",{attrs:{"selection-mode":"range",date:e.leftDate,"default-value":e.defaultValue,"min-date":e.minDate,"max-date":e.maxDate,"range-state":e.rangeState,"disabled-date":e.disabledDate},on:{changerange:e.handleChangeRange,pick:e.handleRangePick}})],1),n("div",{staticClass:"el-picker-panel__content el-date-range-picker__content is-right"},[n("div",{staticClass:"el-date-range-picker__header"},[e.unlinkPanels?n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-left",class:{"is-disabled":!e.enableYearArrow},attrs:{type:"button",disabled:!e.enableYearArrow},on:{click:e.rightPrevYear}}):e._e(),n("button",{staticClass:"el-picker-panel__icon-btn el-icon-d-arrow-right",attrs:{type:"button"},on:{click:e.rightNextYear}}),n("div",[e._v(e._s(e.rightLabel))])]),n("month-table",{attrs:{"selection-mode":"range",date:e.rightDate,"default-value":e.defaultValue,"min-date":e.minDate,"max-date":e.maxDate,"range-state":e.rangeState,"disabled-date":e.disabledDate},on:{changerange:e.handleChangeRange,pick:e.handleRangePick}})],1)])],2)])])},Ca=[];wa._withStripped=!0;var ka=function(e){return Array.isArray(e)?[new Date(e[0]),new Date(e[1])]:e?[new Date(e),Object(ao["nextMonth"])(new Date(e))]:[new Date,Object(ao["nextMonth"])(new Date)]},Sa={mixins:[g.a],directives:{Clickoutside:V.a},computed:{btnDisabled:function(){return!(this.minDate&&this.maxDate&&!this.selecting&&this.isValidValue([this.minDate,this.maxDate]))},leftLabel:function(){return this.leftDate.getFullYear()+" "+this.t("el.datepicker.year")},rightLabel:function(){return this.rightDate.getFullYear()+" "+this.t("el.datepicker.year")},leftYear:function(){return this.leftDate.getFullYear()},rightYear:function(){return this.rightDate.getFullYear()===this.leftDate.getFullYear()?this.leftDate.getFullYear()+1:this.rightDate.getFullYear()},enableYearArrow:function(){return this.unlinkPanels&&this.rightYear>this.leftYear+1}},data:function(){return{popperClass:"",value:[],defaultValue:null,defaultTime:null,minDate:"",maxDate:"",leftDate:new Date,rightDate:Object(ao["nextYear"])(new Date),rangeState:{endDate:null,selecting:!1,row:null,column:null},shortcuts:"",visible:"",disabledDate:"",format:"",arrowControl:!1,unlinkPanels:!1}},watch:{value:function(e){if(e){if(Array.isArray(e))if(this.minDate=Object(ao["isDate"])(e[0])?new Date(e[0]):null,this.maxDate=Object(ao["isDate"])(e[1])?new Date(e[1]):null,this.minDate)if(this.leftDate=this.minDate,this.unlinkPanels&&this.maxDate){var t=this.minDate.getFullYear(),n=this.maxDate.getFullYear();this.rightDate=t===n?Object(ao["nextYear"])(this.maxDate):this.maxDate}else this.rightDate=Object(ao["nextYear"])(this.leftDate);else this.leftDate=ka(this.defaultValue)[0],this.rightDate=Object(ao["nextYear"])(this.leftDate)}else this.minDate=null,this.maxDate=null},defaultValue:function(e){if(!Array.isArray(this.value)){var t=ka(e),n=t[0],i=t[1];this.leftDate=n,this.rightDate=e&&e[1]&&n.getFullYear()!==i.getFullYear()&&this.unlinkPanels?i:Object(ao["nextYear"])(this.leftDate)}}},methods:{handleClear:function(){this.minDate=null,this.maxDate=null,this.leftDate=ka(this.defaultValue)[0],this.rightDate=Object(ao["nextYear"])(this.leftDate),this.$emit("pick",null)},handleChangeRange:function(e){this.minDate=e.minDate,this.maxDate=e.maxDate,this.rangeState=e.rangeState},handleRangePick:function(e){var t=this,n=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=this.defaultTime||[],r=Object(ao["modifyWithTimeString"])(e.minDate,i[0]),o=Object(ao["modifyWithTimeString"])(e.maxDate,i[1]);this.maxDate===o&&this.minDate===r||(this.onPick&&this.onPick(e),this.maxDate=o,this.minDate=r,setTimeout((function(){t.maxDate=o,t.minDate=r}),10),n&&this.handleConfirm())},handleShortcutClick:function(e){e.onClick&&e.onClick(this)},leftPrevYear:function(){this.leftDate=Object(ao["prevYear"])(this.leftDate),this.unlinkPanels||(this.rightDate=Object(ao["prevYear"])(this.rightDate))},rightNextYear:function(){this.unlinkPanels||(this.leftDate=Object(ao["nextYear"])(this.leftDate)),this.rightDate=Object(ao["nextYear"])(this.rightDate)},leftNextYear:function(){this.leftDate=Object(ao["nextYear"])(this.leftDate)},rightPrevYear:function(){this.rightDate=Object(ao["prevYear"])(this.rightDate)},handleConfirm:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.isValidValue([this.minDate,this.maxDate])&&this.$emit("pick",[this.minDate,this.maxDate],e)},isValidValue:function(e){return Array.isArray(e)&&e&&e[0]&&e[1]&&Object(ao["isDate"])(e[0])&&Object(ao["isDate"])(e[1])&&e[0].getTime()<=e[1].getTime()&&("function"!==typeof this.disabledDate||!this.disabledDate(e[0])&&!this.disabledDate(e[1]))},resetView:function(){this.minDate=this.value&&Object(ao["isDate"])(this.value[0])?new Date(this.value[0]):null,this.maxDate=this.value&&Object(ao["isDate"])(this.value[0])?new Date(this.value[1]):null}},components:{MonthTable:ta,ElInput:m.a,ElButton:ae.a}},Oa=Sa,$a=s(Oa,wa,Ca,!1,null,null,null);$a.options.__file="packages/date-picker/src/panel/month-range.vue";var Da=$a.exports,Ea=function(e){return"daterange"===e||"datetimerange"===e?xa:"monthrange"===e?Da:pa},Ta={mixins:[So],name:"ElDatePicker",props:{type:{type:String,default:"date"},timeArrowControl:Boolean},watch:{type:function(e){this.picker?(this.unmountPicker(),this.panel=Ea(e),this.mountPicker()):this.panel=Ea(e)}},created:function(){this.panel=Ea(this.type)},install:function(e){e.component(Ta.name,Ta)}},Pa=Ta,Ma=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"before-enter":e.handleMenuEnter,"after-leave":function(t){e.$emit("dodestroy")}}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],ref:"popper",staticClass:"el-picker-panel time-select el-popper",class:e.popperClass,style:{width:e.width+"px"}},[n("el-scrollbar",{attrs:{noresize:"","wrap-class":"el-picker-panel__content"}},e._l(e.items,(function(t){return n("div",{key:t.value,staticClass:"time-select-item",class:{selected:e.value===t.value,disabled:t.disabled,default:t.value===e.defaultValue},attrs:{disabled:t.disabled},on:{click:function(n){e.handleClick(t)}}},[e._v(e._s(t.value))])})),0)],1)])},Ia=[];Ma._withStripped=!0;var Na=function(e){var t=(e||"").split(":");if(t.length>=2){var n=parseInt(t[0],10),i=parseInt(t[1],10);return{hours:n,minutes:i}}return null},ja=function(e,t){var n=Na(e),i=Na(t),r=n.minutes+60*n.hours,o=i.minutes+60*i.hours;return r===o?0:r>o?1:-1},Aa=function(e){return(e.hours<10?"0"+e.hours:e.hours)+":"+(e.minutes<10?"0"+e.minutes:e.minutes)},Fa=function(e,t){var n=Na(e),i=Na(t),r={hours:n.hours,minutes:n.minutes};return r.minutes+=i.minutes,r.hours+=i.hours,r.hours+=Math.floor(r.minutes/60),r.minutes=r.minutes%60,Aa(r)},La={components:{ElScrollbar:q.a},watch:{value:function(e){var t=this;e&&this.$nextTick((function(){return t.scrollToOption()}))}},methods:{handleClick:function(e){e.disabled||this.$emit("pick",e.value)},handleClear:function(){this.$emit("pick",null)},scrollToOption:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:".selected",t=this.$refs.popper.querySelector(".el-picker-panel__content");ri()(t,t.querySelector(e))},handleMenuEnter:function(){var e=this,t=-1!==this.items.map((function(e){return e.value})).indexOf(this.value),n=-1!==this.items.map((function(e){return e.value})).indexOf(this.defaultValue),i=(t?".selected":n&&".default")||".time-select-item:not(.disabled)";this.$nextTick((function(){return e.scrollToOption(i)}))},scrollDown:function(e){var t=this.items,n=t.length,i=t.length,r=t.map((function(e){return e.value})).indexOf(this.value);while(i--)if(r=(r+e+n)%n,!t[r].disabled)return void this.$emit("pick",t[r].value,!0)},isValidValue:function(e){return-1!==this.items.filter((function(e){return!e.disabled})).map((function(e){return e.value})).indexOf(e)},handleKeydown:function(e){var t=e.keyCode;if(38===t||40===t){var n={40:1,38:-1},i=n[t.toString()];return this.scrollDown(i),void e.stopPropagation()}}},data:function(){return{popperClass:"",start:"09:00",end:"18:00",step:"00:30",value:"",defaultValue:"",visible:!1,minTime:"",maxTime:"",width:0}},computed:{items:function(){var e=this.start,t=this.end,n=this.step,i=[];if(e&&t&&n){var r=e;while(ja(r,t)<=0)i.push({value:r,disabled:ja(r,this.minTime||"-1:-1")<=0||ja(r,this.maxTime||"100:100")>=0}),r=Fa(r,n)}return i}}},Va=La,za=s(Va,Ma,Ia,!1,null,null,null);za.options.__file="packages/date-picker/src/panel/time-select.vue";var Ba=za.exports,Ra={mixins:[So],name:"ElTimeSelect",componentName:"ElTimeSelect",props:{type:{type:String,default:"time-select"}},beforeCreate:function(){this.panel=Ba},install:function(e){e.component(Ra.name,Ra)}},Ha=Ra,Wa=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":function(t){e.$emit("dodestroy")}}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-time-range-picker el-picker-panel el-popper",class:e.popperClass},[n("div",{staticClass:"el-time-range-picker__content"},[n("div",{staticClass:"el-time-range-picker__cell"},[n("div",{staticClass:"el-time-range-picker__header"},[e._v(e._s(e.t("el.datepicker.startTime")))]),n("div",{staticClass:"el-time-range-picker__body el-time-panel__content",class:{"has-seconds":e.showSeconds,"is-arrow":e.arrowControl}},[n("time-spinner",{ref:"minSpinner",attrs:{"show-seconds":e.showSeconds,"am-pm-mode":e.amPmMode,"arrow-control":e.arrowControl,date:e.minDate},on:{change:e.handleMinChange,"select-range":e.setMinSelectionRange}})],1)]),n("div",{staticClass:"el-time-range-picker__cell"},[n("div",{staticClass:"el-time-range-picker__header"},[e._v(e._s(e.t("el.datepicker.endTime")))]),n("div",{staticClass:"el-time-range-picker__body el-time-panel__content",class:{"has-seconds":e.showSeconds,"is-arrow":e.arrowControl}},[n("time-spinner",{ref:"maxSpinner",attrs:{"show-seconds":e.showSeconds,"am-pm-mode":e.amPmMode,"arrow-control":e.arrowControl,date:e.maxDate},on:{change:e.handleMaxChange,"select-range":e.setMaxSelectionRange}})],1)])]),n("div",{staticClass:"el-time-panel__footer"},[n("button",{staticClass:"el-time-panel__btn cancel",attrs:{type:"button"},on:{click:function(t){e.handleCancel()}}},[e._v(e._s(e.t("el.datepicker.cancel")))]),n("button",{staticClass:"el-time-panel__btn confirm",attrs:{type:"button",disabled:e.btnDisabled},on:{click:function(t){e.handleConfirm()}}},[e._v(e._s(e.t("el.datepicker.confirm")))])])])])},qa=[];Wa._withStripped=!0;var Ua=Object(ao["parseDate"])("00:00:00","HH:mm:ss"),Ya=Object(ao["parseDate"])("23:59:59","HH:mm:ss"),Ka=function(e){return Object(ao["modifyDate"])(Ua,e.getFullYear(),e.getMonth(),e.getDate())},Ga=function(e){return Object(ao["modifyDate"])(Ya,e.getFullYear(),e.getMonth(),e.getDate())},Xa=function(e,t){return new Date(Math.min(e.getTime()+t,Ga(e).getTime()))},Za={mixins:[g.a],components:{TimeSpinner:jo},computed:{showSeconds:function(){return-1!==(this.format||"").indexOf("ss")},offset:function(){return this.showSeconds?11:8},spinner:function(){return this.selectionRange[0]this.maxDate.getTime()},amPmMode:function(){return-1!==(this.format||"").indexOf("A")?"A":-1!==(this.format||"").indexOf("a")?"a":""}},data:function(){return{popperClass:"",minDate:new Date,maxDate:new Date,value:[],oldValue:[new Date,new Date],defaultValue:null,format:"HH:mm:ss",visible:!1,selectionRange:[0,2],arrowControl:!1}},watch:{value:function(e){Array.isArray(e)?(this.minDate=new Date(e[0]),this.maxDate=new Date(e[1])):Array.isArray(this.defaultValue)?(this.minDate=new Date(this.defaultValue[0]),this.maxDate=new Date(this.defaultValue[1])):this.defaultValue?(this.minDate=new Date(this.defaultValue),this.maxDate=Xa(new Date(this.defaultValue),36e5)):(this.minDate=new Date,this.maxDate=Xa(new Date,36e5))},visible:function(e){var t=this;e&&(this.oldValue=this.value,this.$nextTick((function(){return t.$refs.minSpinner.emitSelectRange("hours")})))}},methods:{handleClear:function(){this.$emit("pick",null)},handleCancel:function(){this.$emit("pick",this.oldValue)},handleMinChange:function(e){this.minDate=Object(ao["clearMilliseconds"])(e),this.handleChange()},handleMaxChange:function(e){this.maxDate=Object(ao["clearMilliseconds"])(e),this.handleChange()},handleChange:function(){this.isValidValue([this.minDate,this.maxDate])&&(this.$refs.minSpinner.selectableRange=[[Ka(this.minDate),this.maxDate]],this.$refs.maxSpinner.selectableRange=[[this.minDate,Ga(this.maxDate)]],this.$emit("pick",[this.minDate,this.maxDate],!0))},setMinSelectionRange:function(e,t){this.$emit("select-range",e,t,"min"),this.selectionRange=[e,t]},setMaxSelectionRange:function(e,t){this.$emit("select-range",e,t,"max"),this.selectionRange=[e+this.offset,t+this.offset]},handleConfirm:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.$refs.minSpinner.selectableRange,n=this.$refs.maxSpinner.selectableRange;this.minDate=Object(ao["limitTimeRange"])(this.minDate,t,this.format),this.maxDate=Object(ao["limitTimeRange"])(this.maxDate,n,this.format),this.$emit("pick",[this.minDate,this.maxDate],e)},adjustSpinners:function(){this.$refs.minSpinner.adjustSpinners(),this.$refs.maxSpinner.adjustSpinners()},changeSelectionRange:function(e){var t=this.showSeconds?[0,3,6,11,14,17]:[0,3,8,11],n=["hours","minutes"].concat(this.showSeconds?["seconds"]:[]),i=t.indexOf(this.selectionRange[0]),r=(i+e+t.length)%t.length,o=t.length/2;r-1}},openDelay:{type:Number,default:0},closeDelay:{type:Number,default:200},title:String,disabled:Boolean,content:String,reference:{},popperClass:String,width:{},visibleArrow:{default:!0},arrowOffset:{type:Number,default:0},transition:{type:String,default:"fade-in-linear"},tabindex:{type:Number,default:0}},computed:{tooltipId:function(){return"el-popover-"+Object(b["generateId"])()}},watch:{showPopper:function(e){this.disabled||(e?this.$emit("show"):this.$emit("hide"))}},mounted:function(){var e=this,t=this.referenceElm=this.reference||this.$refs.reference,n=this.popper||this.$refs.popper;!t&&this.$slots.reference&&this.$slots.reference[0]&&(t=this.referenceElm=this.$slots.reference[0].elm),t&&(Object(Le["addClass"])(t,"el-popover__reference"),t.setAttribute("aria-describedby",this.tooltipId),t.setAttribute("tabindex",this.tabindex),n.setAttribute("tabindex",0),"click"!==this.trigger&&(Object(Le["on"])(t,"focusin",(function(){e.handleFocus();var n=t.__vue__;n&&"function"===typeof n.focus&&n.focus()})),Object(Le["on"])(n,"focusin",this.handleFocus),Object(Le["on"])(t,"focusout",this.handleBlur),Object(Le["on"])(n,"focusout",this.handleBlur)),Object(Le["on"])(t,"keydown",this.handleKeydown),Object(Le["on"])(t,"click",this.handleClick)),"click"===this.trigger?(Object(Le["on"])(t,"click",this.doToggle),Object(Le["on"])(document,"click",this.handleDocumentClick)):"hover"===this.trigger?(Object(Le["on"])(t,"mouseenter",this.handleMouseEnter),Object(Le["on"])(n,"mouseenter",this.handleMouseEnter),Object(Le["on"])(t,"mouseleave",this.handleMouseLeave),Object(Le["on"])(n,"mouseleave",this.handleMouseLeave)):"focus"===this.trigger&&(this.tabindex<0&&console.warn("[Element Warn][Popover]a negative taindex means that the element cannot be focused by tab key"),t.querySelector("input, textarea")?(Object(Le["on"])(t,"focusin",this.doShow),Object(Le["on"])(t,"focusout",this.doClose)):(Object(Le["on"])(t,"mousedown",this.doShow),Object(Le["on"])(t,"mouseup",this.doClose)))},beforeDestroy:function(){this.cleanup()},deactivated:function(){this.cleanup()},methods:{doToggle:function(){this.showPopper=!this.showPopper},doShow:function(){this.showPopper=!0},doClose:function(){this.showPopper=!1},handleFocus:function(){Object(Le["addClass"])(this.referenceElm,"focusing"),"click"!==this.trigger&&"focus"!==this.trigger||(this.showPopper=!0)},handleClick:function(){Object(Le["removeClass"])(this.referenceElm,"focusing")},handleBlur:function(){Object(Le["removeClass"])(this.referenceElm,"focusing"),"click"!==this.trigger&&"focus"!==this.trigger||(this.showPopper=!1)},handleMouseEnter:function(){var e=this;clearTimeout(this._timer),this.openDelay?this._timer=setTimeout((function(){e.showPopper=!0}),this.openDelay):this.showPopper=!0},handleKeydown:function(e){27===e.keyCode&&"manual"!==this.trigger&&this.doClose()},handleMouseLeave:function(){var e=this;clearTimeout(this._timer),this.closeDelay?this._timer=setTimeout((function(){e.showPopper=!1}),this.closeDelay):this.showPopper=!1},handleDocumentClick:function(e){var t=this.reference||this.$refs.reference,n=this.popper||this.$refs.popper;!t&&this.$slots.reference&&this.$slots.reference[0]&&(t=this.referenceElm=this.$slots.reference[0].elm),this.$el&&t&&!this.$el.contains(e.target)&&!t.contains(e.target)&&n&&!n.contains(e.target)&&(this.showPopper=!1)},handleAfterEnter:function(){this.$emit("after-enter")},handleAfterLeave:function(){this.$emit("after-leave"),this.doDestroy()},cleanup:function(){(this.openDelay||this.closeDelay)&&clearTimeout(this._timer)}},destroyed:function(){var e=this.reference;Object(Le["off"])(e,"click",this.doToggle),Object(Le["off"])(e,"mouseup",this.doClose),Object(Le["off"])(e,"mousedown",this.doShow),Object(Le["off"])(e,"focusin",this.doShow),Object(Le["off"])(e,"focusout",this.doClose),Object(Le["off"])(e,"mousedown",this.doShow),Object(Le["off"])(e,"mouseup",this.doClose),Object(Le["off"])(e,"mouseleave",this.handleMouseLeave),Object(Le["off"])(e,"mouseenter",this.handleMouseEnter),Object(Le["off"])(document,"click",this.handleDocumentClick)}},as=os,ss=s(as,is,rs,!1,null,null,null);ss.options.__file="packages/popover/src/main.vue";var ls=ss.exports,cs=function(e,t,n){var i=t.expression?t.value:t.arg,r=n.context.$refs[i];r&&(Array.isArray(r)?r[0].$refs.reference=e:r.$refs.reference=e)},us={bind:function(e,t,n){cs(e,t,n)},inserted:function(e,t,n){cs(e,t,n)}};Wi.a.directive("popover",us),ls.install=function(e){e.directive("popover",us),e.component(ls.name,ls)},ls.directive=us;var ds=ls,hs={name:"ElTooltip",mixins:[H.a],props:{openDelay:{type:Number,default:0},disabled:Boolean,manual:Boolean,effect:{type:String,default:"dark"},arrowOffset:{type:Number,default:0},popperClass:String,content:String,visibleArrow:{default:!0},transition:{type:String,default:"el-fade-in-linear"},popperOptions:{default:function(){return{boundariesPadding:10,gpuAcceleration:!1}}},enterable:{type:Boolean,default:!0},hideAfter:{type:Number,default:0},tabindex:{type:Number,default:0}},data:function(){return{tooltipId:"el-tooltip-"+Object(b["generateId"])(),timeoutPending:null,focusing:!1}},beforeCreate:function(){var e=this;this.$isServer||(this.popperVM=new Wi.a({data:{node:""},render:function(e){return this.node}}).$mount(),this.debounceClose=F()(200,(function(){return e.handleClosePopper()})))},render:function(e){var t=this;this.popperVM&&(this.popperVM.node=e("transition",{attrs:{name:this.transition},on:{afterLeave:this.doDestroy}},[e("div",{on:{mouseleave:function(){t.setExpectedState(!1),t.debounceClose()},mouseenter:function(){t.setExpectedState(!0)}},ref:"popper",attrs:{role:"tooltip",id:this.tooltipId,"aria-hidden":this.disabled||!this.showPopper?"true":"false"},directives:[{name:"show",value:!this.disabled&&this.showPopper}],class:["el-tooltip__popper","is-"+this.effect,this.popperClass]},[this.$slots.content||this.content])]));var n=this.getFirstElement();if(!n)return null;var i=n.data=n.data||{};return i.staticClass=this.addTooltipClass(i.staticClass),n},mounted:function(){var e=this;this.referenceElm=this.$el,1===this.$el.nodeType&&(this.$el.setAttribute("aria-describedby",this.tooltipId),this.$el.setAttribute("tabindex",this.tabindex),Object(Le["on"])(this.referenceElm,"mouseenter",this.show),Object(Le["on"])(this.referenceElm,"mouseleave",this.hide),Object(Le["on"])(this.referenceElm,"focus",(function(){if(e.$slots.default&&e.$slots.default.length){var t=e.$slots.default[0].componentInstance;t&&t.focus?t.focus():e.handleFocus()}else e.handleFocus()})),Object(Le["on"])(this.referenceElm,"blur",this.handleBlur),Object(Le["on"])(this.referenceElm,"click",this.removeFocusing)),this.value&&this.popperVM&&this.popperVM.$nextTick((function(){e.value&&e.updatePopper()}))},watch:{focusing:function(e){e?Object(Le["addClass"])(this.referenceElm,"focusing"):Object(Le["removeClass"])(this.referenceElm,"focusing")}},methods:{show:function(){this.setExpectedState(!0),this.handleShowPopper()},hide:function(){this.setExpectedState(!1),this.debounceClose()},handleFocus:function(){this.focusing=!0,this.show()},handleBlur:function(){this.focusing=!1,this.hide()},removeFocusing:function(){this.focusing=!1},addTooltipClass:function(e){return e?"el-tooltip "+e.replace("el-tooltip",""):"el-tooltip"},handleShowPopper:function(){var e=this;this.expectedState&&!this.manual&&(clearTimeout(this.timeout),this.timeout=setTimeout((function(){e.showPopper=!0}),this.openDelay),this.hideAfter>0&&(this.timeoutPending=setTimeout((function(){e.showPopper=!1}),this.hideAfter)))},handleClosePopper:function(){this.enterable&&this.expectedState||this.manual||(clearTimeout(this.timeout),this.timeoutPending&&clearTimeout(this.timeoutPending),this.showPopper=!1,this.disabled&&this.doDestroy())},setExpectedState:function(e){!1===e&&clearTimeout(this.timeoutPending),this.expectedState=e},getFirstElement:function(){var e=this.$slots.default;if(!Array.isArray(e))return null;for(var t=null,n=0;n0){Ds=Ts.shift();var t=Ds.options;for(var n in t)t.hasOwnProperty(n)&&(Es[n]=t[n]);void 0===t.callback&&(Es.callback=Ps);var i=Es.callback;Es.callback=function(t,n){i(t,n),e()},Object(ks["isVNode"])(Es.message)?(Es.$slots.default=[Es.message],Es.message=null):delete Es.$slots.default,["modal","showClose","closeOnClickModal","closeOnPressEscape","closeOnHashChange"].forEach((function(e){void 0===Es[e]&&(Es[e]=!0)})),document.body.appendChild(Es.$el),Wi.a.nextTick((function(){Es.visible=!0}))}},Ns=function e(t,n){if(!Wi.a.prototype.$isServer){if("string"===typeof t||Object(ks["isVNode"])(t)?(t={message:t},"string"===typeof arguments[1]&&(t.title=arguments[1])):t.callback&&!n&&(n=t.callback),"undefined"!==typeof Promise)return new Promise((function(i,r){Ts.push({options:St()({},Os,e.defaults,t),callback:n,resolve:i,reject:r}),Is()}));Ts.push({options:St()({},Os,e.defaults,t),callback:n}),Is()}};Ns.setDefaults=function(e){Ns.defaults=e},Ns.alert=function(e,t,n){return"object"===("undefined"===typeof t?"undefined":Ss(t))?(n=t,t=""):void 0===t&&(t=""),Ns(St()({title:t,message:e,$type:"alert",closeOnPressEscape:!1,closeOnClickModal:!1},n))},Ns.confirm=function(e,t,n){return"object"===("undefined"===typeof t?"undefined":Ss(t))?(n=t,t=""):void 0===t&&(t=""),Ns(St()({title:t,message:e,$type:"confirm",showCancelButton:!0},n))},Ns.prompt=function(e,t,n){return"object"===("undefined"===typeof t?"undefined":Ss(t))?(n=t,t=""):void 0===t&&(t=""),Ns(St()({title:t,message:e,showCancelButton:!0,showInput:!0,$type:"prompt"},n))},Ns.close=function(){Es.doClose(),Es.visible=!1,Ts=[],Ds=null};var js=Ns,As=js,Fs=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-breadcrumb",attrs:{"aria-label":"Breadcrumb",role:"navigation"}},[e._t("default")],2)},Ls=[];Fs._withStripped=!0;var Vs={name:"ElBreadcrumb",props:{separator:{type:String,default:"/"},separatorClass:{type:String,default:""}},provide:function(){return{elBreadcrumb:this}},mounted:function(){var e=this.$el.querySelectorAll(".el-breadcrumb__item");e.length&&e[e.length-1].setAttribute("aria-current","page")}},zs=Vs,Bs=s(zs,Fs,Ls,!1,null,null,null);Bs.options.__file="packages/breadcrumb/src/breadcrumb.vue";var Rs=Bs.exports;Rs.install=function(e){e.component(Rs.name,Rs)};var Hs=Rs,Ws=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("span",{staticClass:"el-breadcrumb__item"},[n("span",{ref:"link",class:["el-breadcrumb__inner",e.to?"is-link":""],attrs:{role:"link"}},[e._t("default")],2),e.separatorClass?n("i",{staticClass:"el-breadcrumb__separator",class:e.separatorClass}):n("span",{staticClass:"el-breadcrumb__separator",attrs:{role:"presentation"}},[e._v(e._s(e.separator))])])},qs=[];Ws._withStripped=!0;var Us={name:"ElBreadcrumbItem",props:{to:{},replace:Boolean},data:function(){return{separator:"",separatorClass:""}},inject:["elBreadcrumb"],mounted:function(){var e=this;this.separator=this.elBreadcrumb.separator,this.separatorClass=this.elBreadcrumb.separatorClass;var t=this.$refs.link;t.setAttribute("role","link"),t.addEventListener("click",(function(t){var n=e.to,i=e.$router;n&&i&&(e.replace?i.replace(n):i.push(n))}))}},Ys=Us,Ks=s(Ys,Ws,qs,!1,null,null,null);Ks.options.__file="packages/breadcrumb/src/breadcrumb-item.vue";var Gs=Ks.exports;Gs.install=function(e){e.component(Gs.name,Gs)};var Xs=Gs,Zs=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("form",{staticClass:"el-form",class:[e.labelPosition?"el-form--label-"+e.labelPosition:"",{"el-form--inline":e.inline}]},[e._t("default")],2)},Js=[];Zs._withStripped=!0;var Qs={name:"ElForm",componentName:"ElForm",provide:function(){return{elForm:this}},props:{model:Object,rules:Object,labelPosition:String,labelWidth:String,labelSuffix:{type:String,default:""},inline:Boolean,inlineMessage:Boolean,statusIcon:Boolean,showMessage:{type:Boolean,default:!0},size:String,disabled:Boolean,validateOnRuleChange:{type:Boolean,default:!0},hideRequiredAsterisk:{type:Boolean,default:!1}},watch:{rules:function(){this.fields.forEach((function(e){e.removeValidateEvents(),e.addValidateEvents()})),this.validateOnRuleChange&&this.validate((function(){}))}},computed:{autoLabelWidth:function(){if(!this.potentialLabelWidthArr.length)return 0;var e=Math.max.apply(Math,this.potentialLabelWidthArr);return e?e+"px":""}},data:function(){return{fields:[],potentialLabelWidthArr:[]}},created:function(){var e=this;this.$on("el.form.addField",(function(t){t&&e.fields.push(t)})),this.$on("el.form.removeField",(function(t){t.prop&&e.fields.splice(e.fields.indexOf(t),1)}))},methods:{resetFields:function(){this.model?this.fields.forEach((function(e){e.resetField()})):console.warn("[Element Warn][Form]model is required for resetFields to work.")},clearValidate:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=e.length?"string"===typeof e?this.fields.filter((function(t){return e===t.prop})):this.fields.filter((function(t){return e.indexOf(t.prop)>-1})):this.fields;t.forEach((function(e){e.clearValidate()}))},validate:function(e){var t=this;if(this.model){var n=void 0;"function"!==typeof e&&window.Promise&&(n=new window.Promise((function(t,n){e=function(e){e?t(e):n(e)}})));var i=!0,r=0;0===this.fields.length&&e&&e(!0);var o={};return this.fields.forEach((function(n){n.validate("",(function(n,a){n&&(i=!1),o=St()({},o,a),"function"===typeof e&&++r===t.fields.length&&e(i,o)}))})),n||void 0}console.warn("[Element Warn][Form]model is required for validate to work!")},validateField:function(e,t){e=[].concat(e);var n=this.fields.filter((function(t){return-1!==e.indexOf(t.prop)}));n.length?n.forEach((function(e){e.validate("",t)})):console.warn("[Element Warn]please pass correct props!")},getLabelWidthIndex:function(e){var t=this.potentialLabelWidthArr.indexOf(e);if(-1===t)throw new Error("[ElementForm]unpected width ",e);return t},registerLabelWidth:function(e,t){if(e&&t){var n=this.getLabelWidthIndex(t);this.potentialLabelWidthArr.splice(n,1,e)}else e&&this.potentialLabelWidthArr.push(e)},deregisterLabelWidth:function(e){var t=this.getLabelWidthIndex(e);this.potentialLabelWidthArr.splice(t,1)}}},el=Qs,tl=s(el,Zs,Js,!1,null,null,null);tl.options.__file="packages/form/src/form.vue";var nl=tl.exports;nl.install=function(e){e.component(nl.name,nl)};var il=nl,rl=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-form-item",class:[{"el-form-item--feedback":e.elForm&&e.elForm.statusIcon,"is-error":"error"===e.validateState,"is-validating":"validating"===e.validateState,"is-success":"success"===e.validateState,"is-required":e.isRequired||e.required,"is-no-asterisk":e.elForm&&e.elForm.hideRequiredAsterisk},e.sizeClass?"el-form-item--"+e.sizeClass:""]},[n("label-wrap",{attrs:{"is-auto-width":e.labelStyle&&"auto"===e.labelStyle.width,"update-all":"auto"===e.form.labelWidth}},[e.label||e.$slots.label?n("label",{staticClass:"el-form-item__label",style:e.labelStyle,attrs:{for:e.labelFor}},[e._t("label",[e._v(e._s(e.label+e.form.labelSuffix))])],2):e._e()]),n("div",{staticClass:"el-form-item__content",style:e.contentStyle},[e._t("default"),n("transition",{attrs:{name:"el-zoom-in-top"}},["error"===e.validateState&&e.showMessage&&e.form.showMessage?e._t("error",[n("div",{staticClass:"el-form-item__error",class:{"el-form-item__error--inline":"boolean"===typeof e.inlineMessage?e.inlineMessage:e.elForm&&e.elForm.inlineMessage||!1}},[e._v("\n "+e._s(e.validateMessage)+"\n ")])],{error:e.validateMessage}):e._e()],2)],2)],1)},ol=[];rl._withStripped=!0;var al,sl,ll=n(40),cl=n.n(ll),ul={props:{isAutoWidth:Boolean,updateAll:Boolean},inject:["elForm","elFormItem"],render:function(){var e=arguments[0],t=this.$slots.default;if(!t)return null;if(this.isAutoWidth){var n=this.elForm.autoLabelWidth,i={};if(n&&"auto"!==n){var r=parseInt(n,10)-this.computedWidth;r&&(i.marginLeft=r+"px")}return e("div",{class:"el-form-item__label-wrap",style:i},[t])}return t[0]},methods:{getLabelWidth:function(){if(this.$el&&this.$el.firstElementChild){var e=window.getComputedStyle(this.$el.firstElementChild).width;return Math.ceil(parseFloat(e))}return 0},updateLabelWidth:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"update";this.$slots.default&&this.isAutoWidth&&this.$el.firstElementChild&&("update"===e?this.computedWidth=this.getLabelWidth():"remove"===e&&this.elForm.deregisterLabelWidth(this.computedWidth))}},watch:{computedWidth:function(e,t){this.updateAll&&(this.elForm.registerLabelWidth(e,t),this.elFormItem.updateComputedLabelWidth(e))}},data:function(){return{computedWidth:0}},mounted:function(){this.updateLabelWidth("update")},updated:function(){this.updateLabelWidth("update")},beforeDestroy:function(){this.updateLabelWidth("remove")}},dl=ul,hl=s(dl,al,sl,!1,null,null,null);hl.options.__file="packages/form/src/label-wrap.vue";var fl=hl.exports,pl={name:"ElFormItem",componentName:"ElFormItem",mixins:[D.a],provide:function(){return{elFormItem:this}},inject:["elForm"],props:{label:String,labelWidth:String,prop:String,required:{type:Boolean,default:void 0},rules:[Object,Array],error:String,validateStatus:String,for:String,inlineMessage:{type:[String,Boolean],default:""},showMessage:{type:Boolean,default:!0},size:String},components:{LabelWrap:fl},watch:{error:{immediate:!0,handler:function(e){this.validateMessage=e,this.validateState=e?"error":""}},validateStatus:function(e){this.validateState=e}},computed:{labelFor:function(){return this.for||this.prop},labelStyle:function(){var e={};if("top"===this.form.labelPosition)return e;var t=this.labelWidth||this.form.labelWidth;return t&&(e.width=t),e},contentStyle:function(){var e={},t=this.label;if("top"===this.form.labelPosition||this.form.inline)return e;if(!t&&!this.labelWidth&&this.isNested)return e;var n=this.labelWidth||this.form.labelWidth;return"auto"===n?"auto"===this.labelWidth?e.marginLeft=this.computedLabelWidth:"auto"===this.form.labelWidth&&(e.marginLeft=this.elForm.autoLabelWidth):e.marginLeft=n,e},form:function(){var e=this.$parent,t=e.$options.componentName;while("ElForm"!==t)"ElFormItem"===t&&(this.isNested=!0),e=e.$parent,t=e.$options.componentName;return e},fieldValue:function(){var e=this.form.model;if(e&&this.prop){var t=this.prop;return-1!==t.indexOf(":")&&(t=t.replace(/:/,".")),Object(b["getPropByPath"])(e,t,!0).v}},isRequired:function(){var e=this.getRules(),t=!1;return e&&e.length&&e.every((function(e){return!e.required||(t=!0,!1)})),t},_formSize:function(){return this.elForm.size},elFormItemSize:function(){return this.size||this._formSize},sizeClass:function(){return this.elFormItemSize||(this.$ELEMENT||{}).size}},data:function(){return{validateState:"",validateMessage:"",validateDisabled:!1,validator:{},isNested:!1,computedLabelWidth:""}},methods:{validate:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:b["noop"];this.validateDisabled=!1;var i=this.getFilteredRule(e);if((!i||0===i.length)&&void 0===this.required)return n(),!0;this.validateState="validating";var r={};i&&i.length>0&&i.forEach((function(e){delete e.trigger})),r[this.prop]=i;var o=new cl.a(r),a={};a[this.prop]=this.fieldValue,o.validate(a,{firstFields:!0},(function(e,i){t.validateState=e?"error":"success",t.validateMessage=e?e[0].message:"",n(t.validateMessage,i),t.elForm&&t.elForm.$emit("validate",t.prop,!e,t.validateMessage||null)}))},clearValidate:function(){this.validateState="",this.validateMessage="",this.validateDisabled=!1},resetField:function(){var e=this;this.validateState="",this.validateMessage="";var t=this.form.model,n=this.fieldValue,i=this.prop;-1!==i.indexOf(":")&&(i=i.replace(/:/,"."));var r=Object(b["getPropByPath"])(t,i,!0);this.validateDisabled=!0,Array.isArray(n)?r.o[r.k]=[].concat(this.initialValue):r.o[r.k]=this.initialValue,this.$nextTick((function(){e.validateDisabled=!1})),this.broadcast("ElTimeSelect","fieldReset",this.initialValue)},getRules:function(){var e=this.form.rules,t=this.rules,n=void 0!==this.required?{required:!!this.required}:[],i=Object(b["getPropByPath"])(e,this.prop||"");return e=e?i.o[this.prop||""]||i.v:[],[].concat(t||e||[]).concat(n)},getFilteredRule:function(e){var t=this.getRules();return t.filter((function(t){return!t.trigger||""===e||(Array.isArray(t.trigger)?t.trigger.indexOf(e)>-1:t.trigger===e)})).map((function(e){return St()({},e)}))},onFieldBlur:function(){this.validate("blur")},onFieldChange:function(){this.validateDisabled?this.validateDisabled=!1:this.validate("change")},updateComputedLabelWidth:function(e){this.computedLabelWidth=e?e+"px":""},addValidateEvents:function(){var e=this.getRules();(e.length||void 0!==this.required)&&(this.$on("el.form.blur",this.onFieldBlur),this.$on("el.form.change",this.onFieldChange))},removeValidateEvents:function(){this.$off()}},mounted:function(){if(this.prop){this.dispatch("ElForm","el.form.addField",[this]);var e=this.fieldValue;Array.isArray(e)&&(e=[].concat(e)),Object.defineProperty(this,"initialValue",{value:e}),this.addValidateEvents()}},beforeDestroy:function(){this.dispatch("ElForm","el.form.removeField",[this])}},ml=pl,vl=s(ml,rl,ol,!1,null,null,null);vl.options.__file="packages/form/src/form-item.vue";var gl=vl.exports;gl.install=function(e){e.component(gl.name,gl)};var bl=gl,yl=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-tabs__active-bar",class:"is-"+e.rootTabs.tabPosition,style:e.barStyle})},_l=[];yl._withStripped=!0;var xl={name:"TabBar",props:{tabs:Array},inject:["rootTabs"],computed:{barStyle:{get:function(){var e=this,t={},n=0,i=0,r=-1!==["top","bottom"].indexOf(this.rootTabs.tabPosition)?"width":"height",o="width"===r?"x":"y",a=function(e){return e.toLowerCase().replace(/( |^)[a-z]/g,(function(e){return e.toUpperCase()}))};this.tabs.every((function(t,o){var s=Object(b["arrayFind"])(e.$parent.$refs.tabs||[],(function(e){return e.id.replace("tab-","")===t.paneName}));if(!s)return!1;if(t.active){i=s["client"+a(r)];var l=window.getComputedStyle(s);return"width"===r&&e.tabs.length>1&&(i-=parseFloat(l.paddingLeft)+parseFloat(l.paddingRight)),"width"===r&&(n+=parseFloat(l.paddingLeft)),!1}return n+=s["client"+a(r)],!0}));var s="translate"+a(o)+"("+n+"px)";return t[r]=i+"px",t.transform=s,t.msTransform=s,t.webkitTransform=s,t}}}},wl=xl,Cl=s(wl,yl,_l,!1,null,null,null);Cl.options.__file="packages/tabs/src/tab-bar.vue";var kl=Cl.exports;function Sl(){}var Ol,$l,Dl=function(e){return e.toLowerCase().replace(/( |^)[a-z]/g,(function(e){return e.toUpperCase()}))},El={name:"TabNav",components:{TabBar:kl},inject:["rootTabs"],props:{panes:Array,currentName:String,editable:Boolean,onTabClick:{type:Function,default:Sl},onTabRemove:{type:Function,default:Sl},type:String,stretch:Boolean},data:function(){return{scrollable:!1,navOffset:0,isFocus:!1,focusable:!0}},computed:{navStyle:function(){var e=-1!==["top","bottom"].indexOf(this.rootTabs.tabPosition)?"X":"Y";return{transform:"translate"+e+"(-"+this.navOffset+"px)"}},sizeName:function(){return-1!==["top","bottom"].indexOf(this.rootTabs.tabPosition)?"width":"height"}},methods:{scrollPrev:function(){var e=this.$refs.navScroll["offset"+Dl(this.sizeName)],t=this.navOffset;if(t){var n=t>e?t-e:0;this.navOffset=n}},scrollNext:function(){var e=this.$refs.nav["offset"+Dl(this.sizeName)],t=this.$refs.navScroll["offset"+Dl(this.sizeName)],n=this.navOffset;if(!(e-n<=t)){var i=e-n>2*t?n+t:e-t;this.navOffset=i}},scrollToActiveTab:function(){if(this.scrollable){var e=this.$refs.nav,t=this.$el.querySelector(".is-active");if(t){var n=this.$refs.navScroll,i=-1!==["top","bottom"].indexOf(this.rootTabs.tabPosition),r=t.getBoundingClientRect(),o=n.getBoundingClientRect(),a=i?e.offsetWidth-o.width:e.offsetHeight-o.height,s=this.navOffset,l=s;i?(r.lefto.right&&(l=s+r.right-o.right)):(r.topo.bottom&&(l=s+(r.bottom-o.bottom))),l=Math.max(l,0),this.navOffset=Math.min(l,a)}}},update:function(){if(this.$refs.nav){var e=this.sizeName,t=this.$refs.nav["offset"+Dl(e)],n=this.$refs.navScroll["offset"+Dl(e)],i=this.navOffset;if(n0&&(this.navOffset=0)}},changeTab:function(e){var t=e.keyCode,n=void 0,i=void 0,r=void 0;-1!==[37,38,39,40].indexOf(t)&&(r=e.currentTarget.querySelectorAll("[role=tab]"),i=Array.prototype.indexOf.call(r,e.target),n=37===t||38===t?0===i?r.length-1:i-1:i0&&void 0!==arguments[0]&&arguments[0];if(this.$slots.default){var n=this.$slots.default.filter((function(e){return e.tag&&e.componentOptions&&"ElTabPane"===e.componentOptions.Ctor.options.name})),i=n.map((function(e){var t=e.componentInstance;return t})),r=!(i.length===this.panes.length&&i.every((function(t,n){return t===e.panes[n]})));(t||r)&&(this.panes=i)}else 0!==this.panes.length&&(this.panes=[])},handleTabClick:function(e,t,n){e.disabled||(this.setCurrentName(t),this.$emit("tab-click",e,n))},handleTabRemove:function(e,t){e.disabled||(t.stopPropagation(),this.$emit("edit",e.name,"remove"),this.$emit("tab-remove",e.name))},handleTabAdd:function(){this.$emit("edit",null,"add"),this.$emit("tab-add")},setCurrentName:function(e){var t=this,n=function(){t.currentName=e,t.$emit("input",e)};if(this.currentName!==e&&this.beforeLeave){var i=this.beforeLeave(e,this.currentName);i&&i.then?i.then((function(){n(),t.$refs.nav&&t.$refs.nav.removeFocus()}),(function(){})):!1!==i&&n()}else n()}},render:function(e){var t,n=this.type,i=this.handleTabClick,r=this.handleTabRemove,o=this.handleTabAdd,a=this.currentName,s=this.panes,l=this.editable,c=this.addable,u=this.tabPosition,d=this.stretch,h=l||c?e("span",{class:"el-tabs__new-tab",on:{click:o,keydown:function(e){13===e.keyCode&&o()}},attrs:{tabindex:"0"}},[e("i",{class:"el-icon-plus"})]):null,f={props:{currentName:a,onTabClick:i,onTabRemove:r,editable:l,type:n,panes:s,stretch:d},ref:"nav"},p=e("div",{class:["el-tabs__header","is-"+u]},[h,e("tab-nav",f)]),m=e("div",{class:"el-tabs__content"},[this.$slots.default]);return e("div",{class:(t={"el-tabs":!0,"el-tabs--card":"card"===n},t["el-tabs--"+u]=!0,t["el-tabs--border-card"]="border-card"===n,t)},["bottom"!==u?[p,m]:[m,p]])},created:function(){this.currentName||this.setCurrentName("0"),this.$on("tab-nav-update",this.calcPaneInstances.bind(null,!0))},mounted:function(){this.calcPaneInstances()},updated:function(){this.calcPaneInstances()}},Al=jl,Fl=s(Al,Ml,Il,!1,null,null,null);Fl.options.__file="packages/tabs/src/tabs.vue";var Ll=Fl.exports;Ll.install=function(e){e.component(Ll.name,Ll)};var Vl=Ll,zl=function(){var e=this,t=e.$createElement,n=e._self._c||t;return!e.lazy||e.loaded||e.active?n("div",{directives:[{name:"show",rawName:"v-show",value:e.active,expression:"active"}],staticClass:"el-tab-pane",attrs:{role:"tabpanel","aria-hidden":!e.active,id:"pane-"+e.paneName,"aria-labelledby":"tab-"+e.paneName}},[e._t("default")],2):e._e()},Bl=[];zl._withStripped=!0;var Rl={name:"ElTabPane",componentName:"ElTabPane",props:{label:String,labelContent:Function,name:String,closable:Boolean,disabled:Boolean,lazy:Boolean},data:function(){return{index:null,loaded:!1}},computed:{isClosable:function(){return this.closable||this.$parent.closable},active:function(){var e=this.$parent.currentName===(this.name||this.index);return e&&(this.loaded=!0),e},paneName:function(){return this.name||this.index}},updated:function(){this.$parent.$emit("tab-nav-update")}},Hl=Rl,Wl=s(Hl,zl,Bl,!1,null,null,null);Wl.options.__file="packages/tabs/src/tab-pane.vue";var ql=Wl.exports;ql.install=function(e){e.component(ql.name,ql)};var Ul,Yl,Kl=ql,Gl={name:"ElTag",props:{text:String,closable:Boolean,type:String,hit:Boolean,disableTransitions:Boolean,color:String,size:String,effect:{type:String,default:"light",validator:function(e){return-1!==["dark","light","plain"].indexOf(e)}}},methods:{handleClose:function(e){e.stopPropagation(),this.$emit("close",e)},handleClick:function(e){this.$emit("click",e)}},computed:{tagSize:function(){return this.size||(this.$ELEMENT||{}).size}},render:function(e){var t=this.type,n=this.tagSize,i=this.hit,r=this.effect,o=["el-tag",t?"el-tag--"+t:"",n?"el-tag--"+n:"",r?"el-tag--"+r:"",i&&"is-hit"],a=e("span",{class:o,style:{backgroundColor:this.color},on:{click:this.handleClick}},[this.$slots.default,this.closable&&e("i",{class:"el-tag__close el-icon-close",on:{click:this.handleClose}})]);return this.disableTransitions?a:e("transition",{attrs:{name:"el-zoom-in-center"}},[a])}},Xl=Gl,Zl=s(Xl,Ul,Yl,!1,null,null,null);Zl.options.__file="packages/tag/src/tag.vue";var Jl=Zl.exports;Jl.install=function(e){e.component(Jl.name,Jl)};var Ql=Jl,ec=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-tree",class:{"el-tree--highlight-current":e.highlightCurrent,"is-dragging":!!e.dragState.draggingNode,"is-drop-not-allow":!e.dragState.allowDrop,"is-drop-inner":"inner"===e.dragState.dropType},attrs:{role:"tree"}},[e._l(e.root.childNodes,(function(t){return n("el-tree-node",{key:e.getNodeKey(t),attrs:{node:t,props:e.props,"render-after-expand":e.renderAfterExpand,"show-checkbox":e.showCheckbox,"render-content":e.renderContent},on:{"node-expand":e.handleNodeExpand}})})),e.isEmpty?n("div",{staticClass:"el-tree__empty-block"},[n("span",{staticClass:"el-tree__empty-text"},[e._v(e._s(e.emptyText))])]):e._e(),n("div",{directives:[{name:"show",rawName:"v-show",value:e.dragState.showDropIndicator,expression:"dragState.showDropIndicator"}],ref:"dropIndicator",staticClass:"el-tree__drop-indicator"})],2)},tc=[];ec._withStripped=!0;var nc="$treeNodeId",ic=function(e,t){t&&!t[nc]&&Object.defineProperty(t,nc,{value:e.id,enumerable:!1,configurable:!1,writable:!1})},rc=function(e,t){return e?t[e]:t[nc]},oc=function(e,t){var n=e;while(n&&"BODY"!==n.tagName){if(n.__vue__&&n.__vue__.$options.name===t)return n.__vue__;n=n.parentNode}return null},ac=function(){function e(e,t){for(var n=0;n0&&i.lazy&&i.defaultExpandAll&&this.expand(),Array.isArray(this.data)||ic(this,this.data),this.data){var a=i.defaultExpandedKeys,s=i.key;s&&a&&-1!==a.indexOf(this.key)&&this.expand(null,i.autoExpandParent),s&&void 0!==i.currentNodeKey&&this.key===i.currentNodeKey&&(i.currentNode=this,i.currentNode.isCurrent=!0),i.lazy&&i._initDefaultCheckedNode(this),this.updateLeafState()}}return e.prototype.setData=function(e){Array.isArray(e)||ic(this,e),this.data=e,this.childNodes=[];var t=void 0;t=0===this.level&&this.data instanceof Array?this.data:uc(this,"children")||[];for(var n=0,i=t.length;n1&&void 0!==arguments[1])||arguments[1],n=function n(i){for(var r=i.childNodes||[],o=!1,a=0,s=r.length;a-1&&t.splice(n,1);var i=this.childNodes.indexOf(e);i>-1&&(this.store&&this.store.deregisterNode(e),e.parent=null,this.childNodes.splice(i,1)),this.updateLeafState()},e.prototype.removeChildByData=function(e){for(var t=null,n=0;n0)i.expanded=!0,i=i.parent}n.expanded=!0,e&&e()};this.shouldLoadData()?this.loadData((function(e){e instanceof Array&&(n.checked?n.setChecked(!0,!0):n.store.checkStrictly||cc(n),i())})):i()},e.prototype.doCreateChildren=function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e.forEach((function(e){t.insertChild(St()({data:e},n),void 0,!0)}))},e.prototype.collapse=function(){this.expanded=!1},e.prototype.shouldLoadData=function(){return!0===this.store.lazy&&this.store.load&&!this.loaded},e.prototype.updateLeafState=function(){if(!0!==this.store.lazy||!0===this.loaded||"undefined"===typeof this.isLeafByUser){var e=this.childNodes;!this.store.lazy||!0===this.store.lazy&&!0===this.loaded?this.isLeaf=!e||0===e.length:this.isLeaf=!1}else this.isLeaf=this.isLeafByUser},e.prototype.setChecked=function(e,t,n,i){var r=this;if(this.indeterminate="half"===e,this.checked=!0===e,!this.store.checkStrictly){if(!this.shouldLoadData()||this.store.checkDescendants){var o=lc(this.childNodes),a=o.all,s=o.allWithoutDisable;this.isLeaf||a||!s||(this.checked=!1,e=!1);var l=function(){if(t){for(var n=r.childNodes,o=0,a=n.length;o0&&void 0!==arguments[0]&&arguments[0];if(0===this.level)return this.data;var t=this.data;if(!t)return null;var n=this.store.props,i="children";return n&&(i=n.children||"children"),void 0===t[i]&&(t[i]=null),e&&!t[i]&&(t[i]=[]),t[i]},e.prototype.updateChildren=function(){var e=this,t=this.getChildren()||[],n=this.childNodes.map((function(e){return e.data})),i={},r=[];t.forEach((function(e,t){var o=e[nc],a=!!o&&Object(b["arrayFindIndex"])(n,(function(e){return e[nc]===o}))>=0;a?i[o]={index:t,data:e}:r.push({index:t,data:e})})),this.store.lazy||n.forEach((function(t){i[t[nc]]||e.removeChildByData(t)})),r.forEach((function(t){var n=t.index,i=t.data;e.insertChild({data:i},n)})),this.updateLeafState()},e.prototype.loadData=function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!0!==this.store.lazy||!this.store.load||this.loaded||this.loading&&!Object.keys(n).length)e&&e.call(this);else{this.loading=!0;var i=function(i){t.loaded=!0,t.loading=!1,t.childNodes=[],t.doCreateChildren(i,n),t.updateLeafState(),e&&e.call(t,i)};this.store.load(this,i)}},ac(e,[{key:"label",get:function(){return uc(this,"label")}},{key:"key",get:function(){var e=this.store.key;return this.data?this.data[e]:null}},{key:"disabled",get:function(){return uc(this,"disabled")}},{key:"nextSibling",get:function(){var e=this.parent;if(e){var t=e.childNodes.indexOf(this);if(t>-1)return e.childNodes[t+1]}return null}},{key:"previousSibling",get:function(){var e=this.parent;if(e){var t=e.childNodes.indexOf(this);if(t>-1)return t>0?e.childNodes[t-1]:null}return null}}]),e}(),fc=hc,pc="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function mc(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var vc=function(){function e(t){var n=this;for(var i in mc(this,e),this.currentNode=null,this.currentNodeKey=null,t)t.hasOwnProperty(i)&&(this[i]=t[i]);if(this.nodesMap={},this.root=new fc({data:this.data,store:this}),this.lazy&&this.load){var r=this.load;r(this.root,(function(e){n.root.doCreateChildren(e),n._initDefaultCheckedNodes()}))}else this._initDefaultCheckedNodes()}return e.prototype.filter=function(e){var t=this.filterNodeMethod,n=this.lazy,i=function i(r){var o=r.root?r.root.childNodes:r.childNodes;if(o.forEach((function(n){n.visible=t.call(n,e,n.data,n),i(n)})),!r.visible&&o.length){var a=!0;a=!o.some((function(e){return e.visible})),r.root?r.root.visible=!1===a:r.visible=!1===a}e&&(!r.visible||r.isLeaf||n||r.expand())};i(this)},e.prototype.setData=function(e){var t=e!==this.root.data;t?(this.root.setData(e),this._initDefaultCheckedNodes()):this.root.updateChildren()},e.prototype.getNode=function(e){if(e instanceof fc)return e;var t="object"!==("undefined"===typeof e?"undefined":pc(e))?e:rc(this.key,e);return this.nodesMap[t]||null},e.prototype.insertBefore=function(e,t){var n=this.getNode(t);n.parent.insertBefore({data:e},n)},e.prototype.insertAfter=function(e,t){var n=this.getNode(t);n.parent.insertAfter({data:e},n)},e.prototype.remove=function(e){var t=this.getNode(e);t&&t.parent&&(t===this.currentNode&&(this.currentNode=null),t.parent.removeChild(t))},e.prototype.append=function(e,t){var n=t?this.getNode(t):this.root;n&&n.insertChild({data:e})},e.prototype._initDefaultCheckedNodes=function(){var e=this,t=this.defaultCheckedKeys||[],n=this.nodesMap;t.forEach((function(t){var i=n[t];i&&i.setChecked(!0,!e.checkStrictly)}))},e.prototype._initDefaultCheckedNode=function(e){var t=this.defaultCheckedKeys||[];-1!==t.indexOf(e.key)&&e.setChecked(!0,!this.checkStrictly)},e.prototype.setDefaultCheckedKey=function(e){e!==this.defaultCheckedKeys&&(this.defaultCheckedKeys=e,this._initDefaultCheckedNodes())},e.prototype.registerNode=function(e){var t=this.key;if(t&&e&&e.data){var n=e.key;void 0!==n&&(this.nodesMap[e.key]=e)}},e.prototype.deregisterNode=function(e){var t=this,n=this.key;n&&e&&e.data&&(e.childNodes.forEach((function(e){t.deregisterNode(e)})),delete this.nodesMap[e.key])},e.prototype.getCheckedNodes=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=[],i=function i(r){var o=r.root?r.root.childNodes:r.childNodes;o.forEach((function(r){(r.checked||t&&r.indeterminate)&&(!e||e&&r.isLeaf)&&n.push(r.data),i(r)}))};return i(this),n},e.prototype.getCheckedKeys=function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return this.getCheckedNodes(t).map((function(t){return(t||{})[e.key]}))},e.prototype.getHalfCheckedNodes=function(){var e=[],t=function t(n){var i=n.root?n.root.childNodes:n.childNodes;i.forEach((function(n){n.indeterminate&&e.push(n.data),t(n)}))};return t(this),e},e.prototype.getHalfCheckedKeys=function(){var e=this;return this.getHalfCheckedNodes().map((function(t){return(t||{})[e.key]}))},e.prototype._getAllNodes=function(){var e=[],t=this.nodesMap;for(var n in t)t.hasOwnProperty(n)&&e.push(t[n]);return e},e.prototype.updateChildren=function(e,t){var n=this.nodesMap[e];if(n){for(var i=n.childNodes,r=i.length-1;r>=0;r--){var o=i[r];this.remove(o.data)}for(var a=0,s=t.length;a1&&void 0!==arguments[1]&&arguments[1],n=arguments[2],i=this._getAllNodes().sort((function(e,t){return t.level-e.level})),r=Object.create(null),o=Object.keys(n);i.forEach((function(e){return e.setChecked(!1,!1)}));for(var a=0,s=i.length;a-1;if(u){var d=l.parent;while(d&&d.level>0)r[d.data[e]]=!0,d=d.parent;l.isLeaf||this.checkStrictly?l.setChecked(!0,!1):(l.setChecked(!0,!0),t&&function(){l.setChecked(!1,!1);var e=function e(t){var n=t.childNodes;n.forEach((function(t){t.isLeaf||t.setChecked(!1,!1),e(t)}))};e(l)}())}else l.checked&&!r[c]&&l.setChecked(!1,!1)}},e.prototype.setCheckedNodes=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=this.key,i={};e.forEach((function(e){i[(e||{})[n]]=!0})),this._setCheckedKeys(n,t,i)},e.prototype.setCheckedKeys=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];this.defaultCheckedKeys=e;var n=this.key,i={};e.forEach((function(e){i[e]=!0})),this._setCheckedKeys(n,t,i)},e.prototype.setDefaultExpandedKeys=function(e){var t=this;e=e||[],this.defaultExpandedKeys=e,e.forEach((function(e){var n=t.getNode(e);n&&n.expand(null,t.autoExpandParent)}))},e.prototype.setChecked=function(e,t,n){var i=this.getNode(e);i&&i.setChecked(!!t,n)},e.prototype.getCurrentNode=function(){return this.currentNode},e.prototype.setCurrentNode=function(e){var t=this.currentNode;t&&(t.isCurrent=!1),this.currentNode=e,this.currentNode.isCurrent=!0},e.prototype.setUserCurrentNode=function(e){var t=e[this.key],n=this.nodesMap[t];this.setCurrentNode(n)},e.prototype.setCurrentNodeKey=function(e){if(null===e||void 0===e)return this.currentNode&&(this.currentNode.isCurrent=!1),void(this.currentNode=null);var t=this.getNode(e);t&&this.setCurrentNode(t)},e}(),gc=vc,bc=function(){var e=this,t=this,n=t.$createElement,i=t._self._c||n;return i("div",{directives:[{name:"show",rawName:"v-show",value:t.node.visible,expression:"node.visible"}],ref:"node",staticClass:"el-tree-node",class:{"is-expanded":t.expanded,"is-current":t.node.isCurrent,"is-hidden":!t.node.visible,"is-focusable":!t.node.disabled,"is-checked":!t.node.disabled&&t.node.checked},attrs:{role:"treeitem",tabindex:"-1","aria-expanded":t.expanded,"aria-disabled":t.node.disabled,"aria-checked":t.node.checked,draggable:t.tree.draggable},on:{click:function(e){return e.stopPropagation(),t.handleClick(e)},contextmenu:function(t){return e.handleContextMenu(t)},dragstart:function(e){return e.stopPropagation(),t.handleDragStart(e)},dragover:function(e){return e.stopPropagation(),t.handleDragOver(e)},dragend:function(e){return e.stopPropagation(),t.handleDragEnd(e)},drop:function(e){return e.stopPropagation(),t.handleDrop(e)}}},[i("div",{staticClass:"el-tree-node__content",style:{"padding-left":(t.node.level-1)*t.tree.indent+"px"}},[i("span",{class:[{"is-leaf":t.node.isLeaf,expanded:!t.node.isLeaf&&t.expanded},"el-tree-node__expand-icon",t.tree.iconClass?t.tree.iconClass:"el-icon-caret-right"],on:{click:function(e){return e.stopPropagation(),t.handleExpandIconClick(e)}}}),t.showCheckbox?i("el-checkbox",{attrs:{indeterminate:t.node.indeterminate,disabled:!!t.node.disabled},on:{change:t.handleCheckChange},nativeOn:{click:function(e){e.stopPropagation()}},model:{value:t.node.checked,callback:function(e){t.$set(t.node,"checked",e)},expression:"node.checked"}}):t._e(),t.node.loading?i("span",{staticClass:"el-tree-node__loading-icon el-icon-loading"}):t._e(),i("node-content",{attrs:{node:t.node}})],1),i("el-collapse-transition",[!t.renderAfterExpand||t.childNodeRendered?i("div",{directives:[{name:"show",rawName:"v-show",value:t.expanded,expression:"expanded"}],staticClass:"el-tree-node__children",attrs:{role:"group","aria-expanded":t.expanded}},t._l(t.node.childNodes,(function(e){return i("el-tree-node",{key:t.getNodeKey(e),attrs:{"render-content":t.renderContent,"render-after-expand":t.renderAfterExpand,"show-checkbox":t.showCheckbox,node:e},on:{"node-expand":t.handleChildNodeExpand}})})),1):t._e()])],1)},yc=[];bc._withStripped=!0;var _c={name:"ElTreeNode",componentName:"ElTreeNode",mixins:[D.a],props:{node:{default:function(){return{}}},props:{},renderContent:Function,renderAfterExpand:{type:Boolean,default:!0},showCheckbox:{type:Boolean,default:!1}},components:{ElCollapseTransition:Ye.a,ElCheckbox:Ai.a,NodeContent:{props:{node:{required:!0}},render:function(e){var t=this.$parent,n=t.tree,i=this.node,r=i.data,o=i.store;return t.renderContent?t.renderContent.call(t._renderProxy,e,{_self:n.$vnode.context,node:i,data:r,store:o}):n.$scopedSlots.default?n.$scopedSlots.default({node:i,data:r}):e("span",{class:"el-tree-node__label"},[i.label])}}},data:function(){return{tree:null,expanded:!1,childNodeRendered:!1,oldChecked:null,oldIndeterminate:null}},watch:{"node.indeterminate":function(e){this.handleSelectChange(this.node.checked,e)},"node.checked":function(e){this.handleSelectChange(e,this.node.indeterminate)},"node.expanded":function(e){var t=this;this.$nextTick((function(){return t.expanded=e})),e&&(this.childNodeRendered=!0)}},methods:{getNodeKey:function(e){return rc(this.tree.nodeKey,e.data)},handleSelectChange:function(e,t){this.oldChecked!==e&&this.oldIndeterminate!==t&&this.tree.$emit("check-change",this.node.data,e,t),this.oldChecked=e,this.indeterminate=t},handleClick:function(){var e=this.tree.store;e.setCurrentNode(this.node),this.tree.$emit("current-change",e.currentNode?e.currentNode.data:null,e.currentNode),this.tree.currentNode=this,this.tree.expandOnClickNode&&this.handleExpandIconClick(),this.tree.checkOnClickNode&&!this.node.disabled&&this.handleCheckChange(null,{target:{checked:!this.node.checked}}),this.tree.$emit("node-click",this.node.data,this.node,this)},handleContextMenu:function(e){this.tree._events["node-contextmenu"]&&this.tree._events["node-contextmenu"].length>0&&(e.stopPropagation(),e.preventDefault()),this.tree.$emit("node-contextmenu",e,this.node.data,this.node,this)},handleExpandIconClick:function(){this.node.isLeaf||(this.expanded?(this.tree.$emit("node-collapse",this.node.data,this.node,this),this.node.collapse()):(this.node.expand(),this.$emit("node-expand",this.node.data,this.node,this)))},handleCheckChange:function(e,t){var n=this;this.node.setChecked(t.target.checked,!this.tree.checkStrictly),this.$nextTick((function(){var e=n.tree.store;n.tree.$emit("check",n.node.data,{checkedNodes:e.getCheckedNodes(),checkedKeys:e.getCheckedKeys(),halfCheckedNodes:e.getHalfCheckedNodes(),halfCheckedKeys:e.getHalfCheckedKeys()})}))},handleChildNodeExpand:function(e,t,n){this.broadcast("ElTreeNode","tree-node-expand",t),this.tree.$emit("node-expand",e,t,n)},handleDragStart:function(e){this.tree.draggable&&this.tree.$emit("tree-node-drag-start",e,this)},handleDragOver:function(e){this.tree.draggable&&(this.tree.$emit("tree-node-drag-over",e,this),e.preventDefault())},handleDrop:function(e){e.preventDefault()},handleDragEnd:function(e){this.tree.draggable&&this.tree.$emit("tree-node-drag-end",e,this)}},created:function(){var e=this,t=this.$parent;t.isTree?this.tree=t:this.tree=t.tree;var n=this.tree;n||console.warn("Can not find node's tree.");var i=n.props||{},r=i["children"]||"children";this.$watch("node.data."+r,(function(){e.node.updateChildren()})),this.node.expanded&&(this.expanded=!0,this.childNodeRendered=!0),this.tree.accordion&&this.$on("tree-node-expand",(function(t){e.node!==t&&e.node.collapse()}))}},xc=_c,wc=s(xc,bc,yc,!1,null,null,null);wc.options.__file="packages/tree/src/tree-node.vue";var Cc=wc.exports,kc={name:"ElTree",mixins:[D.a],components:{ElTreeNode:Cc},data:function(){return{store:null,root:null,currentNode:null,treeItems:null,checkboxItems:[],dragState:{showDropIndicator:!1,draggingNode:null,dropNode:null,allowDrop:!0}}},props:{data:{type:Array},emptyText:{type:String,default:function(){return Object(ti["t"])("el.tree.emptyText")}},renderAfterExpand:{type:Boolean,default:!0},nodeKey:String,checkStrictly:Boolean,defaultExpandAll:Boolean,expandOnClickNode:{type:Boolean,default:!0},checkOnClickNode:Boolean,checkDescendants:{type:Boolean,default:!1},autoExpandParent:{type:Boolean,default:!0},defaultCheckedKeys:Array,defaultExpandedKeys:Array,currentNodeKey:[String,Number],renderContent:Function,showCheckbox:{type:Boolean,default:!1},draggable:{type:Boolean,default:!1},allowDrag:Function,allowDrop:Function,props:{default:function(){return{children:"children",label:"label",disabled:"disabled"}}},lazy:{type:Boolean,default:!1},highlightCurrent:Boolean,load:Function,filterNodeMethod:Function,accordion:Boolean,indent:{type:Number,default:18},iconClass:String},computed:{children:{set:function(e){this.data=e},get:function(){return this.data}},treeItemArray:function(){return Array.prototype.slice.call(this.treeItems)},isEmpty:function(){var e=this.root.childNodes;return!e||0===e.length||e.every((function(e){var t=e.visible;return!t}))}},watch:{defaultCheckedKeys:function(e){this.store.setDefaultCheckedKey(e)},defaultExpandedKeys:function(e){this.store.defaultExpandedKeys=e,this.store.setDefaultExpandedKeys(e)},data:function(e){this.store.setData(e)},checkboxItems:function(e){Array.prototype.forEach.call(e,(function(e){e.setAttribute("tabindex",-1)}))},checkStrictly:function(e){this.store.checkStrictly=e}},methods:{filter:function(e){if(!this.filterNodeMethod)throw new Error("[Tree] filterNodeMethod is required when filter");this.store.filter(e)},getNodeKey:function(e){return rc(this.nodeKey,e.data)},getNodePath:function(e){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in getNodePath");var t=this.store.getNode(e);if(!t)return[];var n=[t.data],i=t.parent;while(i&&i!==this.root)n.push(i.data),i=i.parent;return n.reverse()},getCheckedNodes:function(e,t){return this.store.getCheckedNodes(e,t)},getCheckedKeys:function(e){return this.store.getCheckedKeys(e)},getCurrentNode:function(){var e=this.store.getCurrentNode();return e?e.data:null},getCurrentKey:function(){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in getCurrentKey");var e=this.getCurrentNode();return e?e[this.nodeKey]:null},setCheckedNodes:function(e,t){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in setCheckedNodes");this.store.setCheckedNodes(e,t)},setCheckedKeys:function(e,t){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in setCheckedKeys");this.store.setCheckedKeys(e,t)},setChecked:function(e,t,n){this.store.setChecked(e,t,n)},getHalfCheckedNodes:function(){return this.store.getHalfCheckedNodes()},getHalfCheckedKeys:function(){return this.store.getHalfCheckedKeys()},setCurrentNode:function(e){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in setCurrentNode");this.store.setUserCurrentNode(e)},setCurrentKey:function(e){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in setCurrentKey");this.store.setCurrentNodeKey(e)},getNode:function(e){return this.store.getNode(e)},remove:function(e){this.store.remove(e)},append:function(e,t){this.store.append(e,t)},insertBefore:function(e,t){this.store.insertBefore(e,t)},insertAfter:function(e,t){this.store.insertAfter(e,t)},handleNodeExpand:function(e,t,n){this.broadcast("ElTreeNode","tree-node-expand",t),this.$emit("node-expand",e,t,n)},updateKeyChildren:function(e,t){if(!this.nodeKey)throw new Error("[Tree] nodeKey is required in updateKeyChild");this.store.updateChildren(e,t)},initTabIndex:function(){this.treeItems=this.$el.querySelectorAll(".is-focusable[role=treeitem]"),this.checkboxItems=this.$el.querySelectorAll("input[type=checkbox]");var e=this.$el.querySelectorAll(".is-checked[role=treeitem]");e.length?e[0].setAttribute("tabindex",0):this.treeItems[0]&&this.treeItems[0].setAttribute("tabindex",0)},handleKeydown:function(e){var t=e.target;if(-1!==t.className.indexOf("el-tree-node")){var n=e.keyCode;this.treeItems=this.$el.querySelectorAll(".is-focusable[role=treeitem]");var i=this.treeItemArray.indexOf(t),r=void 0;[38,40].indexOf(n)>-1&&(e.preventDefault(),r=38===n?0!==i?i-1:0:i-1&&(e.preventDefault(),t.click());var o=t.querySelector('[type="checkbox"]');[13,32].indexOf(n)>-1&&o&&(e.preventDefault(),o.click())}}},created:function(){var e=this;this.isTree=!0,this.store=new gc({key:this.nodeKey,data:this.data,lazy:this.lazy,props:this.props,load:this.load,currentNodeKey:this.currentNodeKey,checkStrictly:this.checkStrictly,checkDescendants:this.checkDescendants,defaultCheckedKeys:this.defaultCheckedKeys,defaultExpandedKeys:this.defaultExpandedKeys,autoExpandParent:this.autoExpandParent,defaultExpandAll:this.defaultExpandAll,filterNodeMethod:this.filterNodeMethod}),this.root=this.store.root;var t=this.dragState;this.$on("tree-node-drag-start",(function(n,i){if("function"===typeof e.allowDrag&&!e.allowDrag(i.node))return n.preventDefault(),!1;n.dataTransfer.effectAllowed="move";try{n.dataTransfer.setData("text/plain","")}catch(r){}t.draggingNode=i,e.$emit("node-drag-start",i.node,n)})),this.$on("tree-node-drag-over",(function(n,i){var r=oc(n.target,"ElTreeNode"),o=t.dropNode;o&&o!==r&&Object(Le["removeClass"])(o.$el,"is-drop-inner");var a=t.draggingNode;if(a&&r){var s=!0,l=!0,c=!0,u=!0;"function"===typeof e.allowDrop&&(s=e.allowDrop(a.node,r.node,"prev"),u=l=e.allowDrop(a.node,r.node,"inner"),c=e.allowDrop(a.node,r.node,"next")),n.dataTransfer.dropEffect=l?"move":"none",(s||l||c)&&o!==r&&(o&&e.$emit("node-drag-leave",a.node,o.node,n),e.$emit("node-drag-enter",a.node,r.node,n)),(s||l||c)&&(t.dropNode=r),r.node.nextSibling===a.node&&(c=!1),r.node.previousSibling===a.node&&(s=!1),r.node.contains(a.node,!1)&&(l=!1),(a.node===r.node||a.node.contains(r.node))&&(s=!1,l=!1,c=!1);var d=r.$el.getBoundingClientRect(),h=e.$el.getBoundingClientRect(),f=void 0,p=s?l?.25:c?.45:1:-1,m=c?l?.75:s?.55:0:1,v=-9999,g=n.clientY-d.top;f=gd.height*m?"after":l?"inner":"none";var b=r.$el.querySelector(".el-tree-node__expand-icon").getBoundingClientRect(),y=e.$refs.dropIndicator;"before"===f?v=b.top-h.top:"after"===f&&(v=b.bottom-h.top),y.style.top=v+"px",y.style.left=b.right-h.left+"px","inner"===f?Object(Le["addClass"])(r.$el,"is-drop-inner"):Object(Le["removeClass"])(r.$el,"is-drop-inner"),t.showDropIndicator="before"===f||"after"===f,t.allowDrop=t.showDropIndicator||u,t.dropType=f,e.$emit("node-drag-over",a.node,r.node,n)}})),this.$on("tree-node-drag-end",(function(n){var i=t.draggingNode,r=t.dropType,o=t.dropNode;if(n.preventDefault(),n.dataTransfer.dropEffect="move",i&&o){var a={data:i.node.data};"none"!==r&&i.node.remove(),"before"===r?o.node.parent.insertBefore(a,o.node):"after"===r?o.node.parent.insertAfter(a,o.node):"inner"===r&&o.node.insertChild(a),"none"!==r&&e.store.registerNode(a),Object(Le["removeClass"])(o.$el,"is-drop-inner"),e.$emit("node-drag-end",i.node,o.node,r,n),"none"!==r&&e.$emit("node-drop",i.node,o.node,r,n)}i&&!o&&e.$emit("node-drag-end",i.node,null,r,n),t.showDropIndicator=!1,t.draggingNode=null,t.dropNode=null,t.allowDrop=!0}))},mounted:function(){this.initTabIndex(),this.$el.addEventListener("keydown",this.handleKeydown)},updated:function(){this.treeItems=this.$el.querySelectorAll("[role=treeitem]"),this.checkboxItems=this.$el.querySelectorAll("input[type=checkbox]")}},Sc=kc,Oc=s(Sc,ec,tc,!1,null,null,null);Oc.options.__file="packages/tree/src/tree.vue";var $c=Oc.exports;$c.install=function(e){e.component($c.name,$c)};var Dc=$c,Ec=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-alert-fade"}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-alert",class:[e.typeClass,e.center?"is-center":"","is-"+e.effect],attrs:{role:"alert"}},[e.showIcon?n("i",{staticClass:"el-alert__icon",class:[e.iconClass,e.isBigIcon]}):e._e(),n("div",{staticClass:"el-alert__content"},[e.title||e.$slots.title?n("span",{staticClass:"el-alert__title",class:[e.isBoldTitle]},[e._t("title",[e._v(e._s(e.title))])],2):e._e(),e.$slots.default&&!e.description?n("p",{staticClass:"el-alert__description"},[e._t("default")],2):e._e(),e.description&&!e.$slots.default?n("p",{staticClass:"el-alert__description"},[e._v(e._s(e.description))]):e._e(),n("i",{directives:[{name:"show",rawName:"v-show",value:e.closable,expression:"closable"}],staticClass:"el-alert__closebtn",class:{"is-customed":""!==e.closeText,"el-icon-close":""===e.closeText},on:{click:function(t){e.close()}}},[e._v(e._s(e.closeText))])])])])},Tc=[];Ec._withStripped=!0;var Pc={success:"el-icon-success",warning:"el-icon-warning",error:"el-icon-error"},Mc={name:"ElAlert",props:{title:{type:String,default:""},description:{type:String,default:""},type:{type:String,default:"info"},closable:{type:Boolean,default:!0},closeText:{type:String,default:""},showIcon:Boolean,center:Boolean,effect:{type:String,default:"light",validator:function(e){return-1!==["light","dark"].indexOf(e)}}},data:function(){return{visible:!0}},methods:{close:function(){this.visible=!1,this.$emit("close")}},computed:{typeClass:function(){return"el-alert--"+this.type},iconClass:function(){return Pc[this.type]||"el-icon-info"},isBigIcon:function(){return this.description||this.$slots.default?"is-big":""},isBoldTitle:function(){return this.description||this.$slots.default?"is-bold":""}}},Ic=Mc,Nc=s(Ic,Ec,Tc,!1,null,null,null);Nc.options.__file="packages/alert/src/main.vue";var jc=Nc.exports;jc.install=function(e){e.component(jc.name,jc)};var Ac=jc,Fc=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-notification-fade"}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],class:["el-notification",e.customClass,e.horizontalClass],style:e.positionStyle,attrs:{role:"alert"},on:{mouseenter:function(t){e.clearTimer()},mouseleave:function(t){e.startTimer()},click:e.click}},[e.type||e.iconClass?n("i",{staticClass:"el-notification__icon",class:[e.typeClass,e.iconClass]}):e._e(),n("div",{staticClass:"el-notification__group",class:{"is-with-icon":e.typeClass||e.iconClass}},[n("h2",{staticClass:"el-notification__title",domProps:{textContent:e._s(e.title)}}),n("div",{directives:[{name:"show",rawName:"v-show",value:e.message,expression:"message"}],staticClass:"el-notification__content"},[e._t("default",[e.dangerouslyUseHTMLString?n("p",{domProps:{innerHTML:e._s(e.message)}}):n("p",[e._v(e._s(e.message))])])],2),e.showClose?n("div",{staticClass:"el-notification__closeBtn el-icon-close",on:{click:function(t){return t.stopPropagation(),e.close(t)}}}):e._e()])])])},Lc=[];Fc._withStripped=!0;var Vc={success:"success",info:"info",warning:"warning",error:"error"},zc={data:function(){return{visible:!1,title:"",message:"",duration:4500,type:"",showClose:!0,customClass:"",iconClass:"",onClose:null,onClick:null,closed:!1,verticalOffset:0,timer:null,dangerouslyUseHTMLString:!1,position:"top-right"}},computed:{typeClass:function(){return this.type&&Vc[this.type]?"el-icon-"+Vc[this.type]:""},horizontalClass:function(){return this.position.indexOf("right")>-1?"right":"left"},verticalProperty:function(){return/^top-/.test(this.position)?"top":"bottom"},positionStyle:function(){var e;return e={},e[this.verticalProperty]=this.verticalOffset+"px",e}},watch:{closed:function(e){e&&(this.visible=!1,this.$el.addEventListener("transitionend",this.destroyElement))}},methods:{destroyElement:function(){this.$el.removeEventListener("transitionend",this.destroyElement),this.$destroy(!0),this.$el.parentNode.removeChild(this.$el)},click:function(){"function"===typeof this.onClick&&this.onClick()},close:function(){this.closed=!0,"function"===typeof this.onClose&&this.onClose()},clearTimer:function(){clearTimeout(this.timer)},startTimer:function(){var e=this;this.duration>0&&(this.timer=setTimeout((function(){e.closed||e.close()}),this.duration))},keydown:function(e){46===e.keyCode||8===e.keyCode?this.clearTimer():27===e.keyCode?this.closed||this.close():this.startTimer()}},mounted:function(){var e=this;this.duration>0&&(this.timer=setTimeout((function(){e.closed||e.close()}),this.duration)),document.addEventListener("keydown",this.keydown)},beforeDestroy:function(){document.removeEventListener("keydown",this.keydown)}},Bc=zc,Rc=s(Bc,Fc,Lc,!1,null,null,null);Rc.options.__file="packages/notification/src/main.vue";var Hc=Rc.exports,Wc=Wi.a.extend(Hc),qc=void 0,Uc=[],Yc=1,Kc=function e(t){if(!Wi.a.prototype.$isServer){t=St()({},t);var n=t.onClose,i="notification_"+Yc++,r=t.position||"top-right";t.onClose=function(){e.close(i,n)},qc=new Wc({data:t}),Object(ks["isVNode"])(t.message)&&(qc.$slots.default=[t.message],t.message="REPLACED_BY_VNODE"),qc.id=i,qc.$mount(),document.body.appendChild(qc.$el),qc.visible=!0,qc.dom=qc.$el,qc.dom.style.zIndex=C["PopupManager"].nextZIndex();var o=t.offset||0;return Uc.filter((function(e){return e.position===r})).forEach((function(e){o+=e.$el.offsetHeight+16})),o+=16,qc.verticalOffset=o,Uc.push(qc),qc}};["success","warning","info","error"].forEach((function(e){Kc[e]=function(t){return("string"===typeof t||Object(ks["isVNode"])(t))&&(t={message:t}),t.type=e,Kc(t)}})),Kc.close=function(e,t){var n=-1,i=Uc.length,r=Uc.filter((function(t,i){return t.id===e&&(n=i,!0)}))[0];if(r&&("function"===typeof t&&t(r),Uc.splice(n,1),!(i<=1)))for(var o=r.position,a=r.dom.offsetHeight,s=n;s=0;e--)Uc[e].close()};var Gc=Kc,Xc=Gc,Zc=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-slider",class:{"is-vertical":e.vertical,"el-slider--with-input":e.showInput},attrs:{role:"slider","aria-valuemin":e.min,"aria-valuemax":e.max,"aria-orientation":e.vertical?"vertical":"horizontal","aria-disabled":e.sliderDisabled}},[e.showInput&&!e.range?n("el-input-number",{ref:"input",staticClass:"el-slider__input",attrs:{step:e.step,disabled:e.sliderDisabled,controls:e.showInputControls,min:e.min,max:e.max,debounce:e.debounce,size:e.inputSize},on:{change:e.emitChange},model:{value:e.firstValue,callback:function(t){e.firstValue=t},expression:"firstValue"}}):e._e(),n("div",{ref:"slider",staticClass:"el-slider__runway",class:{"show-input":e.showInput,disabled:e.sliderDisabled},style:e.runwayStyle,on:{click:e.onSliderClick}},[n("div",{staticClass:"el-slider__bar",style:e.barStyle}),n("slider-button",{ref:"button1",attrs:{vertical:e.vertical,"tooltip-class":e.tooltipClass},model:{value:e.firstValue,callback:function(t){e.firstValue=t},expression:"firstValue"}}),e.range?n("slider-button",{ref:"button2",attrs:{vertical:e.vertical,"tooltip-class":e.tooltipClass},model:{value:e.secondValue,callback:function(t){e.secondValue=t},expression:"secondValue"}}):e._e(),e._l(e.stops,(function(t,i){return e.showStops?n("div",{key:i,staticClass:"el-slider__stop",style:e.getStopStyle(t)}):e._e()})),e.markList.length>0?[n("div",e._l(e.markList,(function(t,i){return n("div",{key:i,staticClass:"el-slider__stop el-slider__marks-stop",style:e.getStopStyle(t.position)})})),0),n("div",{staticClass:"el-slider__marks"},e._l(e.markList,(function(t,i){return n("slider-marker",{key:i,style:e.getStopStyle(t.position),attrs:{mark:t.mark}})})),1)]:e._e()],2)],1)},Jc=[];Zc._withStripped=!0;var Qc=n(41),eu=n.n(Qc),tu=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{ref:"button",staticClass:"el-slider__button-wrapper",class:{hover:e.hovering,dragging:e.dragging},style:e.wrapperStyle,attrs:{tabindex:"0"},on:{mouseenter:e.handleMouseEnter,mouseleave:e.handleMouseLeave,mousedown:e.onButtonDown,touchstart:e.onButtonDown,focus:e.handleMouseEnter,blur:e.handleMouseLeave,keydown:[function(t){return"button"in t||!e._k(t.keyCode,"left",37,t.key,["Left","ArrowLeft"])?"button"in t&&0!==t.button?null:e.onLeftKeyDown(t):null},function(t){return"button"in t||!e._k(t.keyCode,"right",39,t.key,["Right","ArrowRight"])?"button"in t&&2!==t.button?null:e.onRightKeyDown(t):null},function(t){return"button"in t||!e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"])?(t.preventDefault(),e.onLeftKeyDown(t)):null},function(t){return"button"in t||!e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"])?(t.preventDefault(),e.onRightKeyDown(t)):null}]}},[n("el-tooltip",{ref:"tooltip",attrs:{placement:"top","popper-class":e.tooltipClass,disabled:!e.showTooltip}},[n("span",{attrs:{slot:"content"},slot:"content"},[e._v(e._s(e.formatValue))]),n("div",{staticClass:"el-slider__button",class:{hover:e.hovering,dragging:e.dragging}})])],1)},nu=[];tu._withStripped=!0;var iu={name:"ElSliderButton",components:{ElTooltip:rt.a},props:{value:{type:Number,default:0},vertical:{type:Boolean,default:!1},tooltipClass:String},data:function(){return{hovering:!1,dragging:!1,isClick:!1,startX:0,currentX:0,startY:0,currentY:0,startPosition:0,newPosition:null,oldValue:this.value}},computed:{disabled:function(){return this.$parent.sliderDisabled},max:function(){return this.$parent.max},min:function(){return this.$parent.min},step:function(){return this.$parent.step},showTooltip:function(){return this.$parent.showTooltip},precision:function(){return this.$parent.precision},currentPosition:function(){return(this.value-this.min)/(this.max-this.min)*100+"%"},enableFormat:function(){return this.$parent.formatTooltip instanceof Function},formatValue:function(){return this.enableFormat&&this.$parent.formatTooltip(this.value)||this.value},wrapperStyle:function(){return this.vertical?{bottom:this.currentPosition}:{left:this.currentPosition}}},watch:{dragging:function(e){this.$parent.dragging=e}},methods:{displayTooltip:function(){this.$refs.tooltip&&(this.$refs.tooltip.showPopper=!0)},hideTooltip:function(){this.$refs.tooltip&&(this.$refs.tooltip.showPopper=!1)},handleMouseEnter:function(){this.hovering=!0,this.displayTooltip()},handleMouseLeave:function(){this.hovering=!1,this.hideTooltip()},onButtonDown:function(e){this.disabled||(e.preventDefault(),this.onDragStart(e),window.addEventListener("mousemove",this.onDragging),window.addEventListener("touchmove",this.onDragging),window.addEventListener("mouseup",this.onDragEnd),window.addEventListener("touchend",this.onDragEnd),window.addEventListener("contextmenu",this.onDragEnd))},onLeftKeyDown:function(){this.disabled||(this.newPosition=parseFloat(this.currentPosition)-this.step/(this.max-this.min)*100,this.setPosition(this.newPosition),this.$parent.emitChange())},onRightKeyDown:function(){this.disabled||(this.newPosition=parseFloat(this.currentPosition)+this.step/(this.max-this.min)*100,this.setPosition(this.newPosition),this.$parent.emitChange())},onDragStart:function(e){this.dragging=!0,this.isClick=!0,"touchstart"===e.type&&(e.clientY=e.touches[0].clientY,e.clientX=e.touches[0].clientX),this.vertical?this.startY=e.clientY:this.startX=e.clientX,this.startPosition=parseFloat(this.currentPosition),this.newPosition=this.startPosition},onDragging:function(e){if(this.dragging){this.isClick=!1,this.displayTooltip(),this.$parent.resetSize();var t=0;"touchmove"===e.type&&(e.clientY=e.touches[0].clientY,e.clientX=e.touches[0].clientX),this.vertical?(this.currentY=e.clientY,t=(this.startY-this.currentY)/this.$parent.sliderSize*100):(this.currentX=e.clientX,t=(this.currentX-this.startX)/this.$parent.sliderSize*100),this.newPosition=this.startPosition+t,this.setPosition(this.newPosition)}},onDragEnd:function(){var e=this;this.dragging&&(setTimeout((function(){e.dragging=!1,e.hideTooltip(),e.isClick||(e.setPosition(e.newPosition),e.$parent.emitChange())}),0),window.removeEventListener("mousemove",this.onDragging),window.removeEventListener("touchmove",this.onDragging),window.removeEventListener("mouseup",this.onDragEnd),window.removeEventListener("touchend",this.onDragEnd),window.removeEventListener("contextmenu",this.onDragEnd))},setPosition:function(e){var t=this;if(null!==e&&!isNaN(e)){e<0?e=0:e>100&&(e=100);var n=100/((this.max-this.min)/this.step),i=Math.round(e/n),r=i*n*(this.max-this.min)*.01+this.min;r=parseFloat(r.toFixed(this.precision)),this.$emit("input",r),this.$nextTick((function(){t.displayTooltip(),t.$refs.tooltip&&t.$refs.tooltip.updatePopper()})),this.dragging||this.value===this.oldValue||(this.oldValue=this.value)}}}},ru=iu,ou=s(ru,tu,nu,!1,null,null,null);ou.options.__file="packages/slider/src/button.vue";var au=ou.exports,su={name:"ElMarker",props:{mark:{type:[String,Object]}},render:function(){var e=arguments[0],t="string"===typeof this.mark?this.mark:this.mark.label;return e("div",{class:"el-slider__marks-text",style:this.mark.style||{}},[t])}},lu={name:"ElSlider",mixins:[D.a],inject:{elForm:{default:""}},props:{min:{type:Number,default:0},max:{type:Number,default:100},step:{type:Number,default:1},value:{type:[Number,Array],default:0},showInput:{type:Boolean,default:!1},showInputControls:{type:Boolean,default:!0},inputSize:{type:String,default:"small"},showStops:{type:Boolean,default:!1},showTooltip:{type:Boolean,default:!0},formatTooltip:Function,disabled:{type:Boolean,default:!1},range:{type:Boolean,default:!1},vertical:{type:Boolean,default:!1},height:{type:String},debounce:{type:Number,default:300},label:{type:String},tooltipClass:String,marks:Object},components:{ElInputNumber:eu.a,SliderButton:au,SliderMarker:su},data:function(){return{firstValue:null,secondValue:null,oldValue:null,dragging:!1,sliderSize:1}},watch:{value:function(e,t){this.dragging||Array.isArray(e)&&Array.isArray(t)&&e.every((function(e,n){return e===t[n]}))||this.setValues()},dragging:function(e){e||this.setValues()},firstValue:function(e){this.range?this.$emit("input",[this.minValue,this.maxValue]):this.$emit("input",e)},secondValue:function(){this.range&&this.$emit("input",[this.minValue,this.maxValue])},min:function(){this.setValues()},max:function(){this.setValues()}},methods:{valueChanged:function(){var e=this;return this.range?![this.minValue,this.maxValue].every((function(t,n){return t===e.oldValue[n]})):this.value!==this.oldValue},setValues:function(){if(this.min>this.max)console.error("[Element Error][Slider]min should not be greater than max.");else{var e=this.value;this.range&&Array.isArray(e)?e[1]this.max?this.$emit("input",[this.max,this.max]):e[0]this.max?this.$emit("input",[e[0],this.max]):(this.firstValue=e[0],this.secondValue=e[1],this.valueChanged()&&(this.dispatch("ElFormItem","el.form.change",[this.minValue,this.maxValue]),this.oldValue=e.slice())):this.range||"number"!==typeof e||isNaN(e)||(ethis.max?this.$emit("input",this.max):(this.firstValue=e,this.valueChanged()&&(this.dispatch("ElFormItem","el.form.change",e),this.oldValue=e)))}},setPosition:function(e){var t=this.min+e*(this.max-this.min)/100;if(this.range){var n=void 0;n=Math.abs(this.minValue-t)this.secondValue?"button1":"button2",this.$refs[n].setPosition(e)}else this.$refs.button1.setPosition(e)},onSliderClick:function(e){if(!this.sliderDisabled&&!this.dragging){if(this.resetSize(),this.vertical){var t=this.$refs.slider.getBoundingClientRect().bottom;this.setPosition((t-e.clientY)/this.sliderSize*100)}else{var n=this.$refs.slider.getBoundingClientRect().left;this.setPosition((e.clientX-n)/this.sliderSize*100)}this.emitChange()}},resetSize:function(){this.$refs.slider&&(this.sliderSize=this.$refs.slider["client"+(this.vertical?"Height":"Width")])},emitChange:function(){var e=this;this.$nextTick((function(){e.$emit("change",e.range?[e.minValue,e.maxValue]:e.value)}))},getStopStyle:function(e){return this.vertical?{bottom:e+"%"}:{left:e+"%"}}},computed:{stops:function(){var e=this;if(!this.showStops||this.min>this.max)return[];if(0===this.step)return[];for(var t=(this.max-this.min)/this.step,n=100*this.step/(this.max-this.min),i=[],r=1;r100*(e.maxValue-e.min)/(e.max-e.min)})):i.filter((function(t){return t>100*(e.firstValue-e.min)/(e.max-e.min)}))},markList:function(){var e=this;if(!this.marks)return[];var t=Object.keys(this.marks);return t.map(parseFloat).sort((function(e,t){return e-t})).filter((function(t){return t<=e.max&&t>=e.min})).map((function(t){return{point:t,position:100*(t-e.min)/(e.max-e.min),mark:e.marks[t]}}))},minValue:function(){return Math.min(this.firstValue,this.secondValue)},maxValue:function(){return Math.max(this.firstValue,this.secondValue)},barSize:function(){return this.range?100*(this.maxValue-this.minValue)/(this.max-this.min)+"%":100*(this.firstValue-this.min)/(this.max-this.min)+"%"},barStart:function(){return this.range?100*(this.minValue-this.min)/(this.max-this.min)+"%":"0%"},precision:function(){var e=[this.min,this.max,this.step].map((function(e){var t=(""+e).split(".")[1];return t?t.length:0}));return Math.max.apply(null,e)},runwayStyle:function(){return this.vertical?{height:this.height}:{}},barStyle:function(){return this.vertical?{height:this.barSize,bottom:this.barStart}:{width:this.barSize,left:this.barStart}},sliderDisabled:function(){return this.disabled||(this.elForm||{}).disabled}},mounted:function(){var e=void 0;this.range?(Array.isArray(this.value)?(this.firstValue=Math.max(this.min,this.value[0]),this.secondValue=Math.min(this.max,this.value[1])):(this.firstValue=this.min,this.secondValue=this.max),this.oldValue=[this.firstValue,this.secondValue],e=this.firstValue+"-"+this.secondValue):("number"!==typeof this.value||isNaN(this.value)?this.firstValue=this.min:this.firstValue=Math.min(this.max,Math.max(this.min,this.value)),this.oldValue=this.firstValue,e=this.firstValue),this.$el.setAttribute("aria-valuetext",e),this.$el.setAttribute("aria-label",this.label?this.label:"slider between "+this.min+" and "+this.max),this.resetSize(),window.addEventListener("resize",this.resetSize)},beforeDestroy:function(){window.removeEventListener("resize",this.resetSize)}},cu=lu,uu=s(cu,Zc,Jc,!1,null,null,null);uu.options.__file="packages/slider/src/main.vue";var du=uu.exports;du.install=function(e){e.component(du.name,du)};var hu=du,fu=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-loading-fade"},on:{"after-leave":e.handleAfterLeave}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-loading-mask",class:[e.customClass,{"is-fullscreen":e.fullscreen}],style:{backgroundColor:e.background||""}},[n("div",{staticClass:"el-loading-spinner"},[e.spinner?n("i",{class:e.spinner}):n("svg",{staticClass:"circular",attrs:{viewBox:"25 25 50 50"}},[n("circle",{staticClass:"path",attrs:{cx:"50",cy:"50",r:"20",fill:"none"}})]),e.text?n("p",{staticClass:"el-loading-text"},[e._v(e._s(e.text))]):e._e()])])])},pu=[];fu._withStripped=!0;var mu={data:function(){return{text:null,spinner:null,background:null,fullscreen:!0,visible:!1,customClass:""}},methods:{handleAfterLeave:function(){this.$emit("after-leave")},setText:function(e){this.text=e}}},vu=mu,gu=s(vu,fu,pu,!1,null,null,null);gu.options.__file="packages/loading/src/loading.vue";var bu=gu.exports,yu=n(31),_u=n.n(yu),xu=Wi.a.extend(bu),wu={install:function(e){if(!e.prototype.$isServer){var t=function(t,i){i.value?e.nextTick((function(){i.modifiers.fullscreen?(t.originalPosition=Object(Le["getStyle"])(document.body,"position"),t.originalOverflow=Object(Le["getStyle"])(document.body,"overflow"),t.maskStyle.zIndex=C["PopupManager"].nextZIndex(),Object(Le["addClass"])(t.mask,"is-fullscreen"),n(document.body,t,i)):(Object(Le["removeClass"])(t.mask,"is-fullscreen"),i.modifiers.body?(t.originalPosition=Object(Le["getStyle"])(document.body,"position"),["top","left"].forEach((function(e){var n="top"===e?"scrollTop":"scrollLeft";t.maskStyle[e]=t.getBoundingClientRect()[e]+document.body[n]+document.documentElement[n]-parseInt(Object(Le["getStyle"])(document.body,"margin-"+e),10)+"px"})),["height","width"].forEach((function(e){t.maskStyle[e]=t.getBoundingClientRect()[e]+"px"})),n(document.body,t,i)):(t.originalPosition=Object(Le["getStyle"])(t,"position"),n(t,t,i)))})):(_u()(t.instance,(function(e){if(t.instance.hiding){t.domVisible=!1;var n=i.modifiers.fullscreen||i.modifiers.body?document.body:t;Object(Le["removeClass"])(n,"el-loading-parent--relative"),Object(Le["removeClass"])(n,"el-loading-parent--hidden"),t.instance.hiding=!1}}),300,!0),t.instance.visible=!1,t.instance.hiding=!0)},n=function(t,n,i){n.domVisible||"none"===Object(Le["getStyle"])(n,"display")||"hidden"===Object(Le["getStyle"])(n,"visibility")?n.domVisible&&!0===n.instance.hiding&&(n.instance.visible=!0,n.instance.hiding=!1):(Object.keys(n.maskStyle).forEach((function(e){n.mask.style[e]=n.maskStyle[e]})),"absolute"!==n.originalPosition&&"fixed"!==n.originalPosition&&Object(Le["addClass"])(t,"el-loading-parent--relative"),i.modifiers.fullscreen&&i.modifiers.lock&&Object(Le["addClass"])(t,"el-loading-parent--hidden"),n.domVisible=!0,t.appendChild(n.mask),e.nextTick((function(){n.instance.hiding?n.instance.$emit("after-leave"):n.instance.visible=!0})),n.domInserted=!0)};e.directive("loading",{bind:function(e,n,i){var r=e.getAttribute("element-loading-text"),o=e.getAttribute("element-loading-spinner"),a=e.getAttribute("element-loading-background"),s=e.getAttribute("element-loading-custom-class"),l=i.context,c=new xu({el:document.createElement("div"),data:{text:l&&l[r]||r,spinner:l&&l[o]||o,background:l&&l[a]||a,customClass:l&&l[s]||s,fullscreen:!!n.modifiers.fullscreen}});e.instance=c,e.mask=c.$el,e.maskStyle={},n.value&&t(e,n)},update:function(e,n){e.instance.setText(e.getAttribute("element-loading-text")),n.oldValue!==n.value&&t(e,n)},unbind:function(e,n){e.domInserted&&(e.mask&&e.mask.parentNode&&e.mask.parentNode.removeChild(e.mask),t(e,{value:!1,modifiers:n.modifiers})),e.instance&&e.instance.$destroy()}})}}},Cu=wu,ku=Wi.a.extend(bu),Su={text:null,fullscreen:!0,body:!1,lock:!1,customClass:""},Ou=void 0;ku.prototype.originalPosition="",ku.prototype.originalOverflow="",ku.prototype.close=function(){var e=this;this.fullscreen&&(Ou=void 0),_u()(this,(function(t){var n=e.fullscreen||e.body?document.body:e.target;Object(Le["removeClass"])(n,"el-loading-parent--relative"),Object(Le["removeClass"])(n,"el-loading-parent--hidden"),e.$el&&e.$el.parentNode&&e.$el.parentNode.removeChild(e.$el),e.$destroy()}),300),this.visible=!1};var $u=function(e,t,n){var i={};e.fullscreen?(n.originalPosition=Object(Le["getStyle"])(document.body,"position"),n.originalOverflow=Object(Le["getStyle"])(document.body,"overflow"),i.zIndex=C["PopupManager"].nextZIndex()):e.body?(n.originalPosition=Object(Le["getStyle"])(document.body,"position"),["top","left"].forEach((function(t){var n="top"===t?"scrollTop":"scrollLeft";i[t]=e.target.getBoundingClientRect()[t]+document.body[n]+document.documentElement[n]+"px"})),["height","width"].forEach((function(t){i[t]=e.target.getBoundingClientRect()[t]+"px"}))):n.originalPosition=Object(Le["getStyle"])(t,"position"),Object.keys(i).forEach((function(e){n.$el.style[e]=i[e]}))},Du=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!Wi.a.prototype.$isServer){if(e=St()({},Su,e),"string"===typeof e.target&&(e.target=document.querySelector(e.target)),e.target=e.target||document.body,e.target!==document.body?e.fullscreen=!1:e.body=!0,e.fullscreen&&Ou)return Ou;var t=e.body?document.body:e.target,n=new ku({el:document.createElement("div"),data:e});return $u(e,t,n),"absolute"!==n.originalPosition&&"fixed"!==n.originalPosition&&Object(Le["addClass"])(t,"el-loading-parent--relative"),e.fullscreen&&e.lock&&Object(Le["addClass"])(t,"el-loading-parent--hidden"),t.appendChild(n.$el),Wi.a.nextTick((function(){n.visible=!0})),e.fullscreen&&(Ou=n),n}},Eu=Du,Tu={install:function(e){e.use(Cu),e.prototype.$loading=Eu},directive:Cu,service:Eu},Pu=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("i",{class:"el-icon-"+e.name})},Mu=[];Pu._withStripped=!0;var Iu={name:"ElIcon",props:{name:String}},Nu=Iu,ju=s(Nu,Pu,Mu,!1,null,null,null);ju.options.__file="packages/icon/src/icon.vue";var Au=ju.exports;Au.install=function(e){e.component(Au.name,Au)};var Fu=Au,Lu={name:"ElRow",componentName:"ElRow",props:{tag:{type:String,default:"div"},gutter:Number,type:String,justify:{type:String,default:"start"},align:{type:String,default:"top"}},computed:{style:function(){var e={};return this.gutter&&(e.marginLeft="-"+this.gutter/2+"px",e.marginRight=e.marginLeft),e}},render:function(e){return e(this.tag,{class:["el-row","start"!==this.justify?"is-justify-"+this.justify:"","top"!==this.align?"is-align-"+this.align:"",{"el-row--flex":"flex"===this.type}],style:this.style},this.$slots.default)},install:function(e){e.component(Lu.name,Lu)}},Vu=Lu,zu="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Bu={name:"ElCol",props:{span:{type:Number,default:24},tag:{type:String,default:"div"},offset:Number,pull:Number,push:Number,xs:[Number,Object],sm:[Number,Object],md:[Number,Object],lg:[Number,Object],xl:[Number,Object]},computed:{gutter:function(){var e=this.$parent;while(e&&"ElRow"!==e.$options.componentName)e=e.$parent;return e?e.gutter:0}},render:function(e){var t=this,n=[],i={};return this.gutter&&(i.paddingLeft=this.gutter/2+"px",i.paddingRight=i.paddingLeft),["span","offset","pull","push"].forEach((function(e){(t[e]||0===t[e])&&n.push("span"!==e?"el-col-"+e+"-"+t[e]:"el-col-"+t[e])})),["xs","sm","md","lg","xl"].forEach((function(e){if("number"===typeof t[e])n.push("el-col-"+e+"-"+t[e]);else if("object"===zu(t[e])){var i=t[e];Object.keys(i).forEach((function(t){n.push("span"!==t?"el-col-"+e+"-"+t+"-"+i[t]:"el-col-"+e+"-"+i[t])}))}})),e(this.tag,{class:["el-col",n],style:i},this.$slots.default)},install:function(e){e.component(Bu.name,Bu)}},Ru=Bu,Hu=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition-group",{class:["el-upload-list","el-upload-list--"+e.listType,{"is-disabled":e.disabled}],attrs:{tag:"ul",name:"el-list"}},e._l(e.files,(function(t){return n("li",{key:t.uid,class:["el-upload-list__item","is-"+t.status,e.focusing?"focusing":""],attrs:{tabindex:"0"},on:{keydown:function(n){if(!("button"in n)&&e._k(n.keyCode,"delete",[8,46],n.key,["Backspace","Delete","Del"]))return null;!e.disabled&&e.$emit("remove",t)},focus:function(t){e.focusing=!0},blur:function(t){e.focusing=!1},click:function(t){e.focusing=!1}}},[e._t("default",["uploading"!==t.status&&["picture-card","picture"].indexOf(e.listType)>-1?n("img",{staticClass:"el-upload-list__item-thumbnail",attrs:{src:t.url,alt:""}}):e._e(),n("a",{staticClass:"el-upload-list__item-name",on:{click:function(n){e.handleClick(t)}}},[n("i",{staticClass:"el-icon-document"}),e._v(e._s(t.name)+"\n ")]),n("label",{staticClass:"el-upload-list__item-status-label"},[n("i",{class:{"el-icon-upload-success":!0,"el-icon-circle-check":"text"===e.listType,"el-icon-check":["picture-card","picture"].indexOf(e.listType)>-1}})]),e.disabled?e._e():n("i",{staticClass:"el-icon-close",on:{click:function(n){e.$emit("remove",t)}}}),e.disabled?e._e():n("i",{staticClass:"el-icon-close-tip"},[e._v(e._s(e.t("el.upload.deleteTip")))]),"uploading"===t.status?n("el-progress",{attrs:{type:"picture-card"===e.listType?"circle":"line","stroke-width":"picture-card"===e.listType?6:2,percentage:e.parsePercentage(t.percentage)}}):e._e(),"picture-card"===e.listType?n("span",{staticClass:"el-upload-list__item-actions"},[e.handlePreview&&"picture-card"===e.listType?n("span",{staticClass:"el-upload-list__item-preview",on:{click:function(n){e.handlePreview(t)}}},[n("i",{staticClass:"el-icon-zoom-in"})]):e._e(),e.disabled?e._e():n("span",{staticClass:"el-upload-list__item-delete",on:{click:function(n){e.$emit("remove",t)}}},[n("i",{staticClass:"el-icon-delete"})])]):e._e()],{file:t})],2)})),0)},Wu=[];Hu._withStripped=!0;var qu=n(32),Uu=n.n(qu),Yu={name:"ElUploadList",mixins:[g.a],data:function(){return{focusing:!1}},components:{ElProgress:Uu.a},props:{files:{type:Array,default:function(){return[]}},disabled:{type:Boolean,default:!1},handlePreview:Function,listType:String},methods:{parsePercentage:function(e){return parseInt(e,10)},handleClick:function(e){this.handlePreview&&this.handlePreview(e)}}},Ku=Yu,Gu=s(Ku,Hu,Wu,!1,null,null,null);Gu.options.__file="packages/upload/src/upload-list.vue";var Xu=Gu.exports,Zu=n(24),Ju=n.n(Zu);function Qu(e,t,n){var i=void 0;i=n.response?""+(n.response.error||n.response):n.responseText?""+n.responseText:"fail to post "+e+" "+n.status;var r=new Error(i);return r.status=n.status,r.method="post",r.url=e,r}function ed(e){var t=e.responseText||e.response;if(!t)return t;try{return JSON.parse(t)}catch(n){return t}}function td(e){if("undefined"!==typeof XMLHttpRequest){var t=new XMLHttpRequest,n=e.action;t.upload&&(t.upload.onprogress=function(t){t.total>0&&(t.percent=t.loaded/t.total*100),e.onProgress(t)});var i=new FormData;e.data&&Object.keys(e.data).forEach((function(t){i.append(t,e.data[t])})),i.append(e.filename,e.file,e.file.name),t.onerror=function(t){e.onError(t)},t.onload=function(){if(t.status<200||t.status>=300)return e.onError(Qu(n,e,t));e.onSuccess(ed(t))},t.open("post",n,!0),e.withCredentials&&"withCredentials"in t&&(t.withCredentials=!0);var r=e.headers||{};for(var o in r)r.hasOwnProperty(o)&&null!==r[o]&&t.setRequestHeader(o,r[o]);return t.send(i),t}}var nd=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-upload-dragger",class:{"is-dragover":e.dragover},on:{drop:function(t){return t.preventDefault(),e.onDrop(t)},dragover:function(t){return t.preventDefault(),e.onDragover(t)},dragleave:function(t){t.preventDefault(),e.dragover=!1}}},[e._t("default")],2)},id=[];nd._withStripped=!0;var rd={name:"ElUploadDrag",props:{disabled:Boolean},inject:{uploader:{default:""}},data:function(){return{dragover:!1}},methods:{onDragover:function(){this.disabled||(this.dragover=!0)},onDrop:function(e){if(!this.disabled&&this.uploader){var t=this.uploader.accept;this.dragover=!1,t?this.$emit("file",[].slice.call(e.dataTransfer.files).filter((function(e){var n=e.type,i=e.name,r=i.indexOf(".")>-1?"."+i.split(".").pop():"",o=n.replace(/\/.*$/,"");return t.split(",").map((function(e){return e.trim()})).filter((function(e){return e})).some((function(e){return/\..+$/.test(e)?r===e:/\/\*$/.test(e)?o===e.replace(/\/\*$/,""):!!/^[^\/]+\/[^\/]+$/.test(e)&&n===e}))}))):this.$emit("file",e.dataTransfer.files)}}}},od=rd,ad=s(od,nd,id,!1,null,null,null);ad.options.__file="packages/upload/src/upload-dragger.vue";var sd,ld,cd=ad.exports,ud={inject:["uploader"],components:{UploadDragger:cd},props:{type:String,action:{type:String,required:!0},name:{type:String,default:"file"},data:Object,headers:Object,withCredentials:Boolean,multiple:Boolean,accept:String,onStart:Function,onProgress:Function,onSuccess:Function,onError:Function,beforeUpload:Function,drag:Boolean,onPreview:{type:Function,default:function(){}},onRemove:{type:Function,default:function(){}},fileList:Array,autoUpload:Boolean,listType:String,httpRequest:{type:Function,default:td},disabled:Boolean,limit:Number,onExceed:Function},data:function(){return{mouseover:!1,reqs:{}}},methods:{isImage:function(e){return-1!==e.indexOf("image")},handleChange:function(e){var t=e.target.files;t&&this.uploadFiles(t)},uploadFiles:function(e){var t=this;if(this.limit&&this.fileList.length+e.length>this.limit)this.onExceed&&this.onExceed(e,this.fileList);else{var n=Array.prototype.slice.call(e);this.multiple||(n=n.slice(0,1)),0!==n.length&&n.forEach((function(e){t.onStart(e),t.autoUpload&&t.upload(e)}))}},upload:function(e){var t=this;if(this.$refs.input.value=null,!this.beforeUpload)return this.post(e);var n=this.beforeUpload(e);n&&n.then?n.then((function(n){var i=Object.prototype.toString.call(n);if("[object File]"===i||"[object Blob]"===i){for(var r in"[object Blob]"===i&&(n=new File([n],e.name,{type:e.type})),e)e.hasOwnProperty(r)&&(n[r]=e[r]);t.post(n)}else t.post(e)}),(function(){t.onRemove(null,e)})):!1!==n?this.post(e):this.onRemove(null,e)},abort:function(e){var t=this.reqs;if(e){var n=e;e.uid&&(n=e.uid),t[n]&&t[n].abort()}else Object.keys(t).forEach((function(e){t[e]&&t[e].abort(),delete t[e]}))},post:function(e){var t=this,n=e.uid,i={headers:this.headers,withCredentials:this.withCredentials,file:e,data:this.data,filename:this.name,action:this.action,onProgress:function(n){t.onProgress(n,e)},onSuccess:function(i){t.onSuccess(i,e),delete t.reqs[n]},onError:function(i){t.onError(i,e),delete t.reqs[n]}},r=this.httpRequest(i);this.reqs[n]=r,r&&r.then&&r.then(i.onSuccess,i.onError)},handleClick:function(){this.disabled||(this.$refs.input.value=null,this.$refs.input.click())},handleKeydown:function(e){e.target===e.currentTarget&&(13!==e.keyCode&&32!==e.keyCode||this.handleClick())}},render:function(e){var t=this.handleClick,n=this.drag,i=this.name,r=this.handleChange,o=this.multiple,a=this.accept,s=this.listType,l=this.uploadFiles,c=this.disabled,u=this.handleKeydown,d={class:{"el-upload":!0},on:{click:t,keydown:u}};return d.class["el-upload--"+s]=!0,e("div",Ju()([d,{attrs:{tabindex:"0"}}]),[n?e("upload-dragger",{attrs:{disabled:c},on:{file:l}},[this.$slots.default]):this.$slots.default,e("input",{class:"el-upload__input",attrs:{type:"file",name:i,multiple:o,accept:a},ref:"input",on:{change:r}})])}},dd=ud,hd=s(dd,sd,ld,!1,null,null,null);hd.options.__file="packages/upload/src/upload.vue";var fd=hd.exports;function pd(){}var md,vd,gd={name:"ElUpload",mixins:[O.a],components:{ElProgress:Uu.a,UploadList:Xu,Upload:fd},provide:function(){return{uploader:this}},inject:{elForm:{default:""}},props:{action:{type:String,required:!0},headers:{type:Object,default:function(){return{}}},data:Object,multiple:Boolean,name:{type:String,default:"file"},drag:Boolean,dragger:Boolean,withCredentials:Boolean,showFileList:{type:Boolean,default:!0},accept:String,type:{type:String,default:"select"},beforeUpload:Function,beforeRemove:Function,onRemove:{type:Function,default:pd},onChange:{type:Function,default:pd},onPreview:{type:Function},onSuccess:{type:Function,default:pd},onProgress:{type:Function,default:pd},onError:{type:Function,default:pd},fileList:{type:Array,default:function(){return[]}},autoUpload:{type:Boolean,default:!0},listType:{type:String,default:"text"},httpRequest:Function,disabled:Boolean,limit:Number,onExceed:{type:Function,default:pd}},data:function(){return{uploadFiles:[],dragOver:!1,draging:!1,tempIndex:1}},computed:{uploadDisabled:function(){return this.disabled||(this.elForm||{}).disabled}},watch:{listType:function(e){"picture-card"!==e&&"picture"!==e||(this.uploadFiles=this.uploadFiles.map((function(e){if(!e.url&&e.raw)try{e.url=URL.createObjectURL(e.raw)}catch(t){console.error("[Element Error][Upload]",t)}return e})))},fileList:{immediate:!0,handler:function(e){var t=this;this.uploadFiles=e.map((function(e){return e.uid=e.uid||Date.now()+t.tempIndex++,e.status=e.status||"success",e}))}}},methods:{handleStart:function(e){e.uid=Date.now()+this.tempIndex++;var t={status:"ready",name:e.name,size:e.size,percentage:0,uid:e.uid,raw:e};if("picture-card"===this.listType||"picture"===this.listType)try{t.url=URL.createObjectURL(e)}catch(n){return void console.error("[Element Error][Upload]",n)}this.uploadFiles.push(t),this.onChange(t,this.uploadFiles)},handleProgress:function(e,t){var n=this.getFile(t);this.onProgress(e,n,this.uploadFiles),n.status="uploading",n.percentage=e.percent||0},handleSuccess:function(e,t){var n=this.getFile(t);n&&(n.status="success",n.response=e,this.onSuccess(e,n,this.uploadFiles),this.onChange(n,this.uploadFiles))},handleError:function(e,t){var n=this.getFile(t),i=this.uploadFiles;n.status="fail",i.splice(i.indexOf(n),1),this.onError(e,n,this.uploadFiles),this.onChange(n,this.uploadFiles)},handleRemove:function(e,t){var n=this;t&&(e=this.getFile(t));var i=function(){n.abort(e);var t=n.uploadFiles;t.splice(t.indexOf(e),1),n.onRemove(e,t)};if(this.beforeRemove){if("function"===typeof this.beforeRemove){var r=this.beforeRemove(e,this.uploadFiles);r&&r.then?r.then((function(){i()}),pd):!1!==r&&i()}}else i()},getFile:function(e){var t=this.uploadFiles,n=void 0;return t.every((function(t){return n=e.uid===t.uid?t:null,!n})),n},abort:function(e){this.$refs["upload-inner"].abort(e)},clearFiles:function(){this.uploadFiles=[]},submit:function(){var e=this;this.uploadFiles.filter((function(e){return"ready"===e.status})).forEach((function(t){e.$refs["upload-inner"].upload(t.raw)}))},getMigratingConfig:function(){return{props:{"default-file-list":"default-file-list is renamed to file-list.","show-upload-list":"show-upload-list is renamed to show-file-list.","thumbnail-mode":"thumbnail-mode has been deprecated, you can implement the same effect according to this case: http://element.eleme.io/#/zh-CN/component/upload#yong-hu-tou-xiang-shang-chuan"}}}},beforeDestroy:function(){this.uploadFiles.forEach((function(e){e.url&&0===e.url.indexOf("blob:")&&URL.revokeObjectURL(e.url)}))},render:function(e){var t=this,n=void 0;this.showFileList&&(n=e(Xu,{attrs:{disabled:this.uploadDisabled,listType:this.listType,files:this.uploadFiles,handlePreview:this.onPreview},on:{remove:this.handleRemove}},[function(e){if(t.$scopedSlots.file)return t.$scopedSlots.file({file:e.file})}]));var i={props:{type:this.type,drag:this.drag,action:this.action,multiple:this.multiple,"before-upload":this.beforeUpload,"with-credentials":this.withCredentials,headers:this.headers,name:this.name,data:this.data,accept:this.accept,fileList:this.uploadFiles,autoUpload:this.autoUpload,listType:this.listType,disabled:this.uploadDisabled,limit:this.limit,"on-exceed":this.onExceed,"on-start":this.handleStart,"on-progress":this.handleProgress,"on-success":this.handleSuccess,"on-error":this.handleError,"on-preview":this.onPreview,"on-remove":this.handleRemove,"http-request":this.httpRequest},ref:"upload-inner"},r=this.$slots.trigger||this.$slots.default,o=e("upload",i,[r]);return e("div",["picture-card"===this.listType?n:"",this.$slots.trigger?[o,this.$slots.default]:o,this.$slots.tip,"picture-card"!==this.listType?n:""])}},bd=gd,yd=s(bd,md,vd,!1,null,null,null);yd.options.__file="packages/upload/src/index.vue";var _d=yd.exports;_d.install=function(e){e.component(_d.name,_d)};var xd=_d,wd=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-progress",class:["el-progress--"+e.type,e.status?"is-"+e.status:"",{"el-progress--without-text":!e.showText,"el-progress--text-inside":e.textInside}],attrs:{role:"progressbar","aria-valuenow":e.percentage,"aria-valuemin":"0","aria-valuemax":"100"}},["line"===e.type?n("div",{staticClass:"el-progress-bar"},[n("div",{staticClass:"el-progress-bar__outer",style:{height:e.strokeWidth+"px"}},[n("div",{staticClass:"el-progress-bar__inner",style:e.barStyle},[e.showText&&e.textInside?n("div",{staticClass:"el-progress-bar__innerText"},[e._v(e._s(e.content))]):e._e()])])]):n("div",{staticClass:"el-progress-circle",style:{height:e.width+"px",width:e.width+"px"}},[n("svg",{attrs:{viewBox:"0 0 100 100"}},[n("path",{staticClass:"el-progress-circle__track",style:e.trailPathStyle,attrs:{d:e.trackPath,stroke:"#e5e9f2","stroke-width":e.relativeStrokeWidth,fill:"none"}}),n("path",{staticClass:"el-progress-circle__path",style:e.circlePathStyle,attrs:{d:e.trackPath,stroke:e.stroke,fill:"none","stroke-linecap":"round","stroke-width":e.percentage?e.relativeStrokeWidth:0}})])]),e.showText&&!e.textInside?n("div",{staticClass:"el-progress__text",style:{fontSize:e.progressTextSize+"px"}},[e.status?n("i",{class:e.iconClass}):[e._v(e._s(e.content))]],2):e._e()])},Cd=[];wd._withStripped=!0;var kd={name:"ElProgress",props:{type:{type:String,default:"line",validator:function(e){return["line","circle","dashboard"].indexOf(e)>-1}},percentage:{type:Number,default:0,required:!0,validator:function(e){return e>=0&&e<=100}},status:{type:String,validator:function(e){return["success","exception","warning"].indexOf(e)>-1}},strokeWidth:{type:Number,default:6},textInside:{type:Boolean,default:!1},width:{type:Number,default:126},showText:{type:Boolean,default:!0},color:{type:[String,Array,Function],default:""},format:Function},computed:{barStyle:function(){var e={};return e.width=this.percentage+"%",e.backgroundColor=this.getCurrentColor(this.percentage),e},relativeStrokeWidth:function(){return(this.strokeWidth/this.width*100).toFixed(1)},radius:function(){return"circle"===this.type||"dashboard"===this.type?parseInt(50-parseFloat(this.relativeStrokeWidth)/2,10):0},trackPath:function(){var e=this.radius,t="dashboard"===this.type;return"\n M 50 50\n m 0 "+(t?"":"-")+e+"\n a "+e+" "+e+" 0 1 1 0 "+(t?"-":"")+2*e+"\n a "+e+" "+e+" 0 1 1 0 "+(t?"":"-")+2*e+"\n "},perimeter:function(){return 2*Math.PI*this.radius},rate:function(){return"dashboard"===this.type?.75:1},strokeDashoffset:function(){var e=-1*this.perimeter*(1-this.rate)/2;return e+"px"},trailPathStyle:function(){return{strokeDasharray:this.perimeter*this.rate+"px, "+this.perimeter+"px",strokeDashoffset:this.strokeDashoffset}},circlePathStyle:function(){return{strokeDasharray:this.perimeter*this.rate*(this.percentage/100)+"px, "+this.perimeter+"px",strokeDashoffset:this.strokeDashoffset,transition:"stroke-dasharray 0.6s ease 0s, stroke 0.6s ease"}},stroke:function(){var e=void 0;if(this.color)e=this.getCurrentColor(this.percentage);else switch(this.status){case"success":e="#13ce66";break;case"exception":e="#ff4949";break;case"warning":e="#e6a23c";break;default:e="#20a0ff"}return e},iconClass:function(){return"warning"===this.status?"el-icon-warning":"line"===this.type?"success"===this.status?"el-icon-circle-check":"el-icon-circle-close":"success"===this.status?"el-icon-check":"el-icon-close"},progressTextSize:function(){return"line"===this.type?12+.4*this.strokeWidth:.111111*this.width+2},content:function(){return"function"===typeof this.format?this.format(this.percentage)||"":this.percentage+"%"}},methods:{getCurrentColor:function(e){return"function"===typeof this.color?this.color(e):"string"===typeof this.color?this.color:this.getLevelColor(e)},getLevelColor:function(e){for(var t=this.getColorArray().sort((function(e,t){return e.percentage-t.percentage})),n=0;ne)return t[n].color;return t[t.length-1].color},getColorArray:function(){var e=this.color,t=100/e.length;return e.map((function(e,n){return"string"===typeof e?{color:e,progress:(n+1)*t}:e}))}}},Sd=kd,Od=s(Sd,wd,Cd,!1,null,null,null);Od.options.__file="packages/progress/src/progress.vue";var $d=Od.exports;$d.install=function(e){e.component($d.name,$d)};var Dd=$d,Ed=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("span",{staticClass:"el-spinner"},[n("svg",{staticClass:"el-spinner-inner",style:{width:e.radius/2+"px",height:e.radius/2+"px"},attrs:{viewBox:"0 0 50 50"}},[n("circle",{staticClass:"path",attrs:{cx:"25",cy:"25",r:"20",fill:"none",stroke:e.strokeColor,"stroke-width":e.strokeWidth}})])])},Td=[];Ed._withStripped=!0;var Pd={name:"ElSpinner",props:{type:String,radius:{type:Number,default:100},strokeWidth:{type:Number,default:5},strokeColor:{type:String,default:"#efefef"}}},Md=Pd,Id=s(Md,Ed,Td,!1,null,null,null);Id.options.__file="packages/spinner/src/spinner.vue";var Nd=Id.exports;Nd.install=function(e){e.component(Nd.name,Nd)};var jd=Nd,Ad=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-message-fade"},on:{"after-leave":e.handleAfterLeave}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],class:["el-message",e.type&&!e.iconClass?"el-message--"+e.type:"",e.center?"is-center":"",e.showClose?"is-closable":"",e.customClass],style:e.positionStyle,attrs:{role:"alert"},on:{mouseenter:e.clearTimer,mouseleave:e.startTimer}},[e.iconClass?n("i",{class:e.iconClass}):n("i",{class:e.typeClass}),e._t("default",[e.dangerouslyUseHTMLString?n("p",{staticClass:"el-message__content",domProps:{innerHTML:e._s(e.message)}}):n("p",{staticClass:"el-message__content"},[e._v(e._s(e.message))])]),e.showClose?n("i",{staticClass:"el-message__closeBtn el-icon-close",on:{click:e.close}}):e._e()],2)])},Fd=[];Ad._withStripped=!0;var Ld={success:"success",info:"info",warning:"warning",error:"error"},Vd={data:function(){return{visible:!1,message:"",duration:3e3,type:"info",iconClass:"",customClass:"",onClose:null,showClose:!1,closed:!1,verticalOffset:20,timer:null,dangerouslyUseHTMLString:!1,center:!1}},computed:{typeClass:function(){return this.type&&!this.iconClass?"el-message__icon el-icon-"+Ld[this.type]:""},positionStyle:function(){return{top:this.verticalOffset+"px"}}},watch:{closed:function(e){e&&(this.visible=!1)}},methods:{handleAfterLeave:function(){this.$destroy(!0),this.$el.parentNode.removeChild(this.$el)},close:function(){this.closed=!0,"function"===typeof this.onClose&&this.onClose(this)},clearTimer:function(){clearTimeout(this.timer)},startTimer:function(){var e=this;this.duration>0&&(this.timer=setTimeout((function(){e.closed||e.close()}),this.duration))},keydown:function(e){27===e.keyCode&&(this.closed||this.close())}},mounted:function(){this.startTimer(),document.addEventListener("keydown",this.keydown)},beforeDestroy:function(){document.removeEventListener("keydown",this.keydown)}},zd=Vd,Bd=s(zd,Ad,Fd,!1,null,null,null);Bd.options.__file="packages/message/src/main.vue";var Rd=Bd.exports,Hd=Wi.a.extend(Rd),Wd=void 0,qd=[],Ud=1,Yd=function e(t){if(!Wi.a.prototype.$isServer){t=t||{},"string"===typeof t&&(t={message:t});var n=t.onClose,i="message_"+Ud++;t.onClose=function(){e.close(i,n)},Wd=new Hd({data:t}),Wd.id=i,Object(ks["isVNode"])(Wd.message)&&(Wd.$slots.default=[Wd.message],Wd.message=null),Wd.$mount(),document.body.appendChild(Wd.$el);var r=t.offset||20;return qd.forEach((function(e){r+=e.$el.offsetHeight+16})),Wd.verticalOffset=r,Wd.visible=!0,Wd.$el.style.zIndex=C["PopupManager"].nextZIndex(),qd.push(Wd),Wd}};["success","warning","info","error"].forEach((function(e){Yd[e]=function(t){return"string"===typeof t&&(t={message:t}),t.type=e,Yd(t)}})),Yd.close=function(e,t){for(var n=qd.length,i=-1,r=0;rqd.length-1))for(var o=qd[i].$el.offsetHeight,a=i;a=0;e--)qd[e].close()};var Kd=Yd,Gd=Kd,Xd=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-badge"},[e._t("default"),n("transition",{attrs:{name:"el-zoom-in-center"}},[n("sup",{directives:[{name:"show",rawName:"v-show",value:!e.hidden&&(e.content||0===e.content||e.isDot),expression:"!hidden && (content || content === 0 || isDot)"}],staticClass:"el-badge__content",class:["el-badge__content--"+e.type,{"is-fixed":e.$slots.default,"is-dot":e.isDot}],domProps:{textContent:e._s(e.content)}})])],2)},Zd=[];Xd._withStripped=!0;var Jd={name:"ElBadge",props:{value:[String,Number],max:Number,isDot:Boolean,hidden:Boolean,type:{type:String,validator:function(e){return["primary","success","warning","info","danger"].indexOf(e)>-1}}},computed:{content:function(){if(!this.isDot){var e=this.value,t=this.max;return"number"===typeof e&&"number"===typeof t&&t0&&e-1this.value,n=this.allowHalf&&this.pointerAtLeftHalf&&e-.5<=this.currentValue&&e>this.currentValue;return t||n},getIconStyle:function(e){var t=this.rateDisabled?this.disabledVoidColor:this.voidColor;return{color:e<=this.currentValue?this.activeColor:t}},selectValue:function(e){this.rateDisabled||(this.allowHalf&&this.pointerAtLeftHalf?(this.$emit("input",this.currentValue),this.$emit("change",this.currentValue)):(this.$emit("input",e),this.$emit("change",e)))},handleKey:function(e){if(!this.rateDisabled){var t=this.currentValue,n=e.keyCode;38===n||39===n?(this.allowHalf?t+=.5:t+=1,e.stopPropagation(),e.preventDefault()):37!==n&&40!==n||(this.allowHalf?t-=.5:t-=1,e.stopPropagation(),e.preventDefault()),t=t<0?0:t,t=t>this.max?this.max:t,this.$emit("input",t),this.$emit("change",t)}},setCurrentValue:function(e,t){if(!this.rateDisabled){if(this.allowHalf){var n=t.target;Object(Le["hasClass"])(n,"el-rate__item")&&(n=n.querySelector(".el-rate__icon")),Object(Le["hasClass"])(n,"el-rate__decimal")&&(n=n.parentNode),this.pointerAtLeftHalf=2*t.offsetX<=n.clientWidth,this.currentValue=this.pointerAtLeftHalf?e-.5:e}else this.currentValue=e;this.hoverIndex=e}},resetCurrentValue:function(){this.rateDisabled||(this.allowHalf&&(this.pointerAtLeftHalf=this.value!==Math.floor(this.value)),this.currentValue=this.value,this.hoverIndex=-1)}},created:function(){this.value||this.$emit("input",0)}},ph=fh,mh=s(ph,uh,dh,!1,null,null,null);mh.options.__file="packages/rate/src/main.vue";var vh=mh.exports;vh.install=function(e){e.component(vh.name,vh)};var gh=vh,bh=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-steps",class:[!e.simple&&"el-steps--"+e.direction,e.simple&&"el-steps--simple"]},[e._t("default")],2)},yh=[];bh._withStripped=!0;var _h={name:"ElSteps",mixins:[O.a],props:{space:[Number,String],active:Number,direction:{type:String,default:"horizontal"},alignCenter:Boolean,simple:Boolean,finishStatus:{type:String,default:"finish"},processStatus:{type:String,default:"process"}},data:function(){return{steps:[],stepOffset:0}},methods:{getMigratingConfig:function(){return{props:{center:"center is removed."}}}},watch:{active:function(e,t){this.$emit("change",e,t)},steps:function(e){e.forEach((function(e,t){e.index=t}))}}},xh=_h,wh=s(xh,bh,yh,!1,null,null,null);wh.options.__file="packages/steps/src/steps.vue";var Ch=wh.exports;Ch.install=function(e){e.component(Ch.name,Ch)};var kh=Ch,Sh=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-step",class:[!e.isSimple&&"is-"+e.$parent.direction,e.isSimple&&"is-simple",e.isLast&&!e.space&&!e.isCenter&&"is-flex",e.isCenter&&!e.isVertical&&!e.isSimple&&"is-center"],style:e.style},[n("div",{staticClass:"el-step__head",class:"is-"+e.currentStatus},[n("div",{staticClass:"el-step__line",style:e.isLast?"":{marginRight:e.$parent.stepOffset+"px"}},[n("i",{staticClass:"el-step__line-inner",style:e.lineStyle})]),n("div",{staticClass:"el-step__icon",class:"is-"+(e.icon?"icon":"text")},["success"!==e.currentStatus&&"error"!==e.currentStatus?e._t("icon",[e.icon?n("i",{staticClass:"el-step__icon-inner",class:[e.icon]}):e._e(),e.icon||e.isSimple?e._e():n("div",{staticClass:"el-step__icon-inner"},[e._v(e._s(e.index+1))])]):n("i",{staticClass:"el-step__icon-inner is-status",class:["el-icon-"+("success"===e.currentStatus?"check":"close")]})],2)]),n("div",{staticClass:"el-step__main"},[n("div",{ref:"title",staticClass:"el-step__title",class:["is-"+e.currentStatus]},[e._t("title",[e._v(e._s(e.title))])],2),e.isSimple?n("div",{staticClass:"el-step__arrow"}):n("div",{staticClass:"el-step__description",class:["is-"+e.currentStatus]},[e._t("description",[e._v(e._s(e.description))])],2)])])},Oh=[];Sh._withStripped=!0;var $h={name:"ElStep",props:{title:String,icon:String,description:String,status:String},data:function(){return{index:-1,lineStyle:{},internalStatus:""}},beforeCreate:function(){this.$parent.steps.push(this)},beforeDestroy:function(){var e=this.$parent.steps,t=e.indexOf(this);t>=0&&e.splice(t,1)},computed:{currentStatus:function(){return this.status||this.internalStatus},prevStatus:function(){var e=this.$parent.steps[this.index-1];return e?e.currentStatus:"wait"},isCenter:function(){return this.$parent.alignCenter},isVertical:function(){return"vertical"===this.$parent.direction},isSimple:function(){return this.$parent.simple},isLast:function(){var e=this.$parent;return e.steps[e.steps.length-1]===this},stepsCount:function(){return this.$parent.steps.length},space:function(){var e=this.isSimple,t=this.$parent.space;return e?"":t},style:function(){var e={},t=this.$parent,n=t.steps.length,i="number"===typeof this.space?this.space+"px":this.space?this.space:100/(n-(this.isCenter?0:1))+"%";return e.flexBasis=i,this.isVertical?e:(this.isLast?e.maxWidth=100/this.stepsCount+"%":e.marginRight=-this.$parent.stepOffset+"px",e)}},methods:{updateStatus:function(e){var t=this.$parent.$children[this.index-1];e>this.index?this.internalStatus=this.$parent.finishStatus:e===this.index&&"error"!==this.prevStatus?this.internalStatus=this.$parent.processStatus:this.internalStatus="wait",t&&t.calcProgress(this.internalStatus)},calcProgress:function(e){var t=100,n={};n.transitionDelay=150*this.index+"ms",e===this.$parent.processStatus?(this.currentStatus,t=0):"wait"===e&&(t=0,n.transitionDelay=-150*this.index+"ms"),n.borderWidth=t&&!this.isSimple?"1px":0,"vertical"===this.$parent.direction?n.height=t+"%":n.width=t+"%",this.lineStyle=n}},mounted:function(){var e=this,t=this.$watch("index",(function(n){e.$watch("$parent.active",e.updateStatus,{immediate:!0}),e.$watch("$parent.processStatus",(function(){var t=e.$parent.active;e.updateStatus(t)}),{immediate:!0}),t()}))}},Dh=$h,Eh=s(Dh,Sh,Oh,!1,null,null,null);Eh.options.__file="packages/steps/src/step.vue";var Th=Eh.exports;Th.install=function(e){e.component(Th.name,Th)};var Ph=Th,Mh=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:e.carouselClasses,on:{mouseenter:function(t){return t.stopPropagation(),e.handleMouseEnter(t)},mouseleave:function(t){return t.stopPropagation(),e.handleMouseLeave(t)}}},[n("div",{staticClass:"el-carousel__container",style:{height:e.height}},[e.arrowDisplay?n("transition",{attrs:{name:"carousel-arrow-left"}},[n("button",{directives:[{name:"show",rawName:"v-show",value:("always"===e.arrow||e.hover)&&(e.loop||e.activeIndex>0),expression:"(arrow === 'always' || hover) && (loop || activeIndex > 0)"}],staticClass:"el-carousel__arrow el-carousel__arrow--left",attrs:{type:"button"},on:{mouseenter:function(t){e.handleButtonEnter("left")},mouseleave:e.handleButtonLeave,click:function(t){t.stopPropagation(),e.throttledArrowClick(e.activeIndex-1)}}},[n("i",{staticClass:"el-icon-arrow-left"})])]):e._e(),e.arrowDisplay?n("transition",{attrs:{name:"carousel-arrow-right"}},[n("button",{directives:[{name:"show",rawName:"v-show",value:("always"===e.arrow||e.hover)&&(e.loop||e.activeIndex0}))},carouselClasses:function(){var e=["el-carousel","el-carousel--"+this.direction];return"card"===this.type&&e.push("el-carousel--card"),e},indicatorsClasses:function(){var e=["el-carousel__indicators","el-carousel__indicators--"+this.direction];return this.hasLabel&&e.push("el-carousel__indicators--labels"),"outside"!==this.indicatorPosition&&"card"!==this.type||e.push("el-carousel__indicators--outside"),e}},watch:{items:function(e){e.length>0&&this.setActiveItem(this.initialIndex)},activeIndex:function(e,t){this.resetItemPosition(t),t>-1&&this.$emit("change",e,t)},autoplay:function(e){e?this.startTimer():this.pauseTimer()},loop:function(){this.setActiveItem(this.activeIndex)}},methods:{handleMouseEnter:function(){this.hover=!0,this.pauseTimer()},handleMouseLeave:function(){this.hover=!1,this.startTimer()},itemInStage:function(e,t){var n=this.items.length;return t===n-1&&e.inStage&&this.items[0].active||e.inStage&&this.items[t+1]&&this.items[t+1].active?"left":!!(0===t&&e.inStage&&this.items[n-1].active||e.inStage&&this.items[t-1]&&this.items[t-1].active)&&"right"},handleButtonEnter:function(e){var t=this;"vertical"!==this.direction&&this.items.forEach((function(n,i){e===t.itemInStage(n,i)&&(n.hover=!0)}))},handleButtonLeave:function(){"vertical"!==this.direction&&this.items.forEach((function(e){e.hover=!1}))},updateItems:function(){this.items=this.$children.filter((function(e){return"ElCarouselItem"===e.$options.name}))},resetItemPosition:function(e){var t=this;this.items.forEach((function(n,i){n.translateItem(i,t.activeIndex,e)}))},playSlides:function(){this.activeIndex0&&(e=this.items.indexOf(t[0]))}if(e=Number(e),isNaN(e)||e!==Math.floor(e))console.warn("[Element Warn][Carousel]index must be an integer.");else{var n=this.items.length,i=this.activeIndex;this.activeIndex=e<0?this.loop?n-1:0:e>=n?this.loop?0:n-1:e,i===this.activeIndex&&this.resetItemPosition(i)}},prev:function(){this.setActiveItem(this.activeIndex-1)},next:function(){this.setActiveItem(this.activeIndex+1)},handleIndicatorClick:function(e){this.activeIndex=e},handleIndicatorHover:function(e){"hover"===this.trigger&&e!==this.activeIndex&&(this.activeIndex=e)}},created:function(){var e=this;this.throttledArrowClick=jh()(300,!0,(function(t){e.setActiveItem(t)})),this.throttledIndicatorHover=jh()(300,(function(t){e.handleIndicatorHover(t)}))},mounted:function(){var e=this;this.updateItems(),this.$nextTick((function(){Object(ei["addResizeListener"])(e.$el,e.resetItemPosition),e.initialIndex=0&&(e.activeIndex=e.initialIndex),e.startTimer()}))},beforeDestroy:function(){this.$el&&Object(ei["removeResizeListener"])(this.$el,this.resetItemPosition),this.pauseTimer()}},Fh=Ah,Lh=s(Fh,Mh,Ih,!1,null,null,null);Lh.options.__file="packages/carousel/src/main.vue";var Vh=Lh.exports;Vh.install=function(e){e.component(Vh.name,Vh)};var zh=Vh,Bh={vertical:{offset:"offsetHeight",scroll:"scrollTop",scrollSize:"scrollHeight",size:"height",key:"vertical",axis:"Y",client:"clientY",direction:"top"},horizontal:{offset:"offsetWidth",scroll:"scrollLeft",scrollSize:"scrollWidth",size:"width",key:"horizontal",axis:"X",client:"clientX",direction:"left"}};function Rh(e){var t=e.move,n=e.size,i=e.bar,r={},o="translate"+i.axis+"("+t+"%)";return r[i.size]=n,r.transform=o,r.msTransform=o,r.webkitTransform=o,r}var Hh={name:"Bar",props:{vertical:Boolean,size:String,move:Number},computed:{bar:function(){return Bh[this.vertical?"vertical":"horizontal"]},wrap:function(){return this.$parent.wrap}},render:function(e){var t=this.size,n=this.move,i=this.bar;return e("div",{class:["el-scrollbar__bar","is-"+i.key],on:{mousedown:this.clickTrackHandler}},[e("div",{ref:"thumb",class:"el-scrollbar__thumb",on:{mousedown:this.clickThumbHandler},style:Rh({size:t,move:n,bar:i})})])},methods:{clickThumbHandler:function(e){e.ctrlKey||2===e.button||(this.startDrag(e),this[this.bar.axis]=e.currentTarget[this.bar.offset]-(e[this.bar.client]-e.currentTarget.getBoundingClientRect()[this.bar.direction]))},clickTrackHandler:function(e){var t=Math.abs(e.target.getBoundingClientRect()[this.bar.direction]-e[this.bar.client]),n=this.$refs.thumb[this.bar.offset]/2,i=100*(t-n)/this.$el[this.bar.offset];this.wrap[this.bar.scroll]=i*this.wrap[this.bar.scrollSize]/100},startDrag:function(e){e.stopImmediatePropagation(),this.cursorDown=!0,Object(Le["on"])(document,"mousemove",this.mouseMoveDocumentHandler),Object(Le["on"])(document,"mouseup",this.mouseUpDocumentHandler),document.onselectstart=function(){return!1}},mouseMoveDocumentHandler:function(e){if(!1!==this.cursorDown){var t=this[this.bar.axis];if(t){var n=-1*(this.$el.getBoundingClientRect()[this.bar.direction]-e[this.bar.client]),i=this.$refs.thumb[this.bar.offset]-t,r=100*(n-i)/this.$el[this.bar.offset];this.wrap[this.bar.scroll]=r*this.wrap[this.bar.scrollSize]/100}}},mouseUpDocumentHandler:function(e){this.cursorDown=!1,this[this.bar.axis]=0,Object(Le["off"])(document,"mousemove",this.mouseMoveDocumentHandler),document.onselectstart=null}},destroyed:function(){Object(Le["off"])(document,"mouseup",this.mouseUpDocumentHandler)}},Wh={name:"ElScrollbar",components:{Bar:Hh},props:{native:Boolean,wrapStyle:{},wrapClass:{},viewClass:{},viewStyle:{},noresize:Boolean,tag:{type:String,default:"div"}},data:function(){return{sizeWidth:"0",sizeHeight:"0",moveX:0,moveY:0}},computed:{wrap:function(){return this.$refs.wrap}},render:function(e){var t=yr()(),n=this.wrapStyle;if(t){var i="-"+t+"px",r="margin-bottom: "+i+"; margin-right: "+i+";";Array.isArray(this.wrapStyle)?(n=Object(b["toObject"])(this.wrapStyle),n.marginRight=n.marginBottom=i):"string"===typeof this.wrapStyle?n+=r:n=r}var o=e(this.tag,{class:["el-scrollbar__view",this.viewClass],style:this.viewStyle,ref:"resize"},this.$slots.default),a=e("div",{ref:"wrap",style:n,on:{scroll:this.handleScroll},class:[this.wrapClass,"el-scrollbar__wrap",t?"":"el-scrollbar__wrap--hidden-default"]},[[o]]),s=void 0;return s=this.native?[e("div",{ref:"wrap",class:[this.wrapClass,"el-scrollbar__wrap"],style:n},[[o]])]:[a,e(Hh,{attrs:{move:this.moveX,size:this.sizeWidth}}),e(Hh,{attrs:{vertical:!0,move:this.moveY,size:this.sizeHeight}})],e("div",{class:"el-scrollbar"},s)},methods:{handleScroll:function(){var e=this.wrap;this.moveY=100*e.scrollTop/e.clientHeight,this.moveX=100*e.scrollLeft/e.clientWidth},update:function(){var e=void 0,t=void 0,n=this.wrap;n&&(e=100*n.clientHeight/n.scrollHeight,t=100*n.clientWidth/n.scrollWidth,this.sizeHeight=e<100?e+"%":"",this.sizeWidth=t<100?t+"%":"")}},mounted:function(){this.native||(this.$nextTick(this.update),!this.noresize&&Object(ei["addResizeListener"])(this.$refs.resize,this.update))},beforeDestroy:function(){this.native||!this.noresize&&Object(ei["removeResizeListener"])(this.$refs.resize,this.update)},install:function(e){e.component(Wh.name,Wh)}},qh=Wh,Uh=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"show",rawName:"v-show",value:e.ready,expression:"ready"}],staticClass:"el-carousel__item",class:{"is-active":e.active,"el-carousel__item--card":"card"===e.$parent.type,"is-in-stage":e.inStage,"is-hover":e.hover,"is-animating":e.animating},style:e.itemStyle,on:{click:e.handleItemClick}},["card"===e.$parent.type?n("div",{directives:[{name:"show",rawName:"v-show",value:!e.active,expression:"!active"}],staticClass:"el-carousel__mask"}):e._e(),e._t("default")],2)},Yh=[];Uh._withStripped=!0;var Kh=.83,Gh={name:"ElCarouselItem",props:{name:String,label:{type:[String,Number],default:""}},data:function(){return{hover:!1,translate:0,scale:1,active:!1,ready:!1,inStage:!1,animating:!1}},methods:{processIndex:function(e,t,n){return 0===t&&e===n-1?-1:t===n-1&&0===e?n:e=n/2?n+1:e>t+1&&e-t>=n/2?-2:e},calcCardTranslate:function(e,t){var n=this.$parent.$el.offsetWidth;return this.inStage?n*((2-Kh)*(e-t)+1)/4:e2&&this.$parent.loop&&(e=this.processIndex(e,t,o)),"card"===i)"vertical"===r&&console.warn("[Element Warn][Carousel]vertical directionis not supported in card mode"),this.inStage=Math.round(Math.abs(e-t))<=1,this.active=e===t,this.translate=this.calcCardTranslate(e,t),this.scale=this.active?1:Kh;else{this.active=e===t;var a="vertical"===r;this.translate=this.calcTranslate(e,t,a)}this.ready=!0},handleItemClick:function(){var e=this.$parent;if(e&&"card"===e.type){var t=e.items.indexOf(this);e.setActiveItem(t)}}},computed:{parentDirection:function(){return this.$parent.direction},itemStyle:function(){var e="vertical"===this.parentDirection?"translateY":"translateX",t=e+"("+this.translate+"px) scale("+this.scale+")",n={transform:t};return Object(b["autoprefixer"])(n)}},created:function(){this.$parent&&this.$parent.updateItems()},destroyed:function(){this.$parent&&this.$parent.updateItems()}},Xh=Gh,Zh=s(Xh,Uh,Yh,!1,null,null,null);Zh.options.__file="packages/carousel/src/item.vue";var Jh=Zh.exports;Jh.install=function(e){e.component(Jh.name,Jh)};var Qh=Jh,ef=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-collapse",attrs:{role:"tablist","aria-multiselectable":"true"}},[e._t("default")],2)},tf=[];ef._withStripped=!0;var nf={name:"ElCollapse",componentName:"ElCollapse",props:{accordion:Boolean,value:{type:[Array,String,Number],default:function(){return[]}}},data:function(){return{activeNames:[].concat(this.value)}},provide:function(){return{collapse:this}},watch:{value:function(e){this.activeNames=[].concat(e)}},methods:{setActiveNames:function(e){e=[].concat(e);var t=this.accordion?e[0]:e;this.activeNames=e,this.$emit("input",t),this.$emit("change",t)},handleItemClick:function(e){if(this.accordion)this.setActiveNames(!this.activeNames[0]&&0!==this.activeNames[0]||this.activeNames[0]!==e.name?e.name:"");else{var t=this.activeNames.slice(0),n=t.indexOf(e.name);n>-1?t.splice(n,1):t.push(e.name),this.setActiveNames(t)}}},created:function(){this.$on("item-click",this.handleItemClick)}},rf=nf,of=s(rf,ef,tf,!1,null,null,null);of.options.__file="packages/collapse/src/collapse.vue";var af=of.exports;af.install=function(e){e.component(af.name,af)};var sf=af,lf=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-collapse-item",class:{"is-active":e.isActive,"is-disabled":e.disabled}},[n("div",{attrs:{role:"tab","aria-expanded":e.isActive,"aria-controls":"el-collapse-content-"+e.id,"aria-describedby":"el-collapse-content-"+e.id}},[n("div",{staticClass:"el-collapse-item__header",class:{focusing:e.focusing,"is-active":e.isActive},attrs:{role:"button",id:"el-collapse-head-"+e.id,tabindex:e.disabled?void 0:0},on:{click:e.handleHeaderClick,keyup:function(t){return"button"in t||!e._k(t.keyCode,"space",32,t.key,[" ","Spacebar"])||!e._k(t.keyCode,"enter",13,t.key,"Enter")?(t.stopPropagation(),e.handleEnterClick(t)):null},focus:e.handleFocus,blur:function(t){e.focusing=!1}}},[e._t("title",[e._v(e._s(e.title))]),n("i",{staticClass:"el-collapse-item__arrow el-icon-arrow-right",class:{"is-active":e.isActive}})],2)]),n("el-collapse-transition",[n("div",{directives:[{name:"show",rawName:"v-show",value:e.isActive,expression:"isActive"}],staticClass:"el-collapse-item__wrap",attrs:{role:"tabpanel","aria-hidden":!e.isActive,"aria-labelledby":"el-collapse-head-"+e.id,id:"el-collapse-content-"+e.id}},[n("div",{staticClass:"el-collapse-item__content"},[e._t("default")],2)])])],1)},cf=[];lf._withStripped=!0;var uf={name:"ElCollapseItem",componentName:"ElCollapseItem",mixins:[D.a],components:{ElCollapseTransition:Ye.a},data:function(){return{contentWrapStyle:{height:"auto",display:"block"},contentHeight:0,focusing:!1,isClick:!1,id:Object(b["generateId"])()}},inject:["collapse"],props:{title:String,name:{type:[String,Number],default:function(){return this._uid}},disabled:Boolean},computed:{isActive:function(){return this.collapse.activeNames.indexOf(this.name)>-1}},methods:{handleFocus:function(){var e=this;setTimeout((function(){e.isClick?e.isClick=!1:e.focusing=!0}),50)},handleHeaderClick:function(){this.disabled||(this.dispatch("ElCollapse","item-click",this),this.focusing=!1,this.isClick=!0)},handleEnterClick:function(){this.dispatch("ElCollapse","item-click",this)}}},df=uf,hf=s(df,lf,cf,!1,null,null,null);hf.options.__file="packages/collapse/src/collapse-item.vue";var ff=hf.exports;ff.install=function(e){e.component(ff.name,ff)};var pf=ff,mf=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:function(){return e.toggleDropDownVisible(!1)},expression:"() => toggleDropDownVisible(false)"}],ref:"reference",class:["el-cascader",e.realSize&&"el-cascader--"+e.realSize,{"is-disabled":e.isDisabled}],on:{mouseenter:function(t){e.inputHover=!0},mouseleave:function(t){e.inputHover=!1},click:function(){return e.toggleDropDownVisible(!e.readonly||void 0)},keydown:e.handleKeyDown}},[n("el-input",{ref:"input",class:{"is-focus":e.dropDownVisible},attrs:{size:e.realSize,placeholder:e.placeholder,readonly:e.readonly,disabled:e.isDisabled,"validate-event":!1},on:{focus:e.handleFocus,blur:e.handleBlur,input:e.handleInput},model:{value:e.multiple?e.presentText:e.inputValue,callback:function(t){e.multiple?e.presentText:e.inputValue=t},expression:"multiple ? presentText : inputValue"}},[n("template",{slot:"suffix"},[e.clearBtnVisible?n("i",{key:"clear",staticClass:"el-input__icon el-icon-circle-close",on:{click:function(t){return t.stopPropagation(),e.handleClear(t)}}}):n("i",{key:"arrow-down",class:["el-input__icon","el-icon-arrow-down",e.dropDownVisible&&"is-reverse"],on:{click:function(t){t.stopPropagation(),e.toggleDropDownVisible()}}})])],2),e.multiple?n("div",{staticClass:"el-cascader__tags"},[e._l(e.presentTags,(function(t,i){return n("el-tag",{key:t.key,attrs:{type:"info",size:e.tagSize,hit:t.hitState,closable:t.closable,"disable-transitions":""},on:{close:function(t){e.deleteTag(i)}}},[n("span",[e._v(e._s(t.text))])])})),e.filterable&&!e.isDisabled?n("input",{directives:[{name:"model",rawName:"v-model.trim",value:e.inputValue,expression:"inputValue",modifiers:{trim:!0}}],staticClass:"el-cascader__search-input",attrs:{type:"text",placeholder:e.presentTags.length?"":e.placeholder},domProps:{value:e.inputValue},on:{input:[function(t){t.target.composing||(e.inputValue=t.target.value.trim())},function(t){return e.handleInput(e.inputValue,t)}],click:function(t){t.stopPropagation(),e.toggleDropDownVisible(!0)},keydown:function(t){return"button"in t||!e._k(t.keyCode,"delete",[8,46],t.key,["Backspace","Delete","Del"])?e.handleDelete(t):null},blur:function(t){e.$forceUpdate()}}}):e._e()],2):e._e(),n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":e.handleDropdownLeave}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.dropDownVisible,expression:"dropDownVisible"}],ref:"popper",class:["el-popper","el-cascader__dropdown",e.popperClass]},[n("el-cascader-panel",{directives:[{name:"show",rawName:"v-show",value:!e.filtering,expression:"!filtering"}],ref:"panel",attrs:{options:e.options,props:e.config,border:!1,"render-label":e.$scopedSlots.default},on:{"expand-change":e.handleExpandChange,close:function(t){e.toggleDropDownVisible(!1)}},model:{value:e.checkedValue,callback:function(t){e.checkedValue=t},expression:"checkedValue"}}),e.filterable?n("el-scrollbar",{directives:[{name:"show",rawName:"v-show",value:e.filtering,expression:"filtering"}],ref:"suggestionPanel",staticClass:"el-cascader__suggestion-panel",attrs:{tag:"ul","view-class":"el-cascader__suggestion-list"},nativeOn:{keydown:function(t){return e.handleSuggestionKeyDown(t)}}},[e.suggestions.length?e._l(e.suggestions,(function(t,i){return n("li",{key:t.uid,class:["el-cascader__suggestion-item",t.checked&&"is-checked"],attrs:{tabindex:-1},on:{click:function(t){e.handleSuggestionClick(i)}}},[n("span",[e._v(e._s(t.text))]),t.checked?n("i",{staticClass:"el-icon-check"}):e._e()])})):e._t("empty",[n("li",{staticClass:"el-cascader__empty-text"},[e._v(e._s(e.t("el.cascader.noMatch")))])])],2):e._e()],1)])],1)},vf=[];mf._withStripped=!0;var gf=n(42),bf=n.n(gf),yf=n(33),_f=n.n(yf),xf=_f.a.keys,wf={expandTrigger:{newProp:"expandTrigger",type:String},changeOnSelect:{newProp:"checkStrictly",type:Boolean},hoverThreshold:{newProp:"hoverThreshold",type:Number}},Cf={props:{placement:{type:String,default:"bottom-start"},appendToBody:H.a.props.appendToBody,visibleArrow:{type:Boolean,default:!0},arrowOffset:H.a.props.arrowOffset,offset:H.a.props.offset,boundariesPadding:H.a.props.boundariesPadding,popperOptions:H.a.props.popperOptions},methods:H.a.methods,data:H.a.data,beforeDestroy:H.a.beforeDestroy},kf={medium:36,small:32,mini:28},Sf={name:"ElCascader",directives:{Clickoutside:V.a},mixins:[Cf,D.a,g.a,O.a],inject:{elForm:{default:""},elFormItem:{default:""}},components:{ElInput:m.a,ElTag:Qn.a,ElScrollbar:q.a,ElCascaderPanel:bf.a},props:{value:{},options:Array,props:Object,size:String,placeholder:{type:String,default:function(){return Object(ti["t"])("el.cascader.placeholder")}},disabled:Boolean,clearable:Boolean,filterable:Boolean,filterMethod:Function,separator:{type:String,default:" / "},showAllLevels:{type:Boolean,default:!0},collapseTags:Boolean,debounce:{type:Number,default:300},beforeFilter:{type:Function,default:function(){return function(){}}},popperClass:String},data:function(){return{dropDownVisible:!1,checkedValue:this.value||null,inputHover:!1,inputValue:null,presentText:null,presentTags:[],checkedNodes:[],filtering:!1,suggestions:[],inputInitialHeight:0,pressDeleteCount:0}},computed:{realSize:function(){var e=(this.elFormItem||{}).elFormItemSize;return this.size||e||(this.$ELEMENT||{}).size},tagSize:function(){return["small","mini"].indexOf(this.realSize)>-1?"mini":"small"},isDisabled:function(){return this.disabled||(this.elForm||{}).disabled},config:function(){var e=this.props||{},t=this.$attrs;return Object.keys(wf).forEach((function(n){var i=wf[n],r=i.newProp,o=i.type,a=t[n]||t[Object(b["kebabCase"])(n)];Object(Ot["isDef"])(n)&&!Object(Ot["isDef"])(e[r])&&(o===Boolean&&""===a&&(a=!0),e[r]=a)})),e},multiple:function(){return this.config.multiple},leafOnly:function(){return!this.config.checkStrictly},readonly:function(){return!this.filterable||this.multiple},clearBtnVisible:function(){return!(!this.clearable||this.isDisabled||this.filtering||!this.inputHover)&&(this.multiple?!!this.checkedNodes.filter((function(e){return!e.isDisabled})).length:!!this.presentText)},panel:function(){return this.$refs.panel}},watch:{disabled:function(){this.computePresentContent()},value:function(e){Object(b["isEqual"])(e,this.checkedValue)||(this.checkedValue=e,this.computePresentContent())},checkedValue:function(e){var t=this.value,n=this.dropDownVisible,i=this.config,r=i.checkStrictly,o=i.multiple;Object(b["isEqual"])(e,t)&&!Object(hh["isUndefined"])(t)||(this.computePresentContent(),o||r||!n||this.toggleDropDownVisible(!1),this.$emit("input",e),this.$emit("change",e),this.dispatch("ElFormItem","el.form.change",[e]))},options:{handler:function(){this.$nextTick(this.computePresentContent)},deep:!0},presentText:function(e){this.inputValue=e},presentTags:function(e,t){this.multiple&&(e.length||t.length)&&this.$nextTick(this.updateStyle)},filtering:function(e){this.$nextTick(this.updatePopper)}},mounted:function(){var e=this,t=this.$refs.input;t&&t.$el&&(this.inputInitialHeight=t.$el.offsetHeight||kf[this.realSize]||40),Object(b["isEmpty"])(this.value)||this.computePresentContent(),this.filterHandler=F()(this.debounce,(function(){var t=e.inputValue;if(t){var n=e.beforeFilter(t);n&&n.then?n.then(e.getSuggestions):!1!==n?e.getSuggestions():e.filtering=!1}else e.filtering=!1})),Object(ei["addResizeListener"])(this.$el,this.updateStyle)},beforeDestroy:function(){Object(ei["removeResizeListener"])(this.$el,this.updateStyle)},methods:{getMigratingConfig:function(){return{props:{"expand-trigger":"expand-trigger is removed, use `props.expandTrigger` instead.","change-on-select":"change-on-select is removed, use `props.checkStrictly` instead.","hover-threshold":"hover-threshold is removed, use `props.hoverThreshold` instead"},events:{"active-item-change":"active-item-change is renamed to expand-change"}}},toggleDropDownVisible:function(e){var t=this;if(!this.isDisabled){var n=this.dropDownVisible,i=this.$refs.input;e=Object(Ot["isDef"])(e)?e:!n,e!==n&&(this.dropDownVisible=e,e&&this.$nextTick((function(){t.updatePopper(),t.panel.scrollIntoView()})),i.$refs.input.setAttribute("aria-expanded",e),this.$emit("visible-change",e))}},handleDropdownLeave:function(){this.filtering=!1,this.inputValue=this.presentText},handleKeyDown:function(e){switch(e.keyCode){case xf.enter:this.toggleDropDownVisible();break;case xf.down:this.toggleDropDownVisible(!0),this.focusFirstNode(),e.preventDefault();break;case xf.esc:case xf.tab:this.toggleDropDownVisible(!1);break}},handleFocus:function(e){this.$emit("focus",e)},handleBlur:function(e){this.$emit("blur",e)},handleInput:function(e,t){!this.dropDownVisible&&this.toggleDropDownVisible(!0),t&&t.isComposing||(e?this.filterHandler():this.filtering=!1)},handleClear:function(){this.presentText="",this.panel.clearCheckedNodes()},handleExpandChange:function(e){this.$nextTick(this.updatePopper.bind(this)),this.$emit("expand-change",e),this.$emit("active-item-change",e)},focusFirstNode:function(){var e=this;this.$nextTick((function(){var t=e.filtering,n=e.$refs,i=n.popper,r=n.suggestionPanel,o=null;if(t&&r)o=r.$el.querySelector(".el-cascader__suggestion-item");else{var a=i.querySelector(".el-cascader-menu");o=a.querySelector('.el-cascader-node[tabindex="-1"]')}o&&(o.focus(),!t&&o.click())}))},computePresentContent:function(){var e=this;this.$nextTick((function(){e.config.multiple?(e.computePresentTags(),e.presentText=e.presentTags.length?" ":null):e.computePresentText()}))},computePresentText:function(){var e=this.checkedValue,t=this.config;if(!Object(b["isEmpty"])(e)){var n=this.panel.getNodeByValue(e);if(n&&(t.checkStrictly||n.isLeaf))return void(this.presentText=n.getText(this.showAllLevels,this.separator))}this.presentText=null},computePresentTags:function(){var e=this.isDisabled,t=this.leafOnly,n=this.showAllLevels,i=this.separator,r=this.collapseTags,o=this.getCheckedNodes(t),a=[],s=function(t){return{node:t,key:t.uid,text:t.getText(n,i),hitState:!1,closable:!e&&!t.isDisabled}};if(o.length){var l=o[0],c=o.slice(1),u=c.length;a.push(s(l)),u&&(r?a.push({key:-1,text:"+ "+u,closable:!1}):c.forEach((function(e){return a.push(s(e))})))}this.checkedNodes=o,this.presentTags=a},getSuggestions:function(){var e=this,t=this.filterMethod;Object(hh["isFunction"])(t)||(t=function(e,t){return e.text.includes(t)});var n=this.panel.getFlattedNodes(this.leafOnly).filter((function(n){return!n.isDisabled&&(n.text=n.getText(e.showAllLevels,e.separator)||"",t(n,e.inputValue))}));this.multiple?this.presentTags.forEach((function(e){e.hitState=!1})):n.forEach((function(t){t.checked=Object(b["isEqual"])(e.checkedValue,t.getValueByOption())})),this.filtering=!0,this.suggestions=n,this.$nextTick(this.updatePopper)},handleSuggestionKeyDown:function(e){var t=e.keyCode,n=e.target;switch(t){case xf.enter:n.click();break;case xf.up:var i=n.previousElementSibling;i&&i.focus();break;case xf.down:var r=n.nextElementSibling;r&&r.focus();break;case xf.esc:case xf.tab:this.toggleDropDownVisible(!1);break}},handleDelete:function(){var e=this.inputValue,t=this.pressDeleteCount,n=this.presentTags,i=n.length-1,r=n[i];this.pressDeleteCount=e?0:t+1,r&&this.pressDeleteCount&&(r.hitState?this.deleteTag(i):r.hitState=!0)},handleSuggestionClick:function(e){var t=this.multiple,n=this.suggestions[e];if(t){var i=n.checked;n.doCheck(!i),this.panel.calculateMultiCheckedValue()}else this.checkedValue=n.getValueByOption(),this.toggleDropDownVisible(!1)},deleteTag:function(e){var t=this.checkedValue,n=t[e];this.checkedValue=t.filter((function(t,n){return n!==e})),this.$emit("remove-tag",n)},updateStyle:function(){var e=this.$el,t=this.inputInitialHeight;if(!this.$isServer&&e){var n=this.$refs.suggestionPanel,i=e.querySelector(".el-input__inner");if(i){var r=e.querySelector(".el-cascader__tags"),o=null;if(n&&(o=n.$el)){var a=o.querySelector(".el-cascader__suggestion-list");a.style.minWidth=i.offsetWidth+"px"}if(r){var s=r.offsetHeight,l=Math.max(s+6,t)+"px";i.style.height=l,this.updatePopper()}}}},getCheckedNodes:function(e){return this.panel.getCheckedNodes(e)}}},Of=Sf,$f=s(Of,mf,vf,!1,null,null,null);$f.options.__file="packages/cascader/src/cascader.vue";var Df=$f.exports;Df.install=function(e){e.component(Df.name,Df)};var Ef=Df,Tf=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{directives:[{name:"clickoutside",rawName:"v-clickoutside",value:e.hide,expression:"hide"}],class:["el-color-picker",e.colorDisabled?"is-disabled":"",e.colorSize?"el-color-picker--"+e.colorSize:""]},[e.colorDisabled?n("div",{staticClass:"el-color-picker__mask"}):e._e(),n("div",{staticClass:"el-color-picker__trigger",on:{click:e.handleTrigger}},[n("span",{staticClass:"el-color-picker__color",class:{"is-alpha":e.showAlpha}},[n("span",{staticClass:"el-color-picker__color-inner",style:{backgroundColor:e.displayedColor}}),e.value||e.showPanelColor?e._e():n("span",{staticClass:"el-color-picker__empty el-icon-close"})]),n("span",{directives:[{name:"show",rawName:"v-show",value:e.value||e.showPanelColor,expression:"value || showPanelColor"}],staticClass:"el-color-picker__icon el-icon-arrow-down"})]),n("picker-dropdown",{ref:"dropdown",class:["el-color-picker__panel",e.popperClass||""],attrs:{color:e.color,"show-alpha":e.showAlpha,predefine:e.predefine},on:{pick:e.confirmValue,clear:e.clearValue},model:{value:e.showPicker,callback:function(t){e.showPicker=t},expression:"showPicker"}})],1)},Pf=[];Tf._withStripped=!0;var Mf="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function If(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var Nf=function(e,t,n){return[e,t*n/((e=(2-t)*n)<1?e:2-e)||0,e/2]},jf=function(e){return"string"===typeof e&&-1!==e.indexOf(".")&&1===parseFloat(e)},Af=function(e){return"string"===typeof e&&-1!==e.indexOf("%")},Ff=function(e,t){jf(e)&&(e="100%");var n=Af(e);return e=Math.min(t,Math.max(0,parseFloat(e))),n&&(e=parseInt(e*t,10)/100),Math.abs(e-t)<1e-6?1:e%t/parseFloat(t)},Lf={10:"A",11:"B",12:"C",13:"D",14:"E",15:"F"},Vf=function(e){var t=e.r,n=e.g,i=e.b,r=function(e){e=Math.min(Math.round(e),255);var t=Math.floor(e/16),n=e%16;return""+(Lf[t]||t)+(Lf[n]||n)};return isNaN(t)||isNaN(n)||isNaN(i)?"":"#"+r(t)+r(n)+r(i)},zf={A:10,B:11,C:12,D:13,E:14,F:15},Bf=function(e){return 2===e.length?16*(zf[e[0].toUpperCase()]||+e[0])+(zf[e[1].toUpperCase()]||+e[1]):zf[e[1].toUpperCase()]||+e[1]},Rf=function(e,t,n){t/=100,n/=100;var i=t,r=Math.max(n,.01),o=void 0,a=void 0;return n*=2,t*=n<=1?n:2-n,i*=r<=1?r:2-r,a=(n+t)/2,o=0===n?2*i/(r+i):2*t/(n+t),{h:e,s:100*o,v:100*a}},Hf=function(e,t,n){e=Ff(e,255),t=Ff(t,255),n=Ff(n,255);var i=Math.max(e,t,n),r=Math.min(e,t,n),o=void 0,a=void 0,s=i,l=i-r;if(a=0===i?0:l/i,i===r)o=0;else{switch(i){case e:o=(t-n)/l+(t2?parseFloat(e):parseInt(e,10)}));if(4===i.length?this._alpha=Math.floor(100*parseFloat(i[3])):3===i.length&&(this._alpha=100),i.length>=3){var r=Rf(i[0],i[1],i[2]),o=r.h,a=r.s,s=r.v;n(o,a,s)}}else if(-1!==e.indexOf("hsv")){var l=e.replace(/hsva|hsv|\(|\)/gm,"").split(/\s|,/g).filter((function(e){return""!==e})).map((function(e,t){return t>2?parseFloat(e):parseInt(e,10)}));4===l.length?this._alpha=Math.floor(100*parseFloat(l[3])):3===l.length&&(this._alpha=100),l.length>=3&&n(l[0],l[1],l[2])}else if(-1!==e.indexOf("rgb")){var c=e.replace(/rgba|rgb|\(|\)/gm,"").split(/\s|,/g).filter((function(e){return""!==e})).map((function(e,t){return t>2?parseFloat(e):parseInt(e,10)}));if(4===c.length?this._alpha=Math.floor(100*parseFloat(c[3])):3===c.length&&(this._alpha=100),c.length>=3){var u=Hf(c[0],c[1],c[2]),d=u.h,h=u.s,f=u.v;n(d,h,f)}}else if(-1!==e.indexOf("#")){var p=e.replace("#","").trim();if(!/^(?:[0-9a-fA-F]{3}){1,2}$/.test(p))return;var m=void 0,v=void 0,g=void 0;3===p.length?(m=Bf(p[0]+p[0]),v=Bf(p[1]+p[1]),g=Bf(p[2]+p[2])):6!==p.length&&8!==p.length||(m=Bf(p.substring(0,2)),v=Bf(p.substring(2,4)),g=Bf(p.substring(4,6))),8===p.length?this._alpha=Math.floor(Bf(p.substring(6))/255*100):3!==p.length&&6!==p.length||(this._alpha=100);var b=Hf(m,v,g),y=b.h,_=b.s,x=b.v;n(y,_,x)}},e.prototype.compare=function(e){return Math.abs(e._hue-this._hue)<2&&Math.abs(e._saturation-this._saturation)<1&&Math.abs(e._value-this._value)<1&&Math.abs(e._alpha-this._alpha)<1},e.prototype.doOnChange=function(){var e=this._hue,t=this._saturation,n=this._value,i=this._alpha,r=this.format;if(this.enableAlpha)switch(r){case"hsl":var o=Nf(e,t/100,n/100);this.value="hsla("+e+", "+Math.round(100*o[1])+"%, "+Math.round(100*o[2])+"%, "+i/100+")";break;case"hsv":this.value="hsva("+e+", "+Math.round(t)+"%, "+Math.round(n)+"%, "+i/100+")";break;default:var a=Wf(e,t,n),s=a.r,l=a.g,c=a.b;this.value="rgba("+s+", "+l+", "+c+", "+i/100+")"}else switch(r){case"hsl":var u=Nf(e,t/100,n/100);this.value="hsl("+e+", "+Math.round(100*u[1])+"%, "+Math.round(100*u[2])+"%)";break;case"hsv":this.value="hsv("+e+", "+Math.round(t)+"%, "+Math.round(n)+"%)";break;case"rgb":var d=Wf(e,t,n),h=d.r,f=d.g,p=d.b;this.value="rgb("+h+", "+f+", "+p+")";break;default:this.value=Vf(Wf(e,t,n))}},e}(),Uf=qf,Yf=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-zoom-in-top"},on:{"after-leave":e.doDestroy}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.showPopper,expression:"showPopper"}],staticClass:"el-color-dropdown"},[n("div",{staticClass:"el-color-dropdown__main-wrapper"},[n("hue-slider",{ref:"hue",staticStyle:{float:"right"},attrs:{color:e.color,vertical:""}}),n("sv-panel",{ref:"sl",attrs:{color:e.color}})],1),e.showAlpha?n("alpha-slider",{ref:"alpha",attrs:{color:e.color}}):e._e(),e.predefine?n("predefine",{attrs:{color:e.color,colors:e.predefine}}):e._e(),n("div",{staticClass:"el-color-dropdown__btns"},[n("span",{staticClass:"el-color-dropdown__value"},[n("el-input",{attrs:{"validate-event":!1,size:"mini"},on:{blur:e.handleConfirm},nativeOn:{keyup:function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.handleConfirm(t):null}},model:{value:e.customInput,callback:function(t){e.customInput=t},expression:"customInput"}})],1),n("el-button",{staticClass:"el-color-dropdown__link-btn",attrs:{size:"mini",type:"text"},on:{click:function(t){e.$emit("clear")}}},[e._v("\n "+e._s(e.t("el.colorpicker.clear"))+"\n ")]),n("el-button",{staticClass:"el-color-dropdown__btn",attrs:{plain:"",size:"mini"},on:{click:e.confirmValue}},[e._v("\n "+e._s(e.t("el.colorpicker.confirm"))+"\n ")])],1)],1)])},Kf=[];Yf._withStripped=!0;var Gf=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-color-svpanel",style:{backgroundColor:e.background}},[n("div",{staticClass:"el-color-svpanel__white"}),n("div",{staticClass:"el-color-svpanel__black"}),n("div",{staticClass:"el-color-svpanel__cursor",style:{top:e.cursorTop+"px",left:e.cursorLeft+"px"}},[n("div")])])},Xf=[];Gf._withStripped=!0;var Zf=!1,Jf=function(e,t){if(!Wi.a.prototype.$isServer){var n=function(e){t.drag&&t.drag(e)},i=function e(i){document.removeEventListener("mousemove",n),document.removeEventListener("mouseup",e),document.onselectstart=null,document.ondragstart=null,Zf=!1,t.end&&t.end(i)};e.addEventListener("mousedown",(function(e){Zf||(document.onselectstart=function(){return!1},document.ondragstart=function(){return!1},document.addEventListener("mousemove",n),document.addEventListener("mouseup",i),Zf=!0,t.start&&t.start(e))}))}},Qf={name:"el-sl-panel",props:{color:{required:!0}},computed:{colorValue:function(){var e=this.color.get("hue"),t=this.color.get("value");return{hue:e,value:t}}},watch:{colorValue:function(){this.update()}},methods:{update:function(){var e=this.color.get("saturation"),t=this.color.get("value"),n=this.$el,i=n.clientWidth,r=n.clientHeight;this.cursorLeft=e*i/100,this.cursorTop=(100-t)*r/100,this.background="hsl("+this.color.get("hue")+", 100%, 50%)"},handleDrag:function(e){var t=this.$el,n=t.getBoundingClientRect(),i=e.clientX-n.left,r=e.clientY-n.top;i=Math.max(0,i),i=Math.min(i,n.width),r=Math.max(0,r),r=Math.min(r,n.height),this.cursorLeft=i,this.cursorTop=r,this.color.set({saturation:i/n.width*100,value:100-r/n.height*100})}},mounted:function(){var e=this;Jf(this.$el,{drag:function(t){e.handleDrag(t)},end:function(t){e.handleDrag(t)}}),this.update()},data:function(){return{cursorTop:0,cursorLeft:0,background:"hsl(0, 100%, 50%)"}}},ep=Qf,tp=s(ep,Gf,Xf,!1,null,null,null);tp.options.__file="packages/color-picker/src/components/sv-panel.vue";var np=tp.exports,ip=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-color-hue-slider",class:{"is-vertical":e.vertical}},[n("div",{ref:"bar",staticClass:"el-color-hue-slider__bar",on:{click:e.handleClick}}),n("div",{ref:"thumb",staticClass:"el-color-hue-slider__thumb",style:{left:e.thumbLeft+"px",top:e.thumbTop+"px"}})])},rp=[];ip._withStripped=!0;var op={name:"el-color-hue-slider",props:{color:{required:!0},vertical:Boolean},data:function(){return{thumbLeft:0,thumbTop:0}},computed:{hueValue:function(){var e=this.color.get("hue");return e}},watch:{hueValue:function(){this.update()}},methods:{handleClick:function(e){var t=this.$refs.thumb,n=e.target;n!==t&&this.handleDrag(e)},handleDrag:function(e){var t=this.$el.getBoundingClientRect(),n=this.$refs.thumb,i=void 0;if(this.vertical){var r=e.clientY-t.top;r=Math.min(r,t.height-n.offsetHeight/2),r=Math.max(n.offsetHeight/2,r),i=Math.round((r-n.offsetHeight/2)/(t.height-n.offsetHeight)*360)}else{var o=e.clientX-t.left;o=Math.min(o,t.width-n.offsetWidth/2),o=Math.max(n.offsetWidth/2,o),i=Math.round((o-n.offsetWidth/2)/(t.width-n.offsetWidth)*360)}this.color.set("hue",i)},getThumbLeft:function(){if(this.vertical)return 0;var e=this.$el,t=this.color.get("hue");if(!e)return 0;var n=this.$refs.thumb;return Math.round(t*(e.offsetWidth-n.offsetWidth/2)/360)},getThumbTop:function(){if(!this.vertical)return 0;var e=this.$el,t=this.color.get("hue");if(!e)return 0;var n=this.$refs.thumb;return Math.round(t*(e.offsetHeight-n.offsetHeight/2)/360)},update:function(){this.thumbLeft=this.getThumbLeft(),this.thumbTop=this.getThumbTop()}},mounted:function(){var e=this,t=this.$refs,n=t.bar,i=t.thumb,r={drag:function(t){e.handleDrag(t)},end:function(t){e.handleDrag(t)}};Jf(n,r),Jf(i,r),this.update()}},ap=op,sp=s(ap,ip,rp,!1,null,null,null);sp.options.__file="packages/color-picker/src/components/hue-slider.vue";var lp=sp.exports,cp=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-color-alpha-slider",class:{"is-vertical":e.vertical}},[n("div",{ref:"bar",staticClass:"el-color-alpha-slider__bar",style:{background:e.background},on:{click:e.handleClick}}),n("div",{ref:"thumb",staticClass:"el-color-alpha-slider__thumb",style:{left:e.thumbLeft+"px",top:e.thumbTop+"px"}})])},up=[];cp._withStripped=!0;var dp={name:"el-color-alpha-slider",props:{color:{required:!0},vertical:Boolean},watch:{"color._alpha":function(){this.update()},"color.value":function(){this.update()}},methods:{handleClick:function(e){var t=this.$refs.thumb,n=e.target;n!==t&&this.handleDrag(e)},handleDrag:function(e){var t=this.$el.getBoundingClientRect(),n=this.$refs.thumb;if(this.vertical){var i=e.clientY-t.top;i=Math.max(n.offsetHeight/2,i),i=Math.min(i,t.height-n.offsetHeight/2),this.color.set("alpha",Math.round((i-n.offsetHeight/2)/(t.height-n.offsetHeight)*100))}else{var r=e.clientX-t.left;r=Math.max(n.offsetWidth/2,r),r=Math.min(r,t.width-n.offsetWidth/2),this.color.set("alpha",Math.round((r-n.offsetWidth/2)/(t.width-n.offsetWidth)*100))}},getThumbLeft:function(){if(this.vertical)return 0;var e=this.$el,t=this.color._alpha;if(!e)return 0;var n=this.$refs.thumb;return Math.round(t*(e.offsetWidth-n.offsetWidth/2)/100)},getThumbTop:function(){if(!this.vertical)return 0;var e=this.$el,t=this.color._alpha;if(!e)return 0;var n=this.$refs.thumb;return Math.round(t*(e.offsetHeight-n.offsetHeight/2)/100)},getBackground:function(){if(this.color&&this.color.value){var e=this.color.toRgb(),t=e.r,n=e.g,i=e.b;return"linear-gradient(to right, rgba("+t+", "+n+", "+i+", 0) 0%, rgba("+t+", "+n+", "+i+", 1) 100%)"}return null},update:function(){this.thumbLeft=this.getThumbLeft(),this.thumbTop=this.getThumbTop(),this.background=this.getBackground()}},data:function(){return{thumbLeft:0,thumbTop:0,background:null}},mounted:function(){var e=this,t=this.$refs,n=t.bar,i=t.thumb,r={drag:function(t){e.handleDrag(t)},end:function(t){e.handleDrag(t)}};Jf(n,r),Jf(i,r),this.update()}},hp=dp,fp=s(hp,cp,up,!1,null,null,null);fp.options.__file="packages/color-picker/src/components/alpha-slider.vue";var pp=fp.exports,mp=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-color-predefine"},[n("div",{staticClass:"el-color-predefine__colors"},e._l(e.rgbaColors,(function(t,i){return n("div",{key:e.colors[i],staticClass:"el-color-predefine__color-selector",class:{selected:t.selected,"is-alpha":t._alpha<100},on:{click:function(t){e.handleSelect(i)}}},[n("div",{style:{"background-color":t.value}})])})),0)])},vp=[];mp._withStripped=!0;var gp={props:{colors:{type:Array,required:!0},color:{required:!0}},data:function(){return{rgbaColors:this.parseColors(this.colors,this.color)}},methods:{handleSelect:function(e){this.color.fromString(this.colors[e])},parseColors:function(e,t){return e.map((function(e){var n=new Uf;return n.enableAlpha=!0,n.format="rgba",n.fromString(e),n.selected=n.value===t.value,n}))}},watch:{"$parent.currentColor":function(e){var t=new Uf;t.fromString(e),this.rgbaColors.forEach((function(e){e.selected=t.compare(e)}))},colors:function(e){this.rgbaColors=this.parseColors(e,this.color)},color:function(e){this.rgbaColors=this.parseColors(this.colors,e)}}},bp=gp,yp=s(bp,mp,vp,!1,null,null,null);yp.options.__file="packages/color-picker/src/components/predefine.vue";var _p=yp.exports,xp={name:"el-color-picker-dropdown",mixins:[H.a,g.a],components:{SvPanel:np,HueSlider:lp,AlphaSlider:pp,ElInput:m.a,ElButton:ae.a,Predefine:_p},props:{color:{required:!0},showAlpha:Boolean,predefine:Array},data:function(){return{customInput:""}},computed:{currentColor:function(){var e=this.$parent;return e.value||e.showPanelColor?e.color.value:""}},methods:{confirmValue:function(){this.$emit("pick")},handleConfirm:function(){this.color.fromString(this.customInput)}},mounted:function(){this.$parent.popperElm=this.popperElm=this.$el,this.referenceElm=this.$parent.$el},watch:{showPopper:function(e){var t=this;!0===e&&this.$nextTick((function(){var e=t.$refs,n=e.sl,i=e.hue,r=e.alpha;n&&n.update(),i&&i.update(),r&&r.update()}))},currentColor:{immediate:!0,handler:function(e){this.customInput=e}}}},wp=xp,Cp=s(wp,Yf,Kf,!1,null,null,null);Cp.options.__file="packages/color-picker/src/components/picker-dropdown.vue";var kp=Cp.exports,Sp={name:"ElColorPicker",mixins:[D.a],props:{value:String,showAlpha:Boolean,colorFormat:String,disabled:Boolean,size:String,popperClass:String,predefine:Array},inject:{elForm:{default:""},elFormItem:{default:""}},directives:{Clickoutside:V.a},computed:{displayedColor:function(){return this.value||this.showPanelColor?this.displayedRgb(this.color,this.showAlpha):"transparent"},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},colorSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},colorDisabled:function(){return this.disabled||(this.elForm||{}).disabled}},watch:{value:function(e){e?e&&e!==this.color.value&&this.color.fromString(e):this.showPanelColor=!1},color:{deep:!0,handler:function(){this.showPanelColor=!0}},displayedColor:function(e){if(this.showPicker){var t=new Uf({enableAlpha:this.showAlpha,format:this.colorFormat});t.fromString(this.value);var n=this.displayedRgb(t,this.showAlpha);e!==n&&this.$emit("active-change",e)}}},methods:{handleTrigger:function(){this.colorDisabled||(this.showPicker=!this.showPicker)},confirmValue:function(){var e=this.color.value;this.$emit("input",e),this.$emit("change",e),this.dispatch("ElFormItem","el.form.change",e),this.showPicker=!1},clearValue:function(){this.$emit("input",null),this.$emit("change",null),null!==this.value&&this.dispatch("ElFormItem","el.form.change",null),this.showPanelColor=!1,this.showPicker=!1,this.resetColor()},hide:function(){this.showPicker=!1,this.resetColor()},resetColor:function(){var e=this;this.$nextTick((function(t){e.value?e.color.fromString(e.value):e.showPanelColor=!1}))},displayedRgb:function(e,t){if(!(e instanceof Uf))throw Error("color should be instance of Color Class");var n=e.toRgb(),i=n.r,r=n.g,o=n.b;return t?"rgba("+i+", "+r+", "+o+", "+e.get("alpha")/100+")":"rgb("+i+", "+r+", "+o+")"}},mounted:function(){var e=this.value;e&&this.color.fromString(e),this.popperElm=this.$refs.dropdown.$el},data:function(){var e=new Uf({enableAlpha:this.showAlpha,format:this.colorFormat});return{color:e,showPicker:!1,showPanelColor:!1}},components:{PickerDropdown:kp}},Op=Sp,$p=s(Op,Tf,Pf,!1,null,null,null);$p.options.__file="packages/color-picker/src/main.vue";var Dp=$p.exports;Dp.install=function(e){e.component(Dp.name,Dp)};var Ep=Dp,Tp=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-transfer"},[n("transfer-panel",e._b({ref:"leftPanel",attrs:{data:e.sourceData,title:e.titles[0]||e.t("el.transfer.titles.0"),"default-checked":e.leftDefaultChecked,placeholder:e.filterPlaceholder||e.t("el.transfer.filterPlaceholder")},on:{"checked-change":e.onSourceCheckedChange}},"transfer-panel",e.$props,!1),[e._t("left-footer")],2),n("div",{staticClass:"el-transfer__buttons"},[n("el-button",{class:["el-transfer__button",e.hasButtonTexts?"is-with-texts":""],attrs:{type:"primary",disabled:0===e.rightChecked.length},nativeOn:{click:function(t){return e.addToLeft(t)}}},[n("i",{staticClass:"el-icon-arrow-left"}),void 0!==e.buttonTexts[0]?n("span",[e._v(e._s(e.buttonTexts[0]))]):e._e()]),n("el-button",{class:["el-transfer__button",e.hasButtonTexts?"is-with-texts":""],attrs:{type:"primary",disabled:0===e.leftChecked.length},nativeOn:{click:function(t){return e.addToRight(t)}}},[void 0!==e.buttonTexts[1]?n("span",[e._v(e._s(e.buttonTexts[1]))]):e._e(),n("i",{staticClass:"el-icon-arrow-right"})])],1),n("transfer-panel",e._b({ref:"rightPanel",attrs:{data:e.targetData,title:e.titles[1]||e.t("el.transfer.titles.1"),"default-checked":e.rightDefaultChecked,placeholder:e.filterPlaceholder||e.t("el.transfer.filterPlaceholder")},on:{"checked-change":e.onTargetCheckedChange}},"transfer-panel",e.$props,!1),[e._t("right-footer")],2)],1)},Pp=[];Tp._withStripped=!0;var Mp=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-transfer-panel"},[n("p",{staticClass:"el-transfer-panel__header"},[n("el-checkbox",{attrs:{indeterminate:e.isIndeterminate},on:{change:e.handleAllCheckedChange},model:{value:e.allChecked,callback:function(t){e.allChecked=t},expression:"allChecked"}},[e._v("\n "+e._s(e.title)+"\n "),n("span",[e._v(e._s(e.checkedSummary))])])],1),n("div",{class:["el-transfer-panel__body",e.hasFooter?"is-with-footer":""]},[e.filterable?n("el-input",{staticClass:"el-transfer-panel__filter",attrs:{size:"small",placeholder:e.placeholder},nativeOn:{mouseenter:function(t){e.inputHover=!0},mouseleave:function(t){e.inputHover=!1}},model:{value:e.query,callback:function(t){e.query=t},expression:"query"}},[n("i",{class:["el-input__icon","el-icon-"+e.inputIcon],attrs:{slot:"prefix"},on:{click:e.clearQuery},slot:"prefix"})]):e._e(),n("el-checkbox-group",{directives:[{name:"show",rawName:"v-show",value:!e.hasNoMatch&&e.data.length>0,expression:"!hasNoMatch && data.length > 0"}],staticClass:"el-transfer-panel__list",class:{"is-filterable":e.filterable},model:{value:e.checked,callback:function(t){e.checked=t},expression:"checked"}},e._l(e.filteredData,(function(t){return n("el-checkbox",{key:t[e.keyProp],staticClass:"el-transfer-panel__item",attrs:{label:t[e.keyProp],disabled:t[e.disabledProp]}},[n("option-content",{attrs:{option:t}})],1)})),1),n("p",{directives:[{name:"show",rawName:"v-show",value:e.hasNoMatch,expression:"hasNoMatch"}],staticClass:"el-transfer-panel__empty"},[e._v(e._s(e.t("el.transfer.noMatch")))]),n("p",{directives:[{name:"show",rawName:"v-show",value:0===e.data.length&&!e.hasNoMatch,expression:"data.length === 0 && !hasNoMatch"}],staticClass:"el-transfer-panel__empty"},[e._v(e._s(e.t("el.transfer.noData")))])],1),e.hasFooter?n("p",{staticClass:"el-transfer-panel__footer"},[e._t("default")],2):e._e()])},Ip=[];Mp._withStripped=!0;var Np={mixins:[g.a],name:"ElTransferPanel",componentName:"ElTransferPanel",components:{ElCheckboxGroup:Mr.a,ElCheckbox:Ai.a,ElInput:m.a,OptionContent:{props:{option:Object},render:function(e){var t=function e(t){return"ElTransferPanel"===t.$options.componentName?t:t.$parent?e(t.$parent):t},n=t(this),i=n.$parent||n;return n.renderContent?n.renderContent(e,this.option):i.$scopedSlots.default?i.$scopedSlots.default({option:this.option}):e("span",[this.option[n.labelProp]||this.option[n.keyProp]])}}},props:{data:{type:Array,default:function(){return[]}},renderContent:Function,placeholder:String,title:String,filterable:Boolean,format:Object,filterMethod:Function,defaultChecked:Array,props:Object},data:function(){return{checked:[],allChecked:!1,query:"",inputHover:!1,checkChangeByUser:!0}},watch:{checked:function(e,t){if(this.updateAllChecked(),this.checkChangeByUser){var n=e.concat(t).filter((function(n){return-1===e.indexOf(n)||-1===t.indexOf(n)}));this.$emit("checked-change",e,n)}else this.$emit("checked-change",e),this.checkChangeByUser=!0},data:function(){var e=this,t=[],n=this.filteredData.map((function(t){return t[e.keyProp]}));this.checked.forEach((function(e){n.indexOf(e)>-1&&t.push(e)})),this.checkChangeByUser=!1,this.checked=t},checkableData:function(){this.updateAllChecked()},defaultChecked:{immediate:!0,handler:function(e,t){var n=this;if(!t||e.length!==t.length||!e.every((function(e){return t.indexOf(e)>-1}))){var i=[],r=this.checkableData.map((function(e){return e[n.keyProp]}));e.forEach((function(e){r.indexOf(e)>-1&&i.push(e)})),this.checkChangeByUser=!1,this.checked=i}}}},computed:{filteredData:function(){var e=this;return this.data.filter((function(t){if("function"===typeof e.filterMethod)return e.filterMethod(e.query,t);var n=t[e.labelProp]||t[e.keyProp].toString();return n.toLowerCase().indexOf(e.query.toLowerCase())>-1}))},checkableData:function(){var e=this;return this.filteredData.filter((function(t){return!t[e.disabledProp]}))},checkedSummary:function(){var e=this.checked.length,t=this.data.length,n=this.format,i=n.noChecked,r=n.hasChecked;return i&&r?e>0?r.replace(/\${checked}/g,e).replace(/\${total}/g,t):i.replace(/\${total}/g,t):e+"/"+t},isIndeterminate:function(){var e=this.checked.length;return e>0&&e0&&0===this.filteredData.length},inputIcon:function(){return this.query.length>0&&this.inputHover?"circle-close":"search"},labelProp:function(){return this.props.label||"label"},keyProp:function(){return this.props.key||"key"},disabledProp:function(){return this.props.disabled||"disabled"},hasFooter:function(){return!!this.$slots.default}},methods:{updateAllChecked:function(){var e=this,t=this.checkableData.map((function(t){return t[e.keyProp]}));this.allChecked=t.length>0&&t.every((function(t){return e.checked.indexOf(t)>-1}))},handleAllCheckedChange:function(e){var t=this;this.checked=e?this.checkableData.map((function(e){return e[t.keyProp]})):[]},clearQuery:function(){"circle-close"===this.inputIcon&&(this.query="")}}},jp=Np,Ap=s(jp,Mp,Ip,!1,null,null,null);Ap.options.__file="packages/transfer/src/transfer-panel.vue";var Fp=Ap.exports,Lp={name:"ElTransfer",mixins:[D.a,g.a,O.a],components:{TransferPanel:Fp,ElButton:ae.a},props:{data:{type:Array,default:function(){return[]}},titles:{type:Array,default:function(){return[]}},buttonTexts:{type:Array,default:function(){return[]}},filterPlaceholder:{type:String,default:""},filterMethod:Function,leftDefaultChecked:{type:Array,default:function(){return[]}},rightDefaultChecked:{type:Array,default:function(){return[]}},renderContent:Function,value:{type:Array,default:function(){return[]}},format:{type:Object,default:function(){return{}}},filterable:Boolean,props:{type:Object,default:function(){return{label:"label",key:"key",disabled:"disabled"}}},targetOrder:{type:String,default:"original"}},data:function(){return{leftChecked:[],rightChecked:[]}},computed:{dataObj:function(){var e=this.props.key;return this.data.reduce((function(t,n){return(t[n[e]]=n)&&t}),{})},sourceData:function(){var e=this;return this.data.filter((function(t){return-1===e.value.indexOf(t[e.props.key])}))},targetData:function(){var e=this;return"original"===this.targetOrder?this.data.filter((function(t){return e.value.indexOf(t[e.props.key])>-1})):this.value.reduce((function(t,n){var i=e.dataObj[n];return i&&t.push(i),t}),[])},hasButtonTexts:function(){return 2===this.buttonTexts.length}},watch:{value:function(e){this.dispatch("ElFormItem","el.form.change",e)}},methods:{getMigratingConfig:function(){return{props:{"footer-format":"footer-format is renamed to format."}}},onSourceCheckedChange:function(e,t){this.leftChecked=e,void 0!==t&&this.$emit("left-check-change",e,t)},onTargetCheckedChange:function(e,t){this.rightChecked=e,void 0!==t&&this.$emit("right-check-change",e,t)},addToLeft:function(){var e=this.value.slice();this.rightChecked.forEach((function(t){var n=e.indexOf(t);n>-1&&e.splice(n,1)})),this.$emit("input",e),this.$emit("change",e,"left",this.rightChecked)},addToRight:function(){var e=this,t=this.value.slice(),n=[],i=this.props.key;this.data.forEach((function(t){var r=t[i];e.leftChecked.indexOf(r)>-1&&-1===e.value.indexOf(r)&&n.push(r)})),t="unshift"===this.targetOrder?n.concat(t):t.concat(n),this.$emit("input",t),this.$emit("change",t,"right",this.leftChecked)},clearQuery:function(e){"left"===e?this.$refs.leftPanel.query="":"right"===e&&(this.$refs.rightPanel.query="")}}},Vp=Lp,zp=s(Vp,Tp,Pp,!1,null,null,null);zp.options.__file="packages/transfer/src/main.vue";var Bp=zp.exports;Bp.install=function(e){e.component(Bp.name,Bp)};var Rp=Bp,Hp=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("section",{staticClass:"el-container",class:{"is-vertical":e.isVertical}},[e._t("default")],2)},Wp=[];Hp._withStripped=!0;var qp={name:"ElContainer",componentName:"ElContainer",props:{direction:String},computed:{isVertical:function(){return"vertical"===this.direction||"horizontal"!==this.direction&&(!(!this.$slots||!this.$slots.default)&&this.$slots.default.some((function(e){var t=e.componentOptions&&e.componentOptions.tag;return"el-header"===t||"el-footer"===t})))}}},Up=qp,Yp=s(Up,Hp,Wp,!1,null,null,null);Yp.options.__file="packages/container/src/main.vue";var Kp=Yp.exports;Kp.install=function(e){e.component(Kp.name,Kp)};var Gp=Kp,Xp=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("header",{staticClass:"el-header",style:{height:e.height}},[e._t("default")],2)},Zp=[];Xp._withStripped=!0;var Jp={name:"ElHeader",componentName:"ElHeader",props:{height:{type:String,default:"60px"}}},Qp=Jp,em=s(Qp,Xp,Zp,!1,null,null,null);em.options.__file="packages/header/src/main.vue";var tm=em.exports;tm.install=function(e){e.component(tm.name,tm)};var nm=tm,im=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("aside",{staticClass:"el-aside",style:{width:e.width}},[e._t("default")],2)},rm=[];im._withStripped=!0;var om={name:"ElAside",componentName:"ElAside",props:{width:{type:String,default:"300px"}}},am=om,sm=s(am,im,rm,!1,null,null,null);sm.options.__file="packages/aside/src/main.vue";var lm=sm.exports;lm.install=function(e){e.component(lm.name,lm)};var cm=lm,um=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("main",{staticClass:"el-main"},[e._t("default")],2)},dm=[];um._withStripped=!0;var hm={name:"ElMain",componentName:"ElMain"},fm=hm,pm=s(fm,um,dm,!1,null,null,null);pm.options.__file="packages/main/src/main.vue";var mm=pm.exports;mm.install=function(e){e.component(mm.name,mm)};var vm=mm,gm=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("footer",{staticClass:"el-footer",style:{height:e.height}},[e._t("default")],2)},bm=[];gm._withStripped=!0;var ym={name:"ElFooter",componentName:"ElFooter",props:{height:{type:String,default:"60px"}}},_m=ym,xm=s(_m,gm,bm,!1,null,null,null);xm.options.__file="packages/footer/src/main.vue";var wm=xm.exports;wm.install=function(e){e.component(wm.name,wm)};var Cm,km,Sm=wm,Om={name:"ElTimeline",props:{reverse:{type:Boolean,default:!1}},provide:function(){return{timeline:this}},render:function(){var e=arguments[0],t=this.reverse,n={"el-timeline":!0,"is-reverse":t},i=this.$slots.default||[];return t&&(i=i.reverse()),e("ul",{class:n},[i])}},$m=Om,Dm=s($m,Cm,km,!1,null,null,null);Dm.options.__file="packages/timeline/src/main.vue";var Em=Dm.exports;Em.install=function(e){e.component(Em.name,Em)};var Tm=Em,Pm=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{staticClass:"el-timeline-item"},[n("div",{staticClass:"el-timeline-item__tail"}),e.$slots.dot?e._e():n("div",{staticClass:"el-timeline-item__node",class:["el-timeline-item__node--"+(e.size||""),"el-timeline-item__node--"+(e.type||"")],style:{backgroundColor:e.color}},[e.icon?n("i",{staticClass:"el-timeline-item__icon",class:e.icon}):e._e()]),e.$slots.dot?n("div",{staticClass:"el-timeline-item__dot"},[e._t("dot")],2):e._e(),n("div",{staticClass:"el-timeline-item__wrapper"},[e.hideTimestamp||"top"!==e.placement?e._e():n("div",{staticClass:"el-timeline-item__timestamp is-top"},[e._v("\n "+e._s(e.timestamp)+"\n ")]),n("div",{staticClass:"el-timeline-item__content"},[e._t("default")],2),e.hideTimestamp||"bottom"!==e.placement?e._e():n("div",{staticClass:"el-timeline-item__timestamp is-bottom"},[e._v("\n "+e._s(e.timestamp)+"\n ")])])])},Mm=[];Pm._withStripped=!0;var Im={name:"ElTimelineItem",inject:["timeline"],props:{timestamp:String,hideTimestamp:{type:Boolean,default:!1},placement:{type:String,default:"bottom"},type:String,color:String,size:{type:String,default:"normal"},icon:String}},Nm=Im,jm=s(Nm,Pm,Mm,!1,null,null,null);jm.options.__file="packages/timeline/src/item.vue";var Am=jm.exports;Am.install=function(e){e.component(Am.name,Am)};var Fm=Am,Lm=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("a",e._b({class:["el-link",e.type?"el-link--"+e.type:"",e.disabled&&"is-disabled",e.underline&&!e.disabled&&"is-underline"],attrs:{href:e.disabled?null:e.href},on:{click:e.handleClick}},"a",e.$attrs,!1),[e.icon?n("i",{class:e.icon}):e._e(),e.$slots.default?n("span",{staticClass:"el-link--inner"},[e._t("default")],2):e._e(),e.$slots.icon?[e.$slots.icon?e._t("icon"):e._e()]:e._e()],2)},Vm=[];Lm._withStripped=!0;var zm={name:"ElLink",props:{type:{type:String,default:"default"},underline:{type:Boolean,default:!0},disabled:Boolean,href:String,icon:String},methods:{handleClick:function(e){this.disabled||this.href||this.$emit("click",e)}}},Bm=zm,Rm=s(Bm,Lm,Vm,!1,null,null,null);Rm.options.__file="packages/link/src/main.vue";var Hm=Rm.exports;Hm.install=function(e){e.component(Hm.name,Hm)};var Wm=Hm,qm=function(e,t){var n=t._c;return n("div",t._g(t._b({class:[t.data.staticClass,"el-divider","el-divider--"+t.props.direction]},"div",t.data.attrs,!1),t.listeners),[t.slots().default&&"vertical"!==t.props.direction?n("div",{class:["el-divider__text","is-"+t.props.contentPosition]},[t._t("default")],2):t._e()])},Um=[];qm._withStripped=!0;var Ym={name:"ElDivider",props:{direction:{type:String,default:"horizontal",validator:function(e){return-1!==["horizontal","vertical"].indexOf(e)}},contentPosition:{type:String,default:"center",validator:function(e){return-1!==["left","center","right"].indexOf(e)}}}},Km=Ym,Gm=s(Km,qm,Um,!0,null,null,null);Gm.options.__file="packages/divider/src/main.vue";var Xm=Gm.exports;Xm.install=function(e){e.component(Xm.name,Xm)};var Zm=Xm,Jm=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-image"},[e.loading?e._t("placeholder",[n("div",{staticClass:"el-image__placeholder"})]):e.error?e._t("error",[n("div",{staticClass:"el-image__error"},[e._v(e._s(e.t("el.image.error")))])]):n("img",e._g(e._b({staticClass:"el-image__inner",class:{"el-image__inner--center":e.alignCenter,"el-image__preview":e.preview},style:e.imageStyle,attrs:{src:e.src},on:{click:e.clickHandler}},"img",e.$attrs,!1),e.$listeners)),e.preview&&e.showViewer?n("image-viewer",{attrs:{"z-index":e.zIndex,"on-close":e.closeViewer,"url-list":e.previewSrcList}}):e._e()],2)},Qm=[];Jm._withStripped=!0;var ev=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"viewer-fade"}},[n("div",{staticClass:"el-image-viewer__wrapper",style:{"z-index":e.zIndex}},[n("div",{staticClass:"el-image-viewer__mask"}),n("span",{staticClass:"el-image-viewer__btn el-image-viewer__close",on:{click:e.hide}},[n("i",{staticClass:"el-icon-circle-close"})]),e.isSingle?e._e():[n("span",{staticClass:"el-image-viewer__btn el-image-viewer__prev",class:{"is-disabled":!e.infinite&&e.isFirst},on:{click:e.prev}},[n("i",{staticClass:"el-icon-arrow-left"})]),n("span",{staticClass:"el-image-viewer__btn el-image-viewer__next",class:{"is-disabled":!e.infinite&&e.isLast},on:{click:e.next}},[n("i",{staticClass:"el-icon-arrow-right"})])],n("div",{staticClass:"el-image-viewer__btn el-image-viewer__actions"},[n("div",{staticClass:"el-image-viewer__actions__inner"},[n("i",{staticClass:"el-icon-zoom-out",on:{click:function(t){e.handleActions("zoomOut")}}}),n("i",{staticClass:"el-icon-zoom-in",on:{click:function(t){e.handleActions("zoomIn")}}}),n("i",{staticClass:"el-image-viewer__actions__divider"}),n("i",{class:e.mode.icon,on:{click:e.toggleMode}}),n("i",{staticClass:"el-image-viewer__actions__divider"}),n("i",{staticClass:"el-icon-refresh-left",on:{click:function(t){e.handleActions("anticlocelise")}}}),n("i",{staticClass:"el-icon-refresh-right",on:{click:function(t){e.handleActions("clocelise")}}})])]),n("div",{staticClass:"el-image-viewer__canvas"},e._l(e.urlList,(function(t,i){return i===e.index?n("img",{key:t,ref:"img",refInFor:!0,staticClass:"el-image-viewer__img",style:e.imgStyle,attrs:{src:e.currentImg},on:{load:e.handleImgLoad,error:e.handleImgError,mousedown:e.handleMouseDown}}):e._e()})),0)],2)])},tv=[];ev._withStripped=!0;var nv=Object.assign||function(e){for(var t=1;t0?e.handleActions("zoomIn",{zoomRate:.015,enableTransition:!1}):e.handleActions("zoomOut",{zoomRate:.015,enableTransition:!1})})),Object(Le["on"])(document,"keydown",this._keyDownHandler),Object(Le["on"])(document,rv,this._mouseWheelHandler)},deviceSupportUninstall:function(){Object(Le["off"])(document,"keydown",this._keyDownHandler),Object(Le["off"])(document,rv,this._mouseWheelHandler),this._keyDownHandler=null,this._mouseWheelHandler=null},handleImgLoad:function(e){this.loading=!1},handleImgError:function(e){this.loading=!1,e.target.alt="加载失败"},handleMouseDown:function(e){var t=this;if(!this.loading&&0===e.button){var n=this.transform,i=n.offsetX,r=n.offsetY,o=e.pageX,a=e.pageY;this._dragHandler=Object(b["rafThrottle"])((function(e){t.transform.offsetX=i+e.pageX-o,t.transform.offsetY=r+e.pageY-a})),Object(Le["on"])(document,"mousemove",this._dragHandler),Object(Le["on"])(document,"mouseup",(function(e){Object(Le["off"])(document,"mousemove",t._dragHandler)})),e.preventDefault()}},reset:function(){this.transform={scale:1,deg:0,offsetX:0,offsetY:0,enableTransition:!1}},toggleMode:function(){if(!this.loading){var e=Object.keys(iv),t=Object.values(iv),n=t.indexOf(this.mode),i=(n+1)%e.length;this.mode=iv[e[i]],this.reset()}},prev:function(){if(!this.isFirst||this.infinite){var e=this.urlList.length;this.index=(this.index-1+e)%e}},next:function(){if(!this.isLast||this.infinite){var e=this.urlList.length;this.index=(this.index+1)%e}},handleActions:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!this.loading){var n=nv({zoomRate:.2,rotateDeg:90,enableTransition:!0},t),i=n.zoomRate,r=n.rotateDeg,o=n.enableTransition,a=this.transform;switch(e){case"zoomOut":a.scale>.2&&(a.scale=parseFloat((a.scale-i).toFixed(3)));break;case"zoomIn":a.scale=parseFloat((a.scale+i).toFixed(3));break;case"clocelise":a.deg+=r;break;case"anticlocelise":a.deg-=r;break}a.enableTransition=o}}},mounted:function(){this.deviceSupportInstall()}},av=ov,sv=s(av,ev,tv,!1,null,null,null);sv.options.__file="packages/image/src/image-viewer.vue";var lv=sv.exports,cv=function(){return void 0!==document.documentElement.style.objectFit},uv={NONE:"none",CONTAIN:"contain",COVER:"cover",FILL:"fill",SCALE_DOWN:"scale-down"},dv={name:"ElImage",mixins:[g.a],inheritAttrs:!1,components:{ImageViewer:lv},props:{src:String,fit:String,lazy:Boolean,scrollContainer:{},previewSrcList:{type:Array,default:function(){return[]}},zIndex:{type:Number,default:2e3}},data:function(){return{loading:!0,error:!1,show:!this.lazy,imageWidth:0,imageHeight:0,showViewer:!1}},computed:{imageStyle:function(){var e=this.fit;return!this.$isServer&&e?cv()?{"object-fit":e}:this.getImageStyle(e):{}},alignCenter:function(){return!this.$isServer&&!cv()&&this.fit!==uv.FILL},preview:function(){var e=this.previewSrcList;return Array.isArray(e)&&e.length>0}},watch:{src:function(e){this.show&&this.loadImage()},show:function(e){e&&this.loadImage()}},mounted:function(){this.lazy?this.addLazyLoadListener():this.loadImage()},beforeDestroy:function(){this.lazy&&this.removeLazyLoadListener()},methods:{loadImage:function(){var e=this;if(!this.$isServer){this.loading=!0,this.error=!1;var t=new Image;t.onload=function(n){return e.handleLoad(n,t)},t.onerror=this.handleError.bind(this),Object.keys(this.$attrs).forEach((function(n){var i=e.$attrs[n];t.setAttribute(n,i)})),t.src=this.src}},handleLoad:function(e,t){this.imageWidth=t.width,this.imageHeight=t.height,this.loading=!1},handleError:function(e){this.loading=!1,this.error=!0,this.$emit("error",e)},handleLazyLoad:function(){Object(Le["isInContainer"])(this.$el,this._scrollContainer)&&(this.show=!0,this.removeLazyLoadListener())},addLazyLoadListener:function(){if(!this.$isServer){var e=this.scrollContainer,t=null;t=Object(hh["isHtmlElement"])(e)?e:Object(hh["isString"])(e)?document.querySelector(e):Object(Le["getScrollContainer"])(this.$el),t&&(this._scrollContainer=t,this._lazyLoadHandler=jh()(200,this.handleLazyLoad),Object(Le["on"])(t,"scroll",this._lazyLoadHandler),this.handleLazyLoad())}},removeLazyLoadListener:function(){var e=this._scrollContainer,t=this._lazyLoadHandler;!this.$isServer&&e&&t&&(Object(Le["off"])(e,"scroll",t),this._scrollContainer=null,this._lazyLoadHandler=null)},getImageStyle:function(e){var t=this.imageWidth,n=this.imageHeight,i=this.$el,r=i.clientWidth,o=i.clientHeight;if(!t||!n||!r||!o)return{};var a=t/n<1;if(e===uv.SCALE_DOWN){var s=tr)return console.warn("[ElementCalendar]end time should be greater than start time"),[];if(Object(ao["validateRangeInOneMonth"])(i,r))return[[i,r]];var o=[],a=new Date(i.getFullYear(),i.getMonth()+1,1),s=this.toDate(a.getTime()-Dv);if(!Object(ao["validateRangeInOneMonth"])(a,r))return console.warn("[ElementCalendar]start time and end time interval must not exceed two months"),[];o.push([i,s]);var l=this.realFirstDayOfWeek,c=a.getDay(),u=0;return c!==l&&(0===l?u=7-c:(u=l-c,u=u>0?u:7+u)),a=this.toDate(a.getTime()+u*Dv),a.getDate()6?0:Math.floor(this.firstDayOfWeek)}},data:function(){return{selectedDay:"",now:new Date}}},Tv=Ev,Pv=s(Tv,vv,gv,!1,null,null,null);Pv.options.__file="packages/calendar/src/main.vue";var Mv=Pv.exports;Mv.install=function(e){e.component(Mv.name,Mv)};var Iv=Mv,Nv=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-fade-in"}},[e.visible?n("div",{staticClass:"el-backtop",style:{right:e.styleRight,bottom:e.styleBottom},on:{click:function(t){return t.stopPropagation(),e.handleClick(t)}}},[e._t("default",[n("el-icon",{attrs:{name:"caret-top"}})])],2):e._e()])},jv=[];Nv._withStripped=!0;var Av={name:"ElBacktop",props:{visibilityHeight:{type:Number,default:200},target:[String],right:{type:Number,default:40},bottom:{type:Number,default:40}},data:function(){return{el:null,container:null,visible:!1}},computed:{styleBottom:function(){return this.bottom+"px"},styleRight:function(){return this.right+"px"}},mounted:function(){this.init(),this.throttledScrollHandler=jh()(300,this.onScroll),this.container.addEventListener("scroll",this.throttledScrollHandler)},methods:{init:function(){if(this.container=document,this.el=document.documentElement,this.target){if(this.el=document.querySelector(this.target),!this.el)throw new Error("target is not existed: "+this.target);this.container=this.el}},onScroll:function(){var e=this.el.scrollTop;this.visible=e>=this.visibilityHeight},handleClick:function(e){this.scrollToTop(),this.$emit("click",e)},scrollToTop:function(){var e=this.el,t=0,n=setInterval((function(){e.scrollTop<=0?clearInterval(n):(t+=10,e.scrollTop-=t)}),20)}},beforeDestroy:function(){this.container.removeEventListener("scroll",this.throttledScrollHandler)}},Fv=Av,Lv=s(Fv,Nv,jv,!1,null,null,null);Lv.options.__file="packages/backtop/src/main.vue";var Vv=Lv.exports;Vv.install=function(e){e.component(Vv.name,Vv)};var zv=Vv,Bv=function(e,t){if(e===window&&(e=document.documentElement),1!==e.nodeType)return[];var n=window.getComputedStyle(e,null);return t?n[t]:n},Rv=function(e){return Object.keys(e||{}).map((function(t){return[t,e[t]]}))},Hv=function(e,t){return e===window||e===document?document.documentElement[t]:e[t]},Wv=function(e){return Hv(e,"offsetHeight")},qv=function(e){return Hv(e,"clientHeight")},Uv="ElInfiniteScroll",Yv={delay:{type:Number,default:200},distance:{type:Number,default:0},disabled:{type:Boolean,default:!1},immediate:{type:Boolean,default:!0}},Kv=function(e,t){return Object(hh["isHtmlElement"])(e)?Rv(Yv).reduce((function(n,i){var r=i[0],o=i[1],a=o.type,s=o.default,l=e.getAttribute("infinite-scroll-"+r);switch(l=Object(hh["isUndefined"])(t[l])?l:t[l],a){case Number:l=Number(l),l=Number.isNaN(l)?s:l;break;case Boolean:l=Object(hh["isDefined"])(l)?"false"!==l&&Boolean(l):s;break;default:l=a(l)}return n[r]=l,n}),{}):{}},Gv=function(e){return e.getBoundingClientRect().top},Xv=function(e){var t=this[Uv],n=t.el,i=t.vm,r=t.container,o=t.observer,a=Kv(n,i),s=a.distance,l=a.disabled;if(!l){var c=!1;if(r===n){var u=r.scrollTop+qv(r);c=r.scrollHeight-u<=s}else{var d=Wv(n)+Gv(n)-Gv(r),h=Wv(r),f=Number.parseFloat(Bv(r,"borderBottomWidth"));c=d-h+f<=s}c&&Object(hh["isFunction"])(e)?e.call(i):o&&(o.disconnect(),this[Uv].observer=null)}},Zv={name:"InfiniteScroll",inserted:function(e,t,n){var i=t.value,r=n.context,o=Object(Le["getScrollContainer"])(e,!0),a=Kv(e,r),s=a.delay,l=a.immediate,c=F()(s,Xv.bind(e,i));if(e[Uv]={el:e,vm:r,container:o,onScroll:c},o&&(o.addEventListener("scroll",c),l)){var u=e[Uv].observer=new MutationObserver(c);u.observe(o,{childList:!0,subtree:!0}),c()}},unbind:function(e){var t=e[Uv],n=t.container,i=t.onScroll;n&&n.removeEventListener("scroll",i)},install:function(e){e.directive(Zv.name,Zv)}},Jv=Zv,Qv=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-page-header"},[n("div",{staticClass:"el-page-header__left",on:{click:function(t){e.$emit("back")}}},[n("i",{staticClass:"el-icon-back"}),n("div",{staticClass:"el-page-header__title"},[e._t("title",[e._v(e._s(e.title))])],2)]),n("div",{staticClass:"el-page-header__content"},[e._t("content",[e._v(e._s(e.content))])],2)])},eg=[];Qv._withStripped=!0;var tg={name:"ElPageHeader",props:{title:{type:String,default:function(){return Object(ti["t"])("el.pageHeader.title")}},content:String}},ng=tg,ig=s(ng,Qv,eg,!1,null,null,null);ig.options.__file="packages/page-header/src/main.vue";var rg=ig.exports;rg.install=function(e){e.component(rg.name,rg)};var og=rg,ag=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:["el-cascader-panel",e.border&&"is-bordered"],on:{keydown:e.handleKeyDown}},e._l(e.menus,(function(e,t){return n("cascader-menu",{key:t,ref:"menu",refInFor:!0,attrs:{index:t,nodes:e}})})),1)},sg=[];ag._withStripped=!0;var lg,cg,ug=n(43),dg=n.n(ug),hg=function(e){return e.stopPropagation()},fg={inject:["panel"],components:{ElCheckbox:Ai.a,ElRadio:dg.a},props:{node:{required:!0},nodeId:String},computed:{config:function(){return this.panel.config},isLeaf:function(){return this.node.isLeaf},isDisabled:function(){return this.node.isDisabled},checkedValue:function(){return this.panel.checkedValue},isChecked:function(){return this.node.isSameNode(this.checkedValue)},inActivePath:function(){return this.isInPath(this.panel.activePath)},inCheckedPath:function(){var e=this;return!!this.config.checkStrictly&&this.panel.checkedNodePaths.some((function(t){return e.isInPath(t)}))},value:function(){return this.node.getValueByOption()}},methods:{handleExpand:function(){var e=this,t=this.panel,n=this.node,i=this.isDisabled,r=this.config,o=r.multiple,a=r.checkStrictly;!a&&i||n.loading||(r.lazy&&!n.loaded?t.lazyLoad(n,(function(){var t=e.isLeaf;if(t||e.handleExpand(),o){var i=!!t&&n.checked;e.handleMultiCheckChange(i)}})):t.handleExpand(n))},handleCheckChange:function(){var e=this.panel,t=this.value,n=this.node;e.handleCheckChange(t),e.handleExpand(n)},handleMultiCheckChange:function(e){this.node.doCheck(e),this.panel.calculateMultiCheckedValue()},isInPath:function(e){var t=this.node,n=e[t.level-1]||{};return n.uid===t.uid},renderPrefix:function(e){var t=this.isLeaf,n=this.isChecked,i=this.config,r=i.checkStrictly,o=i.multiple;return o?this.renderCheckbox(e):r?this.renderRadio(e):t&&n?this.renderCheckIcon(e):null},renderPostfix:function(e){var t=this.node,n=this.isLeaf;return t.loading?this.renderLoadingIcon(e):n?null:this.renderExpandIcon(e)},renderCheckbox:function(e){var t=this.node,n=this.config,i=this.isDisabled,r={on:{change:this.handleMultiCheckChange},nativeOn:{}};return n.checkStrictly&&(r.nativeOn.click=hg),e("el-checkbox",Ju()([{attrs:{value:t.checked,indeterminate:t.indeterminate,disabled:i}},r]))},renderRadio:function(e){var t=this.checkedValue,n=this.value,i=this.isDisabled;return Object(b["isEqual"])(n,t)&&(n=t),e("el-radio",{attrs:{value:t,label:n,disabled:i},on:{change:this.handleCheckChange},nativeOn:{click:hg}},[e("span")])},renderCheckIcon:function(e){return e("i",{class:"el-icon-check el-cascader-node__prefix"})},renderLoadingIcon:function(e){return e("i",{class:"el-icon-loading el-cascader-node__postfix"})},renderExpandIcon:function(e){return e("i",{class:"el-icon-arrow-right el-cascader-node__postfix"})},renderContent:function(e){var t=this.panel,n=this.node,i=t.renderLabelFn,r=i?i({node:n,data:n.data}):null;return e("span",{class:"el-cascader-node__label"},[r||n.label])}},render:function(e){var t=this,n=this.inActivePath,i=this.inCheckedPath,r=this.isChecked,o=this.isLeaf,a=this.isDisabled,s=this.config,l=this.nodeId,c=s.expandTrigger,u=s.checkStrictly,d=s.multiple,h=!u&&a,f={on:{}};return"click"===c?f.on.click=this.handleExpand:(f.on.mouseenter=function(e){t.handleExpand(),t.$emit("expand",e)},f.on.focus=function(e){t.handleExpand(),t.$emit("expand",e)}),!o||a||u||d||(f.on.click=this.handleCheckChange),e("li",Ju()([{attrs:{role:"menuitem",id:l,"aria-expanded":n,tabindex:h?null:-1},class:{"el-cascader-node":!0,"is-selectable":u,"in-active-path":n,"in-checked-path":i,"is-active":r,"is-disabled":h}},f]),[this.renderPrefix(e),this.renderContent(e),this.renderPostfix(e)])}},pg=fg,mg=s(pg,lg,cg,!1,null,null,null);mg.options.__file="packages/cascader-panel/src/cascader-node.vue";var vg,gg,bg=mg.exports,yg={name:"ElCascaderMenu",mixins:[g.a],inject:["panel"],components:{ElScrollbar:q.a,CascaderNode:bg},props:{nodes:{type:Array,required:!0},index:Number},data:function(){return{activeNode:null,hoverTimer:null,id:Object(b["generateId"])()}},computed:{isEmpty:function(){return!this.nodes.length},menuId:function(){return"cascader-menu-"+this.id+"-"+this.index}},methods:{handleExpand:function(e){this.activeNode=e.target},handleMouseMove:function(e){var t=this.activeNode,n=this.hoverTimer,i=this.$refs.hoverZone;if(t&&i)if(t.contains(e.target)){clearTimeout(n);var r=this.$el.getBoundingClientRect(),o=r.left,a=e.clientX-o,s=this.$el,l=s.offsetWidth,c=s.offsetHeight,u=t.offsetTop,d=u+t.offsetHeight;i.innerHTML='\n \n \n '}else n||(this.hoverTimer=setTimeout(this.clearHoverZone,this.panel.config.hoverThreshold))},clearHoverZone:function(){var e=this.$refs.hoverZone;e&&(e.innerHTML="")},renderEmptyText:function(e){return e("div",{class:"el-cascader-menu__empty-text"},[this.t("el.cascader.noData")])},renderNodeList:function(e){var t=this.menuId,n=this.panel.isHoverMenu,i={on:{}};n&&(i.on.expand=this.handleExpand);var r=this.nodes.map((function(n,r){var o=n.hasChildren;return e("cascader-node",Ju()([{key:n.uid,attrs:{node:n,"node-id":t+"-"+r,"aria-haspopup":o,"aria-owns":o?t:null}},i]))}));return[].concat(r,[n?e("svg",{ref:"hoverZone",class:"el-cascader-menu__hover-zone"}):null])}},render:function(e){var t=this.isEmpty,n=this.menuId,i={nativeOn:{}};return this.panel.isHoverMenu&&(i.nativeOn.mousemove=this.handleMouseMove),e("el-scrollbar",Ju()([{attrs:{tag:"ul",role:"menu",id:n,"wrap-class":"el-cascader-menu__wrap","view-class":{"el-cascader-menu__list":!0,"is-empty":t}},class:"el-cascader-menu"},i]),[t?this.renderEmptyText(e):this.renderNodeList(e)])}},_g=yg,xg=s(_g,vg,gg,!1,null,null,null);xg.options.__file="packages/cascader-panel/src/cascader-menu.vue";var wg=xg.exports,Cg=function(){function e(e,t){for(var n=0;n1?t-1:0),i=1;i1?i-1:0),o=1;o0},e.prototype.syncCheckState=function(e){var t=this.getValueByOption(),n=this.isSameNode(e,t);this.doCheck(n)},e.prototype.doCheck=function(e){this.checked!==e&&(this.config.checkStrictly?this.checked=e:(this.broadcast("check",e),this.setCheckState(e),this.emit("check")))},Cg(e,[{key:"isDisabled",get:function(){var e=this.data,t=this.parent,n=this.config,i=n.disabled,r=n.checkStrictly;return e[i]||!r&&t&&t.isDisabled}},{key:"isLeaf",get:function(){var e=this.data,t=this.loaded,n=this.hasChildren,i=this.children,r=this.config,o=r.lazy,a=r.leaf;if(o){var s=Object(Ot["isDef"])(e[a])?e[a]:!!t&&!i.length;return this.hasChildren=!s,s}return!n}}]),e}(),$g=Og;function Dg(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var Eg=function e(t,n){return t.reduce((function(t,i){return i.isLeaf?t.push(i):(!n&&t.push(i),t=t.concat(e(i.children,n))),t}),[])},Tg=function(){function e(t,n){Dg(this,e),this.config=n,this.initNodes(t)}return e.prototype.initNodes=function(e){var t=this;e=Object(b["coerceTruthyValueToArray"])(e),this.nodes=e.map((function(e){return new $g(e,t.config)})),this.flattedNodes=this.getFlattedNodes(!1,!1),this.leafNodes=this.getFlattedNodes(!0,!1)},e.prototype.appendNode=function(e,t){var n=new $g(e,this.config,t),i=t?t.children:this.nodes;i.push(n)},e.prototype.appendNodes=function(e,t){var n=this;e=Object(b["coerceTruthyValueToArray"])(e),e.forEach((function(e){return n.appendNode(e,t)}))},e.prototype.getNodes=function(){return this.nodes},e.prototype.getFlattedNodes=function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=e?this.leafNodes:this.flattedNodes;return t?n:Eg(this.nodes,e)},e.prototype.getNodeByValue=function(e){if(e){var t=this.getFlattedNodes(!1,!this.config.lazy).filter((function(t){return Object(b["valueEquals"])(t.path,e)||t.value===e}));return t&&t.length?t[0]:null}return null},e}(),Pg=Tg,Mg=Object.assign||function(e){for(var t=1;t0){var l=n.store.getNodeByValue(o);l.data[s]||n.lazyLoad(l,(function(){n.handleExpand(l)})),n.loadCount===n.checkedValue.length&&n.$parent.computePresentText()}}t&&t(i)};i.lazyLoad(e,r)},calculateMultiCheckedValue:function(){this.checkedValue=this.getCheckedNodes(this.leafOnly).map((function(e){return e.getValueByOption()}))},scrollIntoView:function(){if(!this.$isServer){var e=this.$refs.menu||[];e.forEach((function(e){var t=e.$el;if(t){var n=t.querySelector(".el-scrollbar__wrap"),i=t.querySelector(".el-cascader-node.is-active")||t.querySelector(".el-cascader-node.in-active-path");ri()(n,i)}}))}},getNodeByValue:function(e){return this.store.getNodeByValue(e)},getFlattedNodes:function(e){var t=!this.config.lazy;return this.store.getFlattedNodes(e,t)},getCheckedNodes:function(e){var t=this.checkedValue,n=this.multiple;if(n){var i=this.getFlattedNodes(e);return i.filter((function(e){return e.checked}))}return Object(b["isEmpty"])(t)?[]:[this.getNodeByValue(t)]},clearCheckedNodes:function(){var e=this.config,t=this.leafOnly,n=e.multiple,i=e.emitPath;n?(this.getCheckedNodes(t).filter((function(e){return!e.isDisabled})).forEach((function(e){return e.doCheck(!1)})),this.calculateMultiCheckedValue()):this.checkedValue=i?[]:null}}},Bg=zg,Rg=s(Bg,ag,sg,!1,null,null,null);Rg.options.__file="packages/cascader-panel/src/cascader-panel.vue";var Hg=Rg.exports;Hg.install=function(e){e.component(Hg.name,Hg)};var Wg,qg,Ug=Hg,Yg={name:"ElAvatar",props:{size:{type:[Number,String],validator:function(e){return"string"===typeof e?["large","medium","small"].includes(e):"number"===typeof e}},shape:{type:String,default:"circle",validator:function(e){return["circle","square"].includes(e)}},icon:String,src:String,alt:String,srcSet:String,error:Function,fit:{type:String,default:"cover"}},data:function(){return{isImageExist:!0}},computed:{avatarClass:function(){var e=this.size,t=this.icon,n=this.shape,i=["el-avatar"];return e&&"string"===typeof e&&i.push("el-avatar--"+e),t&&i.push("el-avatar--icon"),n&&i.push("el-avatar--"+n),i.join(" ")}},methods:{handleError:function(){var e=this.error,t=e?e():void 0;!1!==t&&(this.isImageExist=!1)},renderAvatar:function(){var e=this.$createElement,t=this.icon,n=this.src,i=this.alt,r=this.isImageExist,o=this.srcSet,a=this.fit;return r&&n?e("img",{attrs:{src:n,alt:i,srcSet:o},on:{error:this.handleError},style:{"object-fit":a}}):t?e("i",{class:t}):this.$slots.default}},render:function(){var e=arguments[0],t=this.avatarClass,n=this.size,i="number"===typeof n?{height:n+"px",width:n+"px",lineHeight:n+"px"}:{};return e("span",{class:t,style:i},[this.renderAvatar()])}},Kg=Yg,Gg=s(Kg,Wg,qg,!1,null,null,null);Gg.options.__file="packages/avatar/src/main.vue";var Xg=Gg.exports;Xg.install=function(e){e.component(Xg.name,Xg)};var Zg=Xg,Jg=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("transition",{attrs:{name:"el-drawer-fade"},on:{"after-enter":e.afterEnter,"after-leave":e.afterLeave}},[n("div",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-dialog__wrapper",attrs:{role:"presentation"}},[n("div",{staticClass:"el-drawer__container",class:e.visible&&"el-drawer__open",attrs:{role:"document",tabindex:"-1"},on:{click:function(t){return t.target!==t.currentTarget?null:e.handleWrapperClick(t)}}},[n("div",{ref:"drawer",staticClass:"el-drawer",class:[e.direction,e.customClass],style:e.isHorizontal?"width: "+e.size:"height: "+e.size,attrs:{"aria-modal":"true","aria-labelledby":"el-drawer__title",role:"presentation"}},[n("header",{staticClass:"el-drawer__header",attrs:{id:"el-drawer__title"}},[e._t("title",[n("span",{attrs:{role:"heading"}},[e._v(e._s(e.title))])]),e.showClose?n("button",{staticClass:"el-drawer__close-btn",attrs:{"aria-label":"close "+(e.title||"drawer"),type:"button"},on:{click:e.closeDrawer}},[n("i",{staticClass:"el-dialog__close el-icon el-icon-close"})]):e._e()],2),e.rendered?n("section",{staticClass:"el-drawer__body"},[e._t("default")],2):e._e()])])])])},Qg=[];Jg._withStripped=!0;var eb={name:"ElDrawer",mixins:[k.a,D.a,O.a],props:{appendToBody:{type:Boolean,default:!0},beforeClose:{type:Function},customClass:{type:String,default:""},destroyOnClose:{type:Boolean,default:!1},modal:{type:Boolean,default:!0},direction:{type:String,default:"rtl",validator:function(e){return-1!==["ltr","rtl","ttb","btt"].indexOf(e)}},showClose:{type:Boolean,default:!0},size:{type:String,default:"30%"},title:{type:String,default:""},visible:{type:Boolean},wrapperClosable:{type:Boolean,default:!0}},computed:{isHorizontal:function(){return"rtl"===this.direction||"ltr"===this.direction}},data:function(){return{closed:!1}},watch:{visible:function(e){e?(this.closed=!1,this.$emit("open"),this.appendToBody&&document.body.appendChild(this.$el)):this.closed||this.$emit("close")}},methods:{afterEnter:function(){this.$emit("opened")},afterLeave:function(){this.$emit("closed")},hide:function(e){!1!==e&&(this.$emit("update:visible",!1),this.$emit("close"),!0===this.destroyOnClose&&(this.rendered=!1),this.closed=!0)},handleWrapperClick:function(){this.wrapperClosable&&this.closeDrawer()},closeDrawer:function(){"function"===typeof this.beforeClose?this.beforeClose(this.hide):this.hide()}},mounted:function(){this.visible&&(this.rendered=!0,this.open())},destroyed:function(){this.appendToBody&&this.$el&&this.$el.parentNode&&this.$el.parentNode.removeChild(this.$el)}},tb=eb,nb=s(tb,Jg,Qg,!1,null,null,null);nb.options.__file="packages/drawer/src/main.vue";var ib=nb.exports;ib.install=function(e){e.component(ib.name,ib)};var rb=ib,ob=[_,I,re,fe,_e,$e,qe,et,ct,vt,Pt,Vt,Ut,en,ln,mn,wn,En,An,ui,di,bi,Si,Mi,Gr,io,Pa,Ha,ns,ds,fs,Hs,Xs,il,bl,Vl,Kl,Ql,Dc,Ac,hu,Fu,Vu,Ru,xd,Dd,jd,nh,ch,gh,kh,Ph,zh,qh,Qh,sf,pf,Ef,Ep,Rp,Gp,nm,cm,vm,Sm,Tm,Fm,Wm,Zm,mv,Iv,zv,og,Ug,Zg,rb,Ye.a],ab=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};ni.a.use(t.locale),ni.a.i18n(t.i18n),ob.forEach((function(t){e.component(t.name,t)})),e.use(Jv),e.use(Tu.directive),e.prototype.$ELEMENT={size:t.size||"",zIndex:t.zIndex||2e3},e.prototype.$loading=Tu.service,e.prototype.$msgbox=As,e.prototype.$alert=As.alert,e.prototype.$confirm=As.confirm,e.prototype.$prompt=As.prompt,e.prototype.$notify=Xc,e.prototype.$message=Gd};"undefined"!==typeof window&&window.Vue&&ab(window.Vue);t["default"]={version:"2.12.0",locale:ni.a.use,i18n:ni.a.i18n,install:ab,CollapseTransition:Ye.a,Loading:Tu,Pagination:_,Dialog:I,Autocomplete:re,Dropdown:fe,DropdownMenu:_e,DropdownItem:$e,Menu:qe,Submenu:et,MenuItem:ct,MenuItemGroup:vt,Input:Pt,InputNumber:Vt,Radio:Ut,RadioGroup:en,RadioButton:ln,Checkbox:mn,CheckboxButton:wn,CheckboxGroup:En,Switch:An,Select:ui,Option:di,OptionGroup:bi,Button:Si,ButtonGroup:Mi,Table:Gr,TableColumn:io,DatePicker:Pa,TimeSelect:Ha,TimePicker:ns,Popover:ds,Tooltip:fs,MessageBox:As,Breadcrumb:Hs,BreadcrumbItem:Xs,Form:il,FormItem:bl,Tabs:Vl,TabPane:Kl,Tag:Ql,Tree:Dc,Alert:Ac,Notification:Xc,Slider:hu,Icon:Fu,Row:Vu,Col:Ru,Upload:xd,Progress:Dd,Spinner:jd,Message:Gd,Badge:nh,Card:ch,Rate:gh,Steps:kh,Step:Ph,Carousel:zh,Scrollbar:qh,CarouselItem:Qh,Collapse:sf,CollapseItem:pf,Cascader:Ef,ColorPicker:Ep,Transfer:Rp,Container:Gp,Header:nm,Aside:cm,Main:vm,Footer:Sm,Timeline:Tm,TimelineItem:Fm,Link:Wm,Divider:Zm,Image:mv,Calendar:Iv,Backtop:zv,InfiniteScroll:Jv,PageHeader:og,CascaderPanel:Ug,Avatar:Zg,Drawer:rb}}])["default"]},"60ae":function(e,t,n){var i,r,o=n("da84"),a=n("b39a"),s=o.process,l=s&&s.versions,c=l&&l.v8;c?(i=c.split("."),r=i[0]+i[1]):a&&(i=a.match(/Chrome\/(\d+)/),i&&(r=i[1])),e.exports=r&&+r},"60da":function(e,t,n){"use strict";var i=n("83ab"),r=n("d039"),o=n("df75"),a=n("7418"),s=n("d1e7"),l=n("7b0b"),c=n("44ad"),u=Object.assign;e.exports=!u||r((function(){var e={},t={},n=Symbol(),i="abcdefghijklmnopqrst";return e[n]=7,i.split("").forEach((function(e){t[e]=e})),7!=u({},e)[n]||o(u({},t)).join("")!=i}))?function(e,t){var n=l(e),r=arguments.length,u=1,d=a.f,h=s.f;while(r>u){var f,p=c(arguments[u++]),m=d?o(p).concat(d(p)):o(p),v=m.length,g=0;while(v>g)f=m[g++],i&&!h.call(p,f)||(n[f]=p[f])}return n}:u},6167:function(e,t,n){"use strict";var i,r;"function"===typeof Symbol&&Symbol.iterator;(function(o,a){i=a,r="function"===typeof i?i.call(t,n,t,e):i,void 0===r||(e.exports=r)})(0,(function(){var e=window,t={placement:"bottom",gpuAcceleration:!0,offset:0,boundariesElement:"viewport",boundariesPadding:5,preventOverflowOrder:["left","right","top","bottom"],flipBehavior:"flip",arrowElement:"[x-arrow]",arrowOffset:0,modifiers:["shift","offset","preventOverflow","keepTogether","arrow","flip","applyStyle"],modifiersIgnored:[],forceAbsolute:!1};function n(e,n,i){this._reference=e.jquery?e[0]:e,this.state={};var r="undefined"===typeof n||null===n,o=n&&"[object Object]"===Object.prototype.toString.call(n);return this._popper=r||o?this.parse(o?n:{}):n.jquery?n[0]:n,this._options=Object.assign({},t,i),this._options.modifiers=this._options.modifiers.map(function(e){if(-1===this._options.modifiersIgnored.indexOf(e))return"applyStyle"===e&&this._popper.setAttribute("x-placement",this._options.placement),this.modifiers[e]||e}.bind(this)),this.state.position=this._getPosition(this._popper,this._reference),d(this._popper,{position:this.state.position,top:0}),this.update(),this._setupEventListeners(),this}function i(t){var n=t.style.display,i=t.style.visibility;t.style.display="block",t.style.visibility="hidden";t.offsetWidth;var r=e.getComputedStyle(t),o=parseFloat(r.marginTop)+parseFloat(r.marginBottom),a=parseFloat(r.marginLeft)+parseFloat(r.marginRight),s={width:t.offsetWidth+a,height:t.offsetHeight+o};return t.style.display=n,t.style.visibility=i,s}function r(e){var t={left:"right",right:"left",bottom:"top",top:"bottom"};return e.replace(/left|right|bottom|top/g,(function(e){return t[e]}))}function o(e){var t=Object.assign({},e);return t.right=t.left+t.width,t.bottom=t.top+t.height,t}function a(e,t){var n,i=0;for(n in e){if(e[n]===t)return i;i++}return null}function s(t,n){var i=e.getComputedStyle(t,null);return i[n]}function l(t){var n=t.offsetParent;return n!==e.document.body&&n?n:e.document.documentElement}function c(t){var n=t.parentNode;return n?n===e.document?e.document.body.scrollTop||e.document.body.scrollLeft?e.document.body:e.document.documentElement:-1!==["scroll","auto"].indexOf(s(n,"overflow"))||-1!==["scroll","auto"].indexOf(s(n,"overflow-x"))||-1!==["scroll","auto"].indexOf(s(n,"overflow-y"))?n:c(t.parentNode):t}function u(t){return t!==e.document.body&&("fixed"===s(t,"position")||(t.parentNode?u(t.parentNode):t))}function d(e,t){function n(e){return""!==e&&!isNaN(parseFloat(e))&&isFinite(e)}Object.keys(t).forEach((function(i){var r="";-1!==["width","height","top","right","bottom","left"].indexOf(i)&&n(t[i])&&(r="px"),e.style[i]=t[i]+r}))}function h(e){var t={};return e&&"[object Function]"===t.toString.call(e)}function f(e){var t={width:e.offsetWidth,height:e.offsetHeight,left:e.offsetLeft,top:e.offsetTop};return t.right=t.left+t.width,t.bottom=t.top+t.height,t}function p(e){var t=e.getBoundingClientRect(),n=-1!=navigator.userAgent.indexOf("MSIE"),i=n&&"HTML"===e.tagName?-e.scrollTop:t.top;return{left:t.left,top:i,right:t.right,bottom:t.bottom,width:t.right-t.left,height:t.bottom-i}}function m(e,t,n){var i=p(e),r=p(t);if(n){var o=c(t);r.top+=o.scrollTop,r.bottom+=o.scrollTop,r.left+=o.scrollLeft,r.right+=o.scrollLeft}var a={top:i.top-r.top,left:i.left-r.left,bottom:i.top-r.top+i.height,right:i.left-r.left+i.width,width:i.width,height:i.height};return a}function v(t){for(var n=["","ms","webkit","moz","o"],i=0;i1&&console.warn("WARNING: the given `parent` query("+t.parent+") matched more than one element, the first one will be used"),0===a.length)throw"ERROR: the given `parent` doesn't exists!";a=a[0]}return a.length>1&&a instanceof Element===!1&&(console.warn("WARNING: you have passed as parent a list of elements, the first one will be used"),a=a[0]),a.appendChild(r),r;function s(e,t){t.forEach((function(t){e.classList.add(t)}))}function l(e,t){t.forEach((function(t){e.setAttribute(t.split(":")[0],t.split(":")[1]||"")}))}},n.prototype._getPosition=function(e,t){var n=l(t);if(this._options.forceAbsolute)return"absolute";var i=u(t,n);return i?"fixed":"absolute"},n.prototype._getOffsets=function(e,t,n){n=n.split("-")[0];var r={};r.position=this.state.position;var o="fixed"===r.position,a=m(t,l(e),o),s=i(e);return-1!==["right","left"].indexOf(n)?(r.top=a.top+a.height/2-s.height/2,r.left="left"===n?a.left-s.width:a.right):(r.left=a.left+a.width/2-s.width/2,r.top="top"===n?a.top-s.height:a.bottom),r.width=s.width,r.height=s.height,{popper:r,reference:a}},n.prototype._setupEventListeners=function(){if(this.state.updateBound=this.update.bind(this),e.addEventListener("resize",this.state.updateBound),"window"!==this._options.boundariesElement){var t=c(this._reference);t!==e.document.body&&t!==e.document.documentElement||(t=e),t.addEventListener("scroll",this.state.updateBound),this.state.scrollTarget=t}},n.prototype._removeEventListeners=function(){e.removeEventListener("resize",this.state.updateBound),"window"!==this._options.boundariesElement&&this.state.scrollTarget&&(this.state.scrollTarget.removeEventListener("scroll",this.state.updateBound),this.state.scrollTarget=null),this.state.updateBound=null},n.prototype._getBoundaries=function(t,n,i){var r,o,a={};if("window"===i){var s=e.document.body,u=e.document.documentElement;o=Math.max(s.scrollHeight,s.offsetHeight,u.clientHeight,u.scrollHeight,u.offsetHeight),r=Math.max(s.scrollWidth,s.offsetWidth,u.clientWidth,u.scrollWidth,u.offsetWidth),a={top:0,right:r,bottom:o,left:0}}else if("viewport"===i){var d=l(this._popper),h=c(this._popper),p=f(d),m=function(e){return e==document.body?Math.max(document.documentElement.scrollTop,document.body.scrollTop):e.scrollTop},v=function(e){return e==document.body?Math.max(document.documentElement.scrollLeft,document.body.scrollLeft):e.scrollLeft},g="fixed"===t.offsets.popper.position?0:m(h),b="fixed"===t.offsets.popper.position?0:v(h);a={top:0-(p.top-g),right:e.document.documentElement.clientWidth-(p.left-b),bottom:e.document.documentElement.clientHeight-(p.top-g),left:0-(p.left-b)}}else a=l(this._popper)===i?{top:0,left:0,right:i.clientWidth,bottom:i.clientHeight}:f(i);return a.left+=n,a.right-=n,a.top=a.top+n,a.bottom=a.bottom-n,a},n.prototype.runModifiers=function(e,t,n){var i=t.slice();return void 0!==n&&(i=this._options.modifiers.slice(0,a(this._options.modifiers,n))),i.forEach(function(t){h(t)&&(e=t.call(this,e))}.bind(this)),e},n.prototype.isModifierRequired=function(e,t){var n=a(this._options.modifiers,e);return!!this._options.modifiers.slice(0,n).filter((function(e){return e===t})).length},n.prototype.modifiers={},n.prototype.modifiers.applyStyle=function(e){var t,n={position:e.offsets.popper.position},i=Math.round(e.offsets.popper.left),r=Math.round(e.offsets.popper.top);return this._options.gpuAcceleration&&(t=v("transform"))?(n[t]="translate3d("+i+"px, "+r+"px, 0)",n.top=0,n.left=0):(n.left=i,n.top=r),Object.assign(n,e.styles),d(this._popper,n),this._popper.setAttribute("x-placement",e.placement),this.isModifierRequired(this.modifiers.applyStyle,this.modifiers.arrow)&&e.offsets.arrow&&d(e.arrowElement,e.offsets.arrow),e},n.prototype.modifiers.shift=function(e){var t=e.placement,n=t.split("-")[0],i=t.split("-")[1];if(i){var r=e.offsets.reference,a=o(e.offsets.popper),s={y:{start:{top:r.top},end:{top:r.top+r.height-a.height}},x:{start:{left:r.left},end:{left:r.left+r.width-a.width}}},l=-1!==["bottom","top"].indexOf(n)?"x":"y";e.offsets.popper=Object.assign(a,s[l][i])}return e},n.prototype.modifiers.preventOverflow=function(e){var t=this._options.preventOverflowOrder,n=o(e.offsets.popper),i={left:function(){var t=n.left;return n.lefte.boundaries.right&&(t=Math.min(n.left,e.boundaries.right-n.width)),{left:t}},top:function(){var t=n.top;return n.tope.boundaries.bottom&&(t=Math.min(n.top,e.boundaries.bottom-n.height)),{top:t}}};return t.forEach((function(t){e.offsets.popper=Object.assign(n,i[t]())})),e},n.prototype.modifiers.keepTogether=function(e){var t=o(e.offsets.popper),n=e.offsets.reference,i=Math.floor;return t.righti(n.right)&&(e.offsets.popper.left=i(n.right)),t.bottomi(n.bottom)&&(e.offsets.popper.top=i(n.bottom)),e},n.prototype.modifiers.flip=function(e){if(!this.isModifierRequired(this.modifiers.flip,this.modifiers.preventOverflow))return console.warn("WARNING: preventOverflow modifier is required by flip modifier in order to work, be sure to include it before flip!"),e;if(e.flipped&&e.placement===e._originalPlacement)return e;var t=e.placement.split("-")[0],n=r(t),i=e.placement.split("-")[1]||"",a=[];return a="flip"===this._options.flipBehavior?[t,n]:this._options.flipBehavior,a.forEach(function(s,l){if(t===s&&a.length!==l+1){t=e.placement.split("-")[0],n=r(t);var c=o(e.offsets.popper),u=-1!==["right","bottom"].indexOf(t);(u&&Math.floor(e.offsets.reference[t])>Math.floor(c[n])||!u&&Math.floor(e.offsets.reference[t])s[f]&&(e.offsets.popper[d]+=l[d]+p-s[f]);var m=l[d]+(n||l[u]/2-p/2),v=m-s[d];return v=Math.max(Math.min(s[u]-p-8,v),8),r[d]=v,r[h]="",e.offsets.arrow=r,e.arrowElement=t,e},Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(e){if(void 0===e||null===e)throw new TypeError("Cannot convert first argument to object");for(var t=Object(e),n=1;n=e.length?(this._t=void 0,r(1)):r(0,"keys"==t?n:"values"==t?e[n]:[n,e[n]])}),"values"),o.Arguments=o.Array,i("keys"),i("values"),i("entries")},"693d":function(e,t,n){"use strict";var i=n("ef08"),r=n("9c0e"),o=n("0bad"),a=n("512c"),s=n("ba01"),l=n("e34a").KEY,c=n("4b8b"),u=n("b367"),d=n("92f0"),h=n("8b1a"),f=n("cc15"),p=n("fcd4"),m=n("e198"),v=n("0ae2"),g=n("4ebc"),b=n("77e9"),y=n("7a41"),_=n("0983"),x=n("6ca1"),w=n("3397"),C=n("10db"),k=n("6f4f"),S=n("1836"),O=n("4d20"),$=n("fed5"),D=n("1a14"),E=n("9876"),T=O.f,P=D.f,M=S.f,I=i.Symbol,N=i.JSON,j=N&&N.stringify,A="prototype",F=f("_hidden"),L=f("toPrimitive"),V={}.propertyIsEnumerable,z=u("symbol-registry"),B=u("symbols"),R=u("op-symbols"),H=Object[A],W="function"==typeof I&&!!$.f,q=i.QObject,U=!q||!q[A]||!q[A].findChild,Y=o&&c((function(){return 7!=k(P({},"a",{get:function(){return P(this,"a",{value:7}).a}})).a}))?function(e,t,n){var i=T(H,t);i&&delete H[t],P(e,t,n),i&&e!==H&&P(H,t,i)}:P,K=function(e){var t=B[e]=k(I[A]);return t._k=e,t},G=W&&"symbol"==typeof I.iterator?function(e){return"symbol"==typeof e}:function(e){return e instanceof I},X=function(e,t,n){return e===H&&X(R,t,n),b(e),t=w(t,!0),b(n),r(B,t)?(n.enumerable?(r(e,F)&&e[F][t]&&(e[F][t]=!1),n=k(n,{enumerable:C(0,!1)})):(r(e,F)||P(e,F,C(1,{})),e[F][t]=!0),Y(e,t,n)):P(e,t,n)},Z=function(e,t){b(e);var n,i=v(t=x(t)),r=0,o=i.length;while(o>r)X(e,n=i[r++],t[n]);return e},J=function(e,t){return void 0===t?k(e):Z(k(e),t)},Q=function(e){var t=V.call(this,e=w(e,!0));return!(this===H&&r(B,e)&&!r(R,e))&&(!(t||!r(this,e)||!r(B,e)||r(this,F)&&this[F][e])||t)},ee=function(e,t){if(e=x(e),t=w(t,!0),e!==H||!r(B,t)||r(R,t)){var n=T(e,t);return!n||!r(B,t)||r(e,F)&&e[F][t]||(n.enumerable=!0),n}},te=function(e){var t,n=M(x(e)),i=[],o=0;while(n.length>o)r(B,t=n[o++])||t==F||t==l||i.push(t);return i},ne=function(e){var t,n=e===H,i=M(n?R:x(e)),o=[],a=0;while(i.length>a)!r(B,t=i[a++])||n&&!r(H,t)||o.push(B[t]);return o};W||(I=function(){if(this instanceof I)throw TypeError("Symbol is not a constructor!");var e=h(arguments.length>0?arguments[0]:void 0),t=function(n){this===H&&t.call(R,n),r(this,F)&&r(this[F],e)&&(this[F][e]=!1),Y(this,e,C(1,n))};return o&&U&&Y(H,e,{configurable:!0,set:t}),K(e)},s(I[A],"toString",(function(){return this._k})),O.f=ee,D.f=X,n("6438").f=S.f=te,n("1917").f=Q,$.f=ne,o&&!n("e444")&&s(H,"propertyIsEnumerable",Q,!0),p.f=function(e){return K(f(e))}),a(a.G+a.W+a.F*!W,{Symbol:I});for(var ie="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),re=0;ie.length>re;)f(ie[re++]);for(var oe=E(f.store),ae=0;oe.length>ae;)m(oe[ae++]);a(a.S+a.F*!W,"Symbol",{for:function(e){return r(z,e+="")?z[e]:z[e]=I(e)},keyFor:function(e){if(!G(e))throw TypeError(e+" is not a symbol!");for(var t in z)if(z[t]===e)return t},useSetter:function(){U=!0},useSimple:function(){U=!1}}),a(a.S+a.F*!W,"Object",{create:J,defineProperty:X,defineProperties:Z,getOwnPropertyDescriptor:ee,getOwnPropertyNames:te,getOwnPropertySymbols:ne});var se=c((function(){$.f(1)}));a(a.S+a.F*se,"Object",{getOwnPropertySymbols:function(e){return $.f(_(e))}}),N&&a(a.S+a.F*(!W||c((function(){var e=I();return"[null]"!=j([e])||"{}"!=j({a:e})||"{}"!=j(Object(e))}))),"JSON",{stringify:function(e){var t,n,i=[e],r=1;while(arguments.length>r)i.push(arguments[r++]);if(n=t=i[1],(y(t)||void 0!==e)&&!G(e))return g(t)||(t=function(e,t){if("function"==typeof n&&(t=n.call(this,e,t)),!G(t))return t}),i[1]=t,j.apply(N,i)}}),I[A][L]||n("051b")(I[A],L,I[A].valueOf),d(I,"Symbol"),d(Math,"Math",!0),d(i.JSON,"JSON",!0)},"69f3":function(e,t,n){var i,r,o,a=n("7f9a"),s=n("da84"),l=n("861d"),c=n("9112"),u=n("5135"),d=n("f772"),h=n("d012"),f=s.WeakMap,p=function(e){return o(e)?r(e):i(e,{})},m=function(e){return function(t){var n;if(!l(t)||(n=r(t)).type!==e)throw TypeError("Incompatible receiver, "+e+" required");return n}};if(a){var v=new f,g=v.get,b=v.has,y=v.set;i=function(e,t){return y.call(v,e,t),t},r=function(e){return g.call(v,e)||{}},o=function(e){return b.call(v,e)}}else{var _=d("state");h[_]=!0,i=function(e,t){return c(e,_,t),t},r=function(e){return u(e,_)?e[_]:{}},o=function(e){return u(e,_)}}e.exports={set:i,get:r,has:o,enforce:p,getterFor:m}},"6b7c":function(e,t,n){"use strict";t.__esModule=!0;var i=n("4897");t.default={methods:{t:function(){for(var e=arguments.length,t=Array(e),n=0;n0},e.prototype.connect_=function(){i&&!this.connected_&&(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),u?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){i&&this.connected_&&(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(e){var t=e.propertyName,n=void 0===t?"":t,i=c.some((function(e){return!!~n.indexOf(e)}));i&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),h=function(e,t){for(var n=0,i=Object.keys(t);n0},e}(),D="undefined"!==typeof WeakMap?new WeakMap:new n,E=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var n=d.getInstance(),i=new $(t,n,this);D.set(this,i)}return e}();["observe","unobserve","disconnect"].forEach((function(e){E.prototype[e]=function(){var t;return(t=D.get(this))[e].apply(t,arguments)}}));var T=function(){return"undefined"!==typeof r.ResizeObserver?r.ResizeObserver:E}();t["default"]=T}.call(this,n("c8ba"))},"6eeb":function(e,t,n){var i=n("da84"),r=n("5692"),o=n("9112"),a=n("5135"),s=n("ce4e"),l=n("9e81"),c=n("69f3"),u=c.get,d=c.enforce,h=String(l).split("toString");r("inspectSource",(function(e){return l.call(e)})),(e.exports=function(e,t,n,r){var l=!!r&&!!r.unsafe,c=!!r&&!!r.enumerable,u=!!r&&!!r.noTargetGet;"function"==typeof n&&("string"!=typeof t||a(n,"name")||o(n,"name",t),d(n).source=h.join("string"==typeof t?t:"")),e!==i?(l?!u&&e[t]&&(c=!0):delete e[t],c?e[t]=n:o(e,t,n)):c?e[t]=n:s(t,n)})(Function.prototype,"toString",(function(){return"function"==typeof this&&u(this).source||l.call(this)}))},"6f4f":function(e,t,n){var i=n("77e9"),r=n("85e7"),o=n("9742"),a=n("5a94")("IE_PROTO"),s=function(){},l="prototype",c=function(){var e,t=n("05f5")("iframe"),i=o.length,r="<",a=">";t.style.display="none",n("9141").appendChild(t),t.src="javascript:",e=t.contentWindow.document,e.open(),e.write(r+"script"+a+"document.F=Object"+r+"/script"+a),e.close(),c=e.F;while(i--)delete c[l][o[i]];return c()};e.exports=Object.create||function(e,t){var n;return null!==e?(s[l]=i(e),n=new s,s[l]=null,n[a]=e):n=c(),void 0===t?n:r(n,t)}},"722f":function(e,t,n){"use strict";t.__esModule=!0;var i="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r=n("e452"),o=a(r);function a(e){return e&&e.__esModule?e:{default:e}}var s,l=l||{};l.Dialog=function(e,t,n){var r=this;if(this.dialogNode=e,null===this.dialogNode||"dialog"!==this.dialogNode.getAttribute("role"))throw new Error("Dialog() requires a DOM element with ARIA role of dialog.");"string"===typeof t?this.focusAfterClosed=document.getElementById(t):"object"===("undefined"===typeof t?"undefined":i(t))?this.focusAfterClosed=t:this.focusAfterClosed=null,"string"===typeof n?this.focusFirst=document.getElementById(n):"object"===("undefined"===typeof n?"undefined":i(n))?this.focusFirst=n:this.focusFirst=null,this.focusFirst?this.focusFirst.focus():o.default.focusFirstDescendant(this.dialogNode),this.lastFocus=document.activeElement,s=function(e){r.trapFocus(e)},this.addListeners()},l.Dialog.prototype.addListeners=function(){document.addEventListener("focus",s,!0)},l.Dialog.prototype.removeListeners=function(){document.removeEventListener("focus",s,!0)},l.Dialog.prototype.closeDialog=function(){var e=this;this.removeListeners(),this.focusAfterClosed&&setTimeout((function(){e.focusAfterClosed.focus()}))},l.Dialog.prototype.trapFocus=function(e){o.default.IgnoreUtilFocusChanges||(this.dialogNode.contains(e.target)?this.lastFocus=e.target:(o.default.focusFirstDescendant(this.dialogNode),this.lastFocus===document.activeElement&&o.default.focusLastDescendant(this.dialogNode),this.lastFocus=document.activeElement))},t.default=l.Dialog},7418:function(e,t){t.f=Object.getOwnPropertySymbols},"77e9":function(e,t,n){var i=n("7a41");e.exports=function(e){if(!i(e))throw TypeError(e+" is not an object!");return e}},7839:function(e,t){e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},"7a41":function(e,t){e.exports=function(e){return"object"===typeof e?null!==e:"function"===typeof e}},"7a77":function(e,t,n){"use strict";function i(e){this.message=e}i.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},i.prototype.__CANCEL__=!0,e.exports=i},"7aac":function(e,t,n){"use strict";var i=n("c532");e.exports=i.isStandardBrowserEnv()?function(){return{write:function(e,t,n,r,o,a){var s=[];s.push(e+"="+encodeURIComponent(t)),i.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),i.isString(r)&&s.push("path="+r),i.isString(o)&&s.push("domain="+o),!0===a&&s.push("secure"),document.cookie=s.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},"7b0b":function(e,t,n){var i=n("1d80");e.exports=function(e){return Object(i(e))}},"7b3e":function(e,t,n){"use strict";var i,r=n("a3de"); +/** + * Checks if an event is supported in the current execution environment. + * + * NOTE: This will not work correctly for non-generic events such as `change`, + * `reset`, `load`, `error`, and `select`. + * + * Borrows from Modernizr. + * + * @param {string} eventNameSuffix Event name, e.g. "click". + * @param {?boolean} capture Check if the capture phase is supported. + * @return {boolean} True if the event is supported. + * @internal + * @license Modernizr 3.0.0pre (Custom Build) | MIT + */ +function o(e,t){if(!r.canUseDOM||t&&!("addEventListener"in document))return!1;var n="on"+e,o=n in document;if(!o){var a=document.createElement("div");a.setAttribute(n,"return;"),o="function"===typeof a[n]}return!o&&i&&"wheel"===e&&(o=document.implementation.hasFeature("Events.wheel","3.0")),o}r.canUseDOM&&(i=document.implementation&&document.implementation.hasFeature&&!0!==document.implementation.hasFeature("","")),e.exports=o},"7c73":function(e,t,n){var i=n("825a"),r=n("37e8"),o=n("7839"),a=n("d012"),s=n("1be4"),l=n("cc12"),c=n("f772"),u=c("IE_PROTO"),d="prototype",h=function(){},f=function(){var e,t=l("iframe"),n=o.length,i="<",r="script",a=">",c="java"+r+":";t.style.display="none",s.appendChild(t),t.src=String(c),e=t.contentWindow.document,e.open(),e.write(i+r+a+"document.F=Object"+i+"/"+r+a),e.close(),f=e.F;while(n--)delete f[d][o[n]];return f()};e.exports=Object.create||function(e,t){var n;return null!==e?(h[d]=i(e),n=new h,h[d]=null,n[u]=e):n=f(),void 0===t?n:r(n,t)},a[u]=!0},"7dd0":function(e,t,n){"use strict";var i=n("23e7"),r=n("9ed3"),o=n("e163"),a=n("d2bb"),s=n("d44e"),l=n("9112"),c=n("6eeb"),u=n("b622"),d=n("c430"),h=n("3f8c"),f=n("ae93"),p=f.IteratorPrototype,m=f.BUGGY_SAFARI_ITERATORS,v=u("iterator"),g="keys",b="values",y="entries",_=function(){return this};e.exports=function(e,t,n,u,f,x,w){r(n,t,u);var C,k,S,O=function(e){if(e===f&&P)return P;if(!m&&e in E)return E[e];switch(e){case g:return function(){return new n(this,e)};case b:return function(){return new n(this,e)};case y:return function(){return new n(this,e)}}return function(){return new n(this)}},$=t+" Iterator",D=!1,E=e.prototype,T=E[v]||E["@@iterator"]||f&&E[f],P=!m&&T||O(f),M="Array"==t&&E.entries||T;if(M&&(C=o(M.call(new e)),p!==Object.prototype&&C.next&&(d||o(C)===p||(a?a(C,p):"function"!=typeof C[v]&&l(C,v,_)),s(C,$,!0,!0),d&&(h[$]=_))),f==b&&T&&T.name!==b&&(D=!0,P=function(){return T.call(this)}),d&&!w||E[v]===P||l(E,v,P),h[t]=P,f)if(k={values:O(b),keys:x?P:O(g),entries:O(y)},w)for(S in k)!m&&!D&&S in E||c(E,S,k[S]);else i({target:t,proto:!0,forced:m||D},k);return k}},"7f4d":function(e,t,n){"use strict";t.__esModule=!0,t.default=function(e){for(var t=1,n=arguments.length;t0&&void 0!==arguments[0]?arguments[0]:"";return String(e).replace(/[|\\{}()[\]^$+*?.]/g,"\\$&")};var p=t.arrayFindIndex=function(e,t){for(var n=0;n!==e.length;++n)if(t(e[n]))return n;return-1},m=(t.arrayFind=function(e,t){var n=p(e,t);return-1!==n?e[n]:void 0},t.coerceTruthyValueToArray=function(e){return Array.isArray(e)?e:e?[e]:[]},t.isIE=function(){return!o.default.prototype.$isServer&&!isNaN(Number(document.documentMode))},t.isEdge=function(){return!o.default.prototype.$isServer&&navigator.userAgent.indexOf("Edge")>-1},t.isFirefox=function(){return!o.default.prototype.$isServer&&!!window.navigator.userAgent.match(/firefox/i)},t.autoprefixer=function(e){if("object"!==("undefined"===typeof e?"undefined":i(e)))return e;var t=["transform","transition","animation"],n=["ms-","webkit-"];return t.forEach((function(t){var i=e[t];t&&i&&n.forEach((function(n){e[n+t]=i}))})),e},t.kebabCase=function(e){var t=/([^-])([A-Z])/g;return e.replace(t,"$1-$2").replace(t,"$1-$2").toLowerCase()},t.capitalize=function(e){return(0,a.isString)(e)?e.charAt(0).toUpperCase()+e.slice(1):e},t.looseEqual=function(e,t){var n=(0,a.isObject)(e),i=(0,a.isObject)(t);return n&&i?JSON.stringify(e)===JSON.stringify(t):!n&&!i&&String(e)===String(t)}),v=t.arrayEquals=function(e,t){if(e=e||[],t=t||[],e.length!==t.length)return!1;for(var n=0;nl)i.f(e,n=a[l++],t[n]);return e}},"861d":function(e,t){e.exports=function(e){return"object"===typeof e?null!==e:"function"===typeof e}},"8a0d":function(e,t){e.exports={}},"8b1a":function(e,t){var n=0,i=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+i).toString(36))}},"8bbc":function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=123)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},123:function(e,t,n){"use strict";n.r(t);var i,r,o={name:"ElTag",props:{text:String,closable:Boolean,type:String,hit:Boolean,disableTransitions:Boolean,color:String,size:String,effect:{type:String,default:"light",validator:function(e){return-1!==["dark","light","plain"].indexOf(e)}}},methods:{handleClose:function(e){e.stopPropagation(),this.$emit("close",e)},handleClick:function(e){this.$emit("click",e)}},computed:{tagSize:function(){return this.size||(this.$ELEMENT||{}).size}},render:function(e){var t=this.type,n=this.tagSize,i=this.hit,r=this.effect,o=["el-tag",t?"el-tag--"+t:"",n?"el-tag--"+n:"",r?"el-tag--"+r:"",i&&"is-hit"],a=e("span",{class:o,style:{backgroundColor:this.color},on:{click:this.handleClick}},[this.$slots.default,this.closable&&e("i",{class:"el-tag__close el-icon-close",on:{click:this.handleClose}})]);return this.disableTransitions?a:e("transition",{attrs:{name:"el-zoom-in-center"}},[a])}},a=o,s=n(0),l=Object(s["a"])(a,i,r,!1,null,null,null);l.options.__file="packages/tag/src/tag.vue";var c=l.exports;c.install=function(e){e.component(c.name,c)};t["default"]=c}})},"8c4f":function(e,t,n){"use strict"; +/*! + * vue-router v3.1.3 + * (c) 2019 Evan You + * @license MIT + */function i(e,t){0}function r(e){return Object.prototype.toString.call(e).indexOf("Error")>-1}function o(e,t){return t instanceof e||t&&(t.name===e.name||t._name===e._name)}function a(e,t){for(var n in t)e[n]=t[n];return e}var s={name:"RouterView",functional:!0,props:{name:{type:String,default:"default"}},render:function(e,t){var n=t.props,i=t.children,r=t.parent,o=t.data;o.routerView=!0;var s=r.$createElement,c=n.name,u=r.$route,d=r._routerViewCache||(r._routerViewCache={}),h=0,f=!1;while(r&&r._routerRoot!==r){var p=r.$vnode&&r.$vnode.data;p&&(p.routerView&&h++,p.keepAlive&&r._inactive&&(f=!0)),r=r.$parent}if(o.routerViewDepth=h,f)return s(d[c],o,i);var m=u.matched[h];if(!m)return d[c]=null,s();var v=d[c]=m.components[c];o.registerRouteInstance=function(e,t){var n=m.instances[c];(t&&n!==e||!t&&n===e)&&(m.instances[c]=t)},(o.hook||(o.hook={})).prepatch=function(e,t){m.instances[c]=t.componentInstance},o.hook.init=function(e){e.data.keepAlive&&e.componentInstance&&e.componentInstance!==m.instances[c]&&(m.instances[c]=e.componentInstance)};var g=o.props=l(u,m.props&&m.props[c]);if(g){g=o.props=a({},g);var b=o.attrs=o.attrs||{};for(var y in g)v.props&&y in v.props||(b[y]=g[y],delete g[y])}return s(v,o,i)}};function l(e,t){switch(typeof t){case"undefined":return;case"object":return t;case"function":return t(e);case"boolean":return t?e.params:void 0;default:0}}var c=/[!'()*]/g,u=function(e){return"%"+e.charCodeAt(0).toString(16)},d=/%2C/g,h=function(e){return encodeURIComponent(e).replace(c,u).replace(d,",")},f=decodeURIComponent;function p(e,t,n){void 0===t&&(t={});var i,r=n||m;try{i=r(e||"")}catch(a){i={}}for(var o in t)i[o]=t[o];return i}function m(e){var t={};return e=e.trim().replace(/^(\?|#|&)/,""),e?(e.split("&").forEach((function(e){var n=e.replace(/\+/g," ").split("="),i=f(n.shift()),r=n.length>0?f(n.join("=")):null;void 0===t[i]?t[i]=r:Array.isArray(t[i])?t[i].push(r):t[i]=[t[i],r]})),t):t}function v(e){var t=e?Object.keys(e).map((function(t){var n=e[t];if(void 0===n)return"";if(null===n)return h(t);if(Array.isArray(n)){var i=[];return n.forEach((function(e){void 0!==e&&(null===e?i.push(h(t)):i.push(h(t)+"="+h(e)))})),i.join("&")}return h(t)+"="+h(n)})).filter((function(e){return e.length>0})).join("&"):null;return t?"?"+t:""}var g=/\/?$/;function b(e,t,n,i){var r=i&&i.options.stringifyQuery,o=t.query||{};try{o=y(o)}catch(s){}var a={name:t.name||e&&e.name,meta:e&&e.meta||{},path:t.path||"/",hash:t.hash||"",query:o,params:t.params||{},fullPath:w(t,r),matched:e?x(e):[]};return n&&(a.redirectedFrom=w(n,r)),Object.freeze(a)}function y(e){if(Array.isArray(e))return e.map(y);if(e&&"object"===typeof e){var t={};for(var n in e)t[n]=y(e[n]);return t}return e}var _=b(null,{path:"/"});function x(e){var t=[];while(e)t.unshift(e),e=e.parent;return t}function w(e,t){var n=e.path,i=e.query;void 0===i&&(i={});var r=e.hash;void 0===r&&(r="");var o=t||v;return(n||"/")+o(i)+r}function C(e,t){return t===_?e===t:!!t&&(e.path&&t.path?e.path.replace(g,"")===t.path.replace(g,"")&&e.hash===t.hash&&k(e.query,t.query):!(!e.name||!t.name)&&(e.name===t.name&&e.hash===t.hash&&k(e.query,t.query)&&k(e.params,t.params)))}function k(e,t){if(void 0===e&&(e={}),void 0===t&&(t={}),!e||!t)return e===t;var n=Object.keys(e),i=Object.keys(t);return n.length===i.length&&n.every((function(n){var i=e[n],r=t[n];return"object"===typeof i&&"object"===typeof r?k(i,r):String(i)===String(r)}))}function S(e,t){return 0===e.path.replace(g,"/").indexOf(t.path.replace(g,"/"))&&(!t.hash||e.hash===t.hash)&&O(e.query,t.query)}function O(e,t){for(var n in t)if(!(n in e))return!1;return!0}function $(e,t,n){var i=e.charAt(0);if("/"===i)return e;if("?"===i||"#"===i)return t+e;var r=t.split("/");n&&r[r.length-1]||r.pop();for(var o=e.replace(/^\//,"").split("/"),a=0;a=0&&(t=e.slice(i),e=e.slice(0,i));var r=e.indexOf("?");return r>=0&&(n=e.slice(r+1),e=e.slice(0,r)),{path:e,query:n,hash:t}}function E(e){return e.replace(/\/\//g,"/")}var T=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)},P=X,M=F,I=L,N=B,j=G,A=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function F(e,t){var n,i=[],r=0,o=0,a="",s=t&&t.delimiter||"/";while(null!=(n=A.exec(e))){var l=n[0],c=n[1],u=n.index;if(a+=e.slice(o,u),o=u+l.length,c)a+=c[1];else{var d=e[o],h=n[2],f=n[3],p=n[4],m=n[5],v=n[6],g=n[7];a&&(i.push(a),a="");var b=null!=h&&null!=d&&d!==h,y="+"===v||"*"===v,_="?"===v||"*"===v,x=n[2]||s,w=p||m;i.push({name:f||r++,prefix:h||"",delimiter:x,optional:_,repeat:y,partial:b,asterisk:!!g,pattern:w?H(w):g?".*":"[^"+R(x)+"]+?"})}}return o1||!x.length)return 0===x.length?e():e("span",{},x)}if("a"===this.tag)_.on=y,_.attrs={href:l};else{var w=ae(this.$slots.default);if(w){w.isStatic=!1;var k=w.data=a({},w.data);for(var O in k.on=k.on||{},k.on){var $=k.on[O];O in y&&(k.on[O]=Array.isArray($)?$:[$])}for(var D in y)D in k.on?k.on[D].push(y[D]):k.on[D]=g;var E=w.data.attrs=a({},w.data.attrs);E.href=l}else _.on=y}return e(this.tag,_,this.$slots.default)}};function oe(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&(void 0===e.button||0===e.button)){if(e.currentTarget&&e.currentTarget.getAttribute){var t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function ae(e){if(e)for(var t,n=0;n-1&&(s.params[h]=n.params[h]);return s.path=J(c.path,s.params,'named route "'+l+'"'),u(c,s,a)}if(s.path){s.params={};for(var f=0;f=e.length?n():e[r]?t(e[r],(function(){i(r+1)})):i(r+1)};i(0)}function Fe(e){return function(t,n,i){var o=!1,a=0,s=null;Le(e,(function(e,t,n,l){if("function"===typeof e&&void 0===e.cid){o=!0,a++;var c,u=Re((function(t){Be(t)&&(t=t.default),e.resolved="function"===typeof t?t:ee.extend(t),n.components[l]=t,a--,a<=0&&i()})),d=Re((function(e){var t="Failed to resolve async component "+l+": "+e;s||(s=r(e)?e:new Error(t),i(s))}));try{c=e(u,d)}catch(f){d(f)}if(c)if("function"===typeof c.then)c.then(u,d);else{var h=c.component;h&&"function"===typeof h.then&&h.then(u,d)}}})),o||i()}}function Le(e,t){return Ve(e.map((function(e){return Object.keys(e.components).map((function(n){return t(e.components[n],e.instances[n],e,n)}))})))}function Ve(e){return Array.prototype.concat.apply([],e)}var ze="function"===typeof Symbol&&"symbol"===typeof Symbol.toStringTag;function Be(e){return e.__esModule||ze&&"Module"===e[Symbol.toStringTag]}function Re(e){var t=!1;return function(){var n=[],i=arguments.length;while(i--)n[i]=arguments[i];if(!t)return t=!0,e.apply(this,n)}}var He=function(e){function t(t){e.call(this),this.name=this._name="NavigationDuplicated",this.message='Navigating to current location ("'+t.fullPath+'") is not allowed',Object.defineProperty(this,"stack",{value:(new e).stack,writable:!0,configurable:!0})}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t}(Error);He._name="NavigationDuplicated";var We=function(e,t){this.router=e,this.base=qe(t),this.current=_,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[]};function qe(e){if(!e)if(le){var t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^https?:\/\/[^\/]+/,"")}else e="/";return"/"!==e.charAt(0)&&(e="/"+e),e.replace(/\/$/,"")}function Ue(e,t){var n,i=Math.max(e.length,t.length);for(n=0;n-1?decodeURI(e.slice(0,i))+e.slice(i):decodeURI(e)}else n>-1&&(e=decodeURI(e.slice(0,n))+e.slice(n));return e}function st(e){var t=window.location.href,n=t.indexOf("#"),i=n>=0?t.slice(0,n):t;return i+"#"+e}function lt(e){Ie?Ne(st(e)):window.location.hash=e}function ct(e){Ie?je(st(e)):window.location.replace(st(e))}var ut=function(e){function t(t,n){e.call(this,t,n),this.stack=[],this.index=-1}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.push=function(e,t,n){var i=this;this.transitionTo(e,(function(e){i.stack=i.stack.slice(0,i.index+1).concat(e),i.index++,t&&t(e)}),n)},t.prototype.replace=function(e,t,n){var i=this;this.transitionTo(e,(function(e){i.stack=i.stack.slice(0,i.index).concat(e),t&&t(e)}),n)},t.prototype.go=function(e){var t=this,n=this.index+e;if(!(n<0||n>=this.stack.length)){var i=this.stack[n];this.confirmTransition(i,(function(){t.index=n,t.updateRoute(i)}),(function(e){o(He,e)&&(t.index=n)}))}},t.prototype.getCurrentLocation=function(){var e=this.stack[this.stack.length-1];return e?e.fullPath:"/"},t.prototype.ensureURL=function(){},t}(We),dt=function(e){void 0===e&&(e={}),this.app=null,this.apps=[],this.options=e,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=fe(e.routes||[],this);var t=e.mode||"hash";switch(this.fallback="history"===t&&!Ie&&!1!==e.fallback,this.fallback&&(t="hash"),le||(t="abstract"),this.mode=t,t){case"history":this.history=new tt(this,e.base);break;case"hash":this.history=new it(this,e.base,this.fallback);break;case"abstract":this.history=new ut(this,e.base);break;default:0}},ht={currentRoute:{configurable:!0}};function ft(e,t){return e.push(t),function(){var n=e.indexOf(t);n>-1&&e.splice(n,1)}}function pt(e,t,n){var i="hash"===n?"#"+t:t;return e?E(e+"/"+i):i}dt.prototype.match=function(e,t,n){return this.matcher.match(e,t,n)},ht.currentRoute.get=function(){return this.history&&this.history.current},dt.prototype.init=function(e){var t=this;if(this.apps.push(e),e.$once("hook:destroyed",(function(){var n=t.apps.indexOf(e);n>-1&&t.apps.splice(n,1),t.app===e&&(t.app=t.apps[0]||null)})),!this.app){this.app=e;var n=this.history;if(n instanceof tt)n.transitionTo(n.getCurrentLocation());else if(n instanceof it){var i=function(){n.setupListeners()};n.transitionTo(n.getCurrentLocation(),i,i)}n.listen((function(e){t.apps.forEach((function(t){t._route=e}))}))}},dt.prototype.beforeEach=function(e){return ft(this.beforeHooks,e)},dt.prototype.beforeResolve=function(e){return ft(this.resolveHooks,e)},dt.prototype.afterEach=function(e){return ft(this.afterHooks,e)},dt.prototype.onReady=function(e,t){this.history.onReady(e,t)},dt.prototype.onError=function(e){this.history.onError(e)},dt.prototype.push=function(e,t,n){var i=this;if(!t&&!n&&"undefined"!==typeof Promise)return new Promise((function(t,n){i.history.push(e,t,n)}));this.history.push(e,t,n)},dt.prototype.replace=function(e,t,n){var i=this;if(!t&&!n&&"undefined"!==typeof Promise)return new Promise((function(t,n){i.history.replace(e,t,n)}));this.history.replace(e,t,n)},dt.prototype.go=function(e){this.history.go(e)},dt.prototype.back=function(){this.go(-1)},dt.prototype.forward=function(){this.go(1)},dt.prototype.getMatchedComponents=function(e){var t=e?e.matched?e:this.resolve(e).route:this.currentRoute;return t?[].concat.apply([],t.matched.map((function(e){return Object.keys(e.components).map((function(t){return e.components[t]}))}))):[]},dt.prototype.resolve=function(e,t,n){t=t||this.history.current;var i=Q(e,t,n,this),r=this.match(i,t),o=r.redirectedFrom||r.fullPath,a=this.history.base,s=pt(a,o,this.mode);return{location:i,route:r,href:s,normalizedTo:i,resolved:r}},dt.prototype.addRoutes=function(e){this.matcher.addRoutes(e),this.history.current!==_&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(dt.prototype,ht),dt.install=se,dt.version="3.1.3",le&&window.Vue&&window.Vue.use(dt),t["a"]=dt},"8df4":function(e,t,n){"use strict";var i=n("7a77");function r(e){if("function"!==typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise((function(e){t=e}));var n=this;e((function(e){n.reason||(n.reason=new i(e),t(n.reason))}))}r.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},r.source=function(){var e,t=new r((function(t){e=t}));return{token:t,cancel:e}},e.exports=r},"8eb7":function(e,t){var n,i,r,o,a,s,l,c,u,d,h,f,p,m,v,g=!1;function b(){if(!g){g=!0;var e=navigator.userAgent,t=/(?:MSIE.(\d+\.\d+))|(?:(?:Firefox|GranParadiso|Iceweasel).(\d+\.\d+))|(?:Opera(?:.+Version.|.)(\d+\.\d+))|(?:AppleWebKit.(\d+(?:\.\d+)?))|(?:Trident\/\d+\.\d+.*rv:(\d+\.\d+))/.exec(e),b=/(Mac OS X)|(Windows)|(Linux)/.exec(e);if(f=/\b(iPhone|iP[ao]d)/.exec(e),p=/\b(iP[ao]d)/.exec(e),d=/Android/i.exec(e),m=/FBAN\/\w+;/i.exec(e),v=/Mobile/i.exec(e),h=!!/Win64/.exec(e),t){n=t[1]?parseFloat(t[1]):t[5]?parseFloat(t[5]):NaN,n&&document&&document.documentMode&&(n=document.documentMode);var y=/(?:Trident\/(\d+.\d+))/.exec(e);s=y?parseFloat(y[1])+4:n,i=t[2]?parseFloat(t[2]):NaN,r=t[3]?parseFloat(t[3]):NaN,o=t[4]?parseFloat(t[4]):NaN,o?(t=/(?:Chrome\/(\d+\.\d+))/.exec(e),a=t&&t[1]?parseFloat(t[1]):NaN):a=NaN}else n=i=r=a=o=NaN;if(b){if(b[1]){var _=/(?:Mac OS X (\d+(?:[._]\d+)?))/.exec(e);l=!_||parseFloat(_[1].replace("_","."))}else l=!1;c=!!b[2],u=!!b[3]}else l=c=u=!1}}var y={ie:function(){return b()||n},ieCompatibilityMode:function(){return b()||s>n},ie64:function(){return y.ie()&&h},firefox:function(){return b()||i},opera:function(){return b()||r},webkit:function(){return b()||o},safari:function(){return y.webkit()},chrome:function(){return b()||a},windows:function(){return b()||c},osx:function(){return b()||l},linux:function(){return b()||u},iphone:function(){return b()||f},mobile:function(){return b()||f||p||d||v},nativeApp:function(){return b()||m},android:function(){return b()||d},ipad:function(){return b()||p}};e.exports=y},"90e3":function(e,t){var n=0,i=Math.random();e.exports=function(e){return"Symbol("+String(void 0===e?"":e)+")_"+(++n+i).toString(36)}},9112:function(e,t,n){var i=n("83ab"),r=n("9bf2"),o=n("5c6c");e.exports=i?function(e,t,n){return r.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},9141:function(e,t,n){var i=n("ef08").document;e.exports=i&&i.documentElement},"92f0":function(e,t,n){var i=n("1a14").f,r=n("9c0e"),o=n("cc15")("toStringTag");e.exports=function(e,t,n){e&&!r(e=n?e:e.prototype,o)&&i(e,o,{configurable:!0,value:t})}},"92fa":function(e,t){var n=/^(attrs|props|on|nativeOn|class|style|hook)$/;function i(e,t){return function(){e&&e.apply(this,arguments),t&&t.apply(this,arguments)}}e.exports=function(e){return e.reduce((function(e,t){var r,o,a,s,l;for(a in t)if(r=e[a],o=t[a],r&&n.test(a))if("class"===a&&("string"===typeof r&&(l=r,e[a]=r={},r[l]=!0),"string"===typeof o&&(l=o,t[a]=o={},o[l]=!0)),"on"===a||"nativeOn"===a||"hook"===a)for(s in o)r[s]=i(r[s],o[s]);else if(Array.isArray(r))e[a]=r.concat(o);else if(Array.isArray(o))e[a]=[r].concat(o);else for(s in o)r[s]=o[s];else e[a]=t[a];return e}),{})}},"94ca":function(e,t,n){var i=n("d039"),r=/#|\.prototype\./,o=function(e,t){var n=s[a(e)];return n==c||n!=l&&("function"==typeof t?i(t):!!t)},a=o.normalize=function(e){return String(e).replace(r,".").toLowerCase()},s=o.data={},l=o.NATIVE="N",c=o.POLYFILL="P";e.exports=o},9619:function(e,t,n){var i=n("597f"),r=n("0e15");e.exports={throttle:i,debounce:r}},9742:function(e,t){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},9876:function(e,t,n){var i=n("03d6"),r=n("9742");e.exports=Object.keys||function(e){return i(e,r)}},"99af":function(e,t,n){"use strict";var i=n("23e7"),r=n("d039"),o=n("e8b5"),a=n("861d"),s=n("7b0b"),l=n("50c4"),c=n("8418"),u=n("65f0"),d=n("1dde"),h=n("b622"),f=n("60ae"),p=h("isConcatSpreadable"),m=9007199254740991,v="Maximum allowed index exceeded",g=f>=51||!r((function(){var e=[];return e[p]=!1,e.concat()[0]!==e})),b=d("concat"),y=function(e){if(!a(e))return!1;var t=e[p];return void 0!==t?!!t:o(e)},_=!g||!b;i({target:"Array",proto:!0,forced:_},{concat:function(e){var t,n,i,r,o,a=s(this),d=u(a,0),h=0;for(t=-1,i=arguments.length;tm)throw TypeError(v);for(n=0;n=m)throw TypeError(v);c(d,h++,o)}return d.length=h,d}})},"9bdd":function(e,t,n){var i=n("825a");e.exports=function(e,t,n,r){try{return r?t(i(n)[0],n[1]):t(n)}catch(a){var o=e["return"];throw void 0!==o&&i(o.call(e)),a}}},"9bf2":function(e,t,n){var i=n("83ab"),r=n("0cfb"),o=n("825a"),a=n("c04e"),s=Object.defineProperty;t.f=i?s:function(e,t,n){if(o(e),t=a(t,!0),o(n),r)try{return s(e,t,n)}catch(i){}if("get"in n||"set"in n)throw TypeError("Accessors not supported");return"value"in n&&(e[t]=n.value),e}},"9c0c":function(e,t,n){var i=n("1609");e.exports=function(e,t,n){if(i(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,i){return e.call(t,n,i)};case 3:return function(n,i,r){return e.call(t,n,i,r)}}return function(){return e.apply(t,arguments)}}},"9c0e":function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},"9d11":function(e,t,n){var i=n("fc5e"),r=Math.max,o=Math.min;e.exports=function(e,t){return e=i(e),e<0?r(e+t,0):o(e,t)}},"9d7e":function(e,t,n){"use strict";t.__esModule=!0;var i="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};t.default=function(e){function t(e){for(var t=arguments.length,n=Array(t>1?t-1:0),a=1;a=o)return e;switch(e){case"%s":return String(t[i++]);case"%d":return Number(t[i++]);case"%j":try{return JSON.stringify(t[i++])}catch(n){return"[Circular]"}break;default:return e}})),l=t[i];i()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,url:new RegExp("^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$","i"),hex:/^#?([a-f0-9]{6}|[a-f0-9]{3})$/i},C={integer:function(e){return C.number(e)&&parseInt(e,10)===e},float:function(e){return C.number(e)&&!C.integer(e)},array:function(e){return Array.isArray(e)},regexp:function(e){if(e instanceof RegExp)return!0;try{return!!new RegExp(e)}catch(t){return!1}},date:function(e){return"function"===typeof e.getTime&&"function"===typeof e.getMonth&&"function"===typeof e.getYear},number:function(e){return!isNaN(e)&&"number"===typeof e},object:function(e){return"object"===("undefined"===typeof e?"undefined":a()(e))&&!C.array(e)},method:function(e){return"function"===typeof e},email:function(e){return"string"===typeof e&&!!e.match(w.email)&&e.length<255},url:function(e){return"string"===typeof e&&!!e.match(w.url)},hex:function(e){return"string"===typeof e&&!!e.match(w.hex)}};function k(e,t,n,i,r){if(e.required&&void 0===t)y(e,t,n,i,r);else{var o=["integer","float","array","regexp","object","method","email","number","date","url","hex"],s=e.type;o.indexOf(s)>-1?C[s](t)||i.push(c(r.messages.types[s],e.fullField,e.type)):s&&("undefined"===typeof t?"undefined":a()(t))!==e.type&&i.push(c(r.messages.types[s],e.fullField,e.type))}}var S=k;function O(e,t,n,i,r){var o="number"===typeof e.len,a="number"===typeof e.min,s="number"===typeof e.max,l=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,u=t,d=null,h="number"===typeof t,f="string"===typeof t,p=Array.isArray(t);if(h?d="number":f?d="string":p&&(d="array"),!d)return!1;p&&(u=t.length),f&&(u=t.replace(l,"_").length),o?u!==e.len&&i.push(c(r.messages[d].len,e.fullField,e.len)):a&&!s&&ue.max?i.push(c(r.messages[d].max,e.fullField,e.max)):a&&s&&(ue.max)&&i.push(c(r.messages[d].range,e.fullField,e.min,e.max))}var $=O,D="enum";function E(e,t,n,i,r){e[D]=Array.isArray(e[D])?e[D]:[],-1===e[D].indexOf(t)&&i.push(c(r.messages[D],e.fullField,e[D].join(", ")))}var T=E;function P(e,t,n,i,r){if(e.pattern)if(e.pattern instanceof RegExp)e.pattern.lastIndex=0,e.pattern.test(t)||i.push(c(r.messages.pattern.mismatch,e.fullField,t,e.pattern));else if("string"===typeof e.pattern){var o=new RegExp(e.pattern);o.test(t)||i.push(c(r.messages.pattern.mismatch,e.fullField,t,e.pattern))}}var M=P,I={required:y,whitespace:x,type:S,range:$,enum:T,pattern:M};function N(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t,"string")&&!e.required)return n();I.required(e,t,i,o,r,"string"),d(t,"string")||(I.type(e,t,i,o,r),I.range(e,t,i,o,r),I.pattern(e,t,i,o,r),!0===e.whitespace&&I.whitespace(e,t,i,o,r))}n(o)}var j=N;function A(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),void 0!==t&&I.type(e,t,i,o,r)}n(o)}var F=A;function L(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),void 0!==t&&(I.type(e,t,i,o,r),I.range(e,t,i,o,r))}n(o)}var V=L;function z(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),void 0!==t&&I.type(e,t,i,o,r)}n(o)}var B=z;function R(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),d(t)||I.type(e,t,i,o,r)}n(o)}var H=R;function W(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),void 0!==t&&(I.type(e,t,i,o,r),I.range(e,t,i,o,r))}n(o)}var q=W;function U(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),void 0!==t&&(I.type(e,t,i,o,r),I.range(e,t,i,o,r))}n(o)}var Y=U;function K(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t,"array")&&!e.required)return n();I.required(e,t,i,o,r,"array"),d(t,"array")||(I.type(e,t,i,o,r),I.range(e,t,i,o,r))}n(o)}var G=K;function X(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),void 0!==t&&I.type(e,t,i,o,r)}n(o)}var Z=X,J="enum";function Q(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();I.required(e,t,i,o,r),t&&I[J](e,t,i,o,r)}n(o)}var ee=Q;function te(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t,"string")&&!e.required)return n();I.required(e,t,i,o,r),d(t,"string")||I.pattern(e,t,i,o,r)}n(o)}var ne=te;function ie(e,t,n,i,r){var o=[],a=e.required||!e.required&&i.hasOwnProperty(e.field);if(a){if(d(t)&&!e.required)return n();if(I.required(e,t,i,o,r),!d(t)){var s=void 0;s="number"===typeof t?new Date(t):t,I.type(e,s,i,o,r),s&&I.range(e,s.getTime(),i,o,r)}}n(o)}var re=ie;function oe(e,t,n,i,r){var o=[],s=Array.isArray(t)?"array":"undefined"===typeof t?"undefined":a()(t);I.required(e,t,i,o,r,s),n(o)}var ae=oe;function se(e,t,n,i,r){var o=e.type,a=[],s=e.required||!e.required&&i.hasOwnProperty(e.field);if(s){if(d(t,o)&&!e.required)return n();I.required(e,t,i,a,r,o),d(t,o)||I.type(e,t,i,a,r)}n(a)}var le=se,ce={string:j,method:F,number:V,boolean:B,regexp:H,integer:q,float:Y,array:G,object:Z,enum:ee,pattern:ne,date:re,url:le,hex:le,email:le,required:ae};function ue(){return{default:"Validation error on field %s",required:"%s is required",enum:"%s must be one of %s",whitespace:"%s cannot be empty",date:{format:"%s date %s is invalid for format %s",parse:"%s date could not be parsed, %s is invalid ",invalid:"%s date %s is invalid"},types:{string:"%s is not a %s",method:"%s is not a %s (function)",array:"%s is not an %s",object:"%s is not an %s",number:"%s is not a %s",date:"%s is not a %s",boolean:"%s is not a %s",integer:"%s is not an %s",float:"%s is not a %s",regexp:"%s is not a valid %s",email:"%s is not a valid %s",url:"%s is not a valid %s",hex:"%s is not a valid %s"},string:{len:"%s must be exactly %s characters",min:"%s must be at least %s characters",max:"%s cannot be longer than %s characters",range:"%s must be between %s and %s characters"},number:{len:"%s must equal %s",min:"%s cannot be less than %s",max:"%s cannot be greater than %s",range:"%s must be between %s and %s"},array:{len:"%s must be exactly %s in length",min:"%s cannot be less than %s in length",max:"%s cannot be greater than %s in length",range:"%s must be between %s and %s in length"},pattern:{mismatch:"%s value %s does not match pattern %s"},clone:function(){var e=JSON.parse(JSON.stringify(this));return e.clone=this.clone,e}}}var de=ue();function he(e){this.rules=null,this._messages=de,this.define(e)}he.prototype={messages:function(e){return e&&(this._messages=g(ue(),e)),this._messages},define:function(e){if(!e)throw new Error("Cannot configure a schema with no rules");if("object"!==("undefined"===typeof e?"undefined":a()(e))||Array.isArray(e))throw new Error("Rules must be an object");this.rules={};var t=void 0,n=void 0;for(t in e)e.hasOwnProperty(t)&&(n=e[t],this.rules[t]=Array.isArray(n)?n:[n])},validate:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments[2],o=e,s=n,u=i;if("function"===typeof s&&(u=s,s={}),this.rules&&0!==Object.keys(this.rules).length){if(s.messages){var d=this.messages();d===de&&(d=ue()),g(d,s.messages),s.messages=d}else s.messages=this.messages();var h=void 0,f=void 0,p={},b=s.keys||Object.keys(this.rules);b.forEach((function(n){h=t.rules[n],f=o[n],h.forEach((function(i){var a=i;"function"===typeof a.transform&&(o===e&&(o=r()({},o)),f=o[n]=a.transform(f)),a="function"===typeof a?{validator:a}:r()({},a),a.validator=t.getValidationMethod(a),a.field=n,a.fullField=a.fullField||n,a.type=t.getType(a),a.validator&&(p[n]=p[n]||[],p[n].push({rule:a,value:f,source:o,field:n}))}))}));var y={};m(p,s,(function(e,t){var n=e.rule,i=("object"===n.type||"array"===n.type)&&("object"===a()(n.fields)||"object"===a()(n.defaultField));function o(e,t){return r()({},t,{fullField:n.fullField+"."+e})}function u(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],u=a;if(Array.isArray(u)||(u=[u]),u.length&&l("async-validator:",u),u.length&&n.message&&(u=[].concat(n.message)),u=u.map(v(n)),s.first&&u.length)return y[n.field]=1,t(u);if(i){if(n.required&&!e.value)return u=n.message?[].concat(n.message).map(v(n)):s.error?[s.error(n,c(s.messages.required,n.field))]:[],t(u);var d={};if(n.defaultField)for(var h in e.value)e.value.hasOwnProperty(h)&&(d[h]=n.defaultField);for(var f in d=r()({},d,e.rule.fields),d)if(d.hasOwnProperty(f)){var p=Array.isArray(d[f])?d[f]:[d[f]];d[f]=p.map(o.bind(null,f))}var m=new he(d);m.messages(s.messages),e.rule.options&&(e.rule.options.messages=s.messages,e.rule.options.error=s.error),m.validate(e.value,e.rule.options||s,(function(e){t(e&&e.length?u.concat(e):e)}))}else t(u)}i=i&&(n.required||!n.required&&e.value),n.field=e.field;var d=n.validator(n,e.value,u,e.source,s);d&&d.then&&d.then((function(){return u()}),(function(e){return u(e)}))}),(function(e){_(e)}))}else u&&u();function _(e){var t=void 0,n=void 0,i=[],r={};function o(e){Array.isArray(e)?i=i.concat.apply(i,e):i.push(e)}for(t=0;tf)throw TypeError(p);for(u=l(b,i),m=0;my-i+n;m--)delete b[m-1]}else if(n>i)for(m=y-i;m>_;m--)v=m+i-1,g=m+n-1,v in b?b[g]=b[v]:delete b[g];for(m=0;m0?i:n)(e)}},a742:function(e,t,n){"use strict";function i(e){return"[object String]"===Object.prototype.toString.call(e)}function r(e){return"[object Object]"===Object.prototype.toString.call(e)}function o(e){return e&&e.nodeType===Node.ELEMENT_NODE}t.__esModule=!0,t.isString=i,t.isObject=r,t.isHtmlElement=o;t.isFunction=function(e){var t={};return e&&"[object Function]"===t.toString.call(e)},t.isUndefined=function(e){return void 0===e},t.isDefined=function(e){return void 0!==e&&null!==e}},a79d:function(e,t,n){"use strict";var i=n("23e7"),r=n("c430"),o=n("fea9"),a=n("d066"),s=n("4840"),l=n("cdf9"),c=n("6eeb");i({target:"Promise",proto:!0,real:!0},{finally:function(e){var t=s(this,a("Promise")),n="function"==typeof e;return this.then(n?function(n){return l(t,e()).then((function(){return n}))}:e,n?function(n){return l(t,e()).then((function(){throw n}))}:e)}}),r||"function"!=typeof o||o.prototype["finally"]||c(o.prototype,"finally",a("Promise").prototype["finally"])},ae93:function(e,t,n){"use strict";var i,r,o,a=n("e163"),s=n("9112"),l=n("5135"),c=n("b622"),u=n("c430"),d=c("iterator"),h=!1,f=function(){return this};[].keys&&(o=[].keys(),"next"in o?(r=a(a(o)),r!==Object.prototype&&(i=r)):h=!0),void 0==i&&(i={}),u||l(i,d)||s(i,d,f),e.exports={IteratorPrototype:i,BUGGY_SAFARI_ITERATORS:h}},b041:function(e,t,n){"use strict";var i=n("f5df"),r=n("b622"),o=r("toStringTag"),a={};a[o]="z",e.exports="[object z]"!==String(a)?function(){return"[object "+i(this)+"]"}:a.toString},b367:function(e,t,n){var i=n("5524"),r=n("ef08"),o="__core-js_shared__",a=r[o]||(r[o]={});(e.exports=function(e,t){return a[e]||(a[e]=void 0!==t?t:{})})("versions",[]).push({version:i.version,mode:n("e444")?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},b39a:function(e,t,n){var i=n("d066");e.exports=i("navigator","userAgent")||""},b50d:function(e,t,n){"use strict";var i=n("c532"),r=n("467f"),o=n("30b5"),a=n("c345"),s=n("3934"),l=n("2d83");e.exports=function(e){return new Promise((function(t,c){var u=e.data,d=e.headers;i.isFormData(u)&&delete d["Content-Type"];var h=new XMLHttpRequest;if(e.auth){var f=e.auth.username||"",p=e.auth.password||"";d.Authorization="Basic "+btoa(f+":"+p)}if(h.open(e.method.toUpperCase(),o(e.url,e.params,e.paramsSerializer),!0),h.timeout=e.timeout,h.onreadystatechange=function(){if(h&&4===h.readyState&&(0!==h.status||h.responseURL&&0===h.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in h?a(h.getAllResponseHeaders()):null,i=e.responseType&&"text"!==e.responseType?h.response:h.responseText,o={data:i,status:h.status,statusText:h.statusText,headers:n,config:e,request:h};r(t,c,o),h=null}},h.onerror=function(){c(l("Network Error",e,null,h)),h=null},h.ontimeout=function(){c(l("timeout of "+e.timeout+"ms exceeded",e,"ECONNABORTED",h)),h=null},i.isStandardBrowserEnv()){var m=n("7aac"),v=(e.withCredentials||s(e.url))&&e.xsrfCookieName?m.read(e.xsrfCookieName):void 0;v&&(d[e.xsrfHeaderName]=v)}if("setRequestHeader"in h&&i.forEach(d,(function(e,t){"undefined"===typeof u&&"content-type"===t.toLowerCase()?delete d[t]:h.setRequestHeader(t,e)})),e.withCredentials&&(h.withCredentials=!0),e.responseType)try{h.responseType=e.responseType}catch(g){if("json"!==e.responseType)throw g}"function"===typeof e.onDownloadProgress&&h.addEventListener("progress",e.onDownloadProgress),"function"===typeof e.onUploadProgress&&h.upload&&h.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then((function(e){h&&(h.abort(),c(e),h=null)})),void 0===u&&(u=null),h.send(u)}))}},b575:function(e,t,n){var i,r,o,a,s,l,c,u,d=n("da84"),h=n("06cf").f,f=n("c6b6"),p=n("2cf4").set,m=n("b39a"),v=d.MutationObserver||d.WebKitMutationObserver,g=d.process,b=d.Promise,y="process"==f(g),_=h(d,"queueMicrotask"),x=_&&_.value;x||(i=function(){var e,t;y&&(e=g.domain)&&e.exit();while(r){t=r.fn,r=r.next;try{t()}catch(n){throw r?a():o=void 0,n}}o=void 0,e&&e.enter()},y?a=function(){g.nextTick(i)}:v&&!/(iphone|ipod|ipad).*applewebkit/i.test(m)?(s=!0,l=document.createTextNode(""),new v(i).observe(l,{characterData:!0}),a=function(){l.data=s=!s}):b&&b.resolve?(c=b.resolve(void 0),u=c.then,a=function(){u.call(c,i)}):a=function(){p.call(d,i)}),e.exports=x||function(e){var t={fn:e,next:void 0};o&&(o.next=t),r||(r=t,a()),o=t}},b622:function(e,t,n){var i=n("da84"),r=n("5692"),o=n("90e3"),a=n("4930"),s=i.Symbol,l=r("wks");e.exports=function(e){return l[e]||(l[e]=a&&s[e]||(a?s:o)("Symbol."+e))}},b9c7:function(e,t,n){n("e507"),e.exports=n("5524").Object.assign},ba01:function(e,t,n){e.exports=n("051b")},bc3a:function(e,t,n){e.exports=n("cee4")},c04e:function(e,t,n){var i=n("861d");e.exports=function(e,t){if(!i(e))return e;var n,r;if(t&&"function"==typeof(n=e.toString)&&!i(r=n.call(e)))return r;if("function"==typeof(n=e.valueOf)&&!i(r=n.call(e)))return r;if(!t&&"function"==typeof(n=e.toString)&&!i(r=n.call(e)))return r;throw TypeError("Can't convert object to primitive value")}},c098:function(e,t,n){e.exports=n("d4af")},c284:function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=88)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},88:function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"el-progress",class:["el-progress--"+e.type,e.status?"is-"+e.status:"",{"el-progress--without-text":!e.showText,"el-progress--text-inside":e.textInside}],attrs:{role:"progressbar","aria-valuenow":e.percentage,"aria-valuemin":"0","aria-valuemax":"100"}},["line"===e.type?n("div",{staticClass:"el-progress-bar"},[n("div",{staticClass:"el-progress-bar__outer",style:{height:e.strokeWidth+"px"}},[n("div",{staticClass:"el-progress-bar__inner",style:e.barStyle},[e.showText&&e.textInside?n("div",{staticClass:"el-progress-bar__innerText"},[e._v(e._s(e.content))]):e._e()])])]):n("div",{staticClass:"el-progress-circle",style:{height:e.width+"px",width:e.width+"px"}},[n("svg",{attrs:{viewBox:"0 0 100 100"}},[n("path",{staticClass:"el-progress-circle__track",style:e.trailPathStyle,attrs:{d:e.trackPath,stroke:"#e5e9f2","stroke-width":e.relativeStrokeWidth,fill:"none"}}),n("path",{staticClass:"el-progress-circle__path",style:e.circlePathStyle,attrs:{d:e.trackPath,stroke:e.stroke,fill:"none","stroke-linecap":"round","stroke-width":e.percentage?e.relativeStrokeWidth:0}})])]),e.showText&&!e.textInside?n("div",{staticClass:"el-progress__text",style:{fontSize:e.progressTextSize+"px"}},[e.status?n("i",{class:e.iconClass}):[e._v(e._s(e.content))]],2):e._e()])},r=[];i._withStripped=!0;var o={name:"ElProgress",props:{type:{type:String,default:"line",validator:function(e){return["line","circle","dashboard"].indexOf(e)>-1}},percentage:{type:Number,default:0,required:!0,validator:function(e){return e>=0&&e<=100}},status:{type:String,validator:function(e){return["success","exception","warning"].indexOf(e)>-1}},strokeWidth:{type:Number,default:6},textInside:{type:Boolean,default:!1},width:{type:Number,default:126},showText:{type:Boolean,default:!0},color:{type:[String,Array,Function],default:""},format:Function},computed:{barStyle:function(){var e={};return e.width=this.percentage+"%",e.backgroundColor=this.getCurrentColor(this.percentage),e},relativeStrokeWidth:function(){return(this.strokeWidth/this.width*100).toFixed(1)},radius:function(){return"circle"===this.type||"dashboard"===this.type?parseInt(50-parseFloat(this.relativeStrokeWidth)/2,10):0},trackPath:function(){var e=this.radius,t="dashboard"===this.type;return"\n M 50 50\n m 0 "+(t?"":"-")+e+"\n a "+e+" "+e+" 0 1 1 0 "+(t?"-":"")+2*e+"\n a "+e+" "+e+" 0 1 1 0 "+(t?"":"-")+2*e+"\n "},perimeter:function(){return 2*Math.PI*this.radius},rate:function(){return"dashboard"===this.type?.75:1},strokeDashoffset:function(){var e=-1*this.perimeter*(1-this.rate)/2;return e+"px"},trailPathStyle:function(){return{strokeDasharray:this.perimeter*this.rate+"px, "+this.perimeter+"px",strokeDashoffset:this.strokeDashoffset}},circlePathStyle:function(){return{strokeDasharray:this.perimeter*this.rate*(this.percentage/100)+"px, "+this.perimeter+"px",strokeDashoffset:this.strokeDashoffset,transition:"stroke-dasharray 0.6s ease 0s, stroke 0.6s ease"}},stroke:function(){var e=void 0;if(this.color)e=this.getCurrentColor(this.percentage);else switch(this.status){case"success":e="#13ce66";break;case"exception":e="#ff4949";break;case"warning":e="#e6a23c";break;default:e="#20a0ff"}return e},iconClass:function(){return"warning"===this.status?"el-icon-warning":"line"===this.type?"success"===this.status?"el-icon-circle-check":"el-icon-circle-close":"success"===this.status?"el-icon-check":"el-icon-close"},progressTextSize:function(){return"line"===this.type?12+.4*this.strokeWidth:.111111*this.width+2},content:function(){return"function"===typeof this.format?this.format(this.percentage)||"":this.percentage+"%"}},methods:{getCurrentColor:function(e){return"function"===typeof this.color?this.color(e):"string"===typeof this.color?this.color:this.getLevelColor(e)},getLevelColor:function(e){for(var t=this.getColorArray().sort((function(e,t){return e.percentage-t.percentage})),n=0;ne)return t[n].color;return t[t.length-1].color},getColorArray:function(){var e=this.color,t=100/e.length;return e.map((function(e,n){return"string"===typeof e?{color:e,progress:(n+1)*t}:e}))}}},a=o,s=n(0),l=Object(s["a"])(a,i,r,!1,null,null,null);l.options.__file="packages/progress/src/progress.vue";var c=l.exports;c.install=function(e){e.component(c.name,c)};t["default"]=c}})},c345:function(e,t,n){"use strict";var i=n("c532"),r=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,o,a={};return e?(i.forEach(e.split("\n"),(function(e){if(o=e.indexOf(":"),t=i.trim(e.substr(0,o)).toLowerCase(),n=i.trim(e.substr(o+1)),t){if(a[t]&&r.indexOf(t)>=0)return;a[t]="set-cookie"===t?(a[t]?a[t]:[]).concat([n]):a[t]?a[t]+", "+n:n}})),a):a}},c401:function(e,t,n){"use strict";var i=n("c532");e.exports=function(e,t,n){return i.forEach(n,(function(n){e=n(e,t)})),e}},c430:function(e,t){e.exports=!1},c532:function(e,t,n){"use strict";var i=n("1d2b"),r=n("c7ce"),o=Object.prototype.toString;function a(e){return"[object Array]"===o.call(e)}function s(e){return"[object ArrayBuffer]"===o.call(e)}function l(e){return"undefined"!==typeof FormData&&e instanceof FormData}function c(e){var t;return t="undefined"!==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer,t}function u(e){return"string"===typeof e}function d(e){return"number"===typeof e}function h(e){return"undefined"===typeof e}function f(e){return null!==e&&"object"===typeof e}function p(e){return"[object Date]"===o.call(e)}function m(e){return"[object File]"===o.call(e)}function v(e){return"[object Blob]"===o.call(e)}function g(e){return"[object Function]"===o.call(e)}function b(e){return f(e)&&g(e.pipe)}function y(e){return"undefined"!==typeof URLSearchParams&&e instanceof URLSearchParams}function _(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function x(){return("undefined"===typeof navigator||"ReactNative"!==navigator.product)&&("undefined"!==typeof window&&"undefined"!==typeof document)}function w(e,t){if(null!==e&&"undefined"!==typeof e)if("object"!==typeof e&&(e=[e]),a(e))for(var n=0,i=e.length;n2&&void 0!==arguments[2]?arguments[2]:300,i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(!e||!t)throw new Error("instance & callback is required");var r=!1,o=function(){r||(r=!0,t&&t.apply(null,arguments))};i?e.$once("after-leave",o):e.$on("after-leave",o),setTimeout((function(){o()}),n+100)}},c6b6:function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},c6cd:function(e,t,n){var i=n("da84"),r=n("ce4e"),o="__core-js_shared__",a=i[o]||r(o,{});e.exports=a},c7ce:function(e,t){ +/*! + * Determine if an object is a Buffer + * + * @author Feross Aboukhadijeh + * @license MIT + */ +e.exports=function(e){return null!=e&&null!=e.constructor&&"function"===typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}},c8af:function(e,t,n){"use strict";var i=n("c532");e.exports=function(e,t){i.forEach(e,(function(n,i){i!==t&&i.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[i])}))}},c8ba:function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(i){"object"===typeof window&&(n=window)}e.exports=n},c901:function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},ca84:function(e,t,n){var i=n("5135"),r=n("fc6a"),o=n("4d64").indexOf,a=n("d012");e.exports=function(e,t){var n,s=r(e),l=0,c=[];for(n in s)!i(a,n)&&i(s,n)&&c.push(n);while(t.length>l)i(s,n=t[l++])&&(~o(c,n)||c.push(n));return c}},cc12:function(e,t,n){var i=n("da84"),r=n("861d"),o=i.document,a=r(o)&&r(o.createElement);e.exports=function(e){return a?o.createElement(e):{}}},cc15:function(e,t,n){var i=n("b367")("wks"),r=n("8b1a"),o=n("ef08").Symbol,a="function"==typeof o,s=e.exports=function(e){return i[e]||(i[e]=a&&o[e]||(a?o:r)("Symbol."+e))};s.store=i},cca6:function(e,t,n){var i=n("23e7"),r=n("60da");i({target:"Object",stat:!0,forced:Object.assign!==r},{assign:r})},cdf9:function(e,t,n){var i=n("825a"),r=n("861d"),o=n("f069");e.exports=function(e,t){if(i(e),r(t)&&t.constructor===e)return t;var n=o.f(e),a=n.resolve;return a(t),n.promise}},ce4e:function(e,t,n){var i=n("da84"),r=n("9112");e.exports=function(e,t){try{r(i,e,t)}catch(n){i[e]=t}return t}},ce7a:function(e,t,n){var i=n("9c0e"),r=n("0983"),o=n("5a94")("IE_PROTO"),a=Object.prototype;e.exports=Object.getPrototypeOf||function(e){return e=r(e),i(e,o)?e[o]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?a:null}},cee4:function(e,t,n){"use strict";var i=n("c532"),r=n("1d2b"),o=n("0a06"),a=n("2444");function s(e){var t=new o(e),n=r(o.prototype.request,t);return i.extend(n,o.prototype,t),i.extend(n,t),n}var l=s(a);l.Axios=o,l.create=function(e){return s(i.merge(a,e))},l.Cancel=n("7a77"),l.CancelToken=n("8df4"),l.isCancel=n("2e67"),l.all=function(e){return Promise.all(e)},l.spread=n("0df6"),e.exports=l,e.exports.default=l},d010:function(e,t,n){"use strict";function i(e,t,n){this.$children.forEach((function(r){var o=r.$options.componentName;o===e?r.$emit.apply(r,[t].concat(n)):i.apply(r,[e,t].concat([n]))}))}t.__esModule=!0,t.default={methods:{dispatch:function(e,t,n){var i=this.$parent||this.$root,r=i.$options.componentName;while(i&&(!r||r!==e))i=i.$parent,i&&(r=i.$options.componentName);i&&i.$emit.apply(i,[t].concat(n))},broadcast:function(e,t,n){i.call(this,e,t,n)}}}},d012:function(e,t){e.exports={}},d039:function(e,t){e.exports=function(e){try{return!!e()}catch(t){return!0}}},d066:function(e,t,n){var i=n("428f"),r=n("da84"),o=function(e){return"function"==typeof e?e:void 0};e.exports=function(e,t){return arguments.length<2?o(i[e])||o(r[e]):i[e]&&i[e][t]||r[e]&&r[e][t]}},d16a:function(e,t,n){var i=n("fc5e"),r=Math.min;e.exports=function(e){return e>0?r(i(e),9007199254740991):0}},d1e7:function(e,t,n){"use strict";var i={}.propertyIsEnumerable,r=Object.getOwnPropertyDescriptor,o=r&&!i.call({1:2},1);t.f=o?function(e){var t=r(this,e);return!!t&&t.enumerable}:i},d2bb:function(e,t,n){var i=n("825a"),r=n("3bbe");e.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var e,t=!1,n={};try{e=Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set,e.call(n,[]),t=n instanceof Array}catch(o){}return function(n,o){return i(n),r(o),t?e.call(n,o):n.__proto__=o,n}}():void 0)},d397:function(e,t,n){"use strict";function i(e){return void 0!==e&&null!==e}function r(e){var t=/([(\uAC00-\uD7AF)|(\u3130-\u318F)])+/gi;return t.test(e)}t.__esModule=!0,t.isDef=i,t.isKorean=r},d3b7:function(e,t,n){var i=n("6eeb"),r=n("b041"),o=Object.prototype;r!==o.toString&&i(o,"toString",r,{unsafe:!0})},d44e:function(e,t,n){var i=n("9bf2").f,r=n("5135"),o=n("b622"),a=o("toStringTag");e.exports=function(e,t,n){e&&!r(e=n?e:e.prototype,a)&&i(e,a,{configurable:!0,value:t})}},d4af:function(e,t,n){"use strict";var i=n("8eb7"),r=n("7b3e"),o=10,a=40,s=800;function l(e){var t=0,n=0,i=0,r=0;return"detail"in e&&(n=e.detail),"wheelDelta"in e&&(n=-e.wheelDelta/120),"wheelDeltaY"in e&&(n=-e.wheelDeltaY/120),"wheelDeltaX"in e&&(t=-e.wheelDeltaX/120),"axis"in e&&e.axis===e.HORIZONTAL_AXIS&&(t=n,n=0),i=t*o,r=n*o,"deltaY"in e&&(r=e.deltaY),"deltaX"in e&&(i=e.deltaX),(i||r)&&e.deltaMode&&(1==e.deltaMode?(i*=a,r*=a):(i*=s,r*=s)),i&&!t&&(t=i<1?-1:1),r&&!n&&(n=r<1?-1:1),{spinX:t,spinY:n,pixelX:i,pixelY:r}}l.getEventType=function(){return i.firefox()?"DOMMouseScroll":r("wheel")?"wheel":"mousewheel"},e.exports=l},d7d1:function(e,t,n){"use strict";var i;(function(r){var o={},a=/d{1,4}|M{1,4}|yy(?:yy)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g,s="\\d\\d?",l="\\d{3}",c="\\d{4}",u="[^\\s]+",d=/\[([^]*?)\]/gm,h=function(){};function f(e){return e.replace(/[|\\{()[^$+*?.-]/g,"\\$&")}function p(e,t){for(var n=[],i=0,r=e.length;i3?0:(e-e%10!==10)*e%10]}};var x={D:function(e){return e.getDay()},DD:function(e){return v(e.getDay())},Do:function(e,t){return t.DoFn(e.getDate())},d:function(e){return e.getDate()},dd:function(e){return v(e.getDate())},ddd:function(e,t){return t.dayNamesShort[e.getDay()]},dddd:function(e,t){return t.dayNames[e.getDay()]},M:function(e){return e.getMonth()+1},MM:function(e){return v(e.getMonth()+1)},MMM:function(e,t){return t.monthNamesShort[e.getMonth()]},MMMM:function(e,t){return t.monthNames[e.getMonth()]},yy:function(e){return v(String(e.getFullYear()),4).substr(2)},yyyy:function(e){return v(e.getFullYear(),4)},h:function(e){return e.getHours()%12||12},hh:function(e){return v(e.getHours()%12||12)},H:function(e){return e.getHours()},HH:function(e){return v(e.getHours())},m:function(e){return e.getMinutes()},mm:function(e){return v(e.getMinutes())},s:function(e){return e.getSeconds()},ss:function(e){return v(e.getSeconds())},S:function(e){return Math.round(e.getMilliseconds()/100)},SS:function(e){return v(Math.round(e.getMilliseconds()/10),2)},SSS:function(e){return v(e.getMilliseconds(),3)},a:function(e,t){return e.getHours()<12?t.amPm[0]:t.amPm[1]},A:function(e,t){return e.getHours()<12?t.amPm[0].toUpperCase():t.amPm[1].toUpperCase()},ZZ:function(e){var t=e.getTimezoneOffset();return(t>0?"-":"+")+v(100*Math.floor(Math.abs(t)/60)+Math.abs(t)%60,4)}},w={d:[s,function(e,t){e.day=t}],Do:[s+u,function(e,t){e.day=parseInt(t,10)}],M:[s,function(e,t){e.month=t-1}],yy:[s,function(e,t){var n=new Date,i=+(""+n.getFullYear()).substr(0,2);e.year=""+(t>68?i-1:i)+t}],h:[s,function(e,t){e.hour=t}],m:[s,function(e,t){e.minute=t}],s:[s,function(e,t){e.second=t}],yyyy:[c,function(e,t){e.year=t}],S:["\\d",function(e,t){e.millisecond=100*t}],SS:["\\d{2}",function(e,t){e.millisecond=10*t}],SSS:[l,function(e,t){e.millisecond=t}],D:[s,h],ddd:[u,h],MMM:[u,m("monthNamesShort")],MMMM:[u,m("monthNames")],a:[u,function(e,t,n){var i=t.toLowerCase();i===n.amPm[0]?e.isPm=!1:i===n.amPm[1]&&(e.isPm=!0)}],ZZ:["[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z",function(e,t){var n,i=(t+"").match(/([+-]|\d\d)/gi);i&&(n=60*i[1]+parseInt(i[2],10),e.timezoneOffset="+"===i[0]?n:-n)}]};w.dd=w.d,w.dddd=w.ddd,w.DD=w.D,w.mm=w.m,w.hh=w.H=w.HH=w.h,w.MM=w.M,w.ss=w.s,w.A=w.a,o.masks={default:"ddd MMM dd yyyy HH:mm:ss",shortDate:"M/D/yy",mediumDate:"MMM d, yyyy",longDate:"MMMM d, yyyy",fullDate:"dddd, MMMM d, yyyy",shortTime:"HH:mm",mediumTime:"HH:mm:ss",longTime:"HH:mm:ss.SSS"},o.format=function(e,t,n){var i=n||o.i18n;if("number"===typeof e&&(e=new Date(e)),"[object Date]"!==Object.prototype.toString.call(e)||isNaN(e.getTime()))throw new Error("Invalid Date in fecha.format");t=o.masks[t]||t||o.masks["default"];var r=[];return t=t.replace(d,(function(e,t){return r.push(t),"@@@"})),t=t.replace(a,(function(t){return t in x?x[t](e,i):t.slice(1,t.length-1)})),t.replace(/@@@/g,(function(){return r.shift()}))},o.parse=function(e,t,n){var i=n||o.i18n;if("string"!==typeof t)throw new Error("Invalid format in fecha.parse");if(t=o.masks[t]||t,e.length>1e3)return null;var r={},s=[],l=[];t=t.replace(d,(function(e,t){return l.push(t),"@@@"}));var c=f(t).replace(a,(function(e){if(w[e]){var t=w[e];return s.push(t[1]),"("+t[0]+")"}return e}));c=c.replace(/@@@/g,(function(){return l.shift()}));var u=e.match(new RegExp(c,"i"));if(!u)return null;for(var h=1;h1&&void 0!==arguments[1]?arguments[1]:1;return new Date(e.getFullYear(),e.getMonth(),e.getDate()-t)});t.nextDate=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t)},t.getStartDateOfMonth=function(e,t){var n=new Date(e,t,1),i=n.getDay();return m(n,0===i?7:i)},t.getWeekNumber=function(e){if(!h(e))return null;var t=new Date(e.getTime());t.setHours(0,0,0,0),t.setDate(t.getDate()+3-(t.getDay()+6)%7);var n=new Date(t.getFullYear(),0,4);return 1+Math.round(((t.getTime()-n.getTime())/864e5-3+(n.getDay()+6)%7)/7)},t.getRangeHours=function(e){var t=[],n=[];if((e||[]).forEach((function(e){var t=e.map((function(e){return e.getHours()}));n=n.concat(c(t[0],t[1]))})),n.length)for(var i=0;i<24;i++)t[i]=-1===n.indexOf(i);else for(var r=0;r<24;r++)t[r]=!1;return t},t.getPrevMonthLastDays=function(e,t){if(t<=0)return[];var n=new Date(e.getTime());n.setDate(0);var i=n.getDate();return g(t).map((function(e,n){return i-(t-n-1)}))},t.getMonthDays=function(e){var t=new Date(e.getFullYear(),e.getMonth()+1,0),n=t.getDate();return g(n).map((function(e,t){return t+1}))};function v(e,t,n,i){for(var r=t;r0?e.forEach((function(e){var i=e[0],r=e[1],o=i.getHours(),a=i.getMinutes(),s=r.getHours(),l=r.getMinutes();o===t&&s!==t?v(n,a,60,!0):o===t&&s===t?v(n,a,l+1,!0):o!==t&&s===t?v(n,0,l+1,!0):ot&&v(n,0,60,!0)})):v(n,0,60,!0),n};var g=t.range=function(e){return Array.apply(null,{length:e}).map((function(e,t){return t}))},b=t.modifyDate=function(e,t,n,i){return new Date(t,n,i,e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds())},y=t.modifyTime=function(e,t,n,i){return new Date(e.getFullYear(),e.getMonth(),e.getDate(),t,n,i,e.getMilliseconds())},_=(t.modifyWithTimeString=function(e,t){return null!=e&&t?(t=f(t,"HH:mm:ss"),y(e,t.getHours(),t.getMinutes(),t.getSeconds())):e},t.clearTime=function(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate())},t.clearMilliseconds=function(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds(),0)},t.limitTimeRange=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"HH:mm:ss";if(0===t.length)return e;var i=function(e){return r.default.parse(r.default.format(e,n),n)},o=i(e),a=t.map((function(e){return e.map(i)}));if(a.some((function(e){return o>=e[0]&&o<=e[1]})))return e;var s=a[0][0],l=a[0][0];a.forEach((function(e){s=new Date(Math.min(e[0],s)),l=new Date(Math.max(e[1],s))}));var c=o1&&void 0!==arguments[1]?arguments[1]:1,n=e.getFullYear(),i=e.getMonth();return x(e,n-t,i)},t.nextYear=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=e.getFullYear(),i=e.getMonth();return x(e,n+t,i)},t.extractDateFormat=function(e){return e.replace(/\W?m{1,2}|\W?ZZ/g,"").replace(/\W?h{1,2}|\W?s{1,3}|\W?a/gi,"").trim()},t.extractTimeFormat=function(e){return e.replace(/\W?D{1,2}|\W?Do|\W?d{1,4}|\W?M{1,4}|\W?y{2,4}/g,"").trim()},t.validateRangeInOneMonth=function(e,t){return e.getMonth()===t.getMonth()&&e.getFullYear()===t.getFullYear()}},da84:function(e,t,n){(function(t){var n=function(e){return e&&e.Math==Math&&e};e.exports=n("object"==typeof globalThis&&globalThis)||n("object"==typeof window&&window)||n("object"==typeof self&&self)||n("object"==typeof t&&t)||Function("return this")()}).call(this,n("c8ba"))},dcdc:function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=98)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},4:function(e,t){e.exports=n("d010")},98:function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("label",{staticClass:"el-checkbox",class:[e.border&&e.checkboxSize?"el-checkbox--"+e.checkboxSize:"",{"is-disabled":e.isDisabled},{"is-bordered":e.border},{"is-checked":e.isChecked}],attrs:{id:e.id}},[n("span",{staticClass:"el-checkbox__input",class:{"is-disabled":e.isDisabled,"is-checked":e.isChecked,"is-indeterminate":e.indeterminate,"is-focus":e.focus},attrs:{tabindex:!!e.indeterminate&&0,role:!!e.indeterminate&&"checkbox","aria-checked":!!e.indeterminate&&"mixed"}},[n("span",{staticClass:"el-checkbox__inner"}),e.trueLabel||e.falseLabel?n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],staticClass:"el-checkbox__original",attrs:{type:"checkbox","aria-hidden":e.indeterminate?"true":"false",name:e.name,disabled:e.isDisabled,"true-value":e.trueLabel,"false-value":e.falseLabel},domProps:{checked:Array.isArray(e.model)?e._i(e.model,null)>-1:e._q(e.model,e.trueLabel)},on:{change:[function(t){var n=e.model,i=t.target,r=i.checked?e.trueLabel:e.falseLabel;if(Array.isArray(n)){var o=null,a=e._i(n,o);i.checked?a<0&&(e.model=n.concat([o])):a>-1&&(e.model=n.slice(0,a).concat(n.slice(a+1)))}else e.model=r},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}}):n("input",{directives:[{name:"model",rawName:"v-model",value:e.model,expression:"model"}],staticClass:"el-checkbox__original",attrs:{type:"checkbox","aria-hidden":e.indeterminate?"true":"false",disabled:e.isDisabled,name:e.name},domProps:{value:e.label,checked:Array.isArray(e.model)?e._i(e.model,e.label)>-1:e.model},on:{change:[function(t){var n=e.model,i=t.target,r=!!i.checked;if(Array.isArray(n)){var o=e.label,a=e._i(n,o);i.checked?a<0&&(e.model=n.concat([o])):a>-1&&(e.model=n.slice(0,a).concat(n.slice(a+1)))}else e.model=r},e.handleChange],focus:function(t){e.focus=!0},blur:function(t){e.focus=!1}}})]),e.$slots.default||e.label?n("span",{staticClass:"el-checkbox__label"},[e._t("default"),e.$slots.default?e._e():[e._v(e._s(e.label))]],2):e._e()])},r=[];i._withStripped=!0;var o=n(4),a=n.n(o),s={name:"ElCheckbox",mixins:[a.a],inject:{elForm:{default:""},elFormItem:{default:""}},componentName:"ElCheckbox",data:function(){return{selfModel:!1,focus:!1,isLimitExceeded:!1}},computed:{model:{get:function(){return this.isGroup?this.store:void 0!==this.value?this.value:this.selfModel},set:function(e){this.isGroup?(this.isLimitExceeded=!1,void 0!==this._checkboxGroup.min&&e.lengththis._checkboxGroup.max&&(this.isLimitExceeded=!0),!1===this.isLimitExceeded&&this.dispatch("ElCheckboxGroup","input",[e])):(this.$emit("input",e),this.selfModel=e)}},isChecked:function(){return"[object Boolean]"==={}.toString.call(this.model)?this.model:Array.isArray(this.model)?this.model.indexOf(this.label)>-1:null!==this.model&&void 0!==this.model?this.model===this.trueLabel:void 0},isGroup:function(){var e=this.$parent;while(e){if("ElCheckboxGroup"===e.$options.componentName)return this._checkboxGroup=e,!0;e=e.$parent}return!1},store:function(){return this._checkboxGroup?this._checkboxGroup.value:this.value},isLimitDisabled:function(){var e=this._checkboxGroup,t=e.max,n=e.min;return!(!t&&!n)&&this.model.length>=t&&!this.isChecked||this.model.length<=n&&this.isChecked},isDisabled:function(){return this.isGroup?this._checkboxGroup.disabled||this.disabled||(this.elForm||{}).disabled||this.isLimitDisabled:this.disabled||(this.elForm||{}).disabled},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},checkboxSize:function(){var e=this.size||this._elFormItemSize||(this.$ELEMENT||{}).size;return this.isGroup&&this._checkboxGroup.checkboxGroupSize||e}},props:{value:{},label:{},indeterminate:Boolean,disabled:Boolean,checked:Boolean,name:String,trueLabel:[String,Number],falseLabel:[String,Number],id:String,controls:String,border:Boolean,size:String},methods:{addToStore:function(){Array.isArray(this.model)&&-1===this.model.indexOf(this.label)?this.model.push(this.label):this.model=this.trueLabel||!0},handleChange:function(e){var t=this;if(!this.isLimitExceeded){var n=void 0;n=e.target.checked?void 0===this.trueLabel||this.trueLabel:void 0!==this.falseLabel&&this.falseLabel,this.$emit("change",n,e),this.$nextTick((function(){t.isGroup&&t.dispatch("ElCheckboxGroup","change",[t._checkboxGroup.value])}))}}},created:function(){this.checked&&this.addToStore()},mounted:function(){this.indeterminate&&this.$el.setAttribute("aria-controls",this.controls)},watch:{value:function(e){this.dispatch("ElFormItem","el.form.change",e)}}},l=s,c=n(0),u=Object(c["a"])(l,i,r,!1,null,null,null);u.options.__file="packages/checkbox/src/checkbox.vue";var d=u.exports;d.install=function(e){e.component(d.name,d)};t["default"]=d}})},df75:function(e,t,n){var i=n("ca84"),r=n("7839");e.exports=Object.keys||function(e){return i(e,r)}},df7c:function(e,t,n){(function(e){function n(e,t){for(var n=0,i=e.length-1;i>=0;i--){var r=e[i];"."===r?e.splice(i,1):".."===r?(e.splice(i,1),n++):n&&(e.splice(i,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}function i(e){"string"!==typeof e&&(e+="");var t,n=0,i=-1,r=!0;for(t=e.length-1;t>=0;--t)if(47===e.charCodeAt(t)){if(!r){n=t+1;break}}else-1===i&&(r=!1,i=t+1);return-1===i?"":e.slice(n,i)}function r(e,t){if(e.filter)return e.filter(t);for(var n=[],i=0;i=-1&&!i;o--){var a=o>=0?arguments[o]:e.cwd();if("string"!==typeof a)throw new TypeError("Arguments to path.resolve must be strings");a&&(t=a+"/"+t,i="/"===a.charAt(0))}return t=n(r(t.split("/"),(function(e){return!!e})),!i).join("/"),(i?"/":"")+t||"."},t.normalize=function(e){var i=t.isAbsolute(e),a="/"===o(e,-1);return e=n(r(e.split("/"),(function(e){return!!e})),!i).join("/"),e||i||(e="."),e&&a&&(e+="/"),(i?"/":"")+e},t.isAbsolute=function(e){return"/"===e.charAt(0)},t.join=function(){var e=Array.prototype.slice.call(arguments,0);return t.normalize(r(e,(function(e,t){if("string"!==typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},t.relative=function(e,n){function i(e){for(var t=0;t=0;n--)if(""!==e[n])break;return t>n?[]:e.slice(t,n-t+1)}e=t.resolve(e).substr(1),n=t.resolve(n).substr(1);for(var r=i(e.split("/")),o=i(n.split("/")),a=Math.min(r.length,o.length),s=a,l=0;l=1;--o)if(t=e.charCodeAt(o),47===t){if(!r){i=o;break}}else r=!1;return-1===i?n?"/":".":n&&1===i?"/":e.slice(0,i)},t.basename=function(e,t){var n=i(e);return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},t.extname=function(e){"string"!==typeof e&&(e+="");for(var t=-1,n=0,i=-1,r=!0,o=0,a=e.length-1;a>=0;--a){var s=e.charCodeAt(a);if(47!==s)-1===i&&(r=!1,i=a+1),46===s?-1===t?t=a:1!==o&&(o=1):-1!==t&&(o=-1);else if(!r){n=a+1;break}}return-1===t||-1===i||0===o||1===o&&t===i-1&&t===n+1?"":e.slice(t,i)};var o="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)}}).call(this,n("4362"))},dfe5:function(e,t){},e163:function(e,t,n){var i=n("5135"),r=n("7b0b"),o=n("f772"),a=n("e177"),s=o("IE_PROTO"),l=Object.prototype;e.exports=a?Object.getPrototypeOf:function(e){return e=r(e),i(e,s)?e[s]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?l:null}},e177:function(e,t,n){var i=n("d039");e.exports=!i((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype}))},e198:function(e,t,n){var i=n("ef08"),r=n("5524"),o=n("e444"),a=n("fcd4"),s=n("1a14").f;e.exports=function(e){var t=r.Symbol||(r.Symbol=o?{}:i.Symbol||{});"_"==e.charAt(0)||e in t||s(t,e,{value:a.f(e)})}},e260:function(e,t,n){"use strict";var i=n("fc6a"),r=n("44d2"),o=n("3f8c"),a=n("69f3"),s=n("7dd0"),l="Array Iterator",c=a.set,u=a.getterFor(l);e.exports=s(Array,"Array",(function(e,t){c(this,{type:l,target:i(e),index:0,kind:t})}),(function(){var e=u(this),t=e.target,n=e.kind,i=e.index++;return!t||i>=t.length?(e.target=void 0,{value:void 0,done:!0}):"keys"==n?{value:i,done:!1}:"values"==n?{value:t[i],done:!1}:{value:[i,t[i]],done:!1}}),"values"),o.Arguments=o.Array,r("keys"),r("values"),r("entries")},e2cc:function(e,t,n){var i=n("6eeb");e.exports=function(e,t,n){for(var r in t)i(e,r,t[r],n);return e}},e34a:function(e,t,n){var i=n("8b1a")("meta"),r=n("7a41"),o=n("9c0e"),a=n("1a14").f,s=0,l=Object.isExtensible||function(){return!0},c=!n("4b8b")((function(){return l(Object.preventExtensions({}))})),u=function(e){a(e,i,{value:{i:"O"+ ++s,w:{}}})},d=function(e,t){if(!r(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!o(e,i)){if(!l(e))return"F";if(!t)return"E";u(e)}return e[i].i},h=function(e,t){if(!o(e,i)){if(!l(e))return!0;if(!t)return!1;u(e)}return e[i].w},f=function(e){return c&&p.NEED&&l(e)&&!o(e,i)&&u(e),e},p=e.exports={KEY:i,NEED:!1,fastKey:d,getWeak:h,onFreeze:f}},e444:function(e,t){e.exports=!0},e450:function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=111)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},11:function(e,t){e.exports=n("f3ad")},111:function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:["el-input-number",e.inputNumberSize?"el-input-number--"+e.inputNumberSize:"",{"is-disabled":e.inputNumberDisabled},{"is-without-controls":!e.controls},{"is-controls-right":e.controlsAtRight}],on:{dragstart:function(e){e.preventDefault()}}},[e.controls?n("span",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.decrease,expression:"decrease"}],staticClass:"el-input-number__decrease",class:{"is-disabled":e.minDisabled},attrs:{role:"button"},on:{keydown:function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.decrease(t):null}}},[n("i",{class:"el-icon-"+(e.controlsAtRight?"arrow-down":"minus")})]):e._e(),e.controls?n("span",{directives:[{name:"repeat-click",rawName:"v-repeat-click",value:e.increase,expression:"increase"}],staticClass:"el-input-number__increase",class:{"is-disabled":e.maxDisabled},attrs:{role:"button"},on:{keydown:function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.increase(t):null}}},[n("i",{class:"el-icon-"+(e.controlsAtRight?"arrow-up":"plus")})]):e._e(),n("el-input",{ref:"input",attrs:{value:e.displayValue,placeholder:e.placeholder,disabled:e.inputNumberDisabled,size:e.inputNumberSize,max:e.max,min:e.min,name:e.name,label:e.label},on:{blur:e.handleBlur,focus:e.handleFocus,input:e.handleInput,change:e.handleInputChange},nativeOn:{keydown:[function(t){return"button"in t||!e._k(t.keyCode,"up",38,t.key,["Up","ArrowUp"])?(t.preventDefault(),e.increase(t)):null},function(t){return"button"in t||!e._k(t.keyCode,"down",40,t.key,["Down","ArrowDown"])?(t.preventDefault(),e.decrease(t)):null}]}})],1)},r=[];i._withStripped=!0;var o=n(11),a=n.n(o),s=n(22),l=n.n(s),c=n(30),u={name:"ElInputNumber",mixins:[l()("input")],inject:{elForm:{default:""},elFormItem:{default:""}},directives:{repeatClick:c["a"]},components:{ElInput:a.a},props:{step:{type:Number,default:1},stepStrictly:{type:Boolean,default:!1},max:{type:Number,default:1/0},min:{type:Number,default:-1/0},value:{},disabled:Boolean,size:String,controls:{type:Boolean,default:!0},controlsPosition:{type:String,default:""},name:String,label:String,placeholder:String,precision:{type:Number,validator:function(e){return e>=0&&e===parseInt(e,10)}}},data:function(){return{currentValue:0,userInput:null}},watch:{value:{immediate:!0,handler:function(e){var t=void 0===e?e:Number(e);if(void 0!==t){if(isNaN(t))return;if(this.stepStrictly){var n=this.getPrecision(this.step),i=Math.pow(10,n);t=Math.round(t/this.step)*i*this.step/i}void 0!==this.precision&&(t=this.toPrecision(t,this.precision))}t>=this.max&&(t=this.max),t<=this.min&&(t=this.min),this.currentValue=t,this.userInput=null,this.$emit("input",t)}}},computed:{minDisabled:function(){return this._decrease(this.value,this.step)this.max},numPrecision:function(){var e=this.value,t=this.step,n=this.getPrecision,i=this.precision,r=n(t);return void 0!==i?(r>i&&console.warn("[Element Warn][InputNumber]precision should not be less than the decimal places of step"),i):Math.max(n(e),r)},controlsAtRight:function(){return this.controls&&"right"===this.controlsPosition},_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},inputNumberSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},inputNumberDisabled:function(){return this.disabled||(this.elForm||{}).disabled},displayValue:function(){if(null!==this.userInput)return this.userInput;var e=this.currentValue;if("number"===typeof e){if(this.stepStrictly){var t=this.getPrecision(this.step),n=Math.pow(10,t);e=Math.round(e/this.step)*n*this.step/n}void 0!==this.precision&&(e=e.toFixed(this.precision))}return e}},methods:{toPrecision:function(e,t){return void 0===t&&(t=this.numPrecision),parseFloat(Math.round(e*Math.pow(10,t))/Math.pow(10,t))},getPrecision:function(e){if(void 0===e)return 0;var t=e.toString(),n=t.indexOf("."),i=0;return-1!==n&&(i=t.length-n-1),i},_increase:function(e,t){if("number"!==typeof e&&void 0!==e)return this.currentValue;var n=Math.pow(10,this.numPrecision);return this.toPrecision((n*e+n*t)/n)},_decrease:function(e,t){if("number"!==typeof e&&void 0!==e)return this.currentValue;var n=Math.pow(10,this.numPrecision);return this.toPrecision((n*e-n*t)/n)},increase:function(){if(!this.inputNumberDisabled&&!this.maxDisabled){var e=this.value||0,t=this._increase(e,this.step);this.setCurrentValue(t)}},decrease:function(){if(!this.inputNumberDisabled&&!this.minDisabled){var e=this.value||0,t=this._decrease(e,this.step);this.setCurrentValue(t)}},handleBlur:function(e){this.$emit("blur",e)},handleFocus:function(e){this.$emit("focus",e)},setCurrentValue:function(e){var t=this.currentValue;"number"===typeof e&&void 0!==this.precision&&(e=this.toPrecision(e,this.precision)),e>=this.max&&(e=this.max),e<=this.min&&(e=this.min),t!==e&&(this.userInput=null,this.$emit("input",e),this.$emit("change",e,t),this.currentValue=e)},handleInput:function(e){this.userInput=e},handleInputChange:function(e){var t=""===e?void 0:Number(e);isNaN(t)&&""!==e||this.setCurrentValue(t),this.userInput=null},select:function(){this.$refs.input.select()}},mounted:function(){var e=this.$refs.input.$refs.input;e.setAttribute("role","spinbutton"),e.setAttribute("aria-valuemax",this.max),e.setAttribute("aria-valuemin",this.min),e.setAttribute("aria-valuenow",this.currentValue),e.setAttribute("aria-disabled",this.inputNumberDisabled)},updated:function(){if(this.$refs&&this.$refs.input){var e=this.$refs.input.$refs.input;e.setAttribute("aria-valuenow",this.currentValue)}}},d=u,h=n(0),f=Object(h["a"])(d,i,r,!1,null,null,null);f.options.__file="packages/input-number/src/input-number.vue";var p=f.exports;p.install=function(e){e.component(p.name,p)};t["default"]=p},2:function(e,t){e.exports=n("5924")},22:function(e,t){e.exports=n("12f2")},30:function(e,t,n){"use strict";var i=n(2);t["a"]={bind:function(e,t,n){var r=null,o=void 0,a=function(){return n.context[t.expression].apply()},s=function(){Date.now()-o<100&&a(),clearInterval(r),r=null};Object(i["on"])(e,"mousedown",(function(e){0===e.button&&(o=Date.now(),Object(i["once"])(document,"mouseup",s),clearInterval(r),r=setInterval(a,100))}))}}}})},e452:function(e,t,n){"use strict";t.__esModule=!0;var i=i||{};i.Utils=i.Utils||{},i.Utils.focusFirstDescendant=function(e){for(var t=0;t=0;t--){var n=e.childNodes[t];if(i.Utils.attemptFocus(n)||i.Utils.focusLastDescendant(n))return!0}return!1},i.Utils.attemptFocus=function(e){if(!i.Utils.isFocusable(e))return!1;i.Utils.IgnoreUtilFocusChanges=!0;try{e.focus()}catch(t){}return i.Utils.IgnoreUtilFocusChanges=!1,document.activeElement===e},i.Utils.isFocusable=function(e){if(e.tabIndex>0||0===e.tabIndex&&null!==e.getAttribute("tabIndex"))return!0;if(e.disabled)return!1;switch(e.nodeName){case"A":return!!e.href&&"ignore"!==e.rel;case"INPUT":return"hidden"!==e.type&&"file"!==e.type;case"BUTTON":case"SELECT":case"TEXTAREA":return!0;default:return!1}},i.Utils.triggerEvent=function(e,t){var n=void 0;n=/^mouse|click/.test(t)?"MouseEvents":/^key/.test(t)?"KeyboardEvent":"HTMLEvents";for(var i=document.createEvent(n),r=arguments.length,o=Array(r>2?r-2:0),a=2;a=51&&/native code/.test(L))return!1;var e=L.resolve(1),t=function(e){e((function(){}),(function(){}))},n=e.constructor={};return n[I]=t,!(e.then((function(){}))instanceof t)})),te=ee||!x((function(e){L.all(e)["catch"]((function(){}))})),ne=function(e){var t;return!(!v(e)||"function"!=typeof(t=e.then))&&t},ie=function(e,t,n){if(!t.notified){t.notified=!0;var i=t.reactions;k((function(){var r=t.value,o=t.state==X,a=0;while(i.length>a){var s,l,c,u=i[a++],d=o?u.ok:u.fail,h=u.resolve,f=u.reject,p=u.domain;try{d?(o||(t.rejection===Q&&se(e,t),t.rejection=J),!0===d?s=r:(p&&p.enter(),s=d(r),p&&(p.exit(),c=!0)),s===u.promise?f(V("Promise-chain cycle")):(l=ne(s))?l.call(s,h,f):h(s)):f(r)}catch(m){p&&!c&&p.exit(),f(m)}}t.reactions=[],t.notified=!1,n&&!t.rejection&&oe(e,t)}))}},re=function(e,t,n){var i,r;U?(i=z.createEvent("Event"),i.promise=t,i.reason=n,i.initEvent(e,!1,!0),c.dispatchEvent(i)):i={promise:t,reason:n},(r=c["on"+e])?r(i):e===Y&&O("Unhandled promise rejection",n)},oe=function(e,t){C.call(c,(function(){var n,i=t.value,r=ae(t);if(r&&(n=D((function(){q?B.emit("unhandledRejection",i,e):re(Y,e,i)})),t.rejection=q||ae(t)?Q:J,n.error))throw n.value}))},ae=function(e){return e.rejection!==J&&!e.parent},se=function(e,t){C.call(c,(function(){q?B.emit("rejectionHandled",e):re(K,e,t.value)}))},le=function(e,t,n,i){return function(r){e(t,n,r,i)}},ce=function(e,t,n,i){t.done||(t.done=!0,i&&(t=i),t.value=n,t.state=Z,ie(e,t,!0))},ue=function(e,t,n,i){if(!t.done){t.done=!0,i&&(t=i);try{if(e===n)throw V("Promise can't be resolved itself");var r=ne(n);r?k((function(){var i={done:!1};try{r.call(n,le(ue,e,i,t),le(ce,e,i,t))}catch(o){ce(e,i,o,t)}})):(t.value=n,t.state=X,ie(e,t,!1))}catch(o){ce(e,{done:!1},o,t)}}};ee&&(L=function(e){b(this,L,N),g(e),i.call(this);var t=j(this);try{e(le(ue,this,t),le(ce,this,t))}catch(n){ce(this,t,n)}},i=function(e){A(this,{type:N,done:!1,notified:!1,parent:!1,reactions:[],rejection:!1,state:G,value:void 0})},i.prototype=f(L.prototype,{then:function(e,t){var n=F(this),i=H(w(this,L));return i.ok="function"!=typeof e||e,i.fail="function"==typeof t&&t,i.domain=q?B.domain:void 0,n.parent=!0,n.reactions.push(i),n.state!=G&&ie(this,n,!1),i.promise},catch:function(e){return this.then(void 0,e)}}),r=function(){var e=new i,t=j(e);this.promise=e,this.resolve=le(ue,e,t),this.reject=le(ce,e,t)},$.f=H=function(e){return e===L||e===o?new r(e):W(e)},l||"function"!=typeof d||(a=d.prototype.then,h(d.prototype,"then",(function(e,t){var n=this;return new L((function(e,t){a.call(n,e,t)})).then(e,t)}),{unsafe:!0}),"function"==typeof R&&s({global:!0,enumerable:!0,forced:!0},{fetch:function(e){return S(L,R.apply(c,arguments))}}))),s({global:!0,wrap:!0,forced:ee},{Promise:L}),p(L,N,!1,!0),m(N),o=u(N),s({target:N,stat:!0,forced:ee},{reject:function(e){var t=H(this);return t.reject.call(void 0,e),t.promise}}),s({target:N,stat:!0,forced:l||ee},{resolve:function(e){return S(l&&this===o?L:this,e)}}),s({target:N,stat:!0,forced:te},{all:function(e){var t=this,n=H(t),i=n.resolve,r=n.reject,o=D((function(){var n=g(t.resolve),o=[],a=0,s=1;_(e,(function(e){var l=a++,c=!1;o.push(void 0),s++,n.call(t,e).then((function(e){c||(c=!0,o[l]=e,--s||i(o))}),r)})),--s||i(o)}));return o.error&&r(o.value),n.promise},race:function(e){var t=this,n=H(t),i=n.reject,r=D((function(){var r=g(t.resolve);_(e,(function(e){r.call(t,e).then(n.resolve,i)}))}));return r.error&&i(r.value),n.promise}})},e772:function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=52)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},3:function(e,t){e.exports=n("8122")},33:function(e,t,n){"use strict";var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("li",{directives:[{name:"show",rawName:"v-show",value:e.visible,expression:"visible"}],staticClass:"el-select-dropdown__item",class:{selected:e.itemSelected,"is-disabled":e.disabled||e.groupDisabled||e.limitReached,hover:e.hover},on:{mouseenter:e.hoverItem,click:function(t){return t.stopPropagation(),e.selectOptionClick(t)}}},[e._t("default",[n("span",[e._v(e._s(e.currentLabel))])])],2)},r=[];i._withStripped=!0;var o=n(4),a=n.n(o),s=n(3),l="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c={mixins:[a.a],name:"ElOption",componentName:"ElOption",inject:["select"],props:{value:{required:!0},label:[String,Number],created:Boolean,disabled:{type:Boolean,default:!1}},data:function(){return{index:-1,groupDisabled:!1,visible:!0,hitState:!1,hover:!1}},computed:{isObject:function(){return"[object object]"===Object.prototype.toString.call(this.value).toLowerCase()},currentLabel:function(){return this.label||(this.isObject?"":this.value)},currentValue:function(){return this.value||this.label||""},itemSelected:function(){return this.select.multiple?this.contains(this.select.value,this.value):this.isEqual(this.value,this.select.value)},limitReached:function(){return!!this.select.multiple&&(!this.itemSelected&&(this.select.value||[]).length>=this.select.multipleLimit&&this.select.multipleLimit>0)}},watch:{currentLabel:function(){this.created||this.select.remote||this.dispatch("ElSelect","setSelected")},value:function(e,t){var n=this.select,i=n.remote,r=n.valueKey;if(!this.created&&!i){if(r&&"object"===("undefined"===typeof e?"undefined":l(e))&&"object"===("undefined"===typeof t?"undefined":l(t))&&e[r]===t[r])return;this.dispatch("ElSelect","setSelected")}}},methods:{isEqual:function(e,t){if(this.isObject){var n=this.select.valueKey;return Object(s["getValueByPath"])(e,n)===Object(s["getValueByPath"])(t,n)}return e===t},contains:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1];if(this.isObject){var n=this.select.valueKey;return e&&e.some((function(e){return Object(s["getValueByPath"])(e,n)===Object(s["getValueByPath"])(t,n)}))}return e&&e.indexOf(t)>-1},handleGroupDisabled:function(e){this.groupDisabled=e},hoverItem:function(){this.disabled||this.groupDisabled||(this.select.hoverIndex=this.select.options.indexOf(this))},selectOptionClick:function(){!0!==this.disabled&&!0!==this.groupDisabled&&this.dispatch("ElSelect","handleOptionClick",[this,!0])},queryChange:function(e){this.visible=new RegExp(Object(s["escapeRegexpString"])(e),"i").test(this.currentLabel)||this.created,this.visible||this.select.filteredOptionsCount--}},created:function(){this.select.options.push(this),this.select.cachedOptions.push(this),this.select.optionsCount++,this.select.filteredOptionsCount++,this.$on("queryChange",this.queryChange),this.$on("handleGroupDisabled",this.handleGroupDisabled)},beforeDestroy:function(){var e=this.select.cachedOptions.indexOf(this);e>-1&&this.select.cachedOptions.splice(e,1),this.select.onOptionDestroy(this.select.options.indexOf(this))}},u=c,d=n(0),h=Object(d["a"])(u,i,r,!1,null,null,null);h.options.__file="packages/select/src/option.vue";t["a"]=h.exports},4:function(e,t){e.exports=n("d010")},52:function(e,t,n){"use strict";n.r(t);var i=n(33);i["a"].install=function(e){e.component(i["a"].name,i["a"])},t["default"]=i["a"]}})},e893:function(e,t,n){var i=n("5135"),r=n("56ef"),o=n("06cf"),a=n("9bf2");e.exports=function(e,t){for(var n=r(t),s=a.f,l=o.f,c=0;c-1?"center "+n:n+" center"}},appendArrow:function(e){var t=void 0;if(!this.appended){for(var n in this.appended=!0,e.attributes)if(/^_v-/.test(e.attributes[n].name)){t=e.attributes[n].name;break}var i=document.createElement("div");t&&i.setAttribute(t,""),i.setAttribute("x-arrow",""),i.className="popper__arrow",e.appendChild(i)}}},beforeDestroy:function(){this.doDestroy(!0),this.popperElm&&this.popperElm.parentNode===document.body&&(this.popperElm.removeEventListener("click",l),document.body.removeChild(this.popperElm))},deactivated:function(){this.$options.beforeDestroy[0].call(this)}}},ea34:function(e,t){e.exports=function(e,t){return{value:t,done:!!e}}},eedf:function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=118)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},118:function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("button",{staticClass:"el-button",class:[e.type?"el-button--"+e.type:"",e.buttonSize?"el-button--"+e.buttonSize:"",{"is-disabled":e.buttonDisabled,"is-loading":e.loading,"is-plain":e.plain,"is-round":e.round,"is-circle":e.circle}],attrs:{disabled:e.buttonDisabled||e.loading,autofocus:e.autofocus,type:e.nativeType},on:{click:e.handleClick}},[e.loading?n("i",{staticClass:"el-icon-loading"}):e._e(),e.icon&&!e.loading?n("i",{class:e.icon}):e._e(),e.$slots.default?n("span",[e._t("default")],2):e._e()])},r=[];i._withStripped=!0;var o={name:"ElButton",inject:{elForm:{default:""},elFormItem:{default:""}},props:{type:{type:String,default:"default"},size:String,icon:{type:String,default:""},nativeType:{type:String,default:"button"},loading:Boolean,disabled:Boolean,plain:Boolean,autofocus:Boolean,round:Boolean,circle:Boolean},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},buttonSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},buttonDisabled:function(){return this.disabled||(this.elForm||{}).disabled}},methods:{handleClick:function(e){this.$emit("click",e)}}},a=o,s=n(0),l=Object(s["a"])(a,i,r,!1,null,null,null);l.options.__file="packages/button/src/button.vue";var c=l.exports;c.install=function(e){e.component(c.name,c)};t["default"]=c}})},ef08:function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},f069:function(e,t,n){"use strict";var i=n("1c0b"),r=function(e){var t,n;this.promise=new e((function(e,i){if(void 0!==t||void 0!==n)throw TypeError("Bad Promise constructor");t=e,n=i})),this.resolve=i(t),this.reject=i(n)};e.exports.f=function(e){return new r(e)}},f0d9:function(e,t,n){"use strict";t.__esModule=!0,t.default={el:{colorpicker:{confirm:"确定",clear:"清空"},datepicker:{now:"此刻",today:"今天",cancel:"取消",clear:"清空",confirm:"确定",selectDate:"选择日期",selectTime:"选择时间",startDate:"开始日期",startTime:"开始时间",endDate:"结束日期",endTime:"结束时间",prevYear:"前一年",nextYear:"后一年",prevMonth:"上个月",nextMonth:"下个月",year:"年",month1:"1 月",month2:"2 月",month3:"3 月",month4:"4 月",month5:"5 月",month6:"6 月",month7:"7 月",month8:"8 月",month9:"9 月",month10:"10 月",month11:"11 月",month12:"12 月",weeks:{sun:"日",mon:"一",tue:"二",wed:"三",thu:"四",fri:"五",sat:"六"},months:{jan:"一月",feb:"二月",mar:"三月",apr:"四月",may:"五月",jun:"六月",jul:"七月",aug:"八月",sep:"九月",oct:"十月",nov:"十一月",dec:"十二月"}},select:{loading:"加载中",noMatch:"无匹配数据",noData:"无数据",placeholder:"请选择"},cascader:{noMatch:"无匹配数据",loading:"加载中",placeholder:"请选择",noData:"暂无数据"},pagination:{goto:"前往",pagesize:"条/页",total:"共 {total} 条",pageClassifier:"页"},messagebox:{title:"提示",confirm:"确定",cancel:"取消",error:"输入的数据不合法!"},upload:{deleteTip:"按 delete 键可删除",delete:"删除",preview:"查看图片",continue:"继续上传"},table:{emptyText:"暂无数据",confirmFilter:"筛选",resetFilter:"重置",clearFilter:"全部",sumText:"合计"},tree:{emptyText:"暂无数据"},transfer:{noMatch:"无匹配数据",noData:"无数据",titles:["列表 1","列表 2"],filterPlaceholder:"请输入搜索内容",noCheckedFormat:"共 {total} 项",hasCheckedFormat:"已选 {checked}/{total} 项"},image:{error:"加载失败"},pageHeader:{title:"返回"}}}},f3ad:function(e,t,n){e.exports=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=74)}({0:function(e,t,n){"use strict";function i(e,t,n,i,r,o,a,s){var l,c="function"===typeof e?e.options:e;if(t&&(c.render=t,c.staticRenderFns=n,c._compiled=!0),i&&(c.functional=!0),o&&(c._scopeId="data-v-"+o),a?(l=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(a)},c._ssrRegister=l):r&&(l=s?function(){r.call(this,this.$root.$options.shadowRoot)}:r),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(e,t){return l.call(t),u(e,t)}}else{var d=c.beforeCreate;c.beforeCreate=d?[].concat(d,l):[l]}return{exports:e,options:c}}n.d(t,"a",(function(){return i}))},10:function(e,t){e.exports=n("2bb5")},21:function(e,t){e.exports=n("d397")},4:function(e,t){e.exports=n("d010")},74:function(e,t,n){"use strict";n.r(t);var i=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{class:["textarea"===e.type?"el-textarea":"el-input",e.inputSize?"el-input--"+e.inputSize:"",{"is-disabled":e.inputDisabled,"is-exceed":e.inputExceed,"el-input-group":e.$slots.prepend||e.$slots.append,"el-input-group--append":e.$slots.append,"el-input-group--prepend":e.$slots.prepend,"el-input--prefix":e.$slots.prefix||e.prefixIcon,"el-input--suffix":e.$slots.suffix||e.suffixIcon||e.clearable||e.showPassword}],on:{mouseenter:function(t){e.hovering=!0},mouseleave:function(t){e.hovering=!1}}},["textarea"!==e.type?[e.$slots.prepend?n("div",{staticClass:"el-input-group__prepend"},[e._t("prepend")],2):e._e(),"textarea"!==e.type?n("input",e._b({ref:"input",staticClass:"el-input__inner",attrs:{tabindex:e.tabindex,type:e.showPassword?e.passwordVisible?"text":"password":e.type,disabled:e.inputDisabled,readonly:e.readonly,autocomplete:e.autoComplete||e.autocomplete,"aria-label":e.label},on:{compositionstart:e.handleCompositionStart,compositionupdate:e.handleCompositionUpdate,compositionend:e.handleCompositionEnd,input:e.handleInput,focus:e.handleFocus,blur:e.handleBlur,change:e.handleChange}},"input",e.$attrs,!1)):e._e(),e.$slots.prefix||e.prefixIcon?n("span",{staticClass:"el-input__prefix"},[e._t("prefix"),e.prefixIcon?n("i",{staticClass:"el-input__icon",class:e.prefixIcon}):e._e()],2):e._e(),e.getSuffixVisible()?n("span",{staticClass:"el-input__suffix"},[n("span",{staticClass:"el-input__suffix-inner"},[e.showClear&&e.showPwdVisible&&e.isWordLimitVisible?e._e():[e._t("suffix"),e.suffixIcon?n("i",{staticClass:"el-input__icon",class:e.suffixIcon}):e._e()],e.showClear?n("i",{staticClass:"el-input__icon el-icon-circle-close el-input__clear",on:{mousedown:function(e){e.preventDefault()},click:e.clear}}):e._e(),e.showPwdVisible?n("i",{staticClass:"el-input__icon el-icon-view el-input__clear",on:{click:e.handlePasswordVisible}}):e._e(),e.isWordLimitVisible?n("span",{staticClass:"el-input__count"},[n("span",{staticClass:"el-input__count-inner"},[e._v("\n "+e._s(e.textLength)+"/"+e._s(e.upperLimit)+"\n ")])]):e._e()],2),e.validateState?n("i",{staticClass:"el-input__icon",class:["el-input__validateIcon",e.validateIcon]}):e._e()]):e._e(),e.$slots.append?n("div",{staticClass:"el-input-group__append"},[e._t("append")],2):e._e()]:n("textarea",e._b({ref:"textarea",staticClass:"el-textarea__inner",style:e.textareaStyle,attrs:{tabindex:e.tabindex,disabled:e.inputDisabled,readonly:e.readonly,autocomplete:e.autoComplete||e.autocomplete,"aria-label":e.label},on:{compositionstart:e.handleCompositionStart,compositionupdate:e.handleCompositionUpdate,compositionend:e.handleCompositionEnd,input:e.handleInput,focus:e.handleFocus,blur:e.handleBlur,change:e.handleChange}},"textarea",e.$attrs,!1)),e.isWordLimitVisible&&"textarea"===e.type?n("span",{staticClass:"el-input__count"},[e._v(e._s(e.textLength)+"/"+e._s(e.upperLimit))]):e._e()],2)},r=[];i._withStripped=!0;var o=n(4),a=n.n(o),s=n(10),l=n.n(s),c=void 0,u="\n height:0 !important;\n visibility:hidden !important;\n overflow:hidden !important;\n position:absolute !important;\n z-index:-1000 !important;\n top:0 !important;\n right:0 !important\n",d=["letter-spacing","line-height","padding-top","padding-bottom","font-family","font-weight","font-size","text-rendering","text-transform","width","text-indent","padding-left","padding-right","border-width","box-sizing"];function h(e){var t=window.getComputedStyle(e),n=t.getPropertyValue("box-sizing"),i=parseFloat(t.getPropertyValue("padding-bottom"))+parseFloat(t.getPropertyValue("padding-top")),r=parseFloat(t.getPropertyValue("border-bottom-width"))+parseFloat(t.getPropertyValue("border-top-width")),o=d.map((function(e){return e+":"+t.getPropertyValue(e)})).join(";");return{contextStyle:o,paddingSize:i,borderSize:r,boxSizing:n}}function f(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;c||(c=document.createElement("textarea"),document.body.appendChild(c));var i=h(e),r=i.paddingSize,o=i.borderSize,a=i.boxSizing,s=i.contextStyle;c.setAttribute("style",s+";"+u),c.value=e.value||e.placeholder||"";var l=c.scrollHeight,d={};"border-box"===a?l+=o:"content-box"===a&&(l-=r),c.value="";var f=c.scrollHeight-r;if(null!==t){var p=f*t;"border-box"===a&&(p=p+r+o),l=Math.max(p,l),d.minHeight=p+"px"}if(null!==n){var m=f*n;"border-box"===a&&(m=m+r+o),l=Math.min(m,l)}return d.height=l+"px",c.parentNode&&c.parentNode.removeChild(c),c=null,d}var p=n(9),m=n.n(p),v=n(21),g={name:"ElInput",componentName:"ElInput",mixins:[a.a,l.a],inheritAttrs:!1,inject:{elForm:{default:""},elFormItem:{default:""}},data:function(){return{textareaCalcStyle:{},hovering:!1,focused:!1,isComposing:!1,passwordVisible:!1}},props:{value:[String,Number],size:String,resize:String,form:String,disabled:Boolean,readonly:Boolean,type:{type:String,default:"text"},autosize:{type:[Boolean,Object],default:!1},autocomplete:{type:String,default:"off"},autoComplete:{type:String,validator:function(e){return!0}},validateEvent:{type:Boolean,default:!0},suffixIcon:String,prefixIcon:String,label:String,clearable:{type:Boolean,default:!1},showPassword:{type:Boolean,default:!1},showWordLimit:{type:Boolean,default:!1},tabindex:String},computed:{_elFormItemSize:function(){return(this.elFormItem||{}).elFormItemSize},validateState:function(){return this.elFormItem?this.elFormItem.validateState:""},needStatusIcon:function(){return!!this.elForm&&this.elForm.statusIcon},validateIcon:function(){return{validating:"el-icon-loading",success:"el-icon-circle-check",error:"el-icon-circle-close"}[this.validateState]},textareaStyle:function(){return m()({},this.textareaCalcStyle,{resize:this.resize})},inputSize:function(){return this.size||this._elFormItemSize||(this.$ELEMENT||{}).size},inputDisabled:function(){return this.disabled||(this.elForm||{}).disabled},nativeInputValue:function(){return null===this.value||void 0===this.value?"":String(this.value)},showClear:function(){return this.clearable&&!this.inputDisabled&&!this.readonly&&this.nativeInputValue&&(this.focused||this.hovering)},showPwdVisible:function(){return this.showPassword&&!this.inputDisabled&&!this.readonly&&(!!this.nativeInputValue||this.focused)},isWordLimitVisible:function(){return this.showWordLimit&&this.$attrs.maxlength&&("text"===this.type||"textarea"===this.type)&&!this.inputDisabled&&!this.readonly&&!this.showPassword},upperLimit:function(){return this.$attrs.maxlength},textLength:function(){return"number"===typeof this.value?String(this.value).length:(this.value||"").length},inputExceed:function(){return this.isWordLimitVisible&&this.textLength>this.upperLimit}},watch:{value:function(e){this.$nextTick(this.resizeTextarea),this.validateEvent&&this.dispatch("ElFormItem","el.form.change",[e])},nativeInputValue:function(){this.setNativeInputValue()},type:function(){var e=this;this.$nextTick((function(){e.setNativeInputValue(),e.resizeTextarea(),e.updateIconOffset()}))}},methods:{focus:function(){this.getInput().focus()},blur:function(){this.getInput().blur()},getMigratingConfig:function(){return{props:{icon:"icon is removed, use suffix-icon / prefix-icon instead.","on-icon-click":"on-icon-click is removed."},events:{click:"click is removed."}}},handleBlur:function(e){this.focused=!1,this.$emit("blur",e),this.validateEvent&&this.dispatch("ElFormItem","el.form.blur",[this.value])},select:function(){this.getInput().select()},resizeTextarea:function(){if(!this.$isServer){var e=this.autosize,t=this.type;if("textarea"===t)if(e){var n=e.minRows,i=e.maxRows;this.textareaCalcStyle=f(this.$refs.textarea,n,i)}else this.textareaCalcStyle={minHeight:f(this.$refs.textarea).minHeight}}},setNativeInputValue:function(){var e=this.getInput();e&&e.value!==this.nativeInputValue&&(e.value=this.nativeInputValue)},handleFocus:function(e){this.focused=!0,this.$emit("focus",e)},handleCompositionStart:function(){this.isComposing=!0},handleCompositionUpdate:function(e){var t=e.target.value,n=t[t.length-1]||"";this.isComposing=!Object(v["isKorean"])(n)},handleCompositionEnd:function(e){this.isComposing&&(this.isComposing=!1,this.handleInput(e))},handleInput:function(e){this.isComposing||e.target.value!==this.nativeInputValue&&(this.$emit("input",e.target.value),this.$nextTick(this.setNativeInputValue))},handleChange:function(e){this.$emit("change",e.target.value)},calcIconOffset:function(e){var t=[].slice.call(this.$el.querySelectorAll(".el-input__"+e)||[]);if(t.length){for(var n=null,i=0;i0?i:n)(e)}},fc6a:function(e,t,n){var i=n("44ad"),r=n("1d80");e.exports=function(e){return i(r(e))}},fcd4:function(e,t,n){t.f=n("cc15")},fea9:function(e,t,n){var i=n("da84");e.exports=i.Promise},fed5:function(e,t){t.f=Object.getOwnPropertySymbols}}]); \ No newline at end of file diff --git "a/Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/public/favicon.ico" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/templates/favicon.ico" similarity index 100% rename from "Ant/vue\351\241\271\347\233\256\345\274\225\345\205\245ant/antd-demo/public/favicon.ico" rename to "Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/templates/favicon.ico" diff --git "a/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/templates/index.html" "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/templates/index.html" new file mode 100644 index 0000000000000000000000000000000000000000..56ded40e910065a106bf266f908f208db26f2a28 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/Code/lesson27/bubble/templates/index.html" @@ -0,0 +1 @@ +bubble清单
\ No newline at end of file diff --git "a/Golang/Gin\346\241\206\346\236\266/README.md" "b/Golang/Gin\346\241\206\346\236\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b28bd92bff0273c8913587765d2be8da703c5063 --- /dev/null +++ "b/Golang/Gin\346\241\206\346\236\266/README.md" @@ -0,0 +1,3 @@ +# Go Web开发教程 + +来源于bilibili七米老师的视频教程:https://www.bilibili.com/video/BV1gJ411p7xC \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/README.md" "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..4bcf37847d2aafc7c0cb732fdf8eb8c56da0f547 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/README.md" @@ -0,0 +1,104 @@ +# Windows下Go语言的安装 + +## 前言 + +这阵子因为以后工作的原因,所以开始了go语言的学习之旅,工欲善其事必先利其器,首先就得把go语言环境搭建完成 + +## 下载Go + +因为go语言的官网经常打不开,所以我就找了一个 [镜像网站](https://studygolang.com/dl),里面有很多版本的Go语言,选择自己合适的,比如我的是Windows电脑,所以我选中里面的Windows版本的 + +![image-20200718111751694](images/image-20200718111751694.png) + +下载完成是一个安装文件,我们需要进行安装,同时需要注意的就是安装目录,因为事后还需要配置环境变量,下面是安装成功后的图片 + +![image-20200718111822269](images/image-20200718111822269.png) + +## 配置环境变量 + +根据windows系统在查找可执行程序的原理,可以将Go所在路径定义到环境变量中,让系统帮我们去找运行的执行程序,这样在任何目录下都可以执行go指令,需要配置的环境变量有: + +| 环境变量 | 说明 | +| -------- | ----------------- | +| GOROOT | 指定SDK的安装目录 | +| Path | 添加SDK的/binmulu | +| GOPATH | 工作目录 | + +首先我们需要打开我们的环境变量,然后添加上GOROOT + +![image-20200718151418230](images/image-20200718151418230.png) + +然后我们在PATH上添加我们的bin目录 + +![image-20200718151503318](images/image-20200718151503318.png) + +添加完成后,我们输入下面的命令,查看是否配置成功 + +```bash +go version +``` + +![image-20200718112254366](images/image-20200718112254366.png) + +## 下载Jetbrain下的GoLang + +在我们配置好环境,我们就可以使用Jetbrain公司开发的Goland编辑器了,首先进入官网下载 + +https://www.jetbrains.com/ + +下载完成后,进行启动 + +![image-20200718150736688](images/image-20200718150736688.png) + +启动完成后,我们需要配置一下环境,点击:File ->settings -> GOROOT,配置一下刚刚go安装的目录 + +![image-20200718151701767](images/image-20200718151701767.png) + +以及GOPATH项目所在的目录 + +![image-20200718151733127](images/image-20200718151733127.png) + +## hello world + +在上面的方法都完成以后,我来来输出hello world吧~ + +```go +package main + +import "fmt" + +func main() { + fmt.Println("hello world!") +} +``` + +代码的说明 + +- go文件的后缀是.go +- package main:表示该hello.go文件所在的包是main,在go中,每个文件都归属与一个包 +- import "fmt":表示引入一个包,可以调用里面的函数 +- func main():表示程序入口,是一个主函数 + +输出结果 + +![image-20200718151850083](images/image-20200718151850083.png) + +## 编译和执行 + +我们可以通过使用下面命令进行编译和执行 + +```bash +# 编译 hello.go 后 会生成一个 hello.exe文件 +go build hello.go +# 运行 hello.ext +hello.ext +``` + +需要注意的是,我们也可以使用下面的方式,来直接运行的(使用go run会比较慢,因为内部有个编译的过程) + +```bash +go run hello.go +``` + +但是在生产环境中,是需要先编译在执行的 + diff --git "a/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718111751694.png" "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718111751694.png" new file mode 100644 index 0000000000000000000000000000000000000000..cf54c686b89f6e422bc0a2fb1f06db8438fa2bf3 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718111751694.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718111822269.png" "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718111822269.png" new file mode 100644 index 0000000000000000000000000000000000000000..172c73d783b50b144e8c0ffbbb9a261d1da03314 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718111822269.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718112254366.png" "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718112254366.png" new file mode 100644 index 0000000000000000000000000000000000000000..e6ea9b878c1279468e54588ca88af80b45a0a88d Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718112254366.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718150736688.png" "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718150736688.png" new file mode 100644 index 0000000000000000000000000000000000000000..7965bf2aebbe595098f3f9593f0d50ff3a7551b6 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718150736688.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151418230.png" "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151418230.png" new file mode 100644 index 0000000000000000000000000000000000000000..2016065833f2dcb25b867dce58eebc4a123c1b1f Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151418230.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151503318.png" "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151503318.png" new file mode 100644 index 0000000000000000000000000000000000000000..1a3e83b34c69e9e4357ef46f95a96e72a2abe25f Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151503318.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151701767.png" "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151701767.png" new file mode 100644 index 0000000000000000000000000000000000000000..cdb2e59b5eabd3e6af7bb0496fce3f7d7a43a0cc Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151701767.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151733127.png" "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151733127.png" new file mode 100644 index 0000000000000000000000000000000000000000..491118f08f97481a81a9a41fcbeb42e4dc22f444 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151733127.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151850083.png" "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151850083.png" new file mode 100644 index 0000000000000000000000000000000000000000..fa113eb84117b2eb5c02edf4197380bbd43c8fca Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/0_Go\350\257\255\350\250\200\347\232\204\345\256\211\350\243\205/images/image-20200718151850083.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/10_Go\344\270\255\347\232\204\346\227\245\346\234\237\345\207\275\346\225\260/README.md" "b/Golang/Golang\345\237\272\347\241\200/10_Go\344\270\255\347\232\204\346\227\245\346\234\237\345\207\275\346\225\260/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..d58afd2e9f107d049bfaedbc54f4ee2b340b698e --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/10_Go\344\270\255\347\232\204\346\227\245\346\234\237\345\207\275\346\225\260/README.md" @@ -0,0 +1,131 @@ +# Go中的日期函数 + +## time包 + +时间和日期是我们编程中经常会用到的,在golang中time包提供了时间的显示和测量用的函数。 + +## time.Now获取当前时间 + +```go +timeObj := time.Now() +year := timeObj.Year() +month := timeObj.Month() +day := timeObj.Day() +fmt.Printf("%d-%02d-%02d \n", year, month, day) +``` + +## 格式化日期 + +时间类型有一个自带的方法 Format进行格式化 + +需要注意的是Go语言中格式化时间模板不是长久的 Y-m-d H:M:S + +而是使用Go的诞生时间 2006年1月2日 15点04分 (记忆口诀:2006 1 2 3 4 5) + +```go +/** + 时间类型有一个自带的方法 Format进行格式化 + 需要注意的是Go语言中格式化时间模板不是长久的 Y-m-d H:M:S + 而是使用Go的诞生时间 2006年1月2日 15点04分 (记忆口诀:2006 1 2 3 4 5) + */ +timeObj2 := time.Now() +// 24小时值 (15表示二十四小时) +fmt.Println(timeObj2.Format("2006-01-02 15:04:05")) +// 12小时制 +fmt.Println(timeObj2.Format("2006-01-02 03:04:05")) +``` + +## 获取当前时间戳 + +时间戳是自1070年1月1日(08:00:00GMT)至当前时间的总毫秒数。它也被称为Unix时间戳 + +```go +/** + 获取当前时间戳 + */ +timeObj3 := time.Now() +// 获取毫秒时间戳 +unixTime := timeObj3.Unix() +// 获取纳秒时间戳 +unixNaTime := timeObj3.UnixNano() +``` + +## 时间戳转日期字符串 + +通过将时间戳我们可以转换成日期字符串 + +```go +// 时间戳转换年月日时分秒(一个参数是秒,另一个参数是毫秒) +var timeObj4 = time.Unix(1595289901, 0) +var timeStr = timeObj4.Format("2006-01-02 15:04:05") +fmt.Println(timeStr) +``` + +## 日期字符串转换成时间戳 + +```go +// 日期字符串转换成时间戳 +var timeStr2 = "2020-07-21 08:10:05"; +var tmp = "2006-01-02 15:04:05" +timeObj5, _ := time.ParseInLocation(tmp, timeStr2, time.Local) +fmt.Println(timeObj5.Unix()) +``` + +## 时间间隔 + +time.Duration是time包定义的一个类型,它代表两个时间点之间经过的时间,以纳秒为单位。time.Duration表示一段时间间隔,可表示的最大长度段大约290年。 + +time包中定义的时间间隔类型的常量如下: + +![image-20200721081402315](images/image-20200721081402315.png) + +## 时间操作函数 + + + +我们在日常的编码过程中可能会遇到要求时间+时间间隔的需求,Go语言的时间对象有提供Add方法如下 + +```go +func (t Time) Add(d Duration)Time +``` + +例如 + +```go +// 时间相加 +now := time.Now() +// 当前时间加1个小时后 +later := now.Add(time.Hour) +fmt.Println(later) +``` + +同理的方法还有:时间差、判断相等 + +## 定时器 + +方式1:使用time.NewTicker(时间间隔)来设置定时器 + +```go +// 定时器, 定义一个1秒间隔的定时器 +ticker := time.NewTicker(time.Second) +n := 0 +for i := range ticker.C { + fmt.Println(i) + n++ + if n>5 { + // 终止定时器 + ticker.Stop() + return + } +} +``` + +方式2:time.Sleep(time.Second)来实现定时器 + +```go +for { + time.Sleep(time.Second) + fmt.Println("一秒后") +} +``` + diff --git "a/Golang/Golang\345\237\272\347\241\200/10_Go\344\270\255\347\232\204\346\227\245\346\234\237\345\207\275\346\225\260/images/image-20200721081402315.png" "b/Golang/Golang\345\237\272\347\241\200/10_Go\344\270\255\347\232\204\346\227\245\346\234\237\345\207\275\346\225\260/images/image-20200721081402315.png" new file mode 100644 index 0000000000000000000000000000000000000000..953ddbd907f9bc5369fda7d79a2cb27681979f09 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/10_Go\344\270\255\347\232\204\346\227\245\346\234\237\345\207\275\346\225\260/images/image-20200721081402315.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/11_Go\344\270\255\347\232\204\346\214\207\351\222\210/README.md" "b/Golang/Golang\345\237\272\347\241\200/11_Go\344\270\255\347\232\204\346\214\207\351\222\210/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ffcbd058b1d733ed2b46add99451e7488fd67b4d --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/11_Go\344\270\255\347\232\204\346\214\207\351\222\210/README.md" @@ -0,0 +1,143 @@ +# Go中的指针 + +要搞明白Go语言中的指针需要先知道三个概念 + +- 指针地址 +- 指针类型 +- 指针取值 + +Go语言中的指针操作非常简单,我们只需要记住两个符号:&:取地址,*:根据地址取值 + +## 关于指针 + +我们知道变量是用来存储数据的,变量的本质是给存储数据的内存地址起了一个好记的别名。比如我们定义了一个变量a:=10,这个时候可以直接通过a这个变量来读取内存中保存的10这个值。在计算机底层a这个变量其实对应了一个内存地址。 + +指针也是一个变量,但它是一种特殊的变量,它存储的数据不是一个普通的值,而是另一个变量的内存地址。 + +![image-20200721083711830](images/image-20200721083711830.png) + +## 指针地址和指针类型 + +每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go 语言中使用&字符放在变量前面对变量进行取地址操作。Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如: + +``` +*int、,*int64、*string等 +``` + +取变量指针的语法如下: + +```go +ptr := &v +``` + +其中: + +- v:代表被取地址的变量,类型为T +- ptr:用于接收地址的变量,ptr的类型就为*T,被称做T的指针类型。\* 代表指针 + +举个例子: + +![image-20200721084549011](images/image-20200721084549011.png) + +## 指针取值 + +在对普通变量进行&操作符取地址后,会获得这个变量指针,然后可以对指针使用*操作,也就是指针取值 + +```go +// 指针取值 +var c = 20 +// 得到c的地址,赋值给d +var d = &c +// 打印d的值,也就是c的地址 +fmt.Println(d) +// 取出d指针所对应的值 +fmt.Println(*d) +// c对应地址的值,改成30 +*d = 30 +// c已经变成30了 +fmt.Println(c) +``` + +改变内存中的值,会直接改变原来的变量值 + +```go +// 这个类似于值传递 +func fn4(x int) { + x = 10 +} +// 这个类似于引用数据类型 +func fn5(x *int) { + *x = 20 +} +func main() { + x := 5 + fn4(x) + fmt.Println(x) + fn5(&x) + fmt.Println(x) +} +``` + +我们创建了两个方法,一个是传入局部变量,一个是传入指针类型,最后运行得到的结果 + +```bash +5 +20 +``` + +## new和make函数 + +需要注意的是,指针必须在创建内存后才可以使用,这个和 slice 和 map是一样的 + +```go +// 引用数据类型map、slice等,必须使用make分配空间,才能够使用 +var userInfo = make(map[string]string) +userInfo["userName"] = "zhangsan" +fmt.Println(userInfo) + +var array = make([]int, 4, 4) +array[0] = 1 +fmt.Println(array) +``` + +对于指针变量来说 + +```go +// 指针变量初始化 +var a *int +*a = 100 +fmt.Println(a) +``` + +执行上面的代码会引发panic,为什么呢?在Go语言中对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间,否则我们的值就没办法存储。而对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已经默认分配好了内存空间。要分配内存,就引出来今天的new和make。Go 语言中new和make是内建的两个函数,主要用来分配内存。 + +这个时候,我们就需要使用new关键字来分配内存,new是一个内置的函数,它的函数签名如下: + +```go +func new(Type) *Type +``` + +其中 + +- Type表示类型,new函数只接受一个参数,这个参数是一个类型 +- *Type表示类型指针,new函数返回一个指向该类型内存地址的指针 + +实际开发中new函数不太常用,使用new函数得到的是一个类型的指针,并且该指针对应的值为该类型的零值。举个例子: + +```go +// 使用new关键字创建指针 +aPoint := new(int) +bPoint := new(bool) +fmt.Printf("%T \n", aPoint) +fmt.Printf("%T \n", bPoint) +fmt.Println(*aPoint) +fmt.Println(*bPoint) +``` + +本节开始的示例代码中 var a *int 只是声明了一个指针变量a但是没有初始化,指针作为引用类型需要初始化后才会拥有内存空间,才可以给它赋值。应该按照如下方式使用内置的 + +## make和new的区别 + +- 两者都是用来做内存分配的 +- make只能用于slice、map以及channel的初始化,返回的还是这三个引用类型的本身 +- 而new用于类型的内存分配,并且内存赌赢的值为类型的零值,返回的是指向类型的指针 \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/11_Go\344\270\255\347\232\204\346\214\207\351\222\210/images/image-20200721083711830.png" "b/Golang/Golang\345\237\272\347\241\200/11_Go\344\270\255\347\232\204\346\214\207\351\222\210/images/image-20200721083711830.png" new file mode 100644 index 0000000000000000000000000000000000000000..529a994e40403ec637ba25d8b594d071136c2bab Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/11_Go\344\270\255\347\232\204\346\214\207\351\222\210/images/image-20200721083711830.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/11_Go\344\270\255\347\232\204\346\214\207\351\222\210/images/image-20200721084549011.png" "b/Golang/Golang\345\237\272\347\241\200/11_Go\344\270\255\347\232\204\346\214\207\351\222\210/images/image-20200721084549011.png" new file mode 100644 index 0000000000000000000000000000000000000000..381b05feba7b7e187adfa043109226dcf6b6fa4d Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/11_Go\344\270\255\347\232\204\346\214\207\351\222\210/images/image-20200721084549011.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/12_Go\344\270\255\347\232\204\347\273\223\346\236\204\344\275\223/README.md" "b/Golang/Golang\345\237\272\347\241\200/12_Go\344\270\255\347\232\204\347\273\223\346\236\204\344\275\223/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..09280ac934aa1e8a909539d9b1d4b95ccabda0ac --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/12_Go\344\270\255\347\232\204\347\273\223\346\236\204\344\275\223/README.md" @@ -0,0 +1,607 @@ +# Go中的结构体 + +## 关于结构体 + +Golang中没有“类”的概念,Golang中的结构体和其他语言中的类有点相似。和其他面向对象语言中的类相比,Golang中的结构体具有更高的扩展性和灵活性。 + +Golang中的基础数据类型可以装示一些事物的基本属性,但是当我们想表达一个事物的全部或部分属性时,这时候再用单一的基本数据类型就无法满足需求了,Golang提供了一种自定义数据类型,可以封装多个基本数据类型,这种数据类型叫结构体,英文名称struct。也就是我们可以通过struct来定义自己的类型了。 + +## Type关键字 + +Golang中通过type关键词定义一个结构体,需要注意的是,数组和结构体都是值类型,在这个和Java是有区别的 + +### 自定义类型 + +在Go语言中有一些基本的数据类型,如string、整型、浮点型、布尔等数据类型,Go语言中可以使用type关键字来定义自定义类型。 + +```go +type myInt int +``` + +上面代码表示:将mylnt定义为int类型,通过type关键字的定义,mylnt就是一种新的类型,它具有int的特性。 + +示例:如下所示,我们定义了一个myInt类型 + +``` +type myInt int +func main() { + var a myInt = 10 + fmt.Printf("%v %T", a, a) +} +``` + +输出查看它的值以及类型,能够发现该类型就是myInt类型 + +```go +10 main.myInt +``` + +除此之外,我们还可以定义一个方法类型 + +```go +func fun(x int, y int)int { + return x + y +} +func main() { + var fn myFn = fun + fmt.Println(fn(1, 2)) +} +``` + +然后调用并输出 + +```bash +3 +``` + +### 类型别名 + +Golang1.9版本以后添加的新功能 + +类型别名规定:TypeAlias只是Type的别名,本质上TypeAlias与Type是同一个类型。就像一个孩子小时候有大名、小名、英文名,但这些名字都指的是他本人 + +```go +type TypeAlias = Type +``` + +我们之前见过的rune 和 byte 就是类型别名,他们的底层代码如下 + +```go +type byte = uint8 +type rune = int32 +``` + +## 结构体定义和初始化 + +### 结构体的定义 + +使用type 和 struct关键字来定义结构体,具体代码格式如下所示: + +```go +/** + 定义一个人结构体 + */ +type Person struct { + name string + age int + sex string +} +func main() { + // 实例化结构体 + var person Person + person.name = "张三" + person.age = 20 + person.sex = "男" + fmt.Printf("%#v", person) +} +``` + +> 注意:结构体首字母可以大写也可以小写,大写表示这个结构体是公有的,在其它的包里面也可以使用,小写表示结构体属于私有的,在其它地方不能使用 + +例如: + +```go +type Person struct { + Name string + Age int + Sex string +} +``` + +### 实例化结构体 + +刚刚实例化结构体用到了:var person Person + +```go +// 实例化结构体 +var person Person +person.name = "张三" +person.age = 20 +person.sex = "男" +``` + +### 实例化结构体2 + +我们下面使用另外一个方式来实例化结构体,通过new关键字来实例化结构体,得到的是结构体的地址,格式如下 + +```go +var person2 = new(Person) +person2.name = "李四" +person2.age = 30 +person2.sex = "女" +fmt.Printf("%#v", person2) +``` + +输出如下所示,从打印结果可以看出person2是一个结构体指针 + +```bash +&main.Person{name:"李四", age:30, sex:"女"} +``` + +需要注意:在Golang中支持对结构体指针直接使用,来访问结构体的成员 + +```go +person2.name = "李四" +// 等价于 +(*person2).name = "李四" +``` + +### 实例化结构体3 + +使用&对结构体进行取地址操作,相当于对该结构体类型进行了一次new实例化操作 + +```go +// 第三种方式实例化 +var person3 = &Person{} +person3.name = "赵四" +person3.age = 28 +person3.sex = "男" +fmt.Printf("%#v", person3) +``` + +### 实例化结构体4 + +使用键值对的方式来实例化结构体,实例化的时候,可以直接指定对应的值 + +```go +// 第四种方式初始化 +var person4 = Person{ + name: "张三", + age: 10, + sex: "女", +} +fmt.Printf("%#v", person4) +``` + +### 实例化结构体5 + +第五种和第四种差不多,不过是用了取地址,然后返回的也是一个地址 + +```go +// 第五种方式初始化 +var person5 = &Person{ + name: "孙五", + age: 10, + sex: "女", +} +fmt.Printf("%#v", person5) +``` + +### 实例化结构体6 + +第六种方式是可以简写结构体里面的key + +```go +var person6 = Person{ + "张三", + 5, + "女", +} +fmt.Println(person6) +``` + +## 结构体方法和接收者 + +在go语言中,没有类的概念但是可以给类型(结构体,自定义类型)定义方法。所谓方法就是定义了接收者的函数。接收者的概念就类似于其他语言中的this 或者self。 + +方法的定义格式如下: + +```go +func (接收者变量 接收者类型) 方法名(参数列表)(返回参数) { + 函数体 +} +``` + +**其中** + +- 接收者变量:接收者中的参数变量名在命名时,官方建议使用接收者类型名的第一个小写字母,而不是self、this之类的命名。例如,Person类型的接收者变量应该命名为p,Connector类型的接收者变量应该命名为c等。、 +- 接收者类型:接收者类型和参数类似,可以是指针类型和非指针类型。 + - 非指针类型:表示不修改结构体的内容 + - 指针类型:表示修改结构体中的内容 +- 方法名、参数列表、返回参数:具体格式与函数定义相同 + +如果示例所示: + +```go +/** + 定义一个人结构体 + */ +type Person struct { + name string + age int + sex string +} + +// 定义一个结构体方法 +func (p Person) PrintInfo() { + fmt.Print(" 姓名: ", p.name) + fmt.Print(" 年龄: ", p.age) + fmt.Print(" 性别: ", p.sex) + fmt.Println() +} +func (p *Person) SetInfo(name string, age int, sex string) { + p.name = name + p.age = age + p.sex = sex +} + +func main() { + var person = Person{ + "张三", + 18, + "女", + } + person.PrintInfo() + person.SetInfo("李四", 18, "男") + person.PrintInfo() +} +``` + +运行结果为: + +```bash + 姓名: 张三 年龄: 18 性别: 女 + 姓名: 李四 年龄: 18 性别: 男 +``` + + + +注意,因为结构体是值类型,所以我们修改的时候,因为是传入的指针 + +```go +func (p *Person) SetInfo(name string, age int, sex string) { + p.name = name + p.age = age + p.sex = sex +} +``` + +## 给任意类型添加方法 + +在Go语言中,接收者的类型可以是任何类型,不仅仅是结构体,任何类型都可以拥有方法。 + +举个例子,我们基于内置的int类型使用type关键字可以定义新的自定义类型,然后为我们的自定义类型添加方法。 + +```go +type myInt int +func fun(x int, y int)int { + return x + y +} +func (m myInt) PrintInfo() { + fmt.Println("我是自定义类型里面的自定义方法") +} +func main() { + var a myInt = 10 + fmt.Printf("%v %T \n", a, a) + a.PrintInfo() +} +``` + +## 结构体的匿名字段 + +结构体允许其成员字段在声明时没有字段名而只有类型,这种没有名字的字段就被称为匿名字段 + +匿名字段默认采用类型名作为字段名,结构体要求字段名称必须唯一,因此一个结构体中同种类型的匿名字段只能一个 + +```go +/** + 定义一个人结构体 + */ +type Person struct { + string + int +} + +func main() { + // 结构体的匿名字段 + var person = Person{ + "张三", + 18 + } +} +``` + +结构体的字段类型可以是:基本数据类型,也可以是切片、Map 以及结构体 + +如果结构体的字段类似是:指针、slice、和 map 的零值都是nil,即还没有分配空间 + +如果需要使用这样的字段,需要先make,才能使用 + +```go +/** + 定义一个人结构体 + */ +type Person struct { + name string + age int + hobby []string + mapValue map[string]string +} + +func main() { + // 结构体的匿名字段 + var person = Person{} + person.name = "张三" + person.age = 10 + + // 给切片申请内存空间 + person.hobby = make([]string, 4, 4) + person.hobby[0] = "睡觉" + person.hobby[1] = "吃饭" + person.hobby[2] = "打豆豆" + + // 给map申请存储空间 + person.mapValue = make(map[string]string) + person.mapValue["address"] = "北京" + person.mapValue["phone"] = "123456789" + + // 加入#打印完整信息 + fmt.Printf("%#v", person) +} +``` + +同时我们还支持结构体的嵌套,如下所示 + +```go +// 用户结构体 +type User struct { + userName string + password string + sex string + age int + address Address // User结构体嵌套Address结构体 +} + +// 收货地址结构体 +type Address struct { + name string + phone string + city string +} + +func main() { + var u User + u.userName = "moguBlog" + u.password = "123456" + u.sex = "男" + u.age = 18 + + var address Address + address.name = "张三" + address.phone = "110" + address.city = "北京" + u.address = address + fmt.Printf("%#v", u) +} +``` + +## 嵌套结构体的字段名冲突 + +嵌套结构体内部可能存在相同的字段名,这个时候为了避免歧义,需要指定具体的内嵌结构体的字段。(例如,父结构体中的字段 和 子结构体中的字段相似) + +默认会从父结构体中寻找,如果找不到的话,再去子结构体中在找 + +如果子类的结构体中,同时存在着两个相同的字段,那么这个时候就会报错了,因为程序不知道修改那个字段的为准。 + +## 结构体的继承 + +结构体的继承,其实就类似于结构体的嵌套,如下所示,我们定义了两个结构体,分别是Animal 和 Dog,其中每个结构体都有各自的方法,然后通过Dog结构体 继承于 Animal结构体 + +```go +// 用户结构体 +type Animal struct { + name string +} +func (a Animal) run() { + fmt.Printf("%v 在运动 \n", a.name) +} +// 子结构体 +type Dog struct { + age int + // 通过结构体嵌套,完成继承 + Animal +} +func (dog Dog) wang() { + fmt.Printf("%v 在汪汪汪 \n", dog.name) +} + +func main() { + var dog = Dog{ + age: 10, + Animal: Animal{ + name: "阿帕奇", + }, + } + dog.run(); + dog.wang(); +} +``` + +运行后,发现Dog拥有了父类的方法 + +```bash +阿帕奇 在运动 +阿帕奇 在汪汪汪 +``` + +## Go中的结构体和Json相互转换 + +JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。RESTfull Api接口中返回的数据都是json数据。 + +```json +{ + "name": "张三", + "age": 15 +} +``` + +比如我们Golang要给App或者小程序提供Api接口数据,这个时候就需要涉及到结构体和Json之间的相互转换 +Golang JSON序列化是指把结构体数据转化成JSON格式的字符串,Golang JSON的反序列化是指把JSON数据转化成Golang中的结构体对象 + +Golang中的序列化和反序列化主要通过“encoding/json”包中的 json.Marshal() 和 son.Unmarshal() + +```go +// 定义一个学生结构体,注意结构体的首字母必须大写,代表公有,否则将无法转换 +type Student struct { + ID string + Gender string + Name string + Sno string +} +func main() { + var s1 = Student{ + ID: "12", + Gender: "男", + Name: "李四", + Sno: "s001", + } + // 结构体转换成Json(返回的是byte类型的切片) + jsonByte, _ := json.Marshal(s1) + jsonStr := string(jsonByte) + fmt.Printf(jsonStr) +} +``` + +将字符串转换成结构体类型 + +```go +// 定义一个学生结构体,注意结构体的首字母必须大写,代表公有,否则将无法转换 +type Student struct { + ID string + Gender string + Name string + Sno string +} +func main() { + // Json字符串转换成结构体 + var str = `{"ID":"12","Gender":"男","Name":"李四","Sno":"s001"}` + var s2 = Student{} + // 第一个是需要传入byte类型的数据,第二参数需要传入转换的地址 + err := json.Unmarshal([]byte(str), &s2) + if err != nil { + fmt.Printf("转换失败 \n") + } else { + fmt.Printf("%#v \n", s2) + } +} + +``` + +### 注意 + +我们想要实现结构体转换成字符串,必须保证结构体中的字段是公有的,也就是首字母必须是大写的,这样才能够实现结构体 到 Json字符串的转换。 + +## 结构体标签Tag + +Tag是结构体的元信息,可以在运行的时候通过反射的机制读取出来。Tag在结构体字段的后方定义,由一对反引号包裹起来,具体的格式如下: + +```json +key1:"value1" key2:"value2" +``` + +结构体tag由一个或多个键值对组成。键与值使用冒号分隔,值用双引号括起来。同一个结构体字段可以设置多个键值对tag,不同的键值对之间使用空格分隔。 + +注意事项:为结构体编写Tag时,必须严格遵守键值对的规则。结构体标签的解析代码的容错能力很差,一旦格式写错,编译和运行时都不会提示任何错误,通过反射也无法正确取值。例如不要在key和value之间添加空格。 + +如下所示,我们通过tag标签,来转换字符串的key + +```go +// 定义一个Student体,使用结构体标签 +type Student2 struct { + Id string `json:"id"` // 通过指定tag实现json序列化该字段的key + Gender string `json:"gender"` + Name string `json:"name"` + Sno string `json:"sno"` +} +func main() { + var s1 = Student2{ + Id: "12", + Gender: "男", + Name: "李四", + Sno: "s001", + } + // 结构体转换成Json + jsonByte, _ := json.Marshal(s1) + jsonStr := string(jsonByte) + fmt.Println(jsonStr) + + // Json字符串转换成结构体 + var str = `{"Id":"12","Gender":"男","Name":"李四","Sno":"s001"}` + var s2 = Student2{} + // 第一个是需要传入byte类型的数据,第二参数需要传入转换的地址 + err := json.Unmarshal([]byte(str), &s2) + if err != nil { + fmt.Printf("转换失败 \n") + } else { + fmt.Printf("%#v \n", s2) + } +} +``` + +## 嵌套结构体和Json序列化反序列化 + +和刚刚类似,我们同样也是使用的是 json.Marshal() + +```go +// 嵌套结构体 到 Json的互相转换 + +// 定义一个Student结构体 +type Student3 struct { + Id int + Gender string + Name string +} + +// 定义一个班级结构体 +type Class struct { + Title string + Students []Student3 +} + +func main() { + var class = Class{ + Title: "1班", + Students: make([]Student3, 0), + } + for i := 0; i < 10; i++ { + s := Student3{ + Id: i + 1, + Gender: "男", + Name: fmt.Sprintf("stu_%v", i + 1), + } + class.Students = append(class.Students, s) + } + fmt.Printf("%#v \n", class) + + // 转换成Json字符串 + strByte, err := json.Marshal(class) + if err != nil { + fmt.Println("打印失败") + } else { + fmt.Println(string(strByte)) + } +} +``` + + + diff --git "a/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/README.md" "b/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b53ac143b6d97f88259b952054705b3b364c46ed --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/README.md" @@ -0,0 +1,248 @@ +# Go中的包 + +## Go中的包的介绍和定义 + +包(package)是多个Go源码的集合,是一种高级的代码复用方案,Go语言为我们提供了很多内置包,如fmt、strconv、strings、sort、errors、time、encoding/json、os、io等。 + +Golang中的包可以分为三种:1、系统内置包 2、自定义包 3、第三方包 + +- **系统内置包**:Golang 语言给我们提供的内置包,引入后可以直接使用,如fmt、strconv、strings、sort、errors、time、encoding/json、os、io等。 +- **自定义包**:开发者自己写的包 +- **第三方包**:属于自定义包的一种,需要下载安装到本地后才可以使用,如前面给大家介绍的 + "github.com/shopspring/decimal"包解决float精度丢失问题。 + +## Go包管理工具 go mod + +在Golang1.11版本之前如果我们要自定义包的话必须把项目放在GOPATH目录。Go1.11版本之后无需手动配置环境变量,使用go mod 管理项目,也不需要非得把项目放到GOPATH指定目录下,你可以在你磁盘的任何位置新建一个项目,Go1.13以后可以彻底不要GOPATH了。 + +### go mod init初始化项目 + +实际项目开发中我们首先要在我们项目目录中用go mod命令生成一个go.mod文件管理我们项目的依赖。 + +比如我们的golang项目文件要放在了itying这个文件夹,这个时候我们需要在itying文件夹里面使用go mod命令生成一个go.mod文件 + +``` +go mod init goProject +``` + +![image-20200722160717988](images/image-20200722160717988.png) + +然后会生成一个 go.mod 的文件,里面的内容是go版本,以及以后添加的包 + +```go +module goProject + +go 1.14 +``` + +### 引入其它项目的包 + +首先我们创建一个 calc,然后里面有一个calc的文件 + +```go +package calc + +// 自定义包,最好和文件夹统一起来 + +// 公有变量 +var age = 10 +// 私有变量 +var Name = "张三" + +// 首字母大写,表示共有方法 +func Add(x, y int)int { + return x + y +} +func Sub(x, y int)int { + return x - y +} +``` + +在其它地方需要引用的话,就是这样 + +```go +package main +import ( + "fmt" + "goProject/calc" +) +func main() { + fmt.Printf("%v", calc.Add(2, 5)) +} +``` + +## Golang中自定义包 + +包(package)是多个Go源码的集合,一个包可以简单理解为一个存放多个.go文件的文件夹。该文件夹下面的所有go文件都要在代码的第一行添加如下代码,声明该文件归属的包。 + +```go +package 包名 +``` + +**注意事项** + +- 一个文件夹下面直接包含的文件只能归属一个package,同样一个package的文件不能在多个文件夹下。 +- 包名可以不和文件夹的名字一样,包名不能包含-符号。 +- 包名为main的包为应用程序的入口包,这种包编译后会得到一个可执行文件,而编译不包含main包的源代码则不会得到可执行文件。 + +## Go中init()初始化函数 + +### init函数介绍 + +在Go 语言程序执行时导入包语句会自动触发包内部init()函数的调用。需要注意的是:init() +函数没有参数也没有返回值。init()函数在程序运行时自动被调用执行,不能在代码中主动调用它。 +包初始化执行的顺序如下图所示: + +包初始化执行的顺序如下图所示: + +![image-20200722192813667](images/image-20200722192813667.png) + +### init函数执行顺序 + +Go语言包会从main包开始检查其导入的所有包,每个包中又可能导入了其他的包。Go编译器由此构建出一个树状的包引用关系,再根据引用顺序决定编译顺序,依次编译这些包的代码。 + +在运行时,被最后导入的包会最先初始化并调用其init()函数,如下图示: + +![image-20200722192933448](images/image-20200722192933448.png) + +也就是父类中的init先执行 + +## Go中的第三方包 + +我们可以在 https://pkg.go.dev/ 查找看常见的golang第三方包 + +例如,前面找到前面我们需要下载的第三方包的地址 + +``` +https://github.com/shopspring/decimal +``` + +然后安装这个包 + +### 方法1:go get 包全名 (全局) + +```bash +go get github.com/shopspring/decimal +``` + +### 方法2:go mod download (全局) + +```bash +go mod download +``` + +依赖包会自动下载到 $GOPATH/pkg/mod目录,并且多个项目可以共享缓存的mod,注意使用go mod download的时候,需要首先在你的项目中引入第三方包 + +### 方法3:go mod vendor 将依赖复制到当前项目的vendor(本项目) + +```bash +go mod vendor +``` + +将依赖复制到当前项目的vendor下 + +注意:使用go mod vendor的时候,首先需要在你的项目里面引入第三方包 + +### go mod常见命令 + +- go download:下载依赖的module到本地cache +- go edit:编辑go.mod文件 +- go graph:打印模块依赖图 +- go init:在当前文件夹下初始化一个新的module,创建go.mod文件 +- tidy:增加丢失的module,去掉未使用的module +- vendor:将依赖复制到vendor下 +- verify:校验依赖,检查下载的第三方库有没有本地修改,如果有修改,则会返回非0,否则校验成功 + +## 安装依赖 + +首先我们先去官网找到这个包,https://github.com/shopspring/decimal + +然后在我们的项目中引入 + +```go +import ( + "fmt" + "github.com/shopspring/decimal" + "goProject/calc" +) +func main() { + fmt.Printf("%v \n", calc.Add(2, 5)) + // 打印公有变量 + fmt.Println(calc.Name) + + _, err := decimal.NewFromString("136.02") + if err != nil { + panic(err) + } +} +``` + +引入后,我们运行项目,就会去下载了,下载完成后,我们到 go.mod文件夹,能够看到依赖被引入了 + +```go +module goProject + +go 1.14 + +require github.com/shopspring/decimal v1.2.0 // indirect +``` + +同时还生成了一个 go.sum文件 + +```go +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +``` + +这样我们就可以使用第三包开始具体的使用了~,我们实现一个Float类型的加法 + +```go +package main + +import ( + "fmt" + "github.com/shopspring/decimal" +) + +func main() { + var num1 float64 = 3.1 + var num2 float64 = 4.2 + d1 := decimal.NewFromFloat(num1).Add(decimal.NewFromFloat(num2)) + fmt.Println(d1) +} +``` + +## 完整案例 + +### 寻找依赖 + +首先我们需要去 [依赖官网](https://pkg.go.dev/),类似于我们的 maven repository + +![image-20200722200404713](images/image-20200722200404713.png) + +然后我们搜索gJson的包,这个包主要是用于json相关的操作 + +![image-20200722200455221](images/image-20200722200455221.png) + +我们进去后,找到它的https://github.com/tidwall/gjson,然后提供了完整的教程 + +```bash +# 下载依赖 +go get -u github.com/tidwall/gjson +``` + +使用 + +```go +package main + +import "github.com/tidwall/gjson" + +const json = `{"name":{"first":"Janet","last":"Prichard"},"age":47}` + +func main() { + value := gjson.Get(json, "name.last") + println(value.String()) +} +``` + diff --git "a/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722160717988.png" "b/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722160717988.png" new file mode 100644 index 0000000000000000000000000000000000000000..13ec8879a94e1ec10ca0272899c317613cea5b03 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722160717988.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722192813667.png" "b/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722192813667.png" new file mode 100644 index 0000000000000000000000000000000000000000..bd77b2654fd11149033fc66e6ba5ba173812e810 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722192813667.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722192933448.png" "b/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722192933448.png" new file mode 100644 index 0000000000000000000000000000000000000000..1c5c7f970260ff1db7592b70606ddbd47d42e2fe Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722192933448.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722200404713.png" "b/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722200404713.png" new file mode 100644 index 0000000000000000000000000000000000000000..bcacda23600878a32de96f3db93f2d09db36380a Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722200404713.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722200455221.png" "b/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722200455221.png" new file mode 100644 index 0000000000000000000000000000000000000000..23792ebe35a20fe6eadf6138e98e36419cfb8a94 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/13_Go\344\270\255\347\232\204\345\214\205\344\273\245\345\217\212GoMod/images/image-20200722200455221.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/14_Go\344\270\255\347\232\204\346\216\245\345\217\243/README.md" "b/Golang/Golang\345\237\272\347\241\200/14_Go\344\270\255\347\232\204\346\216\245\345\217\243/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..25208edcc0ced04e154e0da9bf5022dd266d55c5 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/14_Go\344\270\255\347\232\204\346\216\245\345\217\243/README.md" @@ -0,0 +1,395 @@ +# Go中的接口 + +## 接口的介绍 + +现实生活中手机、相机、U盘都可以和电脑的USB接口建立连接。我们不需要关注usb卡槽大小是否一样,因为所有的USB接口都是按照统一的标准来设计的。 + +![image-20200722201435128](images/image-20200722201435128.png) + +Golang中的接口是一种抽象数据类型,Golang中接口定义了对象的行为规范,只定义规范不实现。接口中定义的规范由具体的对象来实现。 + +通俗的讲接口就一个标准,它是对一个对象的行为和规范进行约定,约定实现接口的对象必须得按照接口的规范。 + +## Go接口的定义 + +在Golang中接口(interface)是一种类型,一种抽象的类型。接口(interface)是一组函数method的集合,Golang中的接口不能包含任何变量。 + +在Golang中接口中的所有方法都没有方法体,接口定义了一个对象的行为规范,只定义规范不实现。接口体现了程序设计的多态和高内聚低耦合的思想N Golang中的接口也是一种数据类型,不需要显示实现。只需要一个变量含有接口类型中的所有方法,那么这个变量就实现了这个接口。 + +Golang中每个接口由数个方法组成,接口的定义格式如下: + +```go +type 接口名 interface { + 方法名1 (参数列表1) 返回值列表1 + 方法名2 (参数列表2) 返回值列表2 +} +``` + +**其中** + +- **接口名**:使用type将接口定义为自定义的类型名。Go语言的接口在命名时,一般会在单词后面添加er,如有写操作的接口叫Writer,有字符串功能的接口叫Stringer等,接口名最好突出该接口的类型含义。 +- **方法名**:当方法名首字母是大写且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。 +- **参数列表、返回值列表**:参数列表和返回值列表中的参数变量名是可以省略 + +演示:定义一个Usber接口让Phone 和 Camera结构体实现这个接口 + +首先我们定义一个Usber接口,接口里面就定义了两个方法 + +``` +// 定义一个Usber接口 +type Usber interface { + start() + stop() +} +``` + +然后我们在创建一个手机结构体 + +```go +// 如果接口里面有方法的话,必须要通过结构体或自定义类型实现这个接口 + +// 使用结构体来实现 接口 +type Phone struct { + Name string +} +// 手机要实现Usber接口的话,必须实现usb接口的所有方法 +func (p Phone) Start() { + fmt.Println(p.Name, "启动") +} +func (p Phone) Stop() { + fmt.Println(p.Name, "关闭") +} +``` + +然后我们在创建一个Phone的结构体,来实现这个接口 + +```go +// 如果接口里面有方法的话,必须要通过结构体或自定义类型实现这个接口 + +// 使用结构体来实现 接口 +type Phone struct { + Name string +} +// 手机要实现Usber接口的话,必须实现usb接口的所有方法 +func (p Phone) start() { + fmt.Println(p.Name, "启动") +} +func (p Phone) stop() { + fmt.Println(p.Name, "关闭") +} +func main() { + var phone Usber = Phone{ + "三星手机", + } + phone.start() + phone.stop() +} +``` + +我们在创建一个Camera结构体 + +```go +// 使用相机结构体来实现 接口 +type Camera struct { + Name string +} +// 相机要实现Usber接口的话,必须实现usb接口的所有方法 +func (p Camera) start() { + fmt.Println(p.Name, "启动") +} +func (p Camera) stop() { + fmt.Println(p.Name, "关闭") +} +func main() { + var camera Usber = Camera{ + "佳能", + } + camera.start() + camera.stop() +} +``` + +我们创建一个电脑的结构体,电脑的结构体就是用于接收两个实现了Usber的结构体,然后让其工作 + +```go +// 电脑 +type Computer struct { + +} + +// 接收一个实现了Usber接口的 结构体 +func (computer Computer) Startup(usb Usber) { + usb.start() +} + +// 关闭 +func (computer Computer) Shutdown (usb Usber) { + usb.stop() +} +``` + +最后我们在main中调用方法 + +```go +func main() { + var camera interfaceDemo.Camera = interfaceDemo.Camera{ + "佳能", + } + var phone interfaceDemo.Phone = interfaceDemo.Phone{ + "苹果", + } + + var computer interfaceDemo.Computer = interfaceDemo.Computer{} + computer.Startup(camera) + computer.Startup(phone) + computer.Shutdown(camera) + computer.Shutdown(phone) +} +``` + +运行结果如下所示: + +```bash +佳能 启动 +苹果 启动 +佳能 关闭 +苹果 关闭 +``` + +## 空接口(Object类型) + +Golang中的接口可以不定义任何方法,没有定义任何方法的接口就是空接口。空接口表示没有任何约束,因此任何类型变量都可以实现空接口。 + +空接口在实际项目中用的是非常多的,用空接口可以表示任意数据类型。 + +```go +// 空接口表示没有任何约束,任意的类型都可以实现空接口 +type EmptyA interface { + +} + +func main() { + var a EmptyA + var str = "你好golang" + // 让字符串实现A接口 + a = str + fmt.Println(a) +} +``` + +同时golang中空接口也可以直接当做类型来使用,可以表示任意类型。相当于Java中的Object类型 + +```go +var a interface{} +a = 20 +a = "hello" +a = true +``` + +空接口可以作为函数的参数,使用空接口可以接收任意类型的函数参数 + +```go +// 空接口作为函数参数 +func show(a interface{}) { + fmt.println(a) +} +``` + +### map的值实现空接口 + +使用空接口实现可以保存任意值的字典 + +```go +// 定义一个值为空接口类型 +var studentInfo = make(map[string]interface{}) +studentInfo["userName"] = "张三" +studentInfo["age"] = 15 +studentInfo["isWork"] = true +``` + +### slice切片实现空接口 + +```go +// 定义一个空接口类型的切片 +var slice = make([]interface{}, 4, 4) +slice[0] = "张三" +slice[1] = 1 +slice[2] = true +``` + +## 类型断言 + +一个接口的值(简称接口值)是由一个具体类型和具体类型的值两部分组成的。这两部分分别称为接口的动态类型和动态值。 + +如果我们想要判断空接口中值的类型,那么这个时候就可以使用类型断言,其语法格式: + +```bash +x.(T) +``` + +其中: + +- X:表示类型为interface{}的变量 +- T:表示断言x可能是的类型 + +该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,若为true则表示断言成功,为false则表示断言失败 + +```go +// 类型断言 +var a interface{} +a = "132" +value, isString := a.(string) +if isString { + fmt.Println("是String类型, 值为:", value) +} else { + fmt.Println("断言失败") +} +``` + +或者我们可以定义一个能传入任意类型的方法 + +```go +// 定义一个方法,可以传入任意数据类型,然后根据不同类型实现不同的功能 +func Print(x interface{}) { + if _,ok := x.(string); ok { + fmt.Println("传入参数是string类型") + } else if _, ok := x.(int); ok { + fmt.Println("传入参数是int类型") + } else { + fmt.Println("传入其它类型") + } +} +``` + +上面的示例代码中,如果要断言多次,那么就需要写很多if,这个时候我们可以使用switch语句来实现: + +**注意:** 类型.(type) 只能结合switch语句使用 + +```go +func Print2(x interface{}) { + switch x.(type) { + case int: + fmt.Println("int类型") + case string: + fmt.Println("string类型") + case bool: + fmt.Println("bool类型") + default: + fmt.Println("其它类型") + } +} +``` + +## 结构体接收者 + +### 值接收者 + +如果结构体中的方法是值接收者,那么实例化后的结构体值类型和结构体指针类型都可以赋值给接口变量 + +## 结构体实现多个接口 + +实现多个接口的话,可能就同时用两个接口进行结构体的接受 + +```go +// 定义一个Animal的接口,Animal中定义了两个方法,分别是setName 和 getName,分别让DOg结构体和Cat结构体实现 +type Animal interface { + SetName(string) +} + +// 接口2 +type Animal2 interface { + GetName()string +} + +type Dog struct { + Name string +} + +func (d *Dog) SetName(name string) { + d.Name = name +} +func (d Dog)GetName()string { + return d.Name +} + +func main() { + var dog = &Dog{ + "小黑", + } + // 同时实现两个接口 + var d1 Animal = dog + var d2 Animal2 = dog + d1.SetName("小鸡") + fmt.Println(d2.GetName()) +} +``` + +## 接口嵌套 + +在golang中,允许接口嵌套接口,我们首先创建一个 Animal1 和 Animal2 接口,然后使用Animal接受刚刚的两个接口,实现接口的嵌套。 + +```go +// 定义一个Animal的接口,Animal中定义了两个方法,分别是setName 和 getName,分别让DOg结构体和Cat结构体实现 +type Animal1 interface { + SetName(string) +} + +// 接口2 +type Animal2 interface { + GetName()string +} + +type Animal interface { + Animal1 + Animal2 +} + +type Dog struct { + Name string +} + +func (d *Dog) SetName(name string) { + d.Name = name +} +func (d Dog)GetName()string { + return d.Name +} + +func main() { + var dog = &Dog{ + "小黑", + } + // 同时实现两个接口 + var d Animal = dog + d.SetName("小鸡") + fmt.Println(d.GetName()) +} +``` + +## Golang中空接口和类型断言 + +```go +// golang中空接口和类型断言 +var userInfo = make(map[string]interface{}) +userInfo["userName"] = "zhangsan" +userInfo["age"] = 10 +userInfo["hobby"] = []string{"吃饭", "睡觉"} +fmt.Println(userInfo["userName"]) +fmt.Println(userInfo["age"]) +fmt.Println(userInfo["hobby"]) +// 但是我们空接口如何获取数组中的值?发现 userInfo["hobby"][0] 这样做不行 +// fmt.Println(userInfo["hobby"][0]) +``` + +也就是我们的空接口,无法直接通过索引获取数组中的内容,因此这个时候就需要使用类型断言了 + +```go +// 这个时候我们就可以使用类型断言了 +hobbyValue,ok := userInfo["hobby"].([]string) +if ok { + fmt.Println(hobbyValue[0]) +} +``` + +通过类型断言返回来的值,我们就能够直接通过角标获取了。 + diff --git "a/Golang/Golang\345\237\272\347\241\200/14_Go\344\270\255\347\232\204\346\216\245\345\217\243/images/image-20200722201435128.png" "b/Golang/Golang\345\237\272\347\241\200/14_Go\344\270\255\347\232\204\346\216\245\345\217\243/images/image-20200722201435128.png" new file mode 100644 index 0000000000000000000000000000000000000000..b439d4f0f938eaea1843bb38690b79b22c8cfbf9 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/14_Go\344\270\255\347\232\204\346\216\245\345\217\243/images/image-20200722201435128.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/README.md" "b/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..4a62549062fa25ce630a478804e75f238e1a4fed --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/README.md" @@ -0,0 +1,682 @@ +# Golang goroutine channel 实现并发和并行 + +## 为什么要使用goroutine呢 + +需求:要统计1-10000000的数字中那些是素数,并打印这些素数? + +素数:就是除了1和它本身不能被其他数整除的数 + +**实现方法:** + +- 传统方法,通过一个for循环判断各个数是不是素数 +- 使用并发或者并行的方式,将统计素数的任务分配给多个goroutine去完成,这个时候就用到了goroutine +- goroutine 结合 channel + +## 进程、线程以及并行、并发 + +### 进程 + +进程(Process)就是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位,进程是一个动态概念,是程序在执行过程中分配和管理资源的基本单位,每一个进程都有一个自己的地址空间。一个进程至少有5种基本状态,它们是:初始态,执行态,等待状态,就绪状态,终止状态。 + +通俗的讲进程就是一个正在执行的程序。 + +### 线程 + +线程是进程的一个执行实例,是程序执行的最小单元,它是比进程更小的能独立运行的基本单位 + +一个进程可以创建多个线程,同一个进程中多个线程可以并发执行 ,一个线程要运行的话,至少有一个进程 + +### 并发和并行 + +并发:多个线程同时竞争一个位置,竞争到的才可以执行,每一个时间段只有一个线程在执行。 + +并行:多个线程可以同时执行,每一个时间段,可以有多个线程同时执行。 + +通俗的讲多线程程序在单核CPU上面运行就是并发,多线程程序在多核CUP上运行就是并行,如果线程数大于CPU核数,则多线程程序在多个CPU上面运行既有并行又有并发 + +![image-20200723091802816](images/image-20200723091802816.png) + + + +![image-20200723092334895](images/image-20200723092334895.png) + + + +## Golang中协程(goroutine)以及主线程 + +golang中的主线程:(可以理解为线程/也可以理解为进程),在一个Golang程序的主线程上可以起多个协程。Golang中多协程可以实现并行或者并发。 + +**协程**:可以理解为用户级线程,这是对内核透明的,也就是系统并不知道有协程的存在,是完全由用户自己的程序进行调度的。Golang的一大特色就是从语言层面原生持协程,在函数或者方法前面加go关键字就可创建一个协程。可以说Golang中的协程就是goroutine。 + +![image-20200723092645188](images/image-20200723092645188.png) + +Golang中的多协程有点类似于Java中的多线程 + +### 多协程和多线程 + +多协程和多线程:Golang中每个goroutine(协程)默认占用内存远比Java、C的线程少。 + +OS线程(操作系统线程)一般都有固定的栈内存(通常为2MB左右),一个goroutine(协程)占用内存非常小,只有2KB左右,多协程goroutine切换调度开销方面远比线程要少。 + +这也是为什么越来越多的大公司使用Golang的原因之一。 + +## goroutine的使用以及sync.WaitGroup + +### 并行执行需求 + +在主线程(可以理解成进程)中,开启一个goroutine,该协程每隔50毫秒秒输出“你好golang" + +在主线程中也每隔50毫秒输出“你好golang",输出10次后,退出程序,要求主线程和goroutine同时执行。 + +这是时候,我们就可以开启协程来了,通过 go关键字开启 + +```go +// 协程需要运行的方法 +func test() { + for i := 0; i < 5; i++ { + fmt.Println("test 你好golang") + time.Sleep(time.Millisecond * 100) + } +} +func main() { + + // 通过go关键字,就可以直接开启一个协程 + go test() + + // 这是主进程执行的 + for i := 0; i < 5; i++ { + fmt.Println("main 你好golang") + time.Sleep(time.Millisecond * 100) + } +} +``` + +运行结果如下,我们能够看到他们之间不存在所谓的顺序关系了 + +```go +main 你好golang +test 你好golang +main 你好golang +test 你好golang +test 你好golang +main 你好golang +main 你好golang +test 你好golang +test 你好golang +main 你好golang +``` + +但是上述的代码其实还有问题的,也就是说当主进程执行完毕后,不管协程有没有执行完成,都会退出 + +![image-20200723094125527](images/image-20200723094125527.png) + +这是使用我们就需要用到 sync.WaitGroup等待协程 + +首先我们需要创建一个协程计数器 + +```go +// 定义一个协程计数器 +var wg sync.WaitGroup +``` + +然后当我们开启协程的时候,我们要让计数器加1 + +```go +// 开启协程,协程计数器加1 +wg.Add(1) +go test2() +``` + +当我们协程结束前,我们需要让计数器减1 + +```go +// 协程计数器减1 +wg.Done() +``` + +完整代码如下 + +```go +// 定义一个协程计数器 +var wg sync.WaitGroup + +func test() { + // 这是主进程执行的 + for i := 0; i < 1000; i++ { + fmt.Println("test1 你好golang", i) + //time.Sleep(time.Millisecond * 100) + } + // 协程计数器减1 + wg.Done() +} + +func test2() { + // 这是主进程执行的 + for i := 0; i < 1000; i++ { + fmt.Println("test2 你好golang", i) + //time.Sleep(time.Millisecond * 100) + } + // 协程计数器减1 + wg.Done() +} + +func main() { + + // 通过go关键字,就可以直接开启一个协程 + wg.Add(1) + go test() + + // 协程计数器加1 + wg.Add(1) + go test2() + + // 这是主进程执行的 + for i := 0; i < 1000; i++ { + fmt.Println("main 你好golang", i) + //time.Sleep(time.Millisecond * 100) + } + // 等待所有的协程执行完毕 + wg.Wait() + fmt.Println("主线程退出") +} +``` + +## 设置Go并行运行的时候占用的cpu数量 + +Go运行时的调度器使用GOMAXPROCS参数来确定需要使用多少个OS线程来同时执行Go代码。默认值是机器上的CPU核心数。例如在一个8核心的机器上,调度器会把Go代码同时调度到8个oS线程上。 + +Go 语言中可以通过runtime.GOMAXPROCS()函数设置当前程序并发时占用的CPU逻辑核心数。 + +Go1.5版本之前,默认使用的是单核心执行。Go1.5版本之后,默认使用全部的CPU逻辑核心数。 + +```go +func main() { + // 获取cpu个数 + npmCpu := runtime.NumCPU() + fmt.Println("cup的个数:", npmCpu) + // 设置允许使用的CPU数量 + runtime.GOMAXPROCS(runtime.NumCPU() - 1) +} +``` + +## for循环开启多个协程 + +类似于Java里面开启多个线程,同时执行 + +```go +func test(num int) { + for i := 0; i < 10; i++ { + fmt.Printf("协程(%v)打印的第%v条数据 \n", num, i) + } + // 协程计数器减1 + vg.Done() +} + +var vg sync.WaitGroup + +func main() { + for i := 0; i < 10; i++ { + go test(i) + vg.Add(1) + } + vg.Wait() + fmt.Println("主线程退出") +} +``` + +因为我们协程会在主线程退出后就终止,所以我们还需要使用到 sync.WaitGroup来控制主线程的终止。 + +## Channel管道 + +管道是Golang在语言级别上提供的goroutine间的通讯方式,我们可以使用channel在多个goroutine之间传递消息。如果说goroutine是Go程序并发的执行体,channel就是它们之间的连接。channel是可以让一个goroutine发送特定值到另一个goroutine的通信机制。 + +Golang的并发模型是CSP(Communicating Sequential Processes),提倡通过通信共享内存而不是通过共享内存而实现通信。 + +Go语言中的管道(channel)是一种特殊的类型。管道像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序。每一个管道都是一个具体类型的导管,也就是声明channel的时候需要为其指定元素类型。 + +### channel类型 + +channel是一种类型,一种引用类型。声明管道类型的格式如下: + +```go +// 声明一个传递整型的管道 +var ch1 chan int +// 声明一个传递布尔类型的管道 +var ch2 chan bool +// 声明一个传递int切片的管道 +var ch3 chan []int +``` + +### 创建channel + +声明管道后,需要使用make函数初始化之后才能使用 + +```go +make(chan 元素类型, 容量) +``` + +举例如下: + +```go +// 创建一个能存储10个int类型的数据管道 +ch1 = make(chan int, 10) +// 创建一个能存储4个bool类型的数据管道 +ch2 = make(chan bool, 4) +// 创建一个能存储3个[]int切片类型的管道 +ch3 = make(chan []int, 3) +``` + +### channel操作 + +管道有发送,接收和关闭的三个功能 + +发送和接收 都使用 <- 符号 + +现在我们先使用以下语句定义一个管道: + +```go +ch := make(chan int, 3) +``` + +#### 发送 + +将数据放到管道内,将一个值发送到管道内 + +```go +// 把10发送到ch中 +ch <- 10 +``` + +#### 取操作 + +```go +x := <- ch +``` + +#### 关闭管道. + +通过调用内置的close函数来关闭管道 + +```go +close(ch) +``` + + + +#### 完整示例 + +```go +// 创建管道 +ch := make(chan int, 3) + +// 给管道里面存储数据 +ch <- 10 +ch <- 21 +ch <- 32 + +// 获取管道里面的内容 +a := <- ch +fmt.Println("打印出管道的值:", a) +fmt.Println("打印出管道的值:", <- ch) +fmt.Println("打印出管道的值:", <- ch) + +// 管道的值、容量、长度 +fmt.Printf("地址:%v 容量:%v 长度:%v \n", ch, cap(ch), len(ch)) + +// 管道的类型 +fmt.Printf("%T \n", ch) + +// 管道阻塞(当没有数据的时候取,会出现阻塞,同时当管道满了,继续存也会) +<- ch // 没有数据取,出现阻塞 +ch <- 10 +ch <- 10 +ch <- 10 +ch <- 10 // 管道满了,继续存,也出现阻塞 +``` + +## for range从管道循环取值 + +当向管道中发送完数据时,我们可以通过close函数来关闭管道,当管道被关闭时,再往该管道发送值会引发panic,从该管道取值的操作会去完管道中的值,再然后取到的值一直都是对应类型的零值。那如何判断一个管道是否被关闭的呢? + +```go +// 创建管道 +ch := make(chan int, 10) +// 循环写入值 +for i := 0; i < 10; i++ { + ch <- i +} +// 关闭管道 +close(ch) + +// for range循环遍历管道的值(管道没有key) +for value := range ch { + fmt.Println(value) +} +// 通过上述的操作,能够打印值,但是出出现一个deadlock的死锁错误,也就说我们需要关闭管道 +``` + +注意:使用for range遍历的时候,一定在之前需要先关闭管道 + +思考:通过for循环来遍历管道,需要关闭么? + +```go +// 创建管道 +ch := make(chan int, 10) +// 循环写入值 +for i := 0; i < 10; i++ { + ch <- i +} + +for i := 0; i < 10; i++ { + fmt.Println(<- ch) +} +``` + +上述代码没有报错,说明通过for i的循环方式,可以不关闭管道 + +## Goroutine 结合 channel 管道 + +需求1:定义两个方法,一个方法给管道里面写数据,一个给管道里面读取数据。要求同步进行。 + +- 开启一个fn1的的协程给向管道inChan中写入00条数据 +- 开启一个fn2的协程读取inChan中写入的数据 +- 注意:fn1和fn2同时操作一个管道 +- 主线程必须等待操作完成后才可以退出 + +```go +func write(ch chan int) { + for i := 0; i < 10; i++ { + fmt.Println("写入:", i) + ch <- i + time.Sleep(time.Microsecond * 10) + } + wg.Done() +} +func read(ch chan int) { + for i := 0; i < 10; i++ { + fmt.Println("读取:", <- ch) + time.Sleep(time.Microsecond * 10) + } + wg.Done() +} +var wg sync.WaitGroup +func main() { + ch := make(chan int, 10) + wg.Add(1) + go write(ch) + wg.Add(1) + go read(ch) + + // 等待 + wg.Wait() + fmt.Println("主线程执行完毕") +} +``` + +管道是安全的,是一边写入,一边读取,当读取比较快的时候,会等待写入 + +## goroutine 结合 channel打印素数 + +![image-20200723214241459](images/image-20200723214241459.png) + +```go +// 想intChan中放入 1~ 120000个数 +func putNum(intChan chan int) { + for i := 2; i < 120000; i++ { + intChan <- i + } + wg.Done() + close(intChan) +} + +// cong intChan取出数据,并判断是否为素数,如果是的话,就把得到的素数放到primeChan中 +func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) { + for value := range intChan { + var flag = true + for i := 2; i <= int(math.Sqrt(float64(value))); i++ { + if i % i == 0 { + flag = false + break + } + } + if flag { + // 是素数 + primeChan <- value + break + } + } + + // 这里需要关闭 primeChan,因为后面需要遍历输出 primeChan + exitChan <- true + + wg.Done() +} + +// 打印素数 +func printPrime(primeChan chan int) { + for value := range primeChan { + fmt.Println(value) + } + wg.Done() +} + + +var wg sync.WaitGroup +func main() { + // 写入数字 + intChan := make(chan int, 1000) + + // 存放素数 + primeChan := make(chan int, 1000) + + // 存放 primeChan退出状态 + exitChan := make(chan bool, 16) + + // 开启写值的协程 + go putNum(intChan) + + // 开启计算素数的协程 + for i := 0; i < 10; i++ { + wg.Add(1) + go primeNum(intChan, primeChan, exitChan) + } + + // 开启打印的协程 + wg.Add(1) + go printPrime(primeChan) + + // 匿名自运行函数 + wg.Add(1) + go func() { + for i := 0; i < 16; i++ { + // 如果exitChan 没有完成16次遍历,将会等待 + <- exitChan + } + // 关闭primeChan + close(primeChan) + wg.Done() + }() + + wg.Wait() + fmt.Println("主线程执行完毕") + +} +``` + +## 单向管道 + +有时候我们会将管道作为参数在多个任务函数间传递,很多时候我们在不同的任务函数中,使用管道都会对其进行限制,比如限制管道在函数中只能发送或者只能接受 + +> 默认的管道是 可读可写 + +```go +// 定义一种可读可写的管道 +var ch = make(chan int, 2) +ch <- 10 +<- ch + +// 管道声明为只写管道,只能够写入,不能读 +var ch2 = make(chan<- int, 2) +ch2 <- 10 + +// 声明一个只读管道 +var ch3 = make(<-chan int, 2) +<- ch3 +``` + +## Select多路复用 + +在某些场景下我们需要同时从多个通道接收数据。这个时候就可以用到golang中给我们提供的select多路复用。 +通常情况通道在接收数据时,如果没有数据可以接收将会发生阻塞。 + +比如说下面代码来实现从多个通道接受数据的时候就会发生阻塞 + +这种方式虽然可以实现从多个管道接收值的需求,但是运行性能会差很多。为了应对这种场景,Go内置了select关键字,可以同时响应多个管道的操作。 + +select的使用类似于switch 语句,它有一系列case分支和一个默认的分支。每个case会对应一个管道的通信(接收或发送)过程。select会一直等待,直到某个case的通信操作完成时,就会执行case分支对应的语句。具体格式如下: + +```go +intChan := make(chan int, 10) +intChan <- 10 +intChan <- 12 +intChan <- 13 +stringChan := make(chan int, 10) +stringChan <- 20 +stringChan <- 23 +stringChan <- 24 + +// 每次循环的时候,会随机中一个chan中读取,其中for是死循环 +for { + select { + case v:= <- intChan: + fmt.Println("从initChan中读取数据:", v) + case v:= <- stringChan: + fmt.Println("从stringChan中读取数据:", v) + default: + fmt.Println("所有的数据获取完毕") + return + } +} +``` + +> tip:使用select来获取数据的时候,不需要关闭chan,不然会出现问题 + +## Goroutine Recover解决协程中出现的Panic + +```go +func sayHello() { + for i := 0; i < 10; i++ { + fmt.Println("hello") + } +} +func errTest() { + // 捕获异常 + defer func() { + if err := recover(); err != nil { + fmt.Println("errTest发生错误") + } + }() + var myMap map[int]string + myMap[0] = "10" +} +func main { + go sayHello() + go errTest() +} +``` + +当我们出现问题的时候,我们还是按照原来的方法,通过defer func创建匿名自启动 + +```go +// 捕获异常 +defer func() { + if err := recover(); err != nil { + fmt.Println("errTest发生错误") + } +}() +``` + +## Go中的并发安全和锁 + +如下面一段代码,我们在并发环境下进行操作,就会出现并发访问的问题 + +```go +var count = 0 +var wg sync.WaitGroup + +func test() { + count++ + fmt.Println("the count is : ", count) + time.Sleep(time.Millisecond) + wg.Done() +} +func main() { + for i := 0; i < 20; i++ { + wg.Add(1) + go test() + } + time.Sleep(time.Second * 10) +} +``` + +### 互斥锁 + +互斥锁是传统并发编程中对共享资源进行访问控制的主要手段,它由标准库sync中的Mutex结构体类型表示。sync.Mutex类型只有两个公开的指针方法,Lock和Unlock。Lock锁定当前的共享资源,Unlock 进行解锁 + +```go +// 定义一个锁 +var mutex sync.Mutex +// 加锁 +mutex.Lock() +// 解锁 +mutex.Unlock() +``` + +完整代码 + +```go +var count = 0 +var wg sync.WaitGroup +var mutex sync.Mutex + +func test() { + // 加锁 + mutex.Lock() + count++ + fmt.Println("the count is : ", count) + time.Sleep(time.Millisecond) + wg.Done() + // 解锁 + mutex.Unlock() +} +func main() { + for i := 0; i < 20; i++ { + wg.Add(1) + go test() + } + time.Sleep(time.Second * 10) +} +``` + +通过下面命令,build的时候,可以查看是否具有竞争关系 + +```go +// 通过 -race 参数进行构建 +go build -race main.go +// 运行插件 +main.ext +``` + +### 读写互斥锁 + +互斥锁的本质是当一个goroutine访问的时候,其他goroutine都不能访问。这样在资源同步,避免竞争的同时也降低了程序的并发性能。程序由原来的并行执行变成了串行执行。 + +其实,当我们对一个不会变化的数据只做“读”操作的话,是不存在资源竞争的问题的。因为数据是不变的,不管怎么读取,多少goroutine同时读取,都是可以的。 + +所以问题不是出在“读”上,主要是修改,也就是“写”。修改的数据要同步,这样其他goroutine才可以感知到。所以真正的互斥应该是读取和修改、修改和修改之间,读和读是没有互斥操作的必要的。 + +因此,衍生出另外一种锁,叫做读写锁。 + +读写锁可以让多个读操作并发,同时读取,但是对于写操作是完全互斥的。也就是说,当一个goroutine进行写操作的时候,其他goroutine既不能进行读操作,也不能进行写操作。 + +GO中的读写锁由结构体类型sync.RWMutex表示。此类型的方法集合中包含两对方法: \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723091802816.png" "b/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723091802816.png" new file mode 100644 index 0000000000000000000000000000000000000000..1f250ce156672b51f0bcaae391463dc8f77292d1 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723091802816.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723092334895.png" "b/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723092334895.png" new file mode 100644 index 0000000000000000000000000000000000000000..9c901a8ff3c455821fe8047b19e8abbe6e271afe Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723092334895.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723092645188.png" "b/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723092645188.png" new file mode 100644 index 0000000000000000000000000000000000000000..866eed1a77ffd7bc60103d83b7def1e8e9289fff Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723092645188.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723094125527.png" "b/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723094125527.png" new file mode 100644 index 0000000000000000000000000000000000000000..57d877af0ddc4a07fc2d29a5d735bb87d8af323e Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723094125527.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723214241459.png" "b/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723214241459.png" new file mode 100644 index 0000000000000000000000000000000000000000..e537abd36983ed49650239009631d755f56b5d96 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/15_goroutine\345\256\236\347\216\260\345\271\266\350\241\214\345\222\214\345\271\266\345\217\221/images/image-20200723214241459.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/16_Golang\344\270\255\347\232\204\345\217\215\345\260\204/README.md" "b/Golang/Golang\345\237\272\347\241\200/16_Golang\344\270\255\347\232\204\345\217\215\345\260\204/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..1bc35f4613422a75c32b6d93c964f65bc2320132 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/16_Golang\344\270\255\347\232\204\345\217\215\345\260\204/README.md" @@ -0,0 +1,243 @@ +# Go中的反射 + +## 反射 + +有时我们需要写一个函数,这个函数有能力统一处理各种值类型,而这些类型可能无法共享同一个接口,也可能布局未知,也有可能这个类型在我们设计函数时还不存在,这个时候我们就可以用到反射。 + +空接口可以存储任意类型的变量,那我们如何知道这个空接口保存数据的类型是什么? +值是什么呢? + +- 可以使用类型断言 +- 可以使用反射实现,也就是在程序运行时动态的获取一个变量的类型信息和值信息。 + +把结构体序列化成json字符串,自定义结构体Tab标签的时候就用到了反射 + +后面所说的ORM框架,底层就是用到了反射技术 + +ORM:对象关系映射(Object Relational Mapping,简称 ORM)是通过使用描述对象和数据库之间的映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。 + +## 反射的基本介绍 + +反射是指在程序运行期间对程序本身进行访问和修改的能力。正常情况程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分。在运行程序时,程序无法获取自身的信息。支持反射的语言可以在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期获取类型的反射信息,并且有能力修改它们。 + +## Go可以实现的功能 + +- 反射可以在程序运行期间动态的获取变量的各种信息,比如变量的类型类别 +- 如果是结构体,通过反射还可以获取结构体本身的信息,比如结构体的字段、结构体的方法。 +- 通过反射,可以修改变量的值,可以调用关联的方法 + +Go语言中的变量是分为两部分的: + +- 类型信息:预先定义好的元信息。 +- 值信息:程序运行过程中可动态变化的。 + +在Go语言的反射机制中,任何接口值都由是一个具体类型和具体类型的值两部分组成的。 + +在Go语言中反射的相关功能由内置的reflect包提供,任意接口值在反射中都可以理解为由 reflect.Type 和 reflect.Value两部分组成,并且reflect包提供了reflect.TypeOf和reflect.ValueOf两个重要函数来获取任意对象的Value 和 Type + +## reflect.TypeOf()获取任意值的类型对象 + +在Go 语言中,使用reflect.TypeOf()函数可以接受任意interface}参数,可以获得任意值的类型对象(reflect.Type),程序通过类型对象可以访问任意值的类型信息。 + +通过反射获取空接口的类型 + +```go +func reflectFun(x interface{}) { + v := reflect.TypeOf(x) + fmt.Println(v) +} +func main() { + reflectFun(10) + reflectFun(10.01) + reflectFun("abc") + reflectFun(true) +} +``` + +## type name 和 type Kind + +在反射中关于类型还划分为两种:类型(Type)和种类(Kind)。因为在Go语言中我们可以使用type关键字构造很多自定义类型,而种类(Kid)就是指底层的类型,但在反射中,当需要区分指针、结构体等大品种的类型时,就会用到种类(Kind)。举个例子,我们定义了两个指针类型和两个结构体类型,通过反射查看它们的类型和种类。 + +Go 语言的反射中像数组、切片、Map、指针等类型的变量,它们的.Name()都是返回空。 + +```go +v := reflect.TypeOf(x) +fmt.Println("类型 ", v) +fmt.Println("类型名称 ", v.Name()) +fmt.Println("类型种类 ", v.Kind()) +``` + +我们之前可以通过类型断言来实现空接口类型的数相加操作 + +```go +func reflectValue(x interface{}) { + b,_ := x.(int) + var num = 10 + b + fmt.Println(num) +} +``` + +到现在的话,我们就可以使用reflect.TypeOf来实现了 + +```go +func reflectValue2(x interface{}) { + // 通过反射来获取变量的原始值 + v := reflect.ValueOf(x) + fmt.Println(v) + // 获取到V的int类型 + var n = v.Int() + 12 + fmt.Println(n) +} +``` + +同时我们还可以通过switch来完成 + +```go +// 通过反射来获取变量的原始值 +v := reflect.ValueOf(x) +// 获取种类 +kind := v.Kind() +switch kind { + case reflect.Int: + fmt.Println("我是int类型") + case reflect.Float64: + fmt.Println("我是float64类型") + default: + fmt.Println("我是其它类型") +} +``` + +## reflect.ValueOf + +reflect.ValueOf() 返回的是reflect.Value类型,其中包含了原始值的值信息,reflect.Value与原始值之间可以互相转换 + +reflect.value类型提供的获取原始值的方法如下 + +| 方法 | 说明 | +| --------------- | ------------------------------------------------------------ | +| interface{} | 将值以interface{}类型返回,可以通过类型断言转换为指定类型 | +| Int() int64 | 将值以int类型返回,所有有符号整型均可以此方式返回 | +| Uint() uint64 | 将值以uint类型返回,所有无符号整型均可以以此方式返回 | +| Float() float64 | 将值以双精度(float 64)类型返回,所有浮点数(float 32、float64)均可以以此方式返回 | + +## 结构体反射 + +### 与结构体相关的方法 + +任意值通过reflect.Typeof)获得反射对象信息后,如果它的类型是结构体,可以通过反射值对象(reflect.Type)的NumField()和Field()方法获得结构体成员的详细信息。 + +reflect.Type中与获取结构体成员相关的的方法如下表所示。 + +| 方法 | 说明 | +| ------------------------------------------- | -------------------------------------------- | +| Field(i int)StructField | 根据索引,返回索引对应的结构体字段的信息 | +| NumField() int | 返回结构体成员字段数量 | +| FieldByName(name string)(StructField, bool) | 根据给定字符串返回字符串赌赢的结构体字段信息 | +| FieldByIndex(index []int)StructField | 多层成员访问时,根据[] int 提供的每个结构 | +| | | + +示例代码,如下所示 我们修改结构体中的字段和类型 + +```go +// 学生结构体 +type Student4 struct { + Name string `json: "name"` + Age int `json: "age"` + Score int `json: "score"` +} + +func (s Student4)GetInfo()string { + var str = fmt.Sprintf("姓名:%v 年龄:%v 成绩:%v", s.Name, s.Age, s.Score) + return str +} +func (s *Student4)SetInfo(name string, age int, score int) { + s.Name = name + s.Age = age + s.Score = score +} +func (s Student4)PrintStudent() { + fmt.Println("打印学生") +} +// 打印结构体中的字段 +func PrintStructField(s interface{}) { + t := reflect.TypeOf(s) + // 判断传递过来的是否是结构体 + if t.Kind() != reflect.Struct && t.Elem().Kind() != reflect.Struct { + fmt.Println("请传入结构体类型!") + return + } + + // 通过类型变量里面的Field可以获取结构体的字段 + field0 := t.Field(0) // 获取第0个字段 + fmt.Printf("%#v \n", field0) + fmt.Println("字段名称:", field0.Name) + fmt.Println("字段类型:", field0.Type) + fmt.Println("字段Tag:", field0.Tag.Get("json")) + + // 通过类型变量里面的FieldByName可以获取结构体的字段中 + field1, ok := t.FieldByName("Age") + if ok { + fmt.Println("字段名称:", field1.Name) + fmt.Println("字段类型:", field1.Type) + fmt.Println("字段Tag:", field1.Tag) + } + + // 通过类型变量里面的NumField获取该结构体有几个字段 + var fieldCount = t.NumField() + fmt.Println("结构体有:", fieldCount, " 个属性") + + // 获取结构体属性对应的值 + v := reflect.ValueOf(s) + nameValue := v.FieldByName("Name") + fmt.Println("nameValue:", nameValue) + +} +func main() { + + student := Student4{ + "张三", + 18, + 95, + } + PrintStructField(student) +} +``` + +下列代码是获取结构体中的方法,然后调用 + +```go +// 打印执行方法 +func PrintStructFn(s interface{}) { + t := reflect.TypeOf(s) + // 判断传递过来的是否是结构体 + if t.Kind() != reflect.Struct && t.Elem().Kind() != reflect.Struct { + fmt.Println("请传入结构体类型!") + return + } + // 通过类型变量里面的Method,可以获取结构体的方法 + method0 := t.Method(0) + // 获取第一个方法, 这个是和ACSII相关 + fmt.Println(method0.Name) + + // 通过类型变量获取这个结构体有多少方法 + methodCount := t.NumMethod() + fmt.Println("拥有的方法", methodCount) + + // 通过值变量 执行方法(注意需要使用值变量,并且要注意参数) + v := reflect.ValueOf(s) + // 通过值变量来获取参数 + v.MethodByName("PrintStudent").Call(nil) + + // 手动传参 + var params []reflect.Value + params = append(params, reflect.ValueOf("张三")) + params = append(params, reflect.ValueOf(23)) + params = append(params, reflect.ValueOf(99)) + // 执行setInfo方法 + v.MethodByName("SetInfo").Call(params) + + // 通过值变量来获取参数 + v.MethodByName("PrintStudent").Call(nil) +} +``` + diff --git "a/Golang/Golang\345\237\272\347\241\200/17_Go\344\270\255\347\232\204\346\226\207\344\273\266\345\222\214\347\233\256\345\275\225\346\223\215\344\275\234/README.md" "b/Golang/Golang\345\237\272\347\241\200/17_Go\344\270\255\347\232\204\346\226\207\344\273\266\345\222\214\347\233\256\345\275\225\346\223\215\344\275\234/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..06cfd48a60a382dcbb3931c35ccfb4c39b079b0b --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/17_Go\344\270\255\347\232\204\346\226\207\344\273\266\345\222\214\347\233\256\345\275\225\346\223\215\344\275\234/README.md" @@ -0,0 +1,170 @@ +# Go中的文件和目录操作 + +## 文件的读取 + +### 通过os.Open方法读取文件 + +```go +func main() { + // 读取文件 方法1 + file, err := os.Open("./main/test.txt") + // 关闭文件流 + defer file.Close(); + if err != nil { + fmt.Println("打开文件出错") + } + // 读取文件里面的内容 + var tempSlice = make([]byte, 1024) + var strSlice []byte + for { + n, err := file.Read(tempSlice) + if err == io.EOF { + fmt.Printf("读取完毕") + break + } + fmt.Printf("读取到了%v 个字节 \n", n) + strSlice := append(strSlice, tempSlice...) + fmt.Println(string(strSlice)) + } +} +``` + +### 通过bufio的方式读取 + +```go +func main() { + // 读取文件 方法2 + file, err := os.Open("./main/test.txt") + // 关闭文件流 + defer file.Close(); + if err != nil { + fmt.Println("打开文件出错") + } + // 通过创建bufio来读取 + reader := bufio.NewReader(file) + var fileStr string + var count int = 0 + for { + // 相当于读取一行 + str, err := reader.ReadString('\n') + if err == io.EOF { + // 读取完成的时候,也会有内容 + fileStr += str + fmt.Println("读取结束", count) + break + } + if err != nil { + fmt.Println(err) + break + } + count ++ + fileStr += str + } + fmt.Println(fileStr) +} +``` + +### 通过ioutil读取 + +文件比较少的时候,可以通过ioutil来读取文件 + +```go +// 通过IOUtil读取 +byteStr, _ := ioutil.ReadFile("./main/test.txt") +fmt.Println(string(byteStr)) +``` + +## 文件的写入 + +文件的写入,我们首先需要通过 os.OpenFile打开文件 + +```go +// 打开文件 +file, _ := os.OpenFile("./main/test.txt", os.O_CREATE | os.O_RDWR, 777) +``` + +这里有三个参数 + +- name:要打开的文件名 +- flag:打开文件的模式 + - os.O_WRONLY:只读 + - os.O_CREATE:创建 + - os.O_RDONLY:只读 + - os.O_RDWR:读写 + - os.O_TRUNC:清空 + - os.O_APPEND:追加 +- perm:文件权限,一个八进制数,r(读)04,w(写)02,x(执行)01 + +### 通过OpenFile打开文件写入 + +```go +// 打开文件 +file, _ := os.OpenFile("./main/test.txt", os.O_CREATE | os.O_RDWR | os.O_APPEND, 777) +defer file.Close() +str := "啦啦啦 \r\n" +file.WriteString(str) +``` + +### 通过bufio写入 + +```go +// 打开文件 +file, _ := os.OpenFile("./main/test.txt", os.O_CREATE | os.O_RDWR | os.O_APPEND, 777) +defer file.Close() +str := "啦啦啦 \r\n" +file.WriteString(str) + +// 通过bufio写入 +writer := bufio.NewWriter(file) +// 先将数据写入缓存 +writer.WriteString("你好,我是通过writer写入的 \r\n") +// 将缓存中的内容写入文件 +writer.Flush() +``` + +## 通过ioutil写入 + +```go +// 第三种方式,通过ioutil +str2 := "hello" +ioutil.WriteFile("./main/test.txt", []byte(str2), 777) +``` + +## 文件复制 + +通过ioutil读取和复制文件 + +```go +// 读取文件 +byteStr, err := ioutil.ReadFile("./main/test.txt") +if err != nil { + fmt.Println("读取文件出错") + return +} +// 写入指定的文件 +ioutil.WriteFile("./main/test2.txt", byteStr, 777) +``` + +## 创建目录 + +```go +os.Mkdir("./abc", 777) +``` + +## 删除操作 + +```go +// 删除文件 +os.Remove("aaa.txt") +// 删除目录 +os.Remove("./aaa") +// 删除多个文件和目录 +os.RemoveAll("./aaa") +``` + +## 重命名 + +```go +os.Rename("") +``` + diff --git "a/Golang/Golang\345\237\272\347\241\200/1_Go\350\257\255\350\250\200\345\217\221\345\261\225\347\256\200\345\217\262/README.md" "b/Golang/Golang\345\237\272\347\241\200/1_Go\350\257\255\350\250\200\345\217\221\345\261\225\347\256\200\345\217\262/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..59c25515e7d0454d8faba04cb7f9ebee951b54c6 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/1_Go\350\257\255\350\250\200\345\217\221\345\261\225\347\256\200\345\217\262/README.md" @@ -0,0 +1,109 @@ +# Go语言发展简史 + +## 开发文档 + +https://studygolang.com/pkgdoc + +## Go语言核心开发团队 + +Ken Thompson(肯·汤普森):1983年图灵奖(Turing Award)和1998年美国国家技术奖(National Medal of Technology)得主。他与Dennis Ritchie是Unix的原创者。Thompson也发明了后来衍生出C语言的B程序语言,同时也是C语言的主要发明人。 + +Rob Pike(罗布-派克):曾是贝尔实验室(Bell Labs)的Unix团队,和Plan 9操作系统计划的成员。 +他与Thompson共事多年,并共创出广泛使用的UTF-8字元编码。 + +Robert Griesemer:曾协助制作Java的HotSpot编译器,和Chrome浏览器的JavaScript引擎V8。 + +![image-20200718103112309](images/image-20200718103112309.png) + +## Google为什么要创建Go + +- 计算机硬件技术更新频繁,性能提高很快。目前主流的编程语言发展明显落后于硬件,不能合理利用多核多CPU的优势提升软件系统性能。 +- 软件系统复杂度越来越高,维护成本越来越高,目前缺乏一个足够简洁高效的编程语言。 + - 现有编程语言存在:风格不统一、计算能力不够、处理大并发不够好 +- 企业运行维护很多c/c++的项目,c/c++程序运行速度虽然很快,但是编译速度确很慢,同时还存在内存泄漏的一系列的困扰需要解决。 + +## Go语言发展历史 + +- 2007年,谷歌工程师Rob Pike,Ken Thompson和Robert Griesemer开始设计一门全新的语言,这是Go语言的最初原型。 +- 2009年11月10日,Google将Go语言以开放源代码的方式向全球发布。 +- 2015年8月19日,Go1.5版发布,本次更新中移除了”最后残余的c代码” +- 2017年2月17日,Go语言Go1.8版发布。 +- 2017年8月24日,Go语言Go1.9版发布。 +- 2018年2月16日,Go语言Go1.10版发布。 + +## Go语言的特点 + +Go语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发维护的高效率,使用一个表达式来形容Go语言:Go=C+Python,说明Go语言既有C静态语言程序的运行速度,又能达到Python动态语言的快速开发。 + +- 从c语言中继承了很多理念,包括表达式语法,控制结构,基础数据类型,调用参数传值,指针等等,也保留了和C语言一样的编译执行方式及弱化的指针。 + +```go +// go语言的指针使用特点 +func testPtr(num *int) { + *num = 20 +} +``` + +- 引入包的概念,用于组织程序结构,Go语言的一个文件都要归属于一个包,而不能单独存在。 +- 垃圾回收机制,内存自动回收,不需开发人员管理 【稍微不注意就会出现内存泄漏】 +- 天然并发【重要特点】 + - 从语言层面支持并发,实现简单 + - goroutine,轻量级线程,可实现大并发处理,高效利用多核。 + - 基于CPS并发模型(Communicating Sequential Processes)实现 +- 吸收了管道通信机制,形成go语言特有的管道channel,通过管道channel,可以实现不同的goroute之间的相互通信 +- 函数返回多个值(实例代码) +- 新的创新:比如切片slice,延时执行defer等 + +## Hello Go + +我们写一个最简单的入门代码,在控制台输出hello go! + +```go +package main +// fmt包中提供格式化,输入和输出的函数 +import "fmt" +func main() { + fmt.Println("hello go!") +} +``` + +## Golang执行流程分析 + +我们可以通过以下命令来进行操作 + +- go build hello.go -> hello.exe +- go run hello.go + +![image-20200718161111596](images/image-20200718161111596.png) + +### 两种执行流程分析 + +- 如果我们先编译生成了可执行文件,那么我们可以将该可执行文件拷贝到没有go开发环境的机器上,然可以运行 +- 如果我们是直接go rungo源代码,那么如果要在另外一个机器上这么运行,也需要go开发环境,否则无法执行。 +- 在编译时,编译器会将程序运行依赖的库文件包含在可执行文件中,所以,可执行文件变大了很多。 + +### 什么是编译 + +- 有了go源文件,通过编译器将其编译成机器可以识别的二进制码文件。 +- 在该源文件目录下,通过go build 对hello.go文件进行编译。可以指定生成的可执行文件名,在windows下必须是.exe后缀。 +- 如果程序没有错误,没有任何提示,会在当前目录下会出现一个可执行文件(windows下是.exe Linux下是一个可执行文件),该文件是二进制码文件,也是可以执行的程序。 +- 如果程序有错误,编译时,会在错误的那行报错。 + +## Go语言开发注意事项 + +- Go源文件以“go”为扩展名 +- Go应用程序的执行入口是main()方法 +- Go语言严格区分大小写。 +- Go方法由一条条语句构成,每个语句后不需要分号(Go语言会在每行后自动加分号),这也体现出Golang的简洁性。 +- Go编译器是一行行进行编译的,因此我们一行就写一条语句,不能把多条语句写在同一个,否则报错 +- Go语言定义的变量或者import的包如果没有使用到,代码不能编译通过 +- 大括号都是成对出现的,缺一不可。 + +## Go语言中的转义字符 + +GoLang常用的转义字符(escape char) + +- \t:一个制表位,实现对齐的功能 +- \n:换行符 +- \\:一个\ +- \r:一个回车 \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/1_Go\350\257\255\350\250\200\345\217\221\345\261\225\347\256\200\345\217\262/images/image-20200718103112309.png" "b/Golang/Golang\345\237\272\347\241\200/1_Go\350\257\255\350\250\200\345\217\221\345\261\225\347\256\200\345\217\262/images/image-20200718103112309.png" new file mode 100644 index 0000000000000000000000000000000000000000..15d660dab13fa3d9d5cc2e6cc764ae4ad4be4caa Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/1_Go\350\257\255\350\250\200\345\217\221\345\261\225\347\256\200\345\217\262/images/image-20200718103112309.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/1_Go\350\257\255\350\250\200\345\217\221\345\261\225\347\256\200\345\217\262/images/image-20200718161111596.png" "b/Golang/Golang\345\237\272\347\241\200/1_Go\350\257\255\350\250\200\345\217\221\345\261\225\347\256\200\345\217\262/images/image-20200718161111596.png" new file mode 100644 index 0000000000000000000000000000000000000000..7e5bf4604fbbf89945f1756ffa55b13e71b0d8a2 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/1_Go\350\257\255\350\250\200\345\217\221\345\261\225\347\256\200\345\217\262/images/image-20200718161111596.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/2_Go\347\232\204\345\217\230\351\207\217/README.md" "b/Golang/Golang\345\237\272\347\241\200/2_Go\347\232\204\345\217\230\351\207\217/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..799bca7c9d1c253271c58bc4c03993db1146eefc --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/2_Go\347\232\204\345\217\230\351\207\217/README.md" @@ -0,0 +1,136 @@ +# Go语言中的变量和常量 + +## Go语言中变量的声明 + +Go语言变量是由字母、数字、下划线组成,其中首个字符不能为数字。Go语言中关键字和保留字都不能用作变量名 + +Go语言中变量需要声明后才能使用,同一作用域内不支持重复声明。并且Go语言的变量声明后必须使用。 + +变量声明后,没有初始化,打印出来的是空 + +## 如何定义变量 + +### 方式1: + +```go +var name = "zhangsan" +``` + +### 方式2:带类型 + +```go +var name string = "zhangsan" +``` + +### 方式3:类型推导方式定义变量 + +a在函数内部,可以使用更简略的 := 方式声明并初始化变量 + +注意:短变量只能用于声明局部变量,不能用于全局变量声明 + +```go +变量名 := 表达式 +``` + +### 方式4:声明多个变量 + +类型都是一样的变量 + +```go +var 变量名称, 变量名称 类型 +``` + +类型不一样的变量 + +```go +var ( + 变量名称 类型 + 变量名称 类型 +) +``` + +案例 + +```go +var a1, a2 string +a1 = "123" +a2 = "123" +fmt.Printf(a1) +fmt.Printf(a2) +``` + +### 总结 + +全部的定义方式 + +```go +package main +import "fmt" + +func main() { + fmt.Println("hello") + fmt.Print("A", "B", "C") + fmt.Println() + var a = 10 + fmt.Printf( "%d", a ) + + var name = "zhangsan1" + var name2 string = "zhangsan2" + name3 := "zhangsan3" + + fmt.Println(name) + fmt.Println(name2) + fmt.Println(name3) + fmt.Printf("name1=%v name2=%v name3=%v \n", name, name2, name3) +} +``` + +## 如何定义常量 + +相对于变量,常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值。常量的声明和变量声明非常类似,只是把var换成了const,常量在定义的时候必须赋值。 + +```go +// 定义了常量,可以不用立即使用 +const pi = 3.14 + +// 定义两个常量 +const( + A = "A" + B = "B" +) + +// const同时声明多个常量时,如果省略了值表示和上面一行的值相同 +const( + A = "A" + B + C +) +``` + +## Const常量结合iota的使用 + +iota是golang 语言的常量计数器,只能在常量的表达式中使用 + +iota在const关键字出现时将被重置为0(const内部的第一行之前),const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。 + +每次const出现,都会让iota初始化为0【自增长】 + +```go +const a = iota // a = 0 +const ( + b = iota // b=0 + c // c = 1 + d // d = 2 +) +``` + +const iota使用_跳过某些值 + +```go +const ( + b = iota // b=0 + _ + d // d = 2 +) +``` + diff --git "a/Golang/Golang\345\237\272\347\241\200/3_Go\347\232\204\346\225\260\346\215\256\347\261\273\345\236\213/README.md" "b/Golang/Golang\345\237\272\347\241\200/3_Go\347\232\204\346\225\260\346\215\256\347\261\273\345\236\213/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..eb8126548c220c2579a028c051b2feaee244db24 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/3_Go\347\232\204\346\225\260\346\215\256\347\261\273\345\236\213/README.md" @@ -0,0 +1,281 @@ +# Golang的数据类型 + +## 概述 + +Go 语言中数据类型分为:基本数据类型和复合数据类型基本数据类型有: + +整型、浮点型、布尔型、字符串 + +复合数据类型有: + +数组、切片、结构体、函数、map、通道(channel)、接口等。 + +## 整型 + +整型的类型有很多中,包括 int8,int16,int32,int64。我们可以根据具体的情况来进行定义 + +如果我们直接写 int也是可以的,它在不同的操作系统中,int的大小是不一样的 + +- 32位操作系统:int -> int32 +- 64位操作系统:int -> int64 + +![image-20200719084018801](images/image-20200719084018801.png) + +> 可以通过unsafe.Sizeof 查看不同长度的整型,在内存里面的存储空间 +> +> ``` +> var num2 = 12 +> fmt.Println(unsafe.Sizeof(num2)) +> ``` + +### 类型转换 + +通过在变量前面添加指定类型,就可以进行强制类型转换 + +```go +var a1 int16 = 10 +var a2 int32 = 12 +var a3 = int32(a1) + a2 +fmt.Println(a3) +``` + +注意,高位转低位的时候,需要注意,会存在精度丢失,比如上述16转8位的时候,就丢失了 + +```go +var n1 int16 = 130 +fmt.Println(int8(n1)) // 变成 -126 +``` + +### 数字字面量语法 + +Go1.13版本之后,引入了数字字面量语法,这样便于开发者以二进制、八进制或十六进制浮点数的格式定义数字,例如: + +```go +v := 0b00101101 // 代表二进制的101101 +v:= Oo377 // 代表八进制的377 +``` + +### 进制转换 + +```go +var number = 17 +// 原样输出 +fmt.Printf("%v\n", number) +// 十进制输出 +fmt.Printf("%d\n", number) +// 以八进制输出 +fmt.Printf("%o\n", number) +// 以二进制输出 +fmt.Printf("%b\n", number) +// 以十六进制输出 +fmt.Printf("%x\n", number) +``` + +## 浮点型 + +Go语言支持两种浮点型数:float32和float64。这两种浮点型数据格式遵循IEEE754标准: + +float32的浮点数的最大范围约为3.4e38,可以使用常量定义:math.MaxFloat32。float64的浮点数的最大范围约为1.8e308,可以使用一个常量定义:math.MaxFloat64 + +打印浮点数时,可以使用fmt包配合动词%f,代码如下: + +```go +var pi = math.Pi +// 打印浮点类型,默认小数点6位 +fmt.Printf("%f\n", pi) +// 打印浮点类型,打印小数点后2位 +fmt.Printf("%.2f\n", pi) +``` + +### Golang中精度丢失的问题 + +几乎所有的编程语言都有精度丢失的问题,这是典型的二进制浮点数精度损失问题,在定长条件下,二进制小数和十进制小数互转可能有精度丢失 + +```go +d := 1129.6 +fmt.Println(d*100) //输出112959.99999999 +``` + +解决方法,使用第三方包来解决精度损失的问题 + +http://github.com/shopspring/decimal + +## 布尔类型 + +定义 + +```go +var fl = false +if f1 { + fmt.Println("true") +} else { + fmt.Println("false") +} +``` + +## 字符串类型 + +Go 语言中的字符串以原生数据类型出现,使用字符串就像使用其他原生数据类型(int、bool、float32、float64等)一样。Go语言里的字符串的内部实现使用UTF-8编码。字符串的值为双引号(")中的内容,可以在Go语言的源码中直接添加非ASCll码字符,例如: + +```go +s1 := "hello" +s1 := "你好" +``` + +如果想要定义多行字符串,可以使用反引号 + +```go + var str = `第一行 +第二行` + fmt.Println(str) +``` + +### 字符串常见操作 + +- len(str):求长度 +- +或fmt.Sprintf:拼接字符串 +- strings.Split:分割 +- strings.contains:判断是否包含 +- strings.HasPrefix,strings.HasSuffix:前缀/后缀判断 +- strings.Index(),strings.LastIndex():子串出现的位置 +- strings.Join():join操作 +- strings.Index():判断在字符串中的位置 + +## byte 和 rune类型 + +组成每个字符串的元素叫做 “字符”,可以通过遍历字符串元素获得字符。字符用单引号 '' 包裹起来 + +Go语言中的字符有以下两种类型 + +- uint8类型:或者叫byte型,代表了ACII码的一个字符 +- rune类型:代表一个UTF-8字符 + +当需要处理中文,日文或者其他复合字符时,则需要用到rune类型,rune类型实际上是一个int32 + +Go使用了特殊的rune类型来处理Unicode,让基于Unicode的文本处理更为方便,也可以使用byte型进行默认字符串处理,性能和扩展性都有照顾。 + +需要注意的是,在go语言中,一个汉字占用3个字节(utf-8),一个字母占用1个字节 + +```go +package main +import "fmt" + +func main() { + var a byte = 'a' + // 输出的是ASCII码值,也就是说当我们直接输出byte(字符)的时候,输出的是这个字符对应的码值 + fmt.Println(a) + // 输出的是字符 + fmt.Printf("%c", a) + + // for循环打印字符串里面的字符 + // 通过len来循环的,相当于打印的是ASCII码 + s := "你好 golang" + for i := 0; i < len(s); i++ { + fmt.Printf("%v(%c)\t", s[i], s[i]) + } + + // 通过rune打印的是 utf-8字符 + for index, v := range s { + fmt.Println(index, v) + } +} +``` + +### 修改字符串 + +要修改字符串,需要先将其转换成[]rune 或 []byte类型,完成后在转换成string,无论哪种转换都会重新分配内存,并复制字节数组 + +转换为 []byte 类型 + +```go +// 字符串转换 +s1 := "big" +byteS1 := []byte(s1) +byteS1[0] = 'p' +fmt.Println(string(byteS1)) +``` + +转换为rune类型 + +```go +// rune类型 +s2 := "你好golang" +byteS2 := []rune(s2) +byteS2[0] = '我' +fmt.Println(string(byteS2)) +``` + +## 基本数据类型转换 + +### 数值类型转换 + +```go +// 整型和浮点型之间转换 +var aa int8 = 20 +var bb int16 = 40 +fmt.Println(int16(aa) + bb) + +// 建议整型转换成浮点型 +var cc int8 = 20 +var dd float32 = 40 +fmt.Println(float32(cc) + dd) +``` + +建议从低位转换成高位,这样可以避免 + +### 转换成字符串类型 + +第一种方式,就是通过 fmt.Sprintf()来转换 + +```go +// 字符串类型转换 +var i int = 20 +var f float64 = 12.456 +var t bool = true +var b byte = 'a' +str1 := fmt.Sprintf("%d", i) +fmt.Printf("类型:%v-%T \n", str1, str1) + +str2 := fmt.Sprintf("%f", f) +fmt.Printf("类型:%v-%T \n", str2, str2) + +str3 := fmt.Sprintf("%t", t) +fmt.Printf("类型:%v-%T \n", str3, str3) + +str4 := fmt.Sprintf("%c", b) +fmt.Printf("类型:%v-%T \n", str4, str4) +``` + +第二种方法就是通过strconv包里面的集中转换方法进行转换 + +```go +// int类型转换str类型 +var num1 int64 = 20 +s1 := strconv.FormatInt(num1, 10) +fmt.Printf("转换:%v - %T", s1, s1) + +// float类型转换成string类型 +var num2 float64 = 3.1415926 + +/* + 参数1:要转换的值 + 参数2:格式化类型 'f'表示float,'b'表示二进制,‘e’表示 十进制 + 参数3:表示保留的小数点,-1表示不对小数点格式化 + 参数4:格式化的类型,传入64位 或者 32位 + */ +s2 := strconv.FormatFloat(num2, 'f', -1, 64) +fmt.Printf("转换:%v-%T", s2, s2) +``` + +### 字符串转换成int 和 float类型 + +```go +str := "10" +// 第一个参数:需要转换的数,第二个参数:进制, 参数三:32位或64位 +num,_ = strconv.ParseInt(str, 10, 64) + +// 转换成float类型 +str2 := "3.141592654" +num,_ = strconv.ParseFloat(str2, 10) +``` + diff --git "a/Golang/Golang\345\237\272\347\241\200/3_Go\347\232\204\346\225\260\346\215\256\347\261\273\345\236\213/images/image-20200719084018801.png" "b/Golang/Golang\345\237\272\347\241\200/3_Go\347\232\204\346\225\260\346\215\256\347\261\273\345\236\213/images/image-20200719084018801.png" new file mode 100644 index 0000000000000000000000000000000000000000..375ac4313de19f051a8efb036023f00eedef6a5b Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/3_Go\347\232\204\346\225\260\346\215\256\347\261\273\345\236\213/images/image-20200719084018801.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/4_Go\347\232\204\350\277\220\347\256\227\347\254\246/README.md" "b/Golang/Golang\345\237\272\347\241\200/4_Go\347\232\204\350\277\220\347\256\227\347\254\246/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..7ad0ac74956c80431d962ed35ff634bdb616f118 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/4_Go\347\232\204\350\277\220\347\256\227\347\254\246/README.md" @@ -0,0 +1,33 @@ +# Go的运算符 + +## 算数运算符 + +- +:相加 +- -:相减 +- *:相乘 +- /:相除 +- %:求余 + +在golang中, ++ 和 -- 只能单独使用,错误的写法如下 + +```go +var i int = 8 +var a int +a = i++ // 错误,i++只能单独使用 +a = i-- // 错误,i--只能单独使用 +``` + +同时在golang中,没有 ++i这样的操作 + +```go +var i int = 1 +++i // 错误 +``` + +正确的写法 + +```go +var i int = 1 +i++ //正确 +``` + diff --git "a/Golang/Golang\345\237\272\347\241\200/5_Go\347\232\204\346\265\201\347\250\213\346\216\247\345\210\266/README.md" "b/Golang/Golang\345\237\272\347\241\200/5_Go\347\232\204\346\265\201\347\250\213\346\216\247\345\210\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..96bcfb57e5313e8c6f043075a7de2d414d504d15 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/5_Go\347\232\204\346\265\201\347\250\213\346\216\247\345\210\266/README.md" @@ -0,0 +1,222 @@ +# Go的流程控制 + +流程控制是每种编程语言控制逻辑走向和执行次序的重要部分,流程控制可以说是一门语言的“经脉" + +Go 语言中最常用的流程控制有if和for,而switch和goto主要是为了简化代码、降低重复代码而生的结构,属于扩展类的流程控制。 + +## if else + +推荐if后面不适用括号,当然也可以使用括号括起来 + +```go +func main() { + var num = 10 + if num == 10 { + fmt.Println("hello == 10") + } else if(num > 10) { + fmt.Println("hello > 10") + } else { + fmt.Println("hello < 10") + } +} +``` + +if的另外一种写法,下面的方法的区别是 num2是局部变量 + +```go +if num2:= 10; num2>=10 { + fmt.Println("hello >=10") +} +``` + +## for 循环结构 + +Go语言中的所有循环类型均可使用for关键字来完成 + +for循环的基本格式如下: + +``` +for 初始语句; 条件表达式; 结束语句 { + 循环体 +} +``` + +条件表达式返回true时循环体不停地进行循环,直到条件表达式返回false时自动退出循环 + +实例:打印1 ~ 10 + +```go +for i := 0; i < 10; i++ { + fmt.Printf("%v ", i+1) +} +``` + +注意,在Go语言中,没有while语句,我们可以通过for来代替 + +```go +for { + 循环体 +} +``` + +for循环可以通过break、goto、return、panic语句退出循环 + +## for range(键值循环) + +Go 语言中可以使用for range遍历数组、切片、字符串、map及通道(channel)。通过for range遍历的返回值有以下规律: + +- 数组、切片、字符串返回索引和值。 +- map返回键和值。 +- 通道(channel)只返回通道内的值。 + +实例:遍历字符串 + +```go +var str = "你好golang" +for key, value := range str { + fmt.Printf("%v - %c ", key, value) +} +``` + +遍历切片(数组) + +```go +var array = []string{"php", "java", "node", "golang"} +for index, value := range array { + fmt.Printf("%v %s ", index, value) +} +``` + +## switch case + +使用switch语句可方便的对大量的值进行条件判断 + +```go +extname := ".a" +switch extname { + case ".html": { + fmt.Println(".html") + break + } + case ".doc": { + fmt.Println(".doc") + break + } + case ".js": { + fmt.Println(".js") + } + default: { + fmt.Println("其它后缀") + } +} +``` + +switch的另外一种写法 + +```go +switch extname := ".a"; extname { + case ".html": { + fmt.Println(".html") + break + } + case ".doc": { + fmt.Println(".doc") + break + } + case ".js": { + fmt.Println(".js") + } + default: { + fmt.Println("其它后缀") + } +} +``` + +同时一个分支可以有多个值 + +```go +extname := ".txt" +switch extname { + case ".html": { + fmt.Println(".html") + break + } + case ".txt",".doc": { + fmt.Println("传递来的是文档") + break + } + case ".js": { + fmt.Println(".js") + } + default: { + fmt.Println("其它后缀") + } +} +``` + +> tip:在golang中,break可以不写,也能够跳出case,而不会执行其它的。 + +如果我们需要使用switch的穿透 fallthrought,fallthrough语法可以执行满足条件的 case 的下一个case,为了兼容c语言中的case设计 + +``` +extname := ".txt" +switch extname { + case ".html": { + fmt.Println(".html") + fallthrought + } + case ".txt",".doc": { + fmt.Println("传递来的是文档") + fallthrought + } + case ".js": { + fmt.Println(".js") + fallthrought + } + default: { + fmt.Println("其它后缀") + } +} +``` + +fallthrought 只能穿透紧挨着的一层,不会一直穿透,但是如果每一层都写的话,就会导致每一层都进行穿透 + +## break:跳出循环 + +Go语言中break 语句用于以下几个方面: + +- 用于循环语句中跳出循环,并开始执行循环之后的语句。 +- break在switch(开关语句)中在执行一条case后跳出语句的作用。 +- 在多重循环中,可以用标号label标出想break的循环。 + +```go +var i = 0 +for { + if i == 10{ + fmt.Println("跳出循环") + break + } + i++ + fmt.Println(i) +} +``` + +## go:跳转到指定标签 + +goto 语句通过标签进行代码间的无条件跳转。goto 语句可以在快速跳出循环、避免重复退出上有一定的帮助。Go语言中使用goto语句能简化一些代码的实现过程。 + +```go + var n = 20 + if n > 24 { + fmt.Println("成年人") + } else { + goto lable3 + } + + fmt.Println("aaa") + fmt.Println("bbb") +lable3: + fmt.Println("ccc") + fmt.Println("ddd") +``` + diff --git "a/Golang/Golang\345\237\272\347\241\200/6_Go\347\232\204\346\225\260\347\273\204/README.md" "b/Golang/Golang\345\237\272\347\241\200/6_Go\347\232\204\346\225\260\347\273\204/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..32ac07c8dc2db170e79459867f5928f69616ffa8 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/6_Go\347\232\204\346\225\260\347\273\204/README.md" @@ -0,0 +1,234 @@ +# Go的数组 + +## Array数组介绍 + +数组是指一系列同一类型数据的集合。数组中包含的每个数据被称为数组元素(element),这种类型可以是意的原始类型,比如int、string等,也可以是用户自定义的类型。一个数组包含的元素个数被称为数组的长度。在Golang中数组是一个长度固定的数据类型,数组的长度是类型的一部分,也就是说[5]int和[10]int是两个不同的类型。Golang中数组的另一个特点是占用内存的连续性,也就是说数组中的元素是被分配到连续的内存地址中的,因而索引数组元素的速度非常快。 + +和数组对应的类型是Slice(切片),Slice是可以增长和收缩的动态序列,功能也更灵活,但是想要理解slice工作原理的话需要先理解数组,所以本节主要为大家讲解数组的使用。 + +## 数组定义 + +```bash +var 数组变量名 [元素数量] T +``` + +示例 + +```go +// 数组的长度是类型的一部分 +var arr1 [3]int +var arr2 [4]string +fmt.Printf("%T, %T \n", arr1, arr2) + +// 数组的初始化 第一种方法 +var arr3 [3]int +arr3[0] = 1 +arr3[1] = 2 +arr3[2] = 3 +fmt.Println(arr3) + +// 第二种初始化数组的方法 +var arr4 = [4]int {10, 20, 30, 40} +fmt.Println(arr4) + +// 第三种数组初始化方法,自动推断数组长度 +var arr5 = [...]int{1, 2} +fmt.Println(arr5) + +// 第四种初始化数组的方法,指定下标 +a := [...]int{1:1, 3:5} +fmt.Println(a) +``` + +## 遍历数组 + +方法1 + +``` +// 第四种初始化数组的方法,指定下标 +a := [...]int{1:1, 3:5} +for i := 0; i < len(a); i++ { + fmt.Print(a[i], " ") +} +``` + +方法2 + +```go +// 第四种初始化数组的方法,指定下标 +a := [...]int{1:1, 3:5} +for _, value := range a { + fmt.Print(value, " ") +} +``` + +## 数组的值类型 + +数组是值类型,赋值和传参会赋值整个数组,因此改变副本的值,不会改变本身的值 + +```go +// 数组 +var array1 = [...]int {1, 2, 3} +array2 := array1 +array2[0] = 3 +fmt.Println(array1, array2) +``` + +例如上述的代码,我们将数组进行赋值后,该改变数组中的值时,发现结果如下 + +```bash +[1 2 3] [3 2 3] +``` + +这就说明了,golang中的数组是值类型,而不是和java一样属于引用数据类型 + +## 切片定义(引用类型) + +在golang中,切片的定义和数组定义是相似的,但是需要注意的是,切片是引用数据类型,如下 + +```go +// 切片定义 +var array3 = []int{1,2,3} +array4 := array3 +array4[0] = 3 +fmt.Println(array3, array4) +``` + +我们通过改变第一个切片元素,然后查看最后的效果 + +```bash +[3 2 3] [3 2 3] +``` + +## 二维数组 + +Go语言支持多维数组,我们这里以二维数组为例(数组中又嵌套数组): + +```bash +var 数组变量名 [元素数量][元素数量] T +``` + +示例 + +```go +// 二维数组 +var array5 = [2][2]int{{1,2},{2,3}} +fmt.Println(array5) +``` + +### 数组遍历 + +二维数据组的遍历 + +```go +// 二维数组 +var array5 = [2][2]int{{1,2},{2,3}} +for i := 0; i < len(array5); i++ { + for j := 0; j < len(array5[0]); j++ { + fmt.Println(array5[i][j]) + } +} +``` + +遍历方式2 + +```go +for _, item := range array5 { + for _, item2 := range item { + fmt.Println(item2) + } +} +``` + +### 类型推导 + +另外我们在进行数组的创建的时候,还可以使用类型推导,但是只能使用一个 ... + +```go +// 二维数组(正确写法) +var array5 = [...][2]int{{1,2},{2,3}} +``` + +错误写法 + +```go +// 二维数组 +var array5 = [2][...]int{{1,2},{2,3}} +``` + +## 完整代码 + +```go +package main + +import "fmt" + +func main() { + // 数组的长度是类型的一部分 + var arr1 [3]int + var arr2 [4]string + fmt.Printf("%T, %T \n", arr1, arr2) + + // 数组的初始化 第一种方法 + var arr3 [3]int + arr3[0] = 1 + arr3[1] = 2 + arr3[2] = 3 + fmt.Println(arr3) + + // 第二种初始化数组的犯法 + var arr4 = [4]int {10, 20, 30, 40} + fmt.Println(arr4) + + // 第三种数组初始化方法,自动推断数组长度 + var arr5 = [...]int{1, 2} + fmt.Println(arr5) + + // 第四种初始化数组的方法,指定下标 + a := [...]int{1:1, 3:5} + fmt.Println(a) + + for i := 0; i < len(a); i++ { + fmt.Print(a[i], " ") + } + + for _, value := range a { + fmt.Print(value, " ") + } + + fmt.Println() + // 值类型 引用类型 + // 基本数据类型和数组都是值类型 + var aa = 10 + bb := aa + aa = 20 + fmt.Println(aa, bb) + + // 数组 + var array1 = [...]int {1, 2, 3} + array2 := array1 + array2[0] = 3 + fmt.Println(array1, array2) + + // 切片定义 + var array3 = []int{1,2,3} + array4 := array3 + array4[0] = 3 + fmt.Println(array3, array4) + + // 二维数组 + var array5 = [...][2]int{{1,2},{2,3}} + for i := 0; i < len(array5); i++ { + for j := 0; j < len(array5[0]); j++ { + fmt.Println(array5[i][j]) + } + } + + for _, item := range array5 { + for _, item2 := range item { + fmt.Println(item2) + } + } +} +``` + diff --git "a/Golang/Golang\345\237\272\347\241\200/7_Go\347\232\204\345\210\207\347\211\207/README.md" "b/Golang/Golang\345\237\272\347\241\200/7_Go\347\232\204\345\210\207\347\211\207/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..3941d31c90df8ad9013dd66b9fed5afb5acc2b5b --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/7_Go\347\232\204\345\210\207\347\211\207/README.md" @@ -0,0 +1,298 @@ +# Go的切片 + +## 为什么要使用切片 + +切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做的一层封装。 +它非常灵活,支持自动扩容。 + +切片是一个引用类型,它的内部结构包含地址、长度和容量。 + +声明切片类型的基本语法如下: + +```go +var name [] T +``` + +其中: + +- name:表示变量名 +- T:表示切片中的元素类型 + +举例 + +```go +// 声明切片,把长度去除就是切片 +var slice = []int{1,2,3} +fmt.Println(slice) +``` + +## 关于nil的认识 + +当你声明了一个变量,但却还并没有赋值时,golang中会自动给你的变量赋值一个默认的零值。这是每种类型对应的零值。 + +- bool:false +- numbers:0 +- string:"" +- pointers:nil +- slices:nil +- maps:nil +- channels:nil +- functions:nil + +nil表示空,也就是数组初始化的默认值就是nil + +```go +var slice2 [] int +fmt.Println(slice2 == nil) +``` + +运行结果 + +```bash +true +``` + +## 切片的遍历 + +切片的遍历和数组是一样的 + +```go +var slice = []int{1,2,3} +for i := 0; i < len(slice); i++ { + fmt.Print(slice[i], " ") +} +``` + +## 基于数组定义切片 + +由于切片的底层就是一个数组,所以我们可以基于数组来定义切片 + +```go +// 基于数组定义切片 +a := [5]int {55,56,57,58,59} +// 获取数组所有值,返回的是一个切片 +b := a[:] +// 从数组获取指定的切片 +c := a[1:4] +// 获取 下标3之前的数据(不包括3) +d := a[:3] +// 获取下标3以后的数据(包括3) +e := a[3:] +``` + +运行结果 + +```bash +[55 56 57 58 59] +[55 56 57 58 59] +[56 57 58] +[55 56 57] +[58 59] +``` + +同理,我们不仅可以对数组进行切片,还可以切片在切片 + +## 切片的长度和容量 + +切片拥有自己的长度和容量,我们可以通过使用内置的len)函数求长度,使用内置的cap() +函数求切片的容量。 + +切片的长度就是它所包含的元素个数。 + +切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。切片s的长度和容量可通过表达式len(s)和cap(s)来获取。 + +**举例** + +```go +// 长度和容量 +s := []int {2,3,5,7,11,13} +fmt.Printf("长度%d 容量%d\n", len(s), cap(s)) + +ss := s[2:] +fmt.Printf("长度%d 容量%d\n", len(ss), cap(ss)) + +sss := s[2:4] +fmt.Printf("长度%d 容量%d\n", len(sss), cap(sss)) +``` + +运行结果 + +```bash +长度6 容量6 +长度4 容量4 +长度2 容量4 +``` + +为什么最后一个容量不一样呢,因为我们知道,经过切片后sss = [5, 7] 所以切片的长度为2,但是一因为容量是从2的位置一直到末尾,所以为4 + +## 切片的本质 + +切片的本质就是对底层数组的封装,它包含了三个信息 + +- 底层数组的指针 +- 切片的长度(len) +- 切片的容量(cap) + +举个例子,现在有一个数组 a := [8]int {0,1,2,3,4,5,6,7},切片 s1 := a[:5],相应示意图如下 + +![image-20200720094247624](images/image-20200720094247624.png) + +切片 s2 := a[3:6],相应示意图如下: + +![image-20200720094336749](images/image-20200720094336749.png) + +## 使用make函数构造切片 + +我们上面都是基于数组来创建切片的,如果需要动态的创建一个切片,我们就需要使用内置的make函数,格式如下: + +```bash +make ([]T, size, cap) +``` + +其中: + +- T:切片的元素类型 +- size:切片中元素的数量 +- cap:切片的容量 + +举例: + +```go +// make()函数创建切片 +fmt.Println() +var slices = make([]int, 4, 8) +//[0 0 0 0] +fmt.Println(slices) +// 长度:4, 容量8 +fmt.Printf("长度:%d, 容量%d", len(slices), cap(slices)) +``` + +需要注意的是,golang中没办法通过下标来给切片扩容,如果需要扩容,需要用到append + +```go +slices2 := []int{1,2,3,4} +slices2 = append(slices2, 5) +fmt.Println(slices2) +// 输出结果 [1 2 3 4 5] +``` + +同时切片还可以将两个切片进行合并 + +```go +// 合并切片 +slices3 := []int{6,7,8} +slices2 = append(slices2, slices3...) +fmt.Println(slices2) +// 输出结果 [1 2 3 4 5 6 7 8] +``` + +需要注意的是,切片会有一个扩容操作,当元素存放不下的时候,会将原来的容量扩大两倍 + +## 使用copy()函数复制切片 + +前面我们知道,切片就是引用数据类型 + +- 值类型:改变变量副本的时候,不会改变变量本身 +- 引用类型:改变变量副本值的时候,会改变变量本身的值 + +如果我们需要改变切片的值,同时又不想影响到原来的切片,那么就需要用到copy函数 + +```go +// 需要复制的切片 +var slices4 = []int{1,2,3,4} +// 使用make函数创建一个切片 +var slices5 = make([]int, len(slices4), len(slices4)) +// 拷贝切片的值 +copy(slices5, slices4) +// 修改切片 +slices5[0] = 4 +fmt.Println(slices4) +fmt.Println(slices5) +``` + +运行结果为 + +```bash +[1 2 3 4] +[4 2 3 4] +``` + +## 删除切片中的值 + +Go语言中并没有删除切片元素的专用方法,我们可以利用切片本身的特性来删除元素。代码如下 + +```go +// 删除切片中的值 +var slices6 = []int {0,1,2,3,4,5,6,7,8,9} +// 删除下标为1的值 +slices6 = append(slices6[:1], slices6[2:]...) +fmt.Println(slices6) +``` + +运行结果 + +```bash +[0 2 3 4 5 6 7 8 9] +``` + +## 切片的排序算法以及sort包 + +编写一个简单的冒泡排序算法 + +```go +func main() { + var numSlice = []int{9,8,7,6,5,4} + for i := 0; i < len(numSlice); i++ { + flag := false + for j := 0; j < len(numSlice) - i - 1; j++ { + if numSlice[j] > numSlice[j+1] { + var temp = numSlice[j+1] + numSlice[j+1] = numSlice[j] + numSlice[j] = temp + flag = true + } + } + if !flag { + break + } + } + fmt.Println(numSlice) +} +``` + +在来一个选择排序 + +```go +// 编写选择排序 +var numSlice2 = []int{9,8,7,6,5,4} +for i := 0; i < len(numSlice2); i++ { + for j := i + 1; j < len(numSlice2); j++ { + if numSlice2[i] > numSlice2[j] { + var temp = numSlice2[i] + numSlice2[i] = numSlice2[j] + numSlice2[j] = temp + } + } +} +fmt.Println(numSlice2) +``` + +对于int、float64 和 string数组或是切片的排序,go分别提供了sort.Ints()、sort.Float64s() 和 sort.Strings()函数,默认都是从小到大进行排序 + +```go +var numSlice2 = []int{9,8,7,6,5,4} +sort.Ints(numSlice2) +fmt.Println(numSlice2) +``` + +### 降序排列 + +Golang的sort包可以使用 sort.Reverse(slic e) 来调换slice.Interface.Less,也就是比较函数,所以int、float64 和 string的逆序排序函数可以这样写 + +```go +// 逆序排列 +var numSlice4 = []int{9,8,4,5,1,7} +sort.Sort(sort.Reverse(sort.IntSlice(numSlice4))) +fmt.Println(numSlice4) +``` + diff --git "a/Golang/Golang\345\237\272\347\241\200/7_Go\347\232\204\345\210\207\347\211\207/images/image-20200720094247624.png" "b/Golang/Golang\345\237\272\347\241\200/7_Go\347\232\204\345\210\207\347\211\207/images/image-20200720094247624.png" new file mode 100644 index 0000000000000000000000000000000000000000..f5d8dd50bbf6289c6f3330c0065244cd8951b06d Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/7_Go\347\232\204\345\210\207\347\211\207/images/image-20200720094247624.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/7_Go\347\232\204\345\210\207\347\211\207/images/image-20200720094336749.png" "b/Golang/Golang\345\237\272\347\241\200/7_Go\347\232\204\345\210\207\347\211\207/images/image-20200720094336749.png" new file mode 100644 index 0000000000000000000000000000000000000000..3dec55c3cf84ef8438e0fe3411b1bb381033fb72 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/7_Go\347\232\204\345\210\207\347\211\207/images/image-20200720094336749.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/8_Go\347\232\204map/README.md" "b/Golang/Golang\345\237\272\347\241\200/8_Go\347\232\204map/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..09de59bbf010d4fa547541892695b95968d4bd35 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/8_Go\347\232\204map/README.md" @@ -0,0 +1,141 @@ +# Golang map详解 + +## map的介绍 + +map是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用。 + +Go语言中map的定义语法如下: + +```go +map[KeyType]ValueType +``` + +其中: + +- KeyType:表示键的类型 +- ValueType:表示键对应的值的类型 + +map类型的变量默认初始值为nil,需要使用make()函数来分配内存。语法为: + +make:用于slice、map和channel的初始化 + +示例如下所示: + +```go +// 方式1初始化 +var userInfo = make(map[string]string) +userInfo["userName"] = "zhangsan" +userInfo["age"] = "20" +userInfo["sex"] = "男" +fmt.Println(userInfo) +fmt.Println(userInfo["userName"]) +``` + +```go +// 创建方式2,map也支持声明的时候填充元素 +var userInfo2 = map[string]string { + "username":"张三", + "age":"21", + "sex":"女", +} +fmt.Println(userInfo2) +``` + +## 遍历map + +使用for range遍历 + +```go +// 遍历map +for key, value := range userInfo2 { + fmt.Println("key:", key, " value:", value) +} +``` + +## 判断map中某个键值是否存在 + +我们在获取map的时候,会返回两个值,也可以是返回的结果,一个是是否有该元素 + +```go +// 判断是否存在,如果存在 ok = true,否则 ok = false +value, ok := userInfo2["username2"] +fmt.Println(value, ok) +``` + +## 使用delete()函数删除键值对 + +使用delete()内建函数从map中删除一组键值对,delete函数的格式如下所示 + +```bash +delete(map 对象, key) +``` + +其中: + +- map对象:表示要删除键值对的map对象 +- key:表示要删除的键值对的键 + +示例代码如下 + +```go +// 删除map数据里面的key,以及对应的值 +delete(userInfo2, "sex") +fmt.Println(userInfo2) +``` + +## 元素为map类型的切片 + +我们想要在切片里面存放一系列用户的信息,这时候我们就可以定义一个元素为map类型的切片 + +```go +// 切片在中存放map +var userInfoList = make([]map[string]string, 3, 3) +var user = map[string]string{ + "userName": "张安", + "age": "15", +} +var user2 = map[string]string{ + "userName": "张2", + "age": "15", +} +var user3 = map[string]string{ + "userName": "张3", + "age": "15", +} +userInfoList[0] = user +userInfoList[1] = user2 +userInfoList[2] = user3 +fmt.Println(userInfoList) + +for _, item := range userInfoList { + fmt.Println(item) +} +``` + +## 值为切片类型的map + +我们可以在map中存储切片 + +```go +// 将map类型的值 +var userinfo = make(map[string][]string) +userinfo["hobby"] = []string {"吃饭", "睡觉", "敲代码"} +fmt.Println(userinfo) +``` + +## 示例 + +统计字符串中单词出现的次数 + +```go +// 写一个程序,统计一个字符串中每个单词出现的次数。比如 "how do you do" +var str = "how do you do" +array := strings.Split(str, " ") +fmt.Println(array) +countMap := make(map[string]int) +for _, item := range array { + countMap[item]++ +} +fmt.Println(countMap) +``` + diff --git "a/Golang/Golang\345\237\272\347\241\200/9_Go\347\232\204\345\207\275\346\225\260/README.md" "b/Golang/Golang\345\237\272\347\241\200/9_Go\347\232\204\345\207\275\346\225\260/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..5e0b8de6959f78004a87aaeb57b7f7e37694378c --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/9_Go\347\232\204\345\207\275\346\225\260/README.md" @@ -0,0 +1,385 @@ +# Go的函数 + +## 函数定义 + +函数是组织好的、可重复使用的、用于执行指定任务的代码块 + +Go语言支持:函数、匿名函数和闭包 + +Go语言中定义函数使用func关键字,具体格式如下: + +```go +func 函数名(参数)(返回值) { + 函数体 +} +``` + +其中: + +- 函数名:由字母、数字、下划线组成。但函数名的第一个字母不能是数字。在同一个包内,函数名也不能重名 + +示例 + +```go +// 求两个数的和 +func sumFn(x int, y int) int{ + return x + y +} +// 调用方式 +sunFn(1, 2) +``` + +获取可变的参数,可变参数是指函数的参数数量不固定。Go语言中的可变参数通过在参数名后面加... 来标识。 + +注意:可变参数通常要作为函数的最后一个参数 + +```go +func sunFn2(x ...int) int { + sum := 0 + for _, num := range x { + sum = sum + num + } + return sum +} +// 调用方法 +sunFn2(1, 2, 3, 4, 5, 7) +``` + +方法多返回值,Go语言中函数支持多返回值,同时还支持返回值命名,函数定义时可以给返回值命名,并在函数体中直接使用这些变量,最后通过return关键字返回 + +```go +// 方法多返回值 +func sunFn4(x int, y int)(sum int, sub int) { + sum = x + y + sub = x -y + return +} +``` + +## 函数类型和变量 + +### 定义函数类型 + +我们可以使用type关键字来定义一个函数类型,具体格式如下 + +```bash +type calculation func(int, int) int +``` + +上面语句定义了一个calculation类型,它是一种函数类型,这种函数接收两个int类型的参数并且返回一个int类型的返回值。 + +简单来说,凡是满足这两个条件的函数都是calculation类型的函数,例如下面的add 和 sub 是calculation类型 + +```go +type calc func(int, int) int +// 求两个数的和 +func sumFn(x int, y int) int{ + return x + y +} +func main() { + var c calc + c = add +} +``` + +### 方法作为参数 + +``` +/** + 传递两个参数和一个方法 + */ +func sunFn (a int, b int, sum func(int, int)int) int { + return sum(a, b) +} +``` + +或者使用switch定义方法,这里用到了匿名函数 + +```go +// 返回一个方法 +type calcType func(int, int)int +func do(o string) calcType { + switch o { + case "+": + return func(i int, i2 int) int { + return i + i2 + } + case "-": + return func(i int, i2 int) int { + return i - i2 + } + case "*": + return func(i int, i2 int) int { + return i * i2 + } + case "/": + return func(i int, i2 int) int { + return i / i2 + } + default: + return nil + + } +} + +func main() { + add := do("+") + fmt.Println(add(1,5)) +} +``` + +## 匿名函数 + +函数当然还可以作为返回值,但是在Go语言中,函数内部不能再像之前那样定义函数了,只能定义匿名函数。匿名函数就是没有函数名的函数,匿名函数的定义格式如下 + +```go +func (参数)(返回值) { + 函数体 +} +``` + +匿名函数因为没有函数名,所以没有办法像普通函数那样调用,所以匿名函数需要保存到某个变量或者作为立即执行函数: + +``` +func main() { + func () { + fmt.Println("匿名自执行函数") + }() +} +``` + +## Golang中的闭包 + +### 全局变量和局部变量 + +全局变量的特点: + +- 常驻内存 +- 污染全局 + +局部变量的特点 + +- 不常驻内存 +- 不污染全局 + +### 闭包 + +- 可以让一个变量常驻内存 +- 可以让一个变量不污染全局 + +闭包可以理解成 “定义在一个函数内部的函数”。在本质上,闭包就是将函数内部 和 函数外部连接起来的桥梁。或者说是函数和其引用环境的组合体。 + +- 闭包是指有权访问另一个函数作用域中的变量的函数 +- 创建闭包的常见的方式就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量 + +注意:由于闭包里作用域返回的局部变量资源不会被立刻销毁,所以可能会占用更多的内存,过度使用闭包会导致性能下降,建议在非常有必要的时候才使用闭包。 + +```go +// 闭包的写法:函数里面嵌套一个函数,最后返回里面的函数就形成了闭包 +func adder() func() int { + var i = 10 + return func() int { + return i + 1 + } +} + +func main() { + var fn = adder() + fmt.Println(fn()) + fmt.Println(fn()) + fmt.Println(fn()) +} +``` + +最后输出的结果 + +```bash +11 +11 +11 +``` + +另一个闭包的写法,让一个变量常驻内存,不污染全局 + +``` +func adder2() func(y int) int { + var i = 10 + return func(y int) int { + i = i + y + return i + } +} + +func main() { + var fn2 = adder2() + fmt.Println(fn2(10)) + fmt.Println(fn2(10)) + fmt.Println(fn2(10)) +} +``` + +## defer语句 + +Go 语言中的defer 语句会将其后面跟随的语句进行延迟处理。在defer归属的函数即将返回时,将延迟处理的语句按defer定义的逆序进行执行,也就是说,先被defer的语句最后被执行,最后被defer的语句,最先被执行。 + +```go +// defer函数 +fmt.Println("1") +defer fmt.Println("2") +fmt.Println("3") +fmt.Println("4") +``` + +defer将会延迟执行 + +```bash +1 +3 +4 +2 +``` + +如果有多个defer修饰的语句,将会逆序进行执行 + +```go +// defer函数 +fmt.Println("1") +defer fmt.Println("2") +defer fmt.Println("3") +fmt.Println("4") +``` + +运行结果 + +```bash +1 +4 +3 +2 +``` + +如果需要用defer运行一系列的语句,那么就可以使用匿名函数 + +```go +func main() { + fmt.Println("开始") + defer func() { + fmt.Println("1") + fmt.Println("2") + }() + fmt.Println("结束") +} +``` + +运行结果 + +```bash +开始 +结束 +1 +2 +``` + + + +### defer执行时机 + +在Go语言的函数中return语句在底层并不是原子操作,它分为返回值赋值和RET指令两步。而defer语句执行的时机就在返回值赋值操作后,RET指令执行前,具体如下图所示 + +![image-20200720220700249](images/image-20200720220700249.png) + +## panic/revocer处理异常 + +Go语言中是没有异常机制,但是使用panic / recover模式来处理错误 + +- panic:可以在任何地方引发 +- recover:只有在defer调用函数内有效 + +```go +func fn1() { + fmt.Println("fn1") +} + +func fn2() { + panic("抛出一个异常") +} +func main() { + fn1() + fn2() + fmt.Println("结束") +} +``` + +上述程序会直接抛出异常,无法正常运行 + +```bash +fn1 +panic: 抛出一个异常 +``` + +解决方法就是使用 recover进行异常的监听 + +```go +func fn1() { + fmt.Println("fn1") +} + +func fn2() { + // 使用recover监听异常 + defer func() { + err := recover() + if err != nil { + fmt.Println(err) + } + }() + panic("抛出一个异常") +} +func main() { + fn1() + fn2() + fmt.Println("结束") +} +``` + +## 异常运用场景 + +模拟一个读取文件的方法,这里可以主动发送使用panic 和 recover + +```go +func readFile(fileName string) error { + if fileName == "main.go" { + return nil + } else { + return errors.New("读取文件失败") + } +} + +func myFn () { + defer func() { + e := recover() + if e != nil { + fmt.Println("给管理员发送邮件") + } + }() + err := readFile("XXX.go") + if err != nil { + panic(err) + } +} + +func main() { + myFn() +} +``` + +## 内置函数 + +| 内置函数 | 介绍 | +| ------------- | ------------------------------------------------------------ | +| close | 主要用来关闭channel | +| len | 用来求长度,比如string、array、slice、map、channel | +| new | 用来分配内存、主要用来分配值类型,比如 int、struct ,返回的是指针 | +| make | 用来分配内存,主要用来分配引用类型,比如chan、map、slice | +| append | 用来追加元素到数组、slice中 | +| panic\recover | 用来处理错误 | + diff --git "a/Golang/Golang\345\237\272\347\241\200/9_Go\347\232\204\345\207\275\346\225\260/images/image-20200720220700249.png" "b/Golang/Golang\345\237\272\347\241\200/9_Go\347\232\204\345\207\275\346\225\260/images/image-20200720220700249.png" new file mode 100644 index 0000000000000000000000000000000000000000..da9cee43347a27db429031d8046e47aaf92df856 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/9_Go\347\232\204\345\207\275\346\225\260/images/image-20200720220700249.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/.idea/.gitignore" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/.idea/.gitignore" new file mode 100644 index 0000000000000000000000000000000000000000..73f69e0958611ac6e00bde95641f6699030ad235 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/.idea/.gitignore" @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/.idea/goProject.iml" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/.idea/goProject.iml" new file mode 100644 index 0000000000000000000000000000000000000000..c956989b29ad0767edc6cf3a202545927c3d1e76 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/.idea/goProject.iml" @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/.idea/misc.xml" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/.idea/misc.xml" new file mode 100644 index 0000000000000000000000000000000000000000..28a804d8932aba40f168fd757a74cb718a955a1a --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/.idea/misc.xml" @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/.idea/modules.xml" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/.idea/modules.xml" new file mode 100644 index 0000000000000000000000000000000000000000..3c2fb497ed5e83e5a085d32a3d5d7c8f694f39fd --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/.idea/modules.xml" @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/EmptyInterface/EmptyA.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/EmptyInterface/EmptyA.go" new file mode 100644 index 0000000000000000000000000000000000000000..666361d02815d8b4e9151873ca7baa250511728a --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/EmptyInterface/EmptyA.go" @@ -0,0 +1,16 @@ +package EmptyInterface + +import "fmt" + +// 空接口表示没有任何约束,任意的类型都可以实现空接口 +type EmptyA interface { + +} + +func main() { + var a EmptyA + var str = "你好golang" + // 让字符串实现A接口 + a = str + fmt.Println(a) +} \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/SecondInterface/main.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/SecondInterface/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..c5000f1cd51acf20f3de8fc657abefb86374c7c9 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/SecondInterface/main.go" @@ -0,0 +1,39 @@ +package SecondInterface + +import "fmt" + +// 定义一个Animal的接口,Animal中定义了两个方法,分别是setName 和 getName,分别让DOg结构体和Cat结构体实现 +type Animal1 interface { + SetName(string) +} + +// 接口2 +type Animal2 interface { + GetName()string +} + +type Animal interface { + Animal1 + Animal2 +} + +type Dog struct { + Name string +} + +func (d *Dog) SetName(name string) { + d.Name = name +} +func (d Dog)GetName()string { + return d.Name +} + +func main() { + var dog = &Dog{ + "小黑", + } + // 同时实现两个接口 + var d Animal = dog + d.SetName("小鸡") + fmt.Println(d.GetName()) +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/calc/calc.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/calc/calc.go" new file mode 100644 index 0000000000000000000000000000000000000000..a88764f3cba95806bb68eadc8dd38283ff7ad12e --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/calc/calc.go" @@ -0,0 +1,22 @@ +package calc + +import "fmt" + +// 自定义包,最好和文件夹统一起来 + +// 公有变量 +var age = 10 +// 私有变量 +var Name = "张三" + +// init方法 +func init() { + fmt.Println("init") +} +// 首字母大写,表示共有方法 +func Add(x, y int)int { + return x + y +} +func Sub(x, y int)int { + return x - y +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/go.mod" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/go.mod" new file mode 100644 index 0000000000000000000000000000000000000000..4b4e7a88d8b338dd9bec2819abc78a7c0412add2 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/go.mod" @@ -0,0 +1,8 @@ +module goProject + +go 1.14 + +require ( + github.com/shopspring/decimal v1.2.0 + github.com/tidwall/gjson v1.6.0 +) diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/go.sum" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/go.sum" new file mode 100644 index 0000000000000000000000000000000000000000..0684bf3b37cc05adfde0beb2be08c99c5157996c --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/go.sum" @@ -0,0 +1,8 @@ +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc= +github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= +github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= +github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/interfaceDemo/Camera.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/interfaceDemo/Camera.go" new file mode 100644 index 0000000000000000000000000000000000000000..c90a01712248b520c06d4a239a0d6130e2b9424e --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/interfaceDemo/Camera.go" @@ -0,0 +1,24 @@ +package interfaceDemo + +import "fmt" + +// 如果接口里面有方法的话,必须要通过结构体或自定义类型实现这个接口 + +// 使用相机结构体来实现 接口 +type Camera struct { + Name string +} +// 相机要实现Usber接口的话,必须实现usb接口的所有方法 +func (p Camera) start() { + fmt.Println(p.Name, "启动") +} +func (p Camera) stop() { + fmt.Println(p.Name, "关闭") +} +func (p Camera)Start() { + var camera Usber = Camera{ + "佳能", + } + camera.start() + camera.stop() +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/interfaceDemo/Computer.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/interfaceDemo/Computer.go" new file mode 100644 index 0000000000000000000000000000000000000000..fec77e8be9b25eebb4ca601b248cafeb78aa130a --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/interfaceDemo/Computer.go" @@ -0,0 +1,16 @@ +package interfaceDemo + +// 电脑 +type Computer struct { + +} + +// 接收一个实现了Usber接口的 结构体 +func (computer Computer) Startup(usb Usber) { + usb.start() +} + +// 关闭 +func (computer Computer) Shutdown (usb Usber) { + usb.stop() +} \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/interfaceDemo/Phone.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/interfaceDemo/Phone.go" new file mode 100644 index 0000000000000000000000000000000000000000..a125e7d224b1aaf1a2c1d17fb054845497255837 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/interfaceDemo/Phone.go" @@ -0,0 +1,24 @@ +package interfaceDemo + +import "fmt" + +// 如果接口里面有方法的话,必须要通过结构体或自定义类型实现这个接口 + +// 使用结构体来实现 接口 +type Phone struct { + Name string +} +// 手机要实现Usber接口的话,必须实现usb接口的所有方法 +func (p Phone) start() { + fmt.Println(p.Name, "启动") +} +func (p Phone) stop() { + fmt.Println(p.Name, "关闭") +} +func main() { + var phone Usber = Phone{ + "三星手机", + } + phone.start() + phone.stop() +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/interfaceDemo/Usber.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/interfaceDemo/Usber.go" new file mode 100644 index 0000000000000000000000000000000000000000..1e5105cdab71f53a532531e178b99d5ef459c8fb --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/interfaceDemo/Usber.go" @@ -0,0 +1,7 @@ +package interfaceDemo + +// 定义一个Usber接口 +type Usber interface { + start() + stop() +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/main.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..edae1b92b891619f968fce9339b672ad2c978718 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/main.go" @@ -0,0 +1,96 @@ +package main + +import ( + "fmt" + "goProject/SecondInterface" + "goProject/interfaceDemo" +) + +// 定义一个方法,可以传入任意数据类型,然后根据不同类型实现不同的功能 +func Print(x interface{}) { + if _,ok := x.(string); ok { + fmt.Println("传入参数是string类型") + } else if _, ok := x.(int); ok { + fmt.Println("传入参数是int类型") + } else { + fmt.Println("传入其它类型") + } +} + +func Print2(x interface{}) { + switch x.(type) { + case int: + fmt.Println("int类型") + case string: + fmt.Println("string类型") + case bool: + fmt.Println("bool类型") + default: + fmt.Println("其它类型") + } +} + +func main() { + var camera interfaceDemo.Camera = interfaceDemo.Camera{ + "佳能", + } + var phone interfaceDemo.Phone = interfaceDemo.Phone{ + "苹果", + } + + var computer interfaceDemo.Computer = interfaceDemo.Computer{} + computer.Startup(camera) + computer.Startup(phone) + computer.Shutdown(camera) + computer.Shutdown(phone) + + // 定义一个值为空接口类型 + var studentInfo = make(map[string]interface{}) + studentInfo["userName"] = "张三" + studentInfo["age"] = 15 + studentInfo["isWork"] = true + fmt.Printf("%#v \n", studentInfo) + + // 定义一个空接口类型的切片 + var slice = make([]interface{}, 4, 4) + slice[0] = "张三" + slice[1] = 1 + slice[2] = true + + // 类型断言 + var a interface{} + a = "132" + value, isString := a.(string) + if isString { + fmt.Println("是String类型, 值为:", value) + } else { + fmt.Println("断言失败") + } + + Print2("a") + + var dog SecondInterface.Animal = &SecondInterface.Dog{ + "小黑", + } + fmt.Println(dog.GetName()) + dog.SetName("阿帕奇") + fmt.Println(dog.GetName()) + + // golang中空接口和类型断言 + var userInfo = make(map[string]interface{}) + userInfo["userName"] = "zhangsan" + userInfo["age"] = 10 + userInfo["hobby"] = []string{"吃饭", "睡觉"} + fmt.Println(userInfo["userName"]) + fmt.Println(userInfo["age"]) + fmt.Println(userInfo["hobby"]) + // 但是我们空接口如何获取数组中的值?发现 userInfo["hobby"][0] 这样做不行 + // fmt.Println(userInfo["hobby"][0]) + + // 这个时候我们就可以使用类型断言了 + hobbyValue,ok := userInfo["hobby"].([]string) + if ok { + fmt.Println(hobbyValue[0]) + } + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/.gitignore" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/.gitignore" new file mode 100644 index 0000000000000000000000000000000000000000..8a43ce9d7b6b6953a8ebce7ca4951e04b87a137d --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/.gitignore" @@ -0,0 +1,6 @@ +.git +*.swp + +# IntelliJ +.idea/ +*.iml diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/.travis.yml" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/.travis.yml" new file mode 100644 index 0000000000000000000000000000000000000000..55d42b289d09fc2c01eff1fc9d2545184f3eb5d5 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/.travis.yml" @@ -0,0 +1,13 @@ +language: go + +go: + - 1.7.x + - 1.12.x + - 1.13.x + - tip + +install: + - go build . + +script: + - go test -v diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/CHANGELOG.md" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/CHANGELOG.md" new file mode 100644 index 0000000000000000000000000000000000000000..01ba02feb2c7bda2aa2963dd794c202cbcbd8a74 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/CHANGELOG.md" @@ -0,0 +1,19 @@ +## Decimal v1.2.0 + +#### BREAKING +- Drop support for Go version older than 1.7 [#172](https://github.com/shopspring/decimal/pull/172) + +#### FEATURES +- Add NewFromInt and NewFromInt32 initializers [#72](https://github.com/shopspring/decimal/pull/72) +- Add support for Go modules [#157](https://github.com/shopspring/decimal/pull/157) +- Add BigInt, BigFloat helper methods [#171](https://github.com/shopspring/decimal/pull/171) + +#### ENHANCEMENTS +- Memory usage optimization [#160](https://github.com/shopspring/decimal/pull/160) +- Updated travis CI golang versions [#156](https://github.com/shopspring/decimal/pull/156) +- Update documentation [#173](https://github.com/shopspring/decimal/pull/173) +- Improve code quality [#174](https://github.com/shopspring/decimal/pull/174) + +#### BUGFIXES +- Revert remove insignificant digits [#159](https://github.com/shopspring/decimal/pull/159) +- Remove 15 interval for RoundCash [#166](https://github.com/shopspring/decimal/pull/166) diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/LICENSE" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/LICENSE" new file mode 100644 index 0000000000000000000000000000000000000000..ad2148aaf93e381475ab50d7466d91af6d1f8df8 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/LICENSE" @@ -0,0 +1,45 @@ +The MIT License (MIT) + +Copyright (c) 2015 Spring, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +- Based on https://github.com/oguzbilgic/fpd, which has the following license: +""" +The MIT License (MIT) + +Copyright (c) 2013 Oguz Bilgic + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +""" diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/README.md" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b70f901593517ba1e7bf4a0d8a4eb005e5ac5bb5 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/README.md" @@ -0,0 +1,130 @@ +# decimal + +[![Build Status](https://travis-ci.org/shopspring/decimal.png?branch=master)](https://travis-ci.org/shopspring/decimal) [![GoDoc](https://godoc.org/github.com/shopspring/decimal?status.svg)](https://godoc.org/github.com/shopspring/decimal) [![Go Report Card](https://goreportcard.com/badge/github.com/shopspring/decimal)](https://goreportcard.com/report/github.com/shopspring/decimal) + +Arbitrary-precision fixed-point decimal numbers in go. + +_Note:_ Decimal library can "only" represent numbers with a maximum of 2^31 digits after the decimal point. + +## Features + + * The zero-value is 0, and is safe to use without initialization + * Addition, subtraction, multiplication with no loss of precision + * Division with specified precision + * Database/sql serialization/deserialization + * JSON and XML serialization/deserialization + +## Install + +Run `go get github.com/shopspring/decimal` + +## Requirements + +Decimal library requires Go version `>=1.7` + +## Usage + +```go +package main + +import ( + "fmt" + "github.com/shopspring/decimal" +) + +func main() { + price, err := decimal.NewFromString("136.02") + if err != nil { + panic(err) + } + + quantity := decimal.NewFromInt(3) + + fee, _ := decimal.NewFromString(".035") + taxRate, _ := decimal.NewFromString(".08875") + + subtotal := price.Mul(quantity) + + preTax := subtotal.Mul(fee.Add(decimal.NewFromFloat(1))) + + total := preTax.Mul(taxRate.Add(decimal.NewFromFloat(1))) + + fmt.Println("Subtotal:", subtotal) // Subtotal: 408.06 + fmt.Println("Pre-tax:", preTax) // Pre-tax: 422.3421 + fmt.Println("Taxes:", total.Sub(preTax)) // Taxes: 37.482861375 + fmt.Println("Total:", total) // Total: 459.824961375 + fmt.Println("Tax rate:", total.Sub(preTax).Div(preTax)) // Tax rate: 0.08875 +} +``` + +## Documentation + +http://godoc.org/github.com/shopspring/decimal + +## Production Usage + +* [Spring](https://shopspring.com/), since August 14, 2014. +* If you are using this in production, please let us know! + +## FAQ + +#### Why don't you just use float64? + +Because float64 (or any binary floating point type, actually) can't represent +numbers such as `0.1` exactly. + +Consider this code: http://play.golang.org/p/TQBd4yJe6B You might expect that +it prints out `10`, but it actually prints `9.999999999999831`. Over time, +these small errors can really add up! + +#### Why don't you just use big.Rat? + +big.Rat is fine for representing rational numbers, but Decimal is better for +representing money. Why? Here's a (contrived) example: + +Let's say you use big.Rat, and you have two numbers, x and y, both +representing 1/3, and you have `z = 1 - x - y = 1/3`. If you print each one +out, the string output has to stop somewhere (let's say it stops at 3 decimal +digits, for simplicity), so you'll get 0.333, 0.333, and 0.333. But where did +the other 0.001 go? + +Here's the above example as code: http://play.golang.org/p/lCZZs0w9KE + +With Decimal, the strings being printed out represent the number exactly. So, +if you have `x = y = 1/3` (with precision 3), they will actually be equal to +0.333, and when you do `z = 1 - x - y`, `z` will be equal to .334. No money is +unaccounted for! + +You still have to be careful. If you want to split a number `N` 3 ways, you +can't just send `N/3` to three different people. You have to pick one to send +`N - (2/3*N)` to. That person will receive the fraction of a penny remainder. + +But, it is much easier to be careful with Decimal than with big.Rat. + +#### Why isn't the API similar to big.Int's? + +big.Int's API is built to reduce the number of memory allocations for maximal +performance. This makes sense for its use-case, but the trade-off is that the +API is awkward and easy to misuse. + +For example, to add two big.Ints, you do: `z := new(big.Int).Add(x, y)`. A +developer unfamiliar with this API might try to do `z := a.Add(a, b)`. This +modifies `a` and sets `z` as an alias for `a`, which they might not expect. It +also modifies any other aliases to `a`. + +Here's an example of the subtle bugs you can introduce with big.Int's API: +https://play.golang.org/p/x2R_78pa8r + +In contrast, it's difficult to make such mistakes with decimal. Decimals +behave like other go numbers types: even though `a = b` will not deep copy +`b` into `a`, it is impossible to modify a Decimal, since all Decimal methods +return new Decimals and do not modify the originals. The downside is that +this causes extra allocations, so Decimal is less performant. My assumption +is that if you're using Decimals, you probably care more about correctness +than performance. + +## License + +The MIT License (MIT) + +This is a heavily modified fork of [fpd.Decimal](https://github.com/oguzbilgic/fpd), which was also released under the MIT License. diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/decimal-go.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/decimal-go.go" new file mode 100644 index 0000000000000000000000000000000000000000..9958d6902063f1c9f760eef714a2de23ae3f8aa7 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/decimal-go.go" @@ -0,0 +1,415 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Multiprecision decimal numbers. +// For floating-point formatting only; not general purpose. +// Only operations are assign and (binary) left/right shift. +// Can do binary floating point in multiprecision decimal precisely +// because 2 divides 10; cannot do decimal floating point +// in multiprecision binary precisely. + +package decimal + +type decimal struct { + d [800]byte // digits, big-endian representation + nd int // number of digits used + dp int // decimal point + neg bool // negative flag + trunc bool // discarded nonzero digits beyond d[:nd] +} + +func (a *decimal) String() string { + n := 10 + a.nd + if a.dp > 0 { + n += a.dp + } + if a.dp < 0 { + n += -a.dp + } + + buf := make([]byte, n) + w := 0 + switch { + case a.nd == 0: + return "0" + + case a.dp <= 0: + // zeros fill space between decimal point and digits + buf[w] = '0' + w++ + buf[w] = '.' + w++ + w += digitZero(buf[w : w+-a.dp]) + w += copy(buf[w:], a.d[0:a.nd]) + + case a.dp < a.nd: + // decimal point in middle of digits + w += copy(buf[w:], a.d[0:a.dp]) + buf[w] = '.' + w++ + w += copy(buf[w:], a.d[a.dp:a.nd]) + + default: + // zeros fill space between digits and decimal point + w += copy(buf[w:], a.d[0:a.nd]) + w += digitZero(buf[w : w+a.dp-a.nd]) + } + return string(buf[0:w]) +} + +func digitZero(dst []byte) int { + for i := range dst { + dst[i] = '0' + } + return len(dst) +} + +// trim trailing zeros from number. +// (They are meaningless; the decimal point is tracked +// independent of the number of digits.) +func trim(a *decimal) { + for a.nd > 0 && a.d[a.nd-1] == '0' { + a.nd-- + } + if a.nd == 0 { + a.dp = 0 + } +} + +// Assign v to a. +func (a *decimal) Assign(v uint64) { + var buf [24]byte + + // Write reversed decimal in buf. + n := 0 + for v > 0 { + v1 := v / 10 + v -= 10 * v1 + buf[n] = byte(v + '0') + n++ + v = v1 + } + + // Reverse again to produce forward decimal in a.d. + a.nd = 0 + for n--; n >= 0; n-- { + a.d[a.nd] = buf[n] + a.nd++ + } + a.dp = a.nd + trim(a) +} + +// Maximum shift that we can do in one pass without overflow. +// A uint has 32 or 64 bits, and we have to be able to accommodate 9<> 63) +const maxShift = uintSize - 4 + +// Binary shift right (/ 2) by k bits. k <= maxShift to avoid overflow. +func rightShift(a *decimal, k uint) { + r := 0 // read pointer + w := 0 // write pointer + + // Pick up enough leading digits to cover first shift. + var n uint + for ; n>>k == 0; r++ { + if r >= a.nd { + if n == 0 { + // a == 0; shouldn't get here, but handle anyway. + a.nd = 0 + return + } + for n>>k == 0 { + n = n * 10 + r++ + } + break + } + c := uint(a.d[r]) + n = n*10 + c - '0' + } + a.dp -= r - 1 + + var mask uint = (1 << k) - 1 + + // Pick up a digit, put down a digit. + for ; r < a.nd; r++ { + c := uint(a.d[r]) + dig := n >> k + n &= mask + a.d[w] = byte(dig + '0') + w++ + n = n*10 + c - '0' + } + + // Put down extra digits. + for n > 0 { + dig := n >> k + n &= mask + if w < len(a.d) { + a.d[w] = byte(dig + '0') + w++ + } else if dig > 0 { + a.trunc = true + } + n = n * 10 + } + + a.nd = w + trim(a) +} + +// Cheat sheet for left shift: table indexed by shift count giving +// number of new digits that will be introduced by that shift. +// +// For example, leftcheats[4] = {2, "625"}. That means that +// if we are shifting by 4 (multiplying by 16), it will add 2 digits +// when the string prefix is "625" through "999", and one fewer digit +// if the string prefix is "000" through "624". +// +// Credit for this trick goes to Ken. + +type leftCheat struct { + delta int // number of new digits + cutoff string // minus one digit if original < a. +} + +var leftcheats = []leftCheat{ + // Leading digits of 1/2^i = 5^i. + // 5^23 is not an exact 64-bit floating point number, + // so have to use bc for the math. + // Go up to 60 to be large enough for 32bit and 64bit platforms. + /* + seq 60 | sed 's/^/5^/' | bc | + awk 'BEGIN{ print "\t{ 0, \"\" }," } + { + log2 = log(2)/log(10) + printf("\t{ %d, \"%s\" },\t// * %d\n", + int(log2*NR+1), $0, 2**NR) + }' + */ + {0, ""}, + {1, "5"}, // * 2 + {1, "25"}, // * 4 + {1, "125"}, // * 8 + {2, "625"}, // * 16 + {2, "3125"}, // * 32 + {2, "15625"}, // * 64 + {3, "78125"}, // * 128 + {3, "390625"}, // * 256 + {3, "1953125"}, // * 512 + {4, "9765625"}, // * 1024 + {4, "48828125"}, // * 2048 + {4, "244140625"}, // * 4096 + {4, "1220703125"}, // * 8192 + {5, "6103515625"}, // * 16384 + {5, "30517578125"}, // * 32768 + {5, "152587890625"}, // * 65536 + {6, "762939453125"}, // * 131072 + {6, "3814697265625"}, // * 262144 + {6, "19073486328125"}, // * 524288 + {7, "95367431640625"}, // * 1048576 + {7, "476837158203125"}, // * 2097152 + {7, "2384185791015625"}, // * 4194304 + {7, "11920928955078125"}, // * 8388608 + {8, "59604644775390625"}, // * 16777216 + {8, "298023223876953125"}, // * 33554432 + {8, "1490116119384765625"}, // * 67108864 + {9, "7450580596923828125"}, // * 134217728 + {9, "37252902984619140625"}, // * 268435456 + {9, "186264514923095703125"}, // * 536870912 + {10, "931322574615478515625"}, // * 1073741824 + {10, "4656612873077392578125"}, // * 2147483648 + {10, "23283064365386962890625"}, // * 4294967296 + {10, "116415321826934814453125"}, // * 8589934592 + {11, "582076609134674072265625"}, // * 17179869184 + {11, "2910383045673370361328125"}, // * 34359738368 + {11, "14551915228366851806640625"}, // * 68719476736 + {12, "72759576141834259033203125"}, // * 137438953472 + {12, "363797880709171295166015625"}, // * 274877906944 + {12, "1818989403545856475830078125"}, // * 549755813888 + {13, "9094947017729282379150390625"}, // * 1099511627776 + {13, "45474735088646411895751953125"}, // * 2199023255552 + {13, "227373675443232059478759765625"}, // * 4398046511104 + {13, "1136868377216160297393798828125"}, // * 8796093022208 + {14, "5684341886080801486968994140625"}, // * 17592186044416 + {14, "28421709430404007434844970703125"}, // * 35184372088832 + {14, "142108547152020037174224853515625"}, // * 70368744177664 + {15, "710542735760100185871124267578125"}, // * 140737488355328 + {15, "3552713678800500929355621337890625"}, // * 281474976710656 + {15, "17763568394002504646778106689453125"}, // * 562949953421312 + {16, "88817841970012523233890533447265625"}, // * 1125899906842624 + {16, "444089209850062616169452667236328125"}, // * 2251799813685248 + {16, "2220446049250313080847263336181640625"}, // * 4503599627370496 + {16, "11102230246251565404236316680908203125"}, // * 9007199254740992 + {17, "55511151231257827021181583404541015625"}, // * 18014398509481984 + {17, "277555756156289135105907917022705078125"}, // * 36028797018963968 + {17, "1387778780781445675529539585113525390625"}, // * 72057594037927936 + {18, "6938893903907228377647697925567626953125"}, // * 144115188075855872 + {18, "34694469519536141888238489627838134765625"}, // * 288230376151711744 + {18, "173472347597680709441192448139190673828125"}, // * 576460752303423488 + {19, "867361737988403547205962240695953369140625"}, // * 1152921504606846976 +} + +// Is the leading prefix of b lexicographically less than s? +func prefixIsLessThan(b []byte, s string) bool { + for i := 0; i < len(s); i++ { + if i >= len(b) { + return true + } + if b[i] != s[i] { + return b[i] < s[i] + } + } + return false +} + +// Binary shift left (* 2) by k bits. k <= maxShift to avoid overflow. +func leftShift(a *decimal, k uint) { + delta := leftcheats[k].delta + if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) { + delta-- + } + + r := a.nd // read index + w := a.nd + delta // write index + + // Pick up a digit, put down a digit. + var n uint + for r--; r >= 0; r-- { + n += (uint(a.d[r]) - '0') << k + quo := n / 10 + rem := n - 10*quo + w-- + if w < len(a.d) { + a.d[w] = byte(rem + '0') + } else if rem != 0 { + a.trunc = true + } + n = quo + } + + // Put down extra digits. + for n > 0 { + quo := n / 10 + rem := n - 10*quo + w-- + if w < len(a.d) { + a.d[w] = byte(rem + '0') + } else if rem != 0 { + a.trunc = true + } + n = quo + } + + a.nd += delta + if a.nd >= len(a.d) { + a.nd = len(a.d) + } + a.dp += delta + trim(a) +} + +// Binary shift left (k > 0) or right (k < 0). +func (a *decimal) Shift(k int) { + switch { + case a.nd == 0: + // nothing to do: a == 0 + case k > 0: + for k > maxShift { + leftShift(a, maxShift) + k -= maxShift + } + leftShift(a, uint(k)) + case k < 0: + for k < -maxShift { + rightShift(a, maxShift) + k += maxShift + } + rightShift(a, uint(-k)) + } +} + +// If we chop a at nd digits, should we round up? +func shouldRoundUp(a *decimal, nd int) bool { + if nd < 0 || nd >= a.nd { + return false + } + if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even + // if we truncated, a little higher than what's recorded - always round up + if a.trunc { + return true + } + return nd > 0 && (a.d[nd-1]-'0')%2 != 0 + } + // not halfway - digit tells all + return a.d[nd] >= '5' +} + +// Round a to nd digits (or fewer). +// If nd is zero, it means we're rounding +// just to the left of the digits, as in +// 0.09 -> 0.1. +func (a *decimal) Round(nd int) { + if nd < 0 || nd >= a.nd { + return + } + if shouldRoundUp(a, nd) { + a.RoundUp(nd) + } else { + a.RoundDown(nd) + } +} + +// Round a down to nd digits (or fewer). +func (a *decimal) RoundDown(nd int) { + if nd < 0 || nd >= a.nd { + return + } + a.nd = nd + trim(a) +} + +// Round a up to nd digits (or fewer). +func (a *decimal) RoundUp(nd int) { + if nd < 0 || nd >= a.nd { + return + } + + // round up + for i := nd - 1; i >= 0; i-- { + c := a.d[i] + if c < '9' { // can stop after this digit + a.d[i]++ + a.nd = i + 1 + return + } + } + + // Number is all 9s. + // Change to single 1 with adjusted decimal point. + a.d[0] = '1' + a.nd = 1 + a.dp++ +} + +// Extract integer part, rounded appropriately. +// No guarantees about overflow. +func (a *decimal) RoundedInteger() uint64 { + if a.dp > 20 { + return 0xFFFFFFFFFFFFFFFF + } + var i int + n := uint64(0) + for i = 0; i < a.dp && i < a.nd; i++ { + n = n*10 + uint64(a.d[i]-'0') + } + for ; i < a.dp; i++ { + n *= 10 + } + if shouldRoundUp(a, a.dp) { + n++ + } + return n +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/decimal.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/decimal.go" new file mode 100644 index 0000000000000000000000000000000000000000..cb874459757968dbb0c51865868f3d2b4368eaf5 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/decimal.go" @@ -0,0 +1,1477 @@ +// Package decimal implements an arbitrary precision fixed-point decimal. +// +// The zero-value of a Decimal is 0, as you would expect. +// +// The best way to create a new Decimal is to use decimal.NewFromString, ex: +// +// n, err := decimal.NewFromString("-123.4567") +// n.String() // output: "-123.4567" +// +// To use Decimal as part of a struct: +// +// type Struct struct { +// Number Decimal +// } +// +// Note: This can "only" represent numbers with a maximum of 2^31 digits after the decimal point. +package decimal + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "math" + "math/big" + "strconv" + "strings" +) + +// DivisionPrecision is the number of decimal places in the result when it +// doesn't divide exactly. +// +// Example: +// +// d1 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(3)) +// d1.String() // output: "0.6666666666666667" +// d2 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(30000)) +// d2.String() // output: "0.0000666666666667" +// d3 := decimal.NewFromFloat(20000).Div(decimal.NewFromFloat(3)) +// d3.String() // output: "6666.6666666666666667" +// decimal.DivisionPrecision = 3 +// d4 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(3)) +// d4.String() // output: "0.667" +// +var DivisionPrecision = 16 + +// MarshalJSONWithoutQuotes should be set to true if you want the decimal to +// be JSON marshaled as a number, instead of as a string. +// WARNING: this is dangerous for decimals with many digits, since many JSON +// unmarshallers (ex: Javascript's) will unmarshal JSON numbers to IEEE 754 +// double-precision floating point numbers, which means you can potentially +// silently lose precision. +var MarshalJSONWithoutQuotes = false + +// Zero constant, to make computations faster. +// Zero should never be compared with == or != directly, please use decimal.Equal or decimal.Cmp instead. +var Zero = New(0, 1) + +var zeroInt = big.NewInt(0) +var oneInt = big.NewInt(1) +var twoInt = big.NewInt(2) +var fourInt = big.NewInt(4) +var fiveInt = big.NewInt(5) +var tenInt = big.NewInt(10) +var twentyInt = big.NewInt(20) + +// Decimal represents a fixed-point decimal. It is immutable. +// number = value * 10 ^ exp +type Decimal struct { + value *big.Int + + // NOTE(vadim): this must be an int32, because we cast it to float64 during + // calculations. If exp is 64 bit, we might lose precision. + // If we cared about being able to represent every possible decimal, we + // could make exp a *big.Int but it would hurt performance and numbers + // like that are unrealistic. + exp int32 +} + +// New returns a new fixed-point decimal, value * 10 ^ exp. +func New(value int64, exp int32) Decimal { + return Decimal{ + value: big.NewInt(value), + exp: exp, + } +} + +// NewFromInt converts a int64 to Decimal. +// +// Example: +// +// NewFromInt(123).String() // output: "123" +// NewFromInt(-10).String() // output: "-10" +func NewFromInt(value int64) Decimal { + return Decimal{ + value: big.NewInt(value), + exp: 0, + } +} + +// NewFromInt32 converts a int32 to Decimal. +// +// Example: +// +// NewFromInt(123).String() // output: "123" +// NewFromInt(-10).String() // output: "-10" +func NewFromInt32(value int32) Decimal { + return Decimal{ + value: big.NewInt(int64(value)), + exp: 0, + } +} + +// NewFromBigInt returns a new Decimal from a big.Int, value * 10 ^ exp +func NewFromBigInt(value *big.Int, exp int32) Decimal { + return Decimal{ + value: big.NewInt(0).Set(value), + exp: exp, + } +} + +// NewFromString returns a new Decimal from a string representation. +// Trailing zeroes are not trimmed. +// +// Example: +// +// d, err := NewFromString("-123.45") +// d2, err := NewFromString(".0001") +// d3, err := NewFromString("1.47000") +// +func NewFromString(value string) (Decimal, error) { + originalInput := value + var intString string + var exp int64 + + // Check if number is using scientific notation + eIndex := strings.IndexAny(value, "Ee") + if eIndex != -1 { + expInt, err := strconv.ParseInt(value[eIndex+1:], 10, 32) + if err != nil { + if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange { + return Decimal{}, fmt.Errorf("can't convert %s to decimal: fractional part too long", value) + } + return Decimal{}, fmt.Errorf("can't convert %s to decimal: exponent is not numeric", value) + } + value = value[:eIndex] + exp = expInt + } + + parts := strings.Split(value, ".") + if len(parts) == 1 { + // There is no decimal point, we can just parse the original string as + // an int + intString = value + } else if len(parts) == 2 { + intString = parts[0] + parts[1] + expInt := -len(parts[1]) + exp += int64(expInt) + } else { + return Decimal{}, fmt.Errorf("can't convert %s to decimal: too many .s", value) + } + + dValue := new(big.Int) + _, ok := dValue.SetString(intString, 10) + if !ok { + return Decimal{}, fmt.Errorf("can't convert %s to decimal", value) + } + + if exp < math.MinInt32 || exp > math.MaxInt32 { + // NOTE(vadim): I doubt a string could realistically be this long + return Decimal{}, fmt.Errorf("can't convert %s to decimal: fractional part too long", originalInput) + } + + return Decimal{ + value: dValue, + exp: int32(exp), + }, nil +} + +// RequireFromString returns a new Decimal from a string representation +// or panics if NewFromString would have returned an error. +// +// Example: +// +// d := RequireFromString("-123.45") +// d2 := RequireFromString(".0001") +// +func RequireFromString(value string) Decimal { + dec, err := NewFromString(value) + if err != nil { + panic(err) + } + return dec +} + +// NewFromFloat converts a float64 to Decimal. +// +// The converted number will contain the number of significant digits that can be +// represented in a float with reliable roundtrip. +// This is typically 15 digits, but may be more in some cases. +// See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information. +// +// For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms. +// +// NOTE: this will panic on NaN, +/-inf +func NewFromFloat(value float64) Decimal { + if value == 0 { + return New(0, 0) + } + return newFromFloat(value, math.Float64bits(value), &float64info) +} + +// NewFromFloat32 converts a float32 to Decimal. +// +// The converted number will contain the number of significant digits that can be +// represented in a float with reliable roundtrip. +// This is typically 6-8 digits depending on the input. +// See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information. +// +// For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms. +// +// NOTE: this will panic on NaN, +/-inf +func NewFromFloat32(value float32) Decimal { + if value == 0 { + return New(0, 0) + } + // XOR is workaround for https://github.com/golang/go/issues/26285 + a := math.Float32bits(value) ^ 0x80808080 + return newFromFloat(float64(value), uint64(a)^0x80808080, &float32info) +} + +func newFromFloat(val float64, bits uint64, flt *floatInfo) Decimal { + if math.IsNaN(val) || math.IsInf(val, 0) { + panic(fmt.Sprintf("Cannot create a Decimal from %v", val)) + } + exp := int(bits>>flt.mantbits) & (1<>(flt.expbits+flt.mantbits) != 0 + + roundShortest(&d, mant, exp, flt) + // If less than 19 digits, we can do calculation in an int64. + if d.nd < 19 { + tmp := int64(0) + m := int64(1) + for i := d.nd - 1; i >= 0; i-- { + tmp += m * int64(d.d[i]-'0') + m *= 10 + } + if d.neg { + tmp *= -1 + } + return Decimal{value: big.NewInt(tmp), exp: int32(d.dp) - int32(d.nd)} + } + dValue := new(big.Int) + dValue, ok := dValue.SetString(string(d.d[:d.nd]), 10) + if ok { + return Decimal{value: dValue, exp: int32(d.dp) - int32(d.nd)} + } + + return NewFromFloatWithExponent(val, int32(d.dp)-int32(d.nd)) +} + +// NewFromFloatWithExponent converts a float64 to Decimal, with an arbitrary +// number of fractional digits. +// +// Example: +// +// NewFromFloatWithExponent(123.456, -2).String() // output: "123.46" +// +func NewFromFloatWithExponent(value float64, exp int32) Decimal { + if math.IsNaN(value) || math.IsInf(value, 0) { + panic(fmt.Sprintf("Cannot create a Decimal from %v", value)) + } + + bits := math.Float64bits(value) + mant := bits & (1<<52 - 1) + exp2 := int32((bits >> 52) & (1<<11 - 1)) + sign := bits >> 63 + + if exp2 == 0 { + // specials + if mant == 0 { + return Decimal{} + } + // subnormal + exp2++ + } else { + // normal + mant |= 1 << 52 + } + + exp2 -= 1023 + 52 + + // normalizing base-2 values + for mant&1 == 0 { + mant = mant >> 1 + exp2++ + } + + // maximum number of fractional base-10 digits to represent 2^N exactly cannot be more than -N if N<0 + if exp < 0 && exp < exp2 { + if exp2 < 0 { + exp = exp2 + } else { + exp = 0 + } + } + + // representing 10^M * 2^N as 5^M * 2^(M+N) + exp2 -= exp + + temp := big.NewInt(1) + dMant := big.NewInt(int64(mant)) + + // applying 5^M + if exp > 0 { + temp = temp.SetInt64(int64(exp)) + temp = temp.Exp(fiveInt, temp, nil) + } else if exp < 0 { + temp = temp.SetInt64(-int64(exp)) + temp = temp.Exp(fiveInt, temp, nil) + dMant = dMant.Mul(dMant, temp) + temp = temp.SetUint64(1) + } + + // applying 2^(M+N) + if exp2 > 0 { + dMant = dMant.Lsh(dMant, uint(exp2)) + } else if exp2 < 0 { + temp = temp.Lsh(temp, uint(-exp2)) + } + + // rounding and downscaling + if exp > 0 || exp2 < 0 { + halfDown := new(big.Int).Rsh(temp, 1) + dMant = dMant.Add(dMant, halfDown) + dMant = dMant.Quo(dMant, temp) + } + + if sign == 1 { + dMant = dMant.Neg(dMant) + } + + return Decimal{ + value: dMant, + exp: exp, + } +} + +// rescale returns a rescaled version of the decimal. Returned +// decimal may be less precise if the given exponent is bigger +// than the initial exponent of the Decimal. +// NOTE: this will truncate, NOT round +// +// Example: +// +// d := New(12345, -4) +// d2 := d.rescale(-1) +// d3 := d2.rescale(-4) +// println(d1) +// println(d2) +// println(d3) +// +// Output: +// +// 1.2345 +// 1.2 +// 1.2000 +// +func (d Decimal) rescale(exp int32) Decimal { + d.ensureInitialized() + + if d.exp == exp { + return Decimal{ + new(big.Int).Set(d.value), + d.exp, + } + } + + // NOTE(vadim): must convert exps to float64 before - to prevent overflow + diff := math.Abs(float64(exp) - float64(d.exp)) + value := new(big.Int).Set(d.value) + + expScale := new(big.Int).Exp(tenInt, big.NewInt(int64(diff)), nil) + if exp > d.exp { + value = value.Quo(value, expScale) + } else if exp < d.exp { + value = value.Mul(value, expScale) + } + + return Decimal{ + value: value, + exp: exp, + } +} + +// Abs returns the absolute value of the decimal. +func (d Decimal) Abs() Decimal { + d.ensureInitialized() + d2Value := new(big.Int).Abs(d.value) + return Decimal{ + value: d2Value, + exp: d.exp, + } +} + +// Add returns d + d2. +func (d Decimal) Add(d2 Decimal) Decimal { + rd, rd2 := RescalePair(d, d2) + + d3Value := new(big.Int).Add(rd.value, rd2.value) + return Decimal{ + value: d3Value, + exp: rd.exp, + } +} + +// Sub returns d - d2. +func (d Decimal) Sub(d2 Decimal) Decimal { + rd, rd2 := RescalePair(d, d2) + + d3Value := new(big.Int).Sub(rd.value, rd2.value) + return Decimal{ + value: d3Value, + exp: rd.exp, + } +} + +// Neg returns -d. +func (d Decimal) Neg() Decimal { + d.ensureInitialized() + val := new(big.Int).Neg(d.value) + return Decimal{ + value: val, + exp: d.exp, + } +} + +// Mul returns d * d2. +func (d Decimal) Mul(d2 Decimal) Decimal { + d.ensureInitialized() + d2.ensureInitialized() + + expInt64 := int64(d.exp) + int64(d2.exp) + if expInt64 > math.MaxInt32 || expInt64 < math.MinInt32 { + // NOTE(vadim): better to panic than give incorrect results, as + // Decimals are usually used for money + panic(fmt.Sprintf("exponent %v overflows an int32!", expInt64)) + } + + d3Value := new(big.Int).Mul(d.value, d2.value) + return Decimal{ + value: d3Value, + exp: int32(expInt64), + } +} + +// Shift shifts the decimal in base 10. +// It shifts left when shift is positive and right if shift is negative. +// In simpler terms, the given value for shift is added to the exponent +// of the decimal. +func (d Decimal) Shift(shift int32) Decimal { + d.ensureInitialized() + return Decimal{ + value: new(big.Int).Set(d.value), + exp: d.exp + shift, + } +} + +// Div returns d / d2. If it doesn't divide exactly, the result will have +// DivisionPrecision digits after the decimal point. +func (d Decimal) Div(d2 Decimal) Decimal { + return d.DivRound(d2, int32(DivisionPrecision)) +} + +// QuoRem does divsion with remainder +// d.QuoRem(d2,precision) returns quotient q and remainder r such that +// d = d2 * q + r, q an integer multiple of 10^(-precision) +// 0 <= r < abs(d2) * 10 ^(-precision) if d>=0 +// 0 >= r > -abs(d2) * 10 ^(-precision) if d<0 +// Note that precision<0 is allowed as input. +func (d Decimal) QuoRem(d2 Decimal, precision int32) (Decimal, Decimal) { + d.ensureInitialized() + d2.ensureInitialized() + if d2.value.Sign() == 0 { + panic("decimal division by 0") + } + scale := -precision + e := int64(d.exp - d2.exp - scale) + if e > math.MaxInt32 || e < math.MinInt32 { + panic("overflow in decimal QuoRem") + } + var aa, bb, expo big.Int + var scalerest int32 + // d = a 10^ea + // d2 = b 10^eb + if e < 0 { + aa = *d.value + expo.SetInt64(-e) + bb.Exp(tenInt, &expo, nil) + bb.Mul(d2.value, &bb) + scalerest = d.exp + // now aa = a + // bb = b 10^(scale + eb - ea) + } else { + expo.SetInt64(e) + aa.Exp(tenInt, &expo, nil) + aa.Mul(d.value, &aa) + bb = *d2.value + scalerest = scale + d2.exp + // now aa = a ^ (ea - eb - scale) + // bb = b + } + var q, r big.Int + q.QuoRem(&aa, &bb, &r) + dq := Decimal{value: &q, exp: scale} + dr := Decimal{value: &r, exp: scalerest} + return dq, dr +} + +// DivRound divides and rounds to a given precision +// i.e. to an integer multiple of 10^(-precision) +// for a positive quotient digit 5 is rounded up, away from 0 +// if the quotient is negative then digit 5 is rounded down, away from 0 +// Note that precision<0 is allowed as input. +func (d Decimal) DivRound(d2 Decimal, precision int32) Decimal { + // QuoRem already checks initialization + q, r := d.QuoRem(d2, precision) + // the actual rounding decision is based on comparing r*10^precision and d2/2 + // instead compare 2 r 10 ^precision and d2 + var rv2 big.Int + rv2.Abs(r.value) + rv2.Lsh(&rv2, 1) + // now rv2 = abs(r.value) * 2 + r2 := Decimal{value: &rv2, exp: r.exp + precision} + // r2 is now 2 * r * 10 ^ precision + var c = r2.Cmp(d2.Abs()) + + if c < 0 { + return q + } + + if d.value.Sign()*d2.value.Sign() < 0 { + return q.Sub(New(1, -precision)) + } + + return q.Add(New(1, -precision)) +} + +// Mod returns d % d2. +func (d Decimal) Mod(d2 Decimal) Decimal { + quo := d.Div(d2).Truncate(0) + return d.Sub(d2.Mul(quo)) +} + +// Pow returns d to the power d2 +func (d Decimal) Pow(d2 Decimal) Decimal { + var temp Decimal + if d2.IntPart() == 0 { + return NewFromFloat(1) + } + temp = d.Pow(d2.Div(NewFromFloat(2))) + if d2.IntPart()%2 == 0 { + return temp.Mul(temp) + } + if d2.IntPart() > 0 { + return temp.Mul(temp).Mul(d) + } + return temp.Mul(temp).Div(d) +} + +// Cmp compares the numbers represented by d and d2 and returns: +// +// -1 if d < d2 +// 0 if d == d2 +// +1 if d > d2 +// +func (d Decimal) Cmp(d2 Decimal) int { + d.ensureInitialized() + d2.ensureInitialized() + + if d.exp == d2.exp { + return d.value.Cmp(d2.value) + } + + rd, rd2 := RescalePair(d, d2) + + return rd.value.Cmp(rd2.value) +} + +// Equal returns whether the numbers represented by d and d2 are equal. +func (d Decimal) Equal(d2 Decimal) bool { + return d.Cmp(d2) == 0 +} + +// Equals is deprecated, please use Equal method instead +func (d Decimal) Equals(d2 Decimal) bool { + return d.Equal(d2) +} + +// GreaterThan (GT) returns true when d is greater than d2. +func (d Decimal) GreaterThan(d2 Decimal) bool { + return d.Cmp(d2) == 1 +} + +// GreaterThanOrEqual (GTE) returns true when d is greater than or equal to d2. +func (d Decimal) GreaterThanOrEqual(d2 Decimal) bool { + cmp := d.Cmp(d2) + return cmp == 1 || cmp == 0 +} + +// LessThan (LT) returns true when d is less than d2. +func (d Decimal) LessThan(d2 Decimal) bool { + return d.Cmp(d2) == -1 +} + +// LessThanOrEqual (LTE) returns true when d is less than or equal to d2. +func (d Decimal) LessThanOrEqual(d2 Decimal) bool { + cmp := d.Cmp(d2) + return cmp == -1 || cmp == 0 +} + +// Sign returns: +// +// -1 if d < 0 +// 0 if d == 0 +// +1 if d > 0 +// +func (d Decimal) Sign() int { + if d.value == nil { + return 0 + } + return d.value.Sign() +} + +// IsPositive return +// +// true if d > 0 +// false if d == 0 +// false if d < 0 +func (d Decimal) IsPositive() bool { + return d.Sign() == 1 +} + +// IsNegative return +// +// true if d < 0 +// false if d == 0 +// false if d > 0 +func (d Decimal) IsNegative() bool { + return d.Sign() == -1 +} + +// IsZero return +// +// true if d == 0 +// false if d > 0 +// false if d < 0 +func (d Decimal) IsZero() bool { + return d.Sign() == 0 +} + +// Exponent returns the exponent, or scale component of the decimal. +func (d Decimal) Exponent() int32 { + return d.exp +} + +// Coefficient returns the coefficient of the decimal. It is scaled by 10^Exponent() +func (d Decimal) Coefficient() *big.Int { + d.ensureInitialized() + // we copy the coefficient so that mutating the result does not mutate the + // Decimal. + return big.NewInt(0).Set(d.value) +} + +// IntPart returns the integer component of the decimal. +func (d Decimal) IntPart() int64 { + scaledD := d.rescale(0) + return scaledD.value.Int64() +} + +// BigInt returns integer component of the decimal as a BigInt. +func (d Decimal) BigInt() *big.Int { + scaledD := d.rescale(0) + i := &big.Int{} + i.SetString(scaledD.String(), 10) + return i +} + +// BigFloat returns decimal as BigFloat. +// Be aware that casting decimal to BigFloat might cause a loss of precision. +func (d Decimal) BigFloat() *big.Float { + f := &big.Float{} + f.SetString(d.String()) + return f +} + +// Rat returns a rational number representation of the decimal. +func (d Decimal) Rat() *big.Rat { + d.ensureInitialized() + if d.exp <= 0 { + // NOTE(vadim): must negate after casting to prevent int32 overflow + denom := new(big.Int).Exp(tenInt, big.NewInt(-int64(d.exp)), nil) + return new(big.Rat).SetFrac(d.value, denom) + } + + mul := new(big.Int).Exp(tenInt, big.NewInt(int64(d.exp)), nil) + num := new(big.Int).Mul(d.value, mul) + return new(big.Rat).SetFrac(num, oneInt) +} + +// Float64 returns the nearest float64 value for d and a bool indicating +// whether f represents d exactly. +// For more details, see the documentation for big.Rat.Float64 +func (d Decimal) Float64() (f float64, exact bool) { + return d.Rat().Float64() +} + +// String returns the string representation of the decimal +// with the fixed point. +// +// Example: +// +// d := New(-12345, -3) +// println(d.String()) +// +// Output: +// +// -12.345 +// +func (d Decimal) String() string { + return d.string(true) +} + +// StringFixed returns a rounded fixed-point string with places digits after +// the decimal point. +// +// Example: +// +// NewFromFloat(0).StringFixed(2) // output: "0.00" +// NewFromFloat(0).StringFixed(0) // output: "0" +// NewFromFloat(5.45).StringFixed(0) // output: "5" +// NewFromFloat(5.45).StringFixed(1) // output: "5.5" +// NewFromFloat(5.45).StringFixed(2) // output: "5.45" +// NewFromFloat(5.45).StringFixed(3) // output: "5.450" +// NewFromFloat(545).StringFixed(-1) // output: "550" +// +func (d Decimal) StringFixed(places int32) string { + rounded := d.Round(places) + return rounded.string(false) +} + +// StringFixedBank returns a banker rounded fixed-point string with places digits +// after the decimal point. +// +// Example: +// +// NewFromFloat(0).StringFixedBank(2) // output: "0.00" +// NewFromFloat(0).StringFixedBank(0) // output: "0" +// NewFromFloat(5.45).StringFixedBank(0) // output: "5" +// NewFromFloat(5.45).StringFixedBank(1) // output: "5.4" +// NewFromFloat(5.45).StringFixedBank(2) // output: "5.45" +// NewFromFloat(5.45).StringFixedBank(3) // output: "5.450" +// NewFromFloat(545).StringFixedBank(-1) // output: "540" +// +func (d Decimal) StringFixedBank(places int32) string { + rounded := d.RoundBank(places) + return rounded.string(false) +} + +// StringFixedCash returns a Swedish/Cash rounded fixed-point string. For +// more details see the documentation at function RoundCash. +func (d Decimal) StringFixedCash(interval uint8) string { + rounded := d.RoundCash(interval) + return rounded.string(false) +} + +// Round rounds the decimal to places decimal places. +// If places < 0, it will round the integer part to the nearest 10^(-places). +// +// Example: +// +// NewFromFloat(5.45).Round(1).String() // output: "5.5" +// NewFromFloat(545).Round(-1).String() // output: "550" +// +func (d Decimal) Round(places int32) Decimal { + // truncate to places + 1 + ret := d.rescale(-places - 1) + + // add sign(d) * 0.5 + if ret.value.Sign() < 0 { + ret.value.Sub(ret.value, fiveInt) + } else { + ret.value.Add(ret.value, fiveInt) + } + + // floor for positive numbers, ceil for negative numbers + _, m := ret.value.DivMod(ret.value, tenInt, new(big.Int)) + ret.exp++ + if ret.value.Sign() < 0 && m.Cmp(zeroInt) != 0 { + ret.value.Add(ret.value, oneInt) + } + + return ret +} + +// RoundBank rounds the decimal to places decimal places. +// If the final digit to round is equidistant from the nearest two integers the +// rounded value is taken as the even number +// +// If places < 0, it will round the integer part to the nearest 10^(-places). +// +// Examples: +// +// NewFromFloat(5.45).Round(1).String() // output: "5.4" +// NewFromFloat(545).Round(-1).String() // output: "540" +// NewFromFloat(5.46).Round(1).String() // output: "5.5" +// NewFromFloat(546).Round(-1).String() // output: "550" +// NewFromFloat(5.55).Round(1).String() // output: "5.6" +// NewFromFloat(555).Round(-1).String() // output: "560" +// +func (d Decimal) RoundBank(places int32) Decimal { + + round := d.Round(places) + remainder := d.Sub(round).Abs() + + half := New(5, -places-1) + if remainder.Cmp(half) == 0 && round.value.Bit(0) != 0 { + if round.value.Sign() < 0 { + round.value.Add(round.value, oneInt) + } else { + round.value.Sub(round.value, oneInt) + } + } + + return round +} + +// RoundCash aka Cash/Penny/öre rounding rounds decimal to a specific +// interval. The amount payable for a cash transaction is rounded to the nearest +// multiple of the minimum currency unit available. The following intervals are +// available: 5, 10, 25, 50 and 100; any other number throws a panic. +// 5: 5 cent rounding 3.43 => 3.45 +// 10: 10 cent rounding 3.45 => 3.50 (5 gets rounded up) +// 25: 25 cent rounding 3.41 => 3.50 +// 50: 50 cent rounding 3.75 => 4.00 +// 100: 100 cent rounding 3.50 => 4.00 +// For more details: https://en.wikipedia.org/wiki/Cash_rounding +func (d Decimal) RoundCash(interval uint8) Decimal { + var iVal *big.Int + switch interval { + case 5: + iVal = twentyInt + case 10: + iVal = tenInt + case 25: + iVal = fourInt + case 50: + iVal = twoInt + case 100: + iVal = oneInt + default: + panic(fmt.Sprintf("Decimal does not support this Cash rounding interval `%d`. Supported: 5, 10, 25, 50, 100", interval)) + } + dVal := Decimal{ + value: iVal, + } + + // TODO: optimize those calculations to reduce the high allocations (~29 allocs). + return d.Mul(dVal).Round(0).Div(dVal).Truncate(2) +} + +// Floor returns the nearest integer value less than or equal to d. +func (d Decimal) Floor() Decimal { + d.ensureInitialized() + + if d.exp >= 0 { + return d + } + + exp := big.NewInt(10) + + // NOTE(vadim): must negate after casting to prevent int32 overflow + exp.Exp(exp, big.NewInt(-int64(d.exp)), nil) + + z := new(big.Int).Div(d.value, exp) + return Decimal{value: z, exp: 0} +} + +// Ceil returns the nearest integer value greater than or equal to d. +func (d Decimal) Ceil() Decimal { + d.ensureInitialized() + + if d.exp >= 0 { + return d + } + + exp := big.NewInt(10) + + // NOTE(vadim): must negate after casting to prevent int32 overflow + exp.Exp(exp, big.NewInt(-int64(d.exp)), nil) + + z, m := new(big.Int).DivMod(d.value, exp, new(big.Int)) + if m.Cmp(zeroInt) != 0 { + z.Add(z, oneInt) + } + return Decimal{value: z, exp: 0} +} + +// Truncate truncates off digits from the number, without rounding. +// +// NOTE: precision is the last digit that will not be truncated (must be >= 0). +// +// Example: +// +// decimal.NewFromString("123.456").Truncate(2).String() // "123.45" +// +func (d Decimal) Truncate(precision int32) Decimal { + d.ensureInitialized() + if precision >= 0 && -precision > d.exp { + return d.rescale(-precision) + } + return d +} + +// UnmarshalJSON implements the json.Unmarshaler interfaceDemo. +func (d *Decimal) UnmarshalJSON(decimalBytes []byte) error { + if string(decimalBytes) == "null" { + return nil + } + + str, err := unquoteIfQuoted(decimalBytes) + if err != nil { + return fmt.Errorf("error decoding string '%s': %s", decimalBytes, err) + } + + decimal, err := NewFromString(str) + *d = decimal + if err != nil { + return fmt.Errorf("error decoding string '%s': %s", str, err) + } + return nil +} + +// MarshalJSON implements the json.Marshaler interfaceDemo. +func (d Decimal) MarshalJSON() ([]byte, error) { + var str string + if MarshalJSONWithoutQuotes { + str = d.String() + } else { + str = "\"" + d.String() + "\"" + } + return []byte(str), nil +} + +// UnmarshalBinary implements the encoding.BinaryUnmarshaler interfaceDemo. As a string representation +// is already used when encoding to text, this method stores that string as []byte +func (d *Decimal) UnmarshalBinary(data []byte) error { + // Extract the exponent + d.exp = int32(binary.BigEndian.Uint32(data[:4])) + + // Extract the value + d.value = new(big.Int) + return d.value.GobDecode(data[4:]) +} + +// MarshalBinary implements the encoding.BinaryMarshaler interfaceDemo. +func (d Decimal) MarshalBinary() (data []byte, err error) { + // Write the exponent first since it's a fixed size + v1 := make([]byte, 4) + binary.BigEndian.PutUint32(v1, uint32(d.exp)) + + // Add the value + var v2 []byte + if v2, err = d.value.GobEncode(); err != nil { + return + } + + // Return the byte array + data = append(v1, v2...) + return +} + +// Scan implements the sql.Scanner interfaceDemo for database deserialization. +func (d *Decimal) Scan(value interface{}) error { + // first try to see if the data is stored in database as a Numeric datatype + switch v := value.(type) { + + case float32: + *d = NewFromFloat(float64(v)) + return nil + + case float64: + // numeric in sqlite3 sends us float64 + *d = NewFromFloat(v) + return nil + + case int64: + // at least in sqlite3 when the value is 0 in db, the data is sent + // to us as an int64 instead of a float64 ... + *d = New(v, 0) + return nil + + default: + // default is trying to interpret value stored as string + str, err := unquoteIfQuoted(v) + if err != nil { + return err + } + *d, err = NewFromString(str) + return err + } +} + +// Value implements the driver.Valuer interfaceDemo for database serialization. +func (d Decimal) Value() (driver.Value, error) { + return d.String(), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interfaceDemo for XML +// deserialization. +func (d *Decimal) UnmarshalText(text []byte) error { + str := string(text) + + dec, err := NewFromString(str) + *d = dec + if err != nil { + return fmt.Errorf("error decoding string '%s': %s", str, err) + } + + return nil +} + +// MarshalText implements the encoding.TextMarshaler interfaceDemo for XML +// serialization. +func (d Decimal) MarshalText() (text []byte, err error) { + return []byte(d.String()), nil +} + +// GobEncode implements the gob.GobEncoder interfaceDemo for gob serialization. +func (d Decimal) GobEncode() ([]byte, error) { + return d.MarshalBinary() +} + +// GobDecode implements the gob.GobDecoder interfaceDemo for gob serialization. +func (d *Decimal) GobDecode(data []byte) error { + return d.UnmarshalBinary(data) +} + +// StringScaled first scales the decimal then calls .String() on it. +// NOTE: buggy, unintuitive, and DEPRECATED! Use StringFixed instead. +func (d Decimal) StringScaled(exp int32) string { + return d.rescale(exp).String() +} + +func (d Decimal) string(trimTrailingZeros bool) string { + if d.exp >= 0 { + return d.rescale(0).value.String() + } + + abs := new(big.Int).Abs(d.value) + str := abs.String() + + var intPart, fractionalPart string + + // NOTE(vadim): this cast to int will cause bugs if d.exp == INT_MIN + // and you are on a 32-bit machine. Won't fix this super-edge case. + dExpInt := int(d.exp) + if len(str) > -dExpInt { + intPart = str[:len(str)+dExpInt] + fractionalPart = str[len(str)+dExpInt:] + } else { + intPart = "0" + + num0s := -dExpInt - len(str) + fractionalPart = strings.Repeat("0", num0s) + str + } + + if trimTrailingZeros { + i := len(fractionalPart) - 1 + for ; i >= 0; i-- { + if fractionalPart[i] != '0' { + break + } + } + fractionalPart = fractionalPart[:i+1] + } + + number := intPart + if len(fractionalPart) > 0 { + number += "." + fractionalPart + } + + if d.value.Sign() < 0 { + return "-" + number + } + + return number +} + +func (d *Decimal) ensureInitialized() { + if d.value == nil { + d.value = new(big.Int) + } +} + +// Min returns the smallest Decimal that was passed in the arguments. +// +// To call this function with an array, you must do: +// +// Min(arr[0], arr[1:]...) +// +// This makes it harder to accidentally call Min with 0 arguments. +func Min(first Decimal, rest ...Decimal) Decimal { + ans := first + for _, item := range rest { + if item.Cmp(ans) < 0 { + ans = item + } + } + return ans +} + +// Max returns the largest Decimal that was passed in the arguments. +// +// To call this function with an array, you must do: +// +// Max(arr[0], arr[1:]...) +// +// This makes it harder to accidentally call Max with 0 arguments. +func Max(first Decimal, rest ...Decimal) Decimal { + ans := first + for _, item := range rest { + if item.Cmp(ans) > 0 { + ans = item + } + } + return ans +} + +// Sum returns the combined total of the provided first and rest Decimals +func Sum(first Decimal, rest ...Decimal) Decimal { + total := first + for _, item := range rest { + total = total.Add(item) + } + + return total +} + +// Avg returns the average value of the provided first and rest Decimals +func Avg(first Decimal, rest ...Decimal) Decimal { + count := New(int64(len(rest)+1), 0) + sum := Sum(first, rest...) + return sum.Div(count) +} + +// RescalePair rescales two decimals to common exponential value (minimal exp of both decimals) +func RescalePair(d1 Decimal, d2 Decimal) (Decimal, Decimal) { + d1.ensureInitialized() + d2.ensureInitialized() + + if d1.exp == d2.exp { + return d1, d2 + } + + baseScale := min(d1.exp, d2.exp) + if baseScale != d1.exp { + return d1.rescale(baseScale), d2 + } + return d1, d2.rescale(baseScale) +} + +func min(x, y int32) int32 { + if x >= y { + return y + } + return x +} + +func unquoteIfQuoted(value interface{}) (string, error) { + var bytes []byte + + switch v := value.(type) { + case string: + bytes = []byte(v) + case []byte: + bytes = v + default: + return "", fmt.Errorf("could not convert value '%+v' to byte array of type '%T'", + value, value) + } + + // If the amount is quoted, strip the quotes + if len(bytes) > 2 && bytes[0] == '"' && bytes[len(bytes)-1] == '"' { + bytes = bytes[1 : len(bytes)-1] + } + return string(bytes), nil +} + +// NullDecimal represents a nullable decimal with compatibility for +// scanning null values from the database. +type NullDecimal struct { + Decimal Decimal + Valid bool +} + +// Scan implements the sql.Scanner interfaceDemo for database deserialization. +func (d *NullDecimal) Scan(value interface{}) error { + if value == nil { + d.Valid = false + return nil + } + d.Valid = true + return d.Decimal.Scan(value) +} + +// Value implements the driver.Valuer interfaceDemo for database serialization. +func (d NullDecimal) Value() (driver.Value, error) { + if !d.Valid { + return nil, nil + } + return d.Decimal.Value() +} + +// UnmarshalJSON implements the json.Unmarshaler interfaceDemo. +func (d *NullDecimal) UnmarshalJSON(decimalBytes []byte) error { + if string(decimalBytes) == "null" { + d.Valid = false + return nil + } + d.Valid = true + return d.Decimal.UnmarshalJSON(decimalBytes) +} + +// MarshalJSON implements the json.Marshaler interfaceDemo. +func (d NullDecimal) MarshalJSON() ([]byte, error) { + if !d.Valid { + return []byte("null"), nil + } + return d.Decimal.MarshalJSON() +} + +// Trig functions + +// Atan returns the arctangent, in radians, of x. +func (d Decimal) Atan() Decimal { + if d.Equal(NewFromFloat(0.0)) { + return d + } + if d.GreaterThan(NewFromFloat(0.0)) { + return d.satan() + } + return d.Neg().satan().Neg() +} + +func (d Decimal) xatan() Decimal { + P0 := NewFromFloat(-8.750608600031904122785e-01) + P1 := NewFromFloat(-1.615753718733365076637e+01) + P2 := NewFromFloat(-7.500855792314704667340e+01) + P3 := NewFromFloat(-1.228866684490136173410e+02) + P4 := NewFromFloat(-6.485021904942025371773e+01) + Q0 := NewFromFloat(2.485846490142306297962e+01) + Q1 := NewFromFloat(1.650270098316988542046e+02) + Q2 := NewFromFloat(4.328810604912902668951e+02) + Q3 := NewFromFloat(4.853903996359136964868e+02) + Q4 := NewFromFloat(1.945506571482613964425e+02) + z := d.Mul(d) + b1 := P0.Mul(z).Add(P1).Mul(z).Add(P2).Mul(z).Add(P3).Mul(z).Add(P4).Mul(z) + b2 := z.Add(Q0).Mul(z).Add(Q1).Mul(z).Add(Q2).Mul(z).Add(Q3).Mul(z).Add(Q4) + z = b1.Div(b2) + z = d.Mul(z).Add(d) + return z +} + +// satan reduces its argument (known to be positive) +// to the range [0, 0.66] and calls xatan. +func (d Decimal) satan() Decimal { + Morebits := NewFromFloat(6.123233995736765886130e-17) // pi/2 = PIO2 + Morebits + Tan3pio8 := NewFromFloat(2.41421356237309504880) // tan(3*pi/8) + pi := NewFromFloat(3.14159265358979323846264338327950288419716939937510582097494459) + + if d.LessThanOrEqual(NewFromFloat(0.66)) { + return d.xatan() + } + if d.GreaterThan(Tan3pio8) { + return pi.Div(NewFromFloat(2.0)).Sub(NewFromFloat(1.0).Div(d).xatan()).Add(Morebits) + } + return pi.Div(NewFromFloat(4.0)).Add((d.Sub(NewFromFloat(1.0)).Div(d.Add(NewFromFloat(1.0)))).xatan()).Add(NewFromFloat(0.5).Mul(Morebits)) +} + +// sin coefficients +var _sin = [...]Decimal{ + NewFromFloat(1.58962301576546568060e-10), // 0x3de5d8fd1fd19ccd + NewFromFloat(-2.50507477628578072866e-8), // 0xbe5ae5e5a9291f5d + NewFromFloat(2.75573136213857245213e-6), // 0x3ec71de3567d48a1 + NewFromFloat(-1.98412698295895385996e-4), // 0xbf2a01a019bfdf03 + NewFromFloat(8.33333333332211858878e-3), // 0x3f8111111110f7d0 + NewFromFloat(-1.66666666666666307295e-1), // 0xbfc5555555555548 +} + +// Sin returns the sine of the radian argument x. +func (d Decimal) Sin() Decimal { + PI4A := NewFromFloat(7.85398125648498535156e-1) // 0x3fe921fb40000000, Pi/4 split into three parts + PI4B := NewFromFloat(3.77489470793079817668e-8) // 0x3e64442d00000000, + PI4C := NewFromFloat(2.69515142907905952645e-15) // 0x3ce8469898cc5170, + M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi + + if d.Equal(NewFromFloat(0.0)) { + return d + } + // make argument positive but save the sign + sign := false + if d.LessThan(NewFromFloat(0.0)) { + d = d.Neg() + sign = true + } + + j := d.Mul(M4PI).IntPart() // integer part of x/(Pi/4), as integer for tests on the phase angle + y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float + + // map zeros to origin + if j&1 == 1 { + j++ + y = y.Add(NewFromFloat(1.0)) + } + j &= 7 // octant modulo 2Pi radians (360 degrees) + // reflect in x axis + if j > 3 { + sign = !sign + j -= 4 + } + z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic + zz := z.Mul(z) + + if j == 1 || j == 2 { + w := zz.Mul(zz).Mul(_cos[0].Mul(zz).Add(_cos[1]).Mul(zz).Add(_cos[2]).Mul(zz).Add(_cos[3]).Mul(zz).Add(_cos[4]).Mul(zz).Add(_cos[5])) + y = NewFromFloat(1.0).Sub(NewFromFloat(0.5).Mul(zz)).Add(w) + } else { + y = z.Add(z.Mul(zz).Mul(_sin[0].Mul(zz).Add(_sin[1]).Mul(zz).Add(_sin[2]).Mul(zz).Add(_sin[3]).Mul(zz).Add(_sin[4]).Mul(zz).Add(_sin[5]))) + } + if sign { + y = y.Neg() + } + return y +} + +// cos coefficients +var _cos = [...]Decimal{ + NewFromFloat(-1.13585365213876817300e-11), // 0xbda8fa49a0861a9b + NewFromFloat(2.08757008419747316778e-9), // 0x3e21ee9d7b4e3f05 + NewFromFloat(-2.75573141792967388112e-7), // 0xbe927e4f7eac4bc6 + NewFromFloat(2.48015872888517045348e-5), // 0x3efa01a019c844f5 + NewFromFloat(-1.38888888888730564116e-3), // 0xbf56c16c16c14f91 + NewFromFloat(4.16666666666665929218e-2), // 0x3fa555555555554b +} + +// Cos returns the cosine of the radian argument x. +func (d Decimal) Cos() Decimal { + + PI4A := NewFromFloat(7.85398125648498535156e-1) // 0x3fe921fb40000000, Pi/4 split into three parts + PI4B := NewFromFloat(3.77489470793079817668e-8) // 0x3e64442d00000000, + PI4C := NewFromFloat(2.69515142907905952645e-15) // 0x3ce8469898cc5170, + M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi + + // make argument positive + sign := false + if d.LessThan(NewFromFloat(0.0)) { + d = d.Neg() + } + + j := d.Mul(M4PI).IntPart() // integer part of x/(Pi/4), as integer for tests on the phase angle + y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float + + // map zeros to origin + if j&1 == 1 { + j++ + y = y.Add(NewFromFloat(1.0)) + } + j &= 7 // octant modulo 2Pi radians (360 degrees) + // reflect in x axis + if j > 3 { + sign = !sign + j -= 4 + } + if j > 1 { + sign = !sign + } + + z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic + zz := z.Mul(z) + + if j == 1 || j == 2 { + y = z.Add(z.Mul(zz).Mul(_sin[0].Mul(zz).Add(_sin[1]).Mul(zz).Add(_sin[2]).Mul(zz).Add(_sin[3]).Mul(zz).Add(_sin[4]).Mul(zz).Add(_sin[5]))) + } else { + w := zz.Mul(zz).Mul(_cos[0].Mul(zz).Add(_cos[1]).Mul(zz).Add(_cos[2]).Mul(zz).Add(_cos[3]).Mul(zz).Add(_cos[4]).Mul(zz).Add(_cos[5])) + y = NewFromFloat(1.0).Sub(NewFromFloat(0.5).Mul(zz)).Add(w) + } + if sign { + y = y.Neg() + } + return y +} + +var _tanP = [...]Decimal{ + NewFromFloat(-1.30936939181383777646e+4), // 0xc0c992d8d24f3f38 + NewFromFloat(1.15351664838587416140e+6), // 0x413199eca5fc9ddd + NewFromFloat(-1.79565251976484877988e+7), // 0xc1711fead3299176 +} +var _tanQ = [...]Decimal{ + NewFromFloat(1.00000000000000000000e+0), + NewFromFloat(1.36812963470692954678e+4), //0x40cab8a5eeb36572 + NewFromFloat(-1.32089234440210967447e+6), //0xc13427bc582abc96 + NewFromFloat(2.50083801823357915839e+7), //0x4177d98fc2ead8ef + NewFromFloat(-5.38695755929454629881e+7), //0xc189afe03cbe5a31 +} + +// Tan returns the tangent of the radian argument x. +func (d Decimal) Tan() Decimal { + + PI4A := NewFromFloat(7.85398125648498535156e-1) // 0x3fe921fb40000000, Pi/4 split into three parts + PI4B := NewFromFloat(3.77489470793079817668e-8) // 0x3e64442d00000000, + PI4C := NewFromFloat(2.69515142907905952645e-15) // 0x3ce8469898cc5170, + M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi + + if d.Equal(NewFromFloat(0.0)) { + return d + } + + // make argument positive but save the sign + sign := false + if d.LessThan(NewFromFloat(0.0)) { + d = d.Neg() + sign = true + } + + j := d.Mul(M4PI).IntPart() // integer part of x/(Pi/4), as integer for tests on the phase angle + y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float + + // map zeros to origin + if j&1 == 1 { + j++ + y = y.Add(NewFromFloat(1.0)) + } + + z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic + zz := z.Mul(z) + + if zz.GreaterThan(NewFromFloat(1e-14)) { + w := zz.Mul(_tanP[0].Mul(zz).Add(_tanP[1]).Mul(zz).Add(_tanP[2])) + x := zz.Add(_tanQ[1]).Mul(zz).Add(_tanQ[2]).Mul(zz).Add(_tanQ[3]).Mul(zz).Add(_tanQ[4]) + y = z.Add(z.Mul(w.Div(x))) + } else { + y = z + } + if j&2 == 2 { + y = NewFromFloat(-1.0).Div(y) + } + if sign { + y = y.Neg() + } + return y +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/go.mod" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/go.mod" new file mode 100644 index 0000000000000000000000000000000000000000..ae1b7aa3c70587b4f1384ad2bb15bcbd9581d39c --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/go.mod" @@ -0,0 +1,3 @@ +module github.com/shopspring/decimal + +go 1.13 diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/rounding.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/rounding.go" new file mode 100644 index 0000000000000000000000000000000000000000..8008f55cb98012b60577ce848722b4d763c209a0 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/shopspring/decimal/rounding.go" @@ -0,0 +1,119 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Multiprecision decimal numbers. +// For floating-point formatting only; not general purpose. +// Only operations are assign and (binary) left/right shift. +// Can do binary floating point in multiprecision decimal precisely +// because 2 divides 10; cannot do decimal floating point +// in multiprecision binary precisely. + +package decimal + +type floatInfo struct { + mantbits uint + expbits uint + bias int +} + +var float32info = floatInfo{23, 8, -127} +var float64info = floatInfo{52, 11, -1023} + +// roundShortest rounds d (= mant * 2^exp) to the shortest number of digits +// that will let the original floating point value be precisely reconstructed. +func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) { + // If mantissa is zero, the number is zero; stop now. + if mant == 0 { + d.nd = 0 + return + } + + // Compute upper and lower such that any decimal number + // between upper and lower (possibly inclusive) + // will round to the original floating point number. + + // We may see at once that the number is already shortest. + // + // Suppose d is not denormal, so that 2^exp <= d < 10^dp. + // The closest shorter number is at least 10^(dp-nd) away. + // The lower/upper bounds computed below are at distance + // at most 2^(exp-mantbits). + // + // So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits), + // or equivalently log2(10)*(dp-nd) > exp-mantbits. + // It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32). + minexp := flt.bias + 1 // minimum possible exponent + if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) { + // The number is already shortest. + return + } + + // d = mant << (exp - mantbits) + // Next highest floating point number is mant+1 << exp-mantbits. + // Our upper bound is halfway between, mant*2+1 << exp-mantbits-1. + upper := new(decimal) + upper.Assign(mant*2 + 1) + upper.Shift(exp - int(flt.mantbits) - 1) + + // d = mant << (exp - mantbits) + // Next lowest floating point number is mant-1 << exp-mantbits, + // unless mant-1 drops the significant bit and exp is not the minimum exp, + // in which case the next lowest is mant*2-1 << exp-mantbits-1. + // Either way, call it mantlo << explo-mantbits. + // Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1. + var mantlo uint64 + var explo int + if mant > 1< +GJSON +
+Build Status +GoDoc +GJSON Playground +

+ + + +

get json values quickly

+ +GJSON is a Go package that provides a [fast](#performance) and [simple](#get-a-value) way to get values from a json document. +It has features such as [one line retrieval](#get-a-value), [dot notation paths](#path-syntax), [iteration](#iterate-through-an-object-or-array), and [parsing json lines](#json-lines). + +Also check out [SJSON](https://github.com/tidwall/sjson) for modifying json, and the [JJ](https://github.com/tidwall/jj) command line tool. + +Getting Started +=============== + +## Installing + +To start using GJSON, install Go and run `go get`: + +```sh +$ go get -u github.com/tidwall/gjson +``` + +This will retrieve the library. + +## Get a value +Get searches json for the specified path. A path is in dot syntax, such as "name.last" or "age". When the value is found it's returned immediately. + +```go +package main + +import "github.com/tidwall/gjson" + +const json = `{"name":{"first":"Janet","last":"Prichard"},"age":47}` + +func main() { + value := gjson.Get(json, "name.last") + println(value.String()) +} +``` + +This will print: + +``` +Prichard +``` +*There's also the [GetMany](#get-multiple-values-at-once) function to get multiple values at once, and [GetBytes](#working-with-bytes) for working with JSON byte slices.* + +## Path Syntax + +Below is a quick overview of the path syntax, for more complete information please +check out [GJSON Syntax](SYNTAX.md). + +A path is a series of keys separated by a dot. +A key may contain special wildcard characters '\*' and '?'. +To access an array value use the index as the key. +To get the number of elements in an array or to access a child path, use the '#' character. +The dot and wildcard characters can be escaped with '\\'. + +```json +{ + "name": {"first": "Tom", "last": "Anderson"}, + "age":37, + "children": ["Sara","Alex","Jack"], + "fav.movie": "Deer Hunter", + "friends": [ + {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]}, + {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]}, + {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]} + ] +} +``` +``` +"name.last" >> "Anderson" +"age" >> 37 +"children" >> ["Sara","Alex","Jack"] +"children.#" >> 3 +"children.1" >> "Alex" +"child*.2" >> "Jack" +"c?ildren.0" >> "Sara" +"fav\.movie" >> "Deer Hunter" +"friends.#.first" >> ["Dale","Roger","Jane"] +"friends.1.last" >> "Craig" +``` + +You can also query an array for the first match by using `#(...)`, or find all +matches with `#(...)#`. Queries support the `==`, `!=`, `<`, `<=`, `>`, `>=` +comparison operators and the simple pattern matching `%` (like) and `!%` +(not like) operators. + +``` +friends.#(last=="Murphy").first >> "Dale" +friends.#(last=="Murphy")#.first >> ["Dale","Jane"] +friends.#(age>45)#.last >> ["Craig","Murphy"] +friends.#(first%"D*").last >> "Murphy" +friends.#(first!%"D*").last >> "Craig" +friends.#(nets.#(=="fb"))#.first >> ["Dale","Roger"] +``` + +*Please note that prior to v1.3.0, queries used the `#[...]` brackets. This was +changed in v1.3.0 as to avoid confusion with the new +[multipath](SYNTAX.md#multipaths) syntax. For backwards compatibility, +`#[...]` will continue to work until the next major release.* + +## Result Type + +GJSON supports the json types `string`, `number`, `bool`, and `null`. +Arrays and Objects are returned as their raw json types. + +The `Result` type holds one of these: + +``` +bool, for JSON booleans +float64, for JSON numbers +string, for JSON string literals +nil, for JSON null +``` + +To directly access the value: + +```go +result.Type // can be String, Number, True, False, Null, or JSON +result.Str // holds the string +result.Num // holds the float64 number +result.Raw // holds the raw json +result.Index // index of raw value in original json, zero means index unknown +``` + +There are a variety of handy functions that work on a result: + +```go +result.Exists() bool +result.Value() interface{} +result.Int() int64 +result.Uint() uint64 +result.Float() float64 +result.String() string +result.Bool() bool +result.Time() time.Time +result.Array() []gjson.Result +result.Map() map[string]gjson.Result +result.Get(path string) Result +result.ForEach(iterator func(key, value Result) bool) +result.Less(token Result, caseSensitive bool) bool +``` + +The `result.Value()` function returns an `interface{}` which requires type assertion and is one of the following Go types: + +The `result.Array()` function returns back an array of values. +If the result represents a non-existent value, then an empty array will be returned. +If the result is not a JSON array, the return value will be an array containing one result. + +```go +boolean >> bool +number >> float64 +string >> string +null >> nil +array >> []interface{} +object >> map[string]interface{} +``` + +### 64-bit integers + +The `result.Int()` and `result.Uint()` calls are capable of reading all 64 bits, allowing for large JSON integers. + +```go +result.Int() int64 // -9223372036854775808 to 9223372036854775807 +result.Uint() int64 // 0 to 18446744073709551615 +``` + +## Modifiers and path chaining + +New in version 1.2 is support for modifier functions and path chaining. + +A modifier is a path component that performs custom processing on the +json. + +Multiple paths can be "chained" together using the pipe character. +This is useful for getting results from a modified query. + +For example, using the built-in `@reverse` modifier on the above json document, +we'll get `children` array and reverse the order: + +``` +"children|@reverse" >> ["Jack","Alex","Sara"] +"children|@reverse|0" >> "Jack" +``` + +There are currently the following built-in modifiers: + +- `@reverse`: Reverse an array or the members of an object. +- `@ugly`: Remove all whitespace from a json document. +- `@pretty`: Make the json document more human readable. +- `@this`: Returns the current element. It can be used to retrieve the root element. +- `@valid`: Ensure the json document is valid. +- `@flatten`: Flattens an array. +- `@join`: Joins multiple objects into a single object. + +### Modifier arguments + +A modifier may accept an optional argument. The argument can be a valid JSON +document or just characters. + +For example, the `@pretty` modifier takes a json object as its argument. + +``` +@pretty:{"sortKeys":true} +``` + +Which makes the json pretty and orders all of its keys. + +```json +{ + "age":37, + "children": ["Sara","Alex","Jack"], + "fav.movie": "Deer Hunter", + "friends": [ + {"age": 44, "first": "Dale", "last": "Murphy"}, + {"age": 68, "first": "Roger", "last": "Craig"}, + {"age": 47, "first": "Jane", "last": "Murphy"} + ], + "name": {"first": "Tom", "last": "Anderson"} +} +``` + +*The full list of `@pretty` options are `sortKeys`, `indent`, `prefix`, and `width`. +Please see [Pretty Options](https://github.com/tidwall/pretty#customized-output) for more information.* + +### Custom modifiers + +You can also add custom modifiers. + +For example, here we create a modifier that makes the entire json document upper +or lower case. + +```go +gjson.AddModifier("case", func(json, arg string) string { + if arg == "upper" { + return strings.ToUpper(json) + } + if arg == "lower" { + return strings.ToLower(json) + } + return json +}) +``` + +``` +"children|@case:upper" >> ["SARA","ALEX","JACK"] +"children|@case:lower|@reverse" >> ["jack","alex","sara"] +``` + +## JSON Lines + +There's support for [JSON Lines](http://jsonlines.org/) using the `..` prefix, which treats a multilined document as an array. + +For example: + +``` +{"name": "Gilbert", "age": 61} +{"name": "Alexa", "age": 34} +{"name": "May", "age": 57} +{"name": "Deloise", "age": 44} +``` + +``` +..# >> 4 +..1 >> {"name": "Alexa", "age": 34} +..3 >> {"name": "Deloise", "age": 44} +..#.name >> ["Gilbert","Alexa","May","Deloise"] +..#(name="May").age >> 57 +``` + +The `ForEachLines` function will iterate through JSON lines. + +```go +gjson.ForEachLine(json, func(line gjson.Result) bool{ + println(line.String()) + return true +}) +``` + +## Get nested array values + +Suppose you want all the last names from the following json: + +```json +{ + "programmers": [ + { + "firstName": "Janet", + "lastName": "McLaughlin", + }, { + "firstName": "Elliotte", + "lastName": "Hunter", + }, { + "firstName": "Jason", + "lastName": "Harold", + } + ] +} +``` + +You would use the path "programmers.#.lastName" like such: + +```go +result := gjson.Get(json, "programmers.#.lastName") +for _, name := range result.Array() { + println(name.String()) +} +``` + +You can also query an object inside an array: + +```go +name := gjson.Get(json, `programmers.#(lastName="Hunter").firstName`) +println(name.String()) // prints "Elliotte" +``` + +## Iterate through an object or array + +The `ForEach` function allows for quickly iterating through an object or array. +The key and value are passed to the iterator function for objects. +Only the value is passed for arrays. +Returning `false` from an iterator will stop iteration. + +```go +result := gjson.Get(json, "programmers") +result.ForEach(func(key, value gjson.Result) bool { + println(value.String()) + return true // keep iterating +}) +``` + +## Simple Parse and Get + +There's a `Parse(json)` function that will do a simple parse, and `result.Get(path)` that will search a result. + +For example, all of these will return the same result: + +```go +gjson.Parse(json).Get("name").Get("last") +gjson.Get(json, "name").Get("last") +gjson.Get(json, "name.last") +``` + +## Check for the existence of a value + +Sometimes you just want to know if a value exists. + +```go +value := gjson.Get(json, "name.last") +if !value.Exists() { + println("no last name") +} else { + println(value.String()) +} + +// Or as one step +if gjson.Get(json, "name.last").Exists() { + println("has a last name") +} +``` + +## Validate JSON + +The `Get*` and `Parse*` functions expects that the json is well-formed. Bad json will not panic, but it may return back unexpected results. + +If you are consuming JSON from an unpredictable source then you may want to validate prior to using GJSON. + +```go +if !gjson.Valid(json) { + return errors.New("invalid json") +} +value := gjson.Get(json, "name.last") +``` + +## Unmarshal to a map + +To unmarshal to a `map[string]interface{}`: + +```go +m, ok := gjson.Parse(json).Value().(map[string]interface{}) +if !ok { + // not a map +} +``` + +## Working with Bytes + +If your JSON is contained in a `[]byte` slice, there's the [GetBytes](https://godoc.org/github.com/tidwall/gjson#GetBytes) function. This is preferred over `Get(string(data), path)`. + +```go +var json []byte = ... +result := gjson.GetBytes(json, path) +``` + +If you are using the `gjson.GetBytes(json, path)` function and you want to avoid converting `result.Raw` to a `[]byte`, then you can use this pattern: + +```go +var json []byte = ... +result := gjson.GetBytes(json, path) +var raw []byte +if result.Index > 0 { + raw = json[result.Index:result.Index+len(result.Raw)] +} else { + raw = []byte(result.Raw) +} +``` + +This is a best-effort no allocation sub slice of the original json. This method utilizes the `result.Index` field, which is the position of the raw data in the original json. It's possible that the value of `result.Index` equals zero, in which case the `result.Raw` is converted to a `[]byte`. + +## Get multiple values at once + +The `GetMany` function can be used to get multiple values at the same time. + +```go +results := gjson.GetMany(json, "name.first", "name.last", "age") +``` + +The return value is a `[]Result`, which will always contain exactly the same number of items as the input paths. + +## Performance + +Benchmarks of GJSON alongside [encoding/json](https://golang.org/pkg/encoding/json/), +[ffjson](https://github.com/pquerna/ffjson), +[EasyJSON](https://github.com/mailru/easyjson), +[jsonparser](https://github.com/buger/jsonparser), +and [json-iterator](https://github.com/json-iterator/go) + +``` +BenchmarkGJSONGet-8 3000000 372 ns/op 0 B/op 0 allocs/op +BenchmarkGJSONUnmarshalMap-8 900000 4154 ns/op 1920 B/op 26 allocs/op +BenchmarkJSONUnmarshalMap-8 600000 9019 ns/op 3048 B/op 69 allocs/op +BenchmarkJSONDecoder-8 300000 14120 ns/op 4224 B/op 184 allocs/op +BenchmarkFFJSONLexer-8 1500000 3111 ns/op 896 B/op 8 allocs/op +BenchmarkEasyJSONLexer-8 3000000 887 ns/op 613 B/op 6 allocs/op +BenchmarkJSONParserGet-8 3000000 499 ns/op 21 B/op 0 allocs/op +BenchmarkJSONIterator-8 3000000 812 ns/op 544 B/op 9 allocs/op +``` + +JSON document used: + +```json +{ + "widget": { + "debug": "on", + "window": { + "title": "Sample Konfabulator Widget", + "name": "main_window", + "width": 500, + "height": 500 + }, + "image": { + "src": "Images/Sun.png", + "hOffset": 250, + "vOffset": 250, + "alignment": "center" + }, + "text": { + "data": "Click Here", + "size": 36, + "style": "bold", + "vOffset": 100, + "alignment": "center", + "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" + } + } +} +``` + +Each operation was rotated though one of the following search paths: + +``` +widget.window.name +widget.image.hOffset +widget.text.onMouseUp +``` + +*These benchmarks were run on a MacBook Pro 15" 2.8 GHz Intel Core i7 using Go 1.8 and can be be found [here](https://github.com/tidwall/gjson-benchmarks).* + + +## Contact +Josh Baker [@tidwall](http://twitter.com/tidwall) + +## License + +GJSON source code is available under the MIT [License](/LICENSE). diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/SYNTAX.md" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/SYNTAX.md" new file mode 100644 index 0000000000000000000000000000000000000000..5ea0407f5ae470d55b30cbbd498a877ee7b8233c --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/SYNTAX.md" @@ -0,0 +1,277 @@ +# GJSON Path Syntax + +A GJSON Path is a text string syntax that describes a search pattern for quickly retreiving values from a JSON payload. + +This document is designed to explain the structure of a GJSON Path through examples. + +- [Path structure](#path-structure) +- [Basic](#basic) +- [Wildcards](#wildcards) +- [Escape Character](#escape-character) +- [Arrays](#arrays) +- [Queries](#queries) +- [Dot vs Pipe](#dot-vs-pipe) +- [Modifiers](#modifiers) +- [Multipaths](#multipaths) + +The definitive implemenation is [github.com/tidwall/gjson](https://github.com/tidwall/gjson). +Use the [GJSON Playground](https://gjson.dev) to experiment with the syntax online. + + +## Path structure + +A GJSON Path is intended to be easily expressed as a series of components seperated by a `.` character. + +Along with `.` character, there are a few more that have special meaning, including `|`, `#`, `@`, `\`, `*`, and `?`. + +## Example + +Given this JSON + +```json +{ + "name": {"first": "Tom", "last": "Anderson"}, + "age":37, + "children": ["Sara","Alex","Jack"], + "fav.movie": "Deer Hunter", + "friends": [ + {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]}, + {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]}, + {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]} + ] +} +``` + +The following GJSON Paths evaluate to the accompanying values. + +### Basic + +In many cases you'll just want to retreive values by object name or array index. + +```go +name.last "Anderson" +name.first "Tom" +age 37 +children ["Sara","Alex","Jack"] +children.0 "Sara" +children.1 "Alex" +friends.1 {"first": "Roger", "last": "Craig", "age": 68} +friends.1.first "Roger" +``` + +### Wildcards + +A key may contain the special wildcard characters `*` and `?`. +The `*` will match on any zero+ characters, and `?` matches on any one character. + +```go +child*.2 "Jack" +c?ildren.0 "Sara" +``` + +### Escape character + +Special purpose characters, such as `.`, `*`, and `?` can be escaped with `\`. + +```go +fav\.movie "Deer Hunter" +``` + +You'll also need to make sure that the `\` character is correctly escaped when hardcoding a path in source code. + +```go +res := gjson.Get(json, "fav\\.movie") // must escape the slash +res := gjson.Get(json, `fav\.movie`) // no need to escape the slash + +``` + +### Arrays + +The `#` character allows for digging into JSON Arrays. + +To get the length of an array you'll just use the `#` all by itself. + +```go +friends.# 3 +friends.#.age [44,68,47] +``` + +### Queries + +You can also query an array for the first match by using `#(...)`, or find all matches with `#(...)#`. +Queries support the `==`, `!=`, `<`, `<=`, `>`, `>=` comparison operators, +and the simple pattern matching `%` (like) and `!%` (not like) operators. + +```go +friends.#(last=="Murphy").first "Dale" +friends.#(last=="Murphy")#.first ["Dale","Jane"] +friends.#(age>45)#.last ["Craig","Murphy"] +friends.#(first%"D*").last "Murphy" +friends.#(first!%"D*").last "Craig" +``` + +To query for a non-object value in an array, you can forgo the string to the right of the operator. + +```go +children.#(!%"*a*") "Alex" +children.#(%"*a*")# ["Sara","Jack"] +``` + +Nested queries are allowed. + +```go +friends.#(nets.#(=="fb"))#.first >> ["Dale","Roger"] +``` + +*Please note that prior to v1.3.0, queries used the `#[...]` brackets. This was +changed in v1.3.0 as to avoid confusion with the new [multipath](#multipaths) +syntax. For backwards compatibility, `#[...]` will continue to work until the +next major release.* + +### Dot vs Pipe + +The `.` is standard separator, but it's also possible to use a `|`. +In most cases they both end up returning the same results. +The cases where`|` differs from `.` is when it's used after the `#` for [Arrays](#arrays) and [Queries](#queries). + +Here are some examples + +```go +friends.0.first "Dale" +friends|0.first "Dale" +friends.0|first "Dale" +friends|0|first "Dale" +friends|# 3 +friends.# 3 +friends.#(last="Murphy")# [{"first": "Dale", "last": "Murphy", "age": 44},{"first": "Jane", "last": "Murphy", "age": 47}] +friends.#(last="Murphy")#.first ["Dale","Jane"] +friends.#(last="Murphy")#|first +friends.#(last="Murphy")#.0 [] +friends.#(last="Murphy")#|0 {"first": "Dale", "last": "Murphy", "age": 44} +friends.#(last="Murphy")#.# [] +friends.#(last="Murphy")#|# 2 +``` + +Let's break down a few of these. + +The path `friends.#(last="Murphy")#` all by itself results in + +```json +[{"first": "Dale", "last": "Murphy", "age": 44},{"first": "Jane", "last": "Murphy", "age": 47}] +``` + +The `.first` suffix will process the `first` path on each array element *before* returning the results. Which becomes + +```json +["Dale","Jane"] +``` + +But the `|first` suffix actually processes the `first` path *after* the previous result. +Since the previous result is an array, not an object, it's not possible to process +because `first` does not exist. + +Yet, `|0` suffix returns + +```json +{"first": "Dale", "last": "Murphy", "age": 44} +``` + +Because `0` is the first index of the previous result. + +### Modifiers + +A modifier is a path component that performs custom processing on the JSON. + +For example, using the built-in `@reverse` modifier on the above JSON payload will reverse the `children` array: + +```go +children.@reverse ["Jack","Alex","Sara"] +children.@reverse.0 "Jack" +``` + +There are currently the following built-in modifiers: + +- `@reverse`: Reverse an array or the members of an object. +- `@ugly`: Remove all whitespace from JSON. +- `@pretty`: Make the JSON more human readable. +- `@this`: Returns the current element. It can be used to retrieve the root element. +- `@valid`: Ensure the json document is valid. +- `@flatten`: Flattens an array. +- `@join`: Joins multiple objects into a single object. + +#### Modifier arguments + +A modifier may accept an optional argument. The argument can be a valid JSON payload or just characters. + +For example, the `@pretty` modifier takes a json object as its argument. + +``` +@pretty:{"sortKeys":true} +``` + +Which makes the json pretty and orders all of its keys. + +```json +{ + "age":37, + "children": ["Sara","Alex","Jack"], + "fav.movie": "Deer Hunter", + "friends": [ + {"age": 44, "first": "Dale", "last": "Murphy"}, + {"age": 68, "first": "Roger", "last": "Craig"}, + {"age": 47, "first": "Jane", "last": "Murphy"} + ], + "name": {"first": "Tom", "last": "Anderson"} +} +``` + +*The full list of `@pretty` options are `sortKeys`, `indent`, `prefix`, and `width`. +Please see [Pretty Options](https://github.com/tidwall/pretty#customized-output) for more information.* + +#### Custom modifiers + +You can also add custom modifiers. + +For example, here we create a modifier which makes the entire JSON payload upper or lower case. + +```go +gjson.AddModifier("case", func(json, arg string) string { + if arg == "upper" { + return strings.ToUpper(json) + } + if arg == "lower" { + return strings.ToLower(json) + } + return json +}) +"children.@case:upper" ["SARA","ALEX","JACK"] +"children.@case:lower.@reverse" ["jack","alex","sara"] +``` + +### Multipaths + +Starting with v1.3.0, GJSON added the ability to join multiple paths together +to form new documents. Wrapping comma-separated paths between `{...}` or +`[...]` will result in a new array or object, respectively. + +For example, using the given multipath + +``` +{name.first,age,"the_murphys":friends.#(last="Murphy")#.first} +``` + +Here we selected the first name, age, and the first name for friends with the +last name "Murphy". + +You'll notice that an optional key can be provided, in this case +"the_murphys", to force assign a key to a value. Otherwise, the name of the +actual field will be used, in this case "first". If a name cannot be +determined, then "_" is used. + +This results in + +``` +{"first":"Tom","age":37,"the_murphys":["Dale","Jane"]} +``` + + diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/gjson.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/gjson.go" new file mode 100644 index 0000000000000000000000000000000000000000..1dc0540af2de53920a1b973ddc162103ab98daa6 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/gjson.go" @@ -0,0 +1,2898 @@ +// Package gjson provides searching for json strings. +package gjson + +import ( + "encoding/json" + "reflect" + "strconv" + "strings" + "time" + "unicode/utf16" + "unicode/utf8" + "unsafe" + + "github.com/tidwall/match" + "github.com/tidwall/pretty" +) + +// Type is Result type +type Type int + +const ( + // Null is a null json value + Null Type = iota + // False is a json false boolean + False + // Number is json number + Number + // String is a json string + String + // True is a json true boolean + True + // JSON is a raw block of JSON + JSON +) + +// String returns a string representation of the type. +func (t Type) String() string { + switch t { + default: + return "" + case Null: + return "Null" + case False: + return "False" + case Number: + return "Number" + case String: + return "String" + case True: + return "True" + case JSON: + return "JSON" + } +} + +// Result represents a json value that is returned from Get(). +type Result struct { + // Type is the json type + Type Type + // Raw is the raw json + Raw string + // Str is the json string + Str string + // Num is the json number + Num float64 + // Index of raw value in original json, zero means index unknown + Index int +} + +// String returns a string representation of the value. +func (t Result) String() string { + switch t.Type { + default: + return "" + case False: + return "false" + case Number: + if len(t.Raw) == 0 { + // calculated result + return strconv.FormatFloat(t.Num, 'f', -1, 64) + } + var i int + if t.Raw[0] == '-' { + i++ + } + for ; i < len(t.Raw); i++ { + if t.Raw[i] < '0' || t.Raw[i] > '9' { + return strconv.FormatFloat(t.Num, 'f', -1, 64) + } + } + return t.Raw + case String: + return t.Str + case JSON: + return t.Raw + case True: + return "true" + } +} + +// Bool returns an boolean representation. +func (t Result) Bool() bool { + switch t.Type { + default: + return false + case True: + return true + case String: + return t.Str != "" && t.Str != "0" && t.Str != "false" + case Number: + return t.Num != 0 + } +} + +// Int returns an integer representation. +func (t Result) Int() int64 { + switch t.Type { + default: + return 0 + case True: + return 1 + case String: + n, _ := parseInt(t.Str) + return n + case Number: + // try to directly convert the float64 to int64 + n, ok := floatToInt(t.Num) + if !ok { + // now try to parse the raw string + n, ok = parseInt(t.Raw) + if !ok { + // fallback to a standard conversion + return int64(t.Num) + } + } + return n + } +} + +// Uint returns an unsigned integer representation. +func (t Result) Uint() uint64 { + switch t.Type { + default: + return 0 + case True: + return 1 + case String: + n, _ := parseUint(t.Str) + return n + case Number: + // try to directly convert the float64 to uint64 + n, ok := floatToUint(t.Num) + if !ok { + // now try to parse the raw string + n, ok = parseUint(t.Raw) + if !ok { + // fallback to a standard conversion + return uint64(t.Num) + } + } + return n + } +} + +// Float returns an float64 representation. +func (t Result) Float() float64 { + switch t.Type { + default: + return 0 + case True: + return 1 + case String: + n, _ := strconv.ParseFloat(t.Str, 64) + return n + case Number: + return t.Num + } +} + +// Time returns a time.Time representation. +func (t Result) Time() time.Time { + res, _ := time.Parse(time.RFC3339, t.String()) + return res +} + +// Array returns back an array of values. +// If the result represents a non-existent value, then an empty array will be +// returned. If the result is not a JSON array, the return value will be an +// array containing one result. +func (t Result) Array() []Result { + if t.Type == Null { + return []Result{} + } + if t.Type != JSON { + return []Result{t} + } + r := t.arrayOrMap('[', false) + return r.a +} + +// IsObject returns true if the result value is a JSON object. +func (t Result) IsObject() bool { + return t.Type == JSON && len(t.Raw) > 0 && t.Raw[0] == '{' +} + +// IsArray returns true if the result value is a JSON array. +func (t Result) IsArray() bool { + return t.Type == JSON && len(t.Raw) > 0 && t.Raw[0] == '[' +} + +// ForEach iterates through values. +// If the result represents a non-existent value, then no values will be +// iterated. If the result is an Object, the iterator will pass the key and +// value of each item. If the result is an Array, the iterator will only pass +// the value of each item. If the result is not a JSON array or object, the +// iterator will pass back one value equal to the result. +func (t Result) ForEach(iterator func(key, value Result) bool) { + if !t.Exists() { + return + } + if t.Type != JSON { + iterator(Result{}, t) + return + } + json := t.Raw + var keys bool + var i int + var key, value Result + for ; i < len(json); i++ { + if json[i] == '{' { + i++ + key.Type = String + keys = true + break + } else if json[i] == '[' { + i++ + break + } + if json[i] > ' ' { + return + } + } + var str string + var vesc bool + var ok bool + for ; i < len(json); i++ { + if keys { + if json[i] != '"' { + continue + } + s := i + i, str, vesc, ok = parseString(json, i+1) + if !ok { + return + } + if vesc { + key.Str = unescape(str[1 : len(str)-1]) + } else { + key.Str = str[1 : len(str)-1] + } + key.Raw = str + key.Index = s + } + for ; i < len(json); i++ { + if json[i] <= ' ' || json[i] == ',' || json[i] == ':' { + continue + } + break + } + s := i + i, value, ok = parseAny(json, i, true) + if !ok { + return + } + value.Index = s + if !iterator(key, value) { + return + } + } +} + +// Map returns back an map of values. The result should be a JSON array. +func (t Result) Map() map[string]Result { + if t.Type != JSON { + return map[string]Result{} + } + r := t.arrayOrMap('{', false) + return r.o +} + +// Get searches result for the specified path. +// The result should be a JSON array or object. +func (t Result) Get(path string) Result { + return Get(t.Raw, path) +} + +type arrayOrMapResult struct { + a []Result + ai []interface{} + o map[string]Result + oi map[string]interface{} + vc byte +} + +func (t Result) arrayOrMap(vc byte, valueize bool) (r arrayOrMapResult) { + var json = t.Raw + var i int + var value Result + var count int + var key Result + if vc == 0 { + for ; i < len(json); i++ { + if json[i] == '{' || json[i] == '[' { + r.vc = json[i] + i++ + break + } + if json[i] > ' ' { + goto end + } + } + } else { + for ; i < len(json); i++ { + if json[i] == vc { + i++ + break + } + if json[i] > ' ' { + goto end + } + } + r.vc = vc + } + if r.vc == '{' { + if valueize { + r.oi = make(map[string]interface{}) + } else { + r.o = make(map[string]Result) + } + } else { + if valueize { + r.ai = make([]interface{}, 0) + } else { + r.a = make([]Result, 0) + } + } + for ; i < len(json); i++ { + if json[i] <= ' ' { + continue + } + // get next value + if json[i] == ']' || json[i] == '}' { + break + } + switch json[i] { + default: + if (json[i] >= '0' && json[i] <= '9') || json[i] == '-' { + value.Type = Number + value.Raw, value.Num = tonum(json[i:]) + value.Str = "" + } else { + continue + } + case '{', '[': + value.Type = JSON + value.Raw = squash(json[i:]) + value.Str, value.Num = "", 0 + case 'n': + value.Type = Null + value.Raw = tolit(json[i:]) + value.Str, value.Num = "", 0 + case 't': + value.Type = True + value.Raw = tolit(json[i:]) + value.Str, value.Num = "", 0 + case 'f': + value.Type = False + value.Raw = tolit(json[i:]) + value.Str, value.Num = "", 0 + case '"': + value.Type = String + value.Raw, value.Str = tostr(json[i:]) + value.Num = 0 + } + i += len(value.Raw) - 1 + + if r.vc == '{' { + if count%2 == 0 { + key = value + } else { + if valueize { + if _, ok := r.oi[key.Str]; !ok { + r.oi[key.Str] = value.Value() + } + } else { + if _, ok := r.o[key.Str]; !ok { + r.o[key.Str] = value + } + } + } + count++ + } else { + if valueize { + r.ai = append(r.ai, value.Value()) + } else { + r.a = append(r.a, value) + } + } + } +end: + return +} + +// Parse parses the json and returns a result. +// +// This function expects that the json is well-formed, and does not validate. +// Invalid json will not panic, but it may return back unexpected results. +// If you are consuming JSON from an unpredictable source then you may want to +// use the Valid function first. +func Parse(json string) Result { + var value Result + for i := 0; i < len(json); i++ { + if json[i] == '{' || json[i] == '[' { + value.Type = JSON + value.Raw = json[i:] // just take the entire raw + break + } + if json[i] <= ' ' { + continue + } + switch json[i] { + default: + if (json[i] >= '0' && json[i] <= '9') || json[i] == '-' { + value.Type = Number + value.Raw, value.Num = tonum(json[i:]) + } else { + return Result{} + } + case 'n': + value.Type = Null + value.Raw = tolit(json[i:]) + case 't': + value.Type = True + value.Raw = tolit(json[i:]) + case 'f': + value.Type = False + value.Raw = tolit(json[i:]) + case '"': + value.Type = String + value.Raw, value.Str = tostr(json[i:]) + } + break + } + return value +} + +// ParseBytes parses the json and returns a result. +// If working with bytes, this method preferred over Parse(string(data)) +func ParseBytes(json []byte) Result { + return Parse(string(json)) +} + +func squash(json string) string { + // expects that the lead character is a '[' or '{' or '(' or '"' + // squash the value, ignoring all nested arrays and objects. + var i, depth int + if json[0] != '"' { + i, depth = 1, 1 + } + for ; i < len(json); i++ { + if json[i] >= '"' && json[i] <= '}' { + switch json[i] { + case '"': + i++ + s2 := i + for ; i < len(json); i++ { + if json[i] > '\\' { + continue + } + if json[i] == '"' { + // look for an escaped slash + if json[i-1] == '\\' { + n := 0 + for j := i - 2; j > s2-1; j-- { + if json[j] != '\\' { + break + } + n++ + } + if n%2 == 0 { + continue + } + } + break + } + } + if depth == 0 { + return json[:i+1] + } + case '{', '[', '(': + depth++ + case '}', ']', ')': + depth-- + if depth == 0 { + return json[:i+1] + } + } + } + } + return json +} + +func tonum(json string) (raw string, num float64) { + for i := 1; i < len(json); i++ { + // less than dash might have valid characters + if json[i] <= '-' { + if json[i] <= ' ' || json[i] == ',' { + // break on whitespace and comma + raw = json[:i] + num, _ = strconv.ParseFloat(raw, 64) + return + } + // could be a '+' or '-'. let's assume so. + continue + } + if json[i] < ']' { + // probably a valid number + continue + } + if json[i] == 'e' || json[i] == 'E' { + // allow for exponential numbers + continue + } + // likely a ']' or '}' + raw = json[:i] + num, _ = strconv.ParseFloat(raw, 64) + return + } + raw = json + num, _ = strconv.ParseFloat(raw, 64) + return +} + +func tolit(json string) (raw string) { + for i := 1; i < len(json); i++ { + if json[i] < 'a' || json[i] > 'z' { + return json[:i] + } + } + return json +} + +func tostr(json string) (raw string, str string) { + // expects that the lead character is a '"' + for i := 1; i < len(json); i++ { + if json[i] > '\\' { + continue + } + if json[i] == '"' { + return json[:i+1], json[1:i] + } + if json[i] == '\\' { + i++ + for ; i < len(json); i++ { + if json[i] > '\\' { + continue + } + if json[i] == '"' { + // look for an escaped slash + if json[i-1] == '\\' { + n := 0 + for j := i - 2; j > 0; j-- { + if json[j] != '\\' { + break + } + n++ + } + if n%2 == 0 { + continue + } + } + break + } + } + var ret string + if i+1 < len(json) { + ret = json[:i+1] + } else { + ret = json[:i] + } + return ret, unescape(json[1:i]) + } + } + return json, json[1:] +} + +// Exists returns true if value exists. +// +// if gjson.Get(json, "name.last").Exists(){ +// println("value exists") +// } +func (t Result) Exists() bool { + return t.Type != Null || len(t.Raw) != 0 +} + +// Value returns one of these types: +// +// bool, for JSON booleans +// float64, for JSON numbers +// Number, for JSON numbers +// string, for JSON string literals +// nil, for JSON null +// map[string]interfaceDemo{}, for JSON objects +// []interfaceDemo{}, for JSON arrays +// +func (t Result) Value() interface{} { + if t.Type == String { + return t.Str + } + switch t.Type { + default: + return nil + case False: + return false + case Number: + return t.Num + case JSON: + r := t.arrayOrMap(0, true) + if r.vc == '{' { + return r.oi + } else if r.vc == '[' { + return r.ai + } + return nil + case True: + return true + } +} + +func parseString(json string, i int) (int, string, bool, bool) { + var s = i + for ; i < len(json); i++ { + if json[i] > '\\' { + continue + } + if json[i] == '"' { + return i + 1, json[s-1 : i+1], false, true + } + if json[i] == '\\' { + i++ + for ; i < len(json); i++ { + if json[i] > '\\' { + continue + } + if json[i] == '"' { + // look for an escaped slash + if json[i-1] == '\\' { + n := 0 + for j := i - 2; j > 0; j-- { + if json[j] != '\\' { + break + } + n++ + } + if n%2 == 0 { + continue + } + } + return i + 1, json[s-1 : i+1], true, true + } + } + break + } + } + return i, json[s-1:], false, false +} + +func parseNumber(json string, i int) (int, string) { + var s = i + i++ + for ; i < len(json); i++ { + if json[i] <= ' ' || json[i] == ',' || json[i] == ']' || + json[i] == '}' { + return i, json[s:i] + } + } + return i, json[s:] +} + +func parseLiteral(json string, i int) (int, string) { + var s = i + i++ + for ; i < len(json); i++ { + if json[i] < 'a' || json[i] > 'z' { + return i, json[s:i] + } + } + return i, json[s:] +} + +type arrayPathResult struct { + part string + path string + pipe string + piped bool + more bool + alogok bool + arrch bool + alogkey string + query struct { + on bool + path string + op string + value string + all bool + } +} + +func parseArrayPath(path string) (r arrayPathResult) { + for i := 0; i < len(path); i++ { + if path[i] == '|' { + r.part = path[:i] + r.pipe = path[i+1:] + r.piped = true + return + } + if path[i] == '.' { + r.part = path[:i] + r.path = path[i+1:] + r.more = true + return + } + if path[i] == '#' { + r.arrch = true + if i == 0 && len(path) > 1 { + if path[1] == '.' { + r.alogok = true + r.alogkey = path[2:] + r.path = path[:1] + } else if path[1] == '[' || path[1] == '(' { + // query + r.query.on = true + if true { + qpath, op, value, _, fi, ok := parseQuery(path[i:]) + if !ok { + // bad query, end now + break + } + r.query.path = qpath + r.query.op = op + r.query.value = value + i = fi - 1 + if i+1 < len(path) && path[i+1] == '#' { + r.query.all = true + } + } else { + var end byte + if path[1] == '[' { + end = ']' + } else { + end = ')' + } + i += 2 + // whitespace + for ; i < len(path); i++ { + if path[i] > ' ' { + break + } + } + s := i + for ; i < len(path); i++ { + if path[i] <= ' ' || + path[i] == '!' || + path[i] == '=' || + path[i] == '<' || + path[i] == '>' || + path[i] == '%' || + path[i] == end { + break + } + } + r.query.path = path[s:i] + // whitespace + for ; i < len(path); i++ { + if path[i] > ' ' { + break + } + } + if i < len(path) { + s = i + if path[i] == '!' { + if i < len(path)-1 && (path[i+1] == '=' || + path[i+1] == '%') { + i++ + } + } else if path[i] == '<' || path[i] == '>' { + if i < len(path)-1 && path[i+1] == '=' { + i++ + } + } else if path[i] == '=' { + if i < len(path)-1 && path[i+1] == '=' { + s++ + i++ + } + } + i++ + r.query.op = path[s:i] + // whitespace + for ; i < len(path); i++ { + if path[i] > ' ' { + break + } + } + s = i + for ; i < len(path); i++ { + if path[i] == '"' { + i++ + s2 := i + for ; i < len(path); i++ { + if path[i] > '\\' { + continue + } + if path[i] == '"' { + // look for an escaped slash + if path[i-1] == '\\' { + n := 0 + for j := i - 2; j > s2-1; j-- { + if path[j] != '\\' { + break + } + n++ + } + if n%2 == 0 { + continue + } + } + break + } + } + } else if path[i] == end { + if i+1 < len(path) && path[i+1] == '#' { + r.query.all = true + } + break + } + } + if i > len(path) { + i = len(path) + } + v := path[s:i] + for len(v) > 0 && v[len(v)-1] <= ' ' { + v = v[:len(v)-1] + } + r.query.value = v + } + } + } + } + continue + } + } + r.part = path + r.path = "" + return +} + +// splitQuery takes a query and splits it into three parts: +// path, op, middle, and right. +// So for this query: +// #(first_name=="Murphy").last +// Becomes +// first_name # path +// =="Murphy" # middle +// .last # right +// Or, +// #(service_roles.#(=="one")).cap +// Becomes +// service_roles.#(=="one") # path +// # middle +// .cap # right +func parseQuery(query string) ( + path, op, value, remain string, i int, ok bool, +) { + if len(query) < 2 || query[0] != '#' || + (query[1] != '(' && query[1] != '[') { + return "", "", "", "", i, false + } + i = 2 + j := 0 // start of value part + depth := 1 + for ; i < len(query); i++ { + if depth == 1 && j == 0 { + switch query[i] { + case '!', '=', '<', '>', '%': + // start of the value part + j = i + continue + } + } + if query[i] == '\\' { + i++ + } else if query[i] == '[' || query[i] == '(' { + depth++ + } else if query[i] == ']' || query[i] == ')' { + depth-- + if depth == 0 { + break + } + } else if query[i] == '"' { + // inside selector string, balance quotes + i++ + for ; i < len(query); i++ { + if query[i] == '\\' { + i++ + } else if query[i] == '"' { + break + } + } + } + } + if depth > 0 { + return "", "", "", "", i, false + } + if j > 0 { + path = trim(query[2:j]) + value = trim(query[j:i]) + remain = query[i+1:] + // parse the compare op from the value + var opsz int + switch { + case len(value) == 1: + opsz = 1 + case value[0] == '!' && value[1] == '=': + opsz = 2 + case value[0] == '!' && value[1] == '%': + opsz = 2 + case value[0] == '<' && value[1] == '=': + opsz = 2 + case value[0] == '>' && value[1] == '=': + opsz = 2 + case value[0] == '=' && value[1] == '=': + value = value[1:] + opsz = 1 + case value[0] == '<': + opsz = 1 + case value[0] == '>': + opsz = 1 + case value[0] == '=': + opsz = 1 + case value[0] == '%': + opsz = 1 + } + op = value[:opsz] + value = trim(value[opsz:]) + } else { + path = trim(query[2:i]) + remain = query[i+1:] + } + return path, op, value, remain, i + 1, true +} + +func trim(s string) string { +left: + if len(s) > 0 && s[0] <= ' ' { + s = s[1:] + goto left + } +right: + if len(s) > 0 && s[len(s)-1] <= ' ' { + s = s[:len(s)-1] + goto right + } + return s +} + +type objectPathResult struct { + part string + path string + pipe string + piped bool + wild bool + more bool +} + +func parseObjectPath(path string) (r objectPathResult) { + for i := 0; i < len(path); i++ { + if path[i] == '|' { + r.part = path[:i] + r.pipe = path[i+1:] + r.piped = true + return + } + if path[i] == '.' { + // peek at the next byte and see if it's a '@', '[', or '{'. + r.part = path[:i] + if !DisableModifiers && + i < len(path)-1 && + (path[i+1] == '@' || + path[i+1] == '[' || path[i+1] == '{') { + r.pipe = path[i+1:] + r.piped = true + } else { + r.path = path[i+1:] + r.more = true + } + return + } + if path[i] == '*' || path[i] == '?' { + r.wild = true + continue + } + if path[i] == '\\' { + // go into escape mode. this is a slower path that + // strips off the escape character from the part. + epart := []byte(path[:i]) + i++ + if i < len(path) { + epart = append(epart, path[i]) + i++ + for ; i < len(path); i++ { + if path[i] == '\\' { + i++ + if i < len(path) { + epart = append(epart, path[i]) + } + continue + } else if path[i] == '.' { + r.part = string(epart) + // peek at the next byte and see if it's a '@' modifier + if !DisableModifiers && + i < len(path)-1 && path[i+1] == '@' { + r.pipe = path[i+1:] + r.piped = true + } else { + r.path = path[i+1:] + r.more = true + } + r.more = true + return + } else if path[i] == '|' { + r.part = string(epart) + r.pipe = path[i+1:] + r.piped = true + return + } else if path[i] == '*' || path[i] == '?' { + r.wild = true + } + epart = append(epart, path[i]) + } + } + // append the last part + r.part = string(epart) + return + } + } + r.part = path + return +} + +func parseSquash(json string, i int) (int, string) { + // expects that the lead character is a '[' or '{' or '(' + // squash the value, ignoring all nested arrays and objects. + // the first '[' or '{' or '(' has already been read + s := i + i++ + depth := 1 + for ; i < len(json); i++ { + if json[i] >= '"' && json[i] <= '}' { + switch json[i] { + case '"': + i++ + s2 := i + for ; i < len(json); i++ { + if json[i] > '\\' { + continue + } + if json[i] == '"' { + // look for an escaped slash + if json[i-1] == '\\' { + n := 0 + for j := i - 2; j > s2-1; j-- { + if json[j] != '\\' { + break + } + n++ + } + if n%2 == 0 { + continue + } + } + break + } + } + case '{', '[', '(': + depth++ + case '}', ']', ')': + depth-- + if depth == 0 { + i++ + return i, json[s:i] + } + } + } + } + return i, json[s:] +} + +func parseObject(c *parseContext, i int, path string) (int, bool) { + var pmatch, kesc, vesc, ok, hit bool + var key, val string + rp := parseObjectPath(path) + if !rp.more && rp.piped { + c.pipe = rp.pipe + c.piped = true + } + for i < len(c.json) { + for ; i < len(c.json); i++ { + if c.json[i] == '"' { + // parse_key_string + // this is slightly different from getting s string value + // because we don't need the outer quotes. + i++ + var s = i + for ; i < len(c.json); i++ { + if c.json[i] > '\\' { + continue + } + if c.json[i] == '"' { + i, key, kesc, ok = i+1, c.json[s:i], false, true + goto parse_key_string_done + } + if c.json[i] == '\\' { + i++ + for ; i < len(c.json); i++ { + if c.json[i] > '\\' { + continue + } + if c.json[i] == '"' { + // look for an escaped slash + if c.json[i-1] == '\\' { + n := 0 + for j := i - 2; j > 0; j-- { + if c.json[j] != '\\' { + break + } + n++ + } + if n%2 == 0 { + continue + } + } + i, key, kesc, ok = i+1, c.json[s:i], true, true + goto parse_key_string_done + } + } + break + } + } + key, kesc, ok = c.json[s:], false, false + parse_key_string_done: + break + } + if c.json[i] == '}' { + return i + 1, false + } + } + if !ok { + return i, false + } + if rp.wild { + if kesc { + pmatch = match.Match(unescape(key), rp.part) + } else { + pmatch = match.Match(key, rp.part) + } + } else { + if kesc { + pmatch = rp.part == unescape(key) + } else { + pmatch = rp.part == key + } + } + hit = pmatch && !rp.more + for ; i < len(c.json); i++ { + switch c.json[i] { + default: + continue + case '"': + i++ + i, val, vesc, ok = parseString(c.json, i) + if !ok { + return i, false + } + if hit { + if vesc { + c.value.Str = unescape(val[1 : len(val)-1]) + } else { + c.value.Str = val[1 : len(val)-1] + } + c.value.Raw = val + c.value.Type = String + return i, true + } + case '{': + if pmatch && !hit { + i, hit = parseObject(c, i+1, rp.path) + if hit { + return i, true + } + } else { + i, val = parseSquash(c.json, i) + if hit { + c.value.Raw = val + c.value.Type = JSON + return i, true + } + } + case '[': + if pmatch && !hit { + i, hit = parseArray(c, i+1, rp.path) + if hit { + return i, true + } + } else { + i, val = parseSquash(c.json, i) + if hit { + c.value.Raw = val + c.value.Type = JSON + return i, true + } + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + i, val = parseNumber(c.json, i) + if hit { + c.value.Raw = val + c.value.Type = Number + c.value.Num, _ = strconv.ParseFloat(val, 64) + return i, true + } + case 't', 'f', 'n': + vc := c.json[i] + i, val = parseLiteral(c.json, i) + if hit { + c.value.Raw = val + switch vc { + case 't': + c.value.Type = True + case 'f': + c.value.Type = False + } + return i, true + } + } + break + } + } + return i, false +} +func queryMatches(rp *arrayPathResult, value Result) bool { + rpv := rp.query.value + if len(rpv) > 2 && rpv[0] == '"' && rpv[len(rpv)-1] == '"' { + rpv = rpv[1 : len(rpv)-1] + } + if !value.Exists() { + return false + } + if rp.query.op == "" { + // the query is only looking for existence, such as: + // friends.#(name) + // which makes sure that the array "friends" has an element of + // "name" that exists + return true + } + switch value.Type { + case String: + switch rp.query.op { + case "=": + return value.Str == rpv + case "!=": + return value.Str != rpv + case "<": + return value.Str < rpv + case "<=": + return value.Str <= rpv + case ">": + return value.Str > rpv + case ">=": + return value.Str >= rpv + case "%": + return match.Match(value.Str, rpv) + case "!%": + return !match.Match(value.Str, rpv) + } + case Number: + rpvn, _ := strconv.ParseFloat(rpv, 64) + switch rp.query.op { + case "=": + return value.Num == rpvn + case "!=": + return value.Num != rpvn + case "<": + return value.Num < rpvn + case "<=": + return value.Num <= rpvn + case ">": + return value.Num > rpvn + case ">=": + return value.Num >= rpvn + } + case True: + switch rp.query.op { + case "=": + return rpv == "true" + case "!=": + return rpv != "true" + case ">": + return rpv == "false" + case ">=": + return true + } + case False: + switch rp.query.op { + case "=": + return rpv == "false" + case "!=": + return rpv != "false" + case "<": + return rpv == "true" + case "<=": + return true + } + } + return false +} +func parseArray(c *parseContext, i int, path string) (int, bool) { + var pmatch, vesc, ok, hit bool + var val string + var h int + var alog []int + var partidx int + var multires []byte + rp := parseArrayPath(path) + if !rp.arrch { + n, ok := parseUint(rp.part) + if !ok { + partidx = -1 + } else { + partidx = int(n) + } + } + if !rp.more && rp.piped { + c.pipe = rp.pipe + c.piped = true + } + + procQuery := func(qval Result) bool { + if rp.query.all { + if len(multires) == 0 { + multires = append(multires, '[') + } + } + var res Result + if qval.Type == JSON { + res = qval.Get(rp.query.path) + } else { + if rp.query.path != "" { + return false + } + res = qval + } + if queryMatches(&rp, res) { + if rp.more { + left, right, ok := splitPossiblePipe(rp.path) + if ok { + rp.path = left + c.pipe = right + c.piped = true + } + res = qval.Get(rp.path) + } else { + res = qval + } + if rp.query.all { + raw := res.Raw + if len(raw) == 0 { + raw = res.String() + } + if raw != "" { + if len(multires) > 1 { + multires = append(multires, ',') + } + multires = append(multires, raw...) + } + } else { + c.value = res + return true + } + } + return false + } + + for i < len(c.json)+1 { + if !rp.arrch { + pmatch = partidx == h + hit = pmatch && !rp.more + } + h++ + if rp.alogok { + alog = append(alog, i) + } + for ; ; i++ { + var ch byte + if i > len(c.json) { + break + } else if i == len(c.json) { + ch = ']' + } else { + ch = c.json[i] + } + switch ch { + default: + continue + case '"': + i++ + i, val, vesc, ok = parseString(c.json, i) + if !ok { + return i, false + } + if rp.query.on { + var qval Result + if vesc { + qval.Str = unescape(val[1 : len(val)-1]) + } else { + qval.Str = val[1 : len(val)-1] + } + qval.Raw = val + qval.Type = String + if procQuery(qval) { + return i, true + } + } else if hit { + if rp.alogok { + break + } + if vesc { + c.value.Str = unescape(val[1 : len(val)-1]) + } else { + c.value.Str = val[1 : len(val)-1] + } + c.value.Raw = val + c.value.Type = String + return i, true + } + case '{': + if pmatch && !hit { + i, hit = parseObject(c, i+1, rp.path) + if hit { + if rp.alogok { + break + } + return i, true + } + } else { + i, val = parseSquash(c.json, i) + if rp.query.on { + if procQuery(Result{Raw: val, Type: JSON}) { + return i, true + } + } else if hit { + if rp.alogok { + break + } + c.value.Raw = val + c.value.Type = JSON + return i, true + } + } + case '[': + if pmatch && !hit { + i, hit = parseArray(c, i+1, rp.path) + if hit { + if rp.alogok { + break + } + return i, true + } + } else { + i, val = parseSquash(c.json, i) + if rp.query.on { + if procQuery(Result{Raw: val, Type: JSON}) { + return i, true + } + } else if hit { + if rp.alogok { + break + } + c.value.Raw = val + c.value.Type = JSON + return i, true + } + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + i, val = parseNumber(c.json, i) + if rp.query.on { + var qval Result + qval.Raw = val + qval.Type = Number + qval.Num, _ = strconv.ParseFloat(val, 64) + if procQuery(qval) { + return i, true + } + } else if hit { + if rp.alogok { + break + } + c.value.Raw = val + c.value.Type = Number + c.value.Num, _ = strconv.ParseFloat(val, 64) + return i, true + } + case 't', 'f', 'n': + vc := c.json[i] + i, val = parseLiteral(c.json, i) + if rp.query.on { + var qval Result + qval.Raw = val + switch vc { + case 't': + qval.Type = True + case 'f': + qval.Type = False + } + if procQuery(qval) { + return i, true + } + } else if hit { + if rp.alogok { + break + } + c.value.Raw = val + switch vc { + case 't': + c.value.Type = True + case 'f': + c.value.Type = False + } + return i, true + } + case ']': + if rp.arrch && rp.part == "#" { + if rp.alogok { + left, right, ok := splitPossiblePipe(rp.alogkey) + if ok { + rp.alogkey = left + c.pipe = right + c.piped = true + } + var jsons = make([]byte, 0, 64) + jsons = append(jsons, '[') + for j, k := 0, 0; j < len(alog); j++ { + idx := alog[j] + for idx < len(c.json) { + switch c.json[idx] { + case ' ', '\t', '\r', '\n': + idx++ + continue + } + break + } + if idx < len(c.json) && c.json[idx] != ']' { + _, res, ok := parseAny(c.json, idx, true) + if ok { + res := res.Get(rp.alogkey) + if res.Exists() { + if k > 0 { + jsons = append(jsons, ',') + } + raw := res.Raw + if len(raw) == 0 { + raw = res.String() + } + jsons = append(jsons, []byte(raw)...) + k++ + } + } + } + } + jsons = append(jsons, ']') + c.value.Type = JSON + c.value.Raw = string(jsons) + return i + 1, true + } + if rp.alogok { + break + } + + c.value.Type = Number + c.value.Num = float64(h - 1) + c.value.Raw = strconv.Itoa(h - 1) + c.calcd = true + return i + 1, true + } + if len(multires) > 0 && !c.value.Exists() { + c.value = Result{ + Raw: string(append(multires, ']')), + Type: JSON, + } + } + return i + 1, false + } + break + } + } + return i, false +} + +func splitPossiblePipe(path string) (left, right string, ok bool) { + // take a quick peek for the pipe character. If found we'll split the piped + // part of the path into the c.pipe field and shorten the rp. + var possible bool + for i := 0; i < len(path); i++ { + if path[i] == '|' { + possible = true + break + } + } + if !possible { + return + } + + if len(path) > 0 && path[0] == '{' { + squashed := squash(path[1:]) + if len(squashed) < len(path)-1 { + squashed = path[:len(squashed)+1] + remain := path[len(squashed):] + if remain[0] == '|' { + return squashed, remain[1:], true + } + } + return + } + + // split the left and right side of the path with the pipe character as + // the delimiter. This is a little tricky because we'll need to basically + // parse the entire path. + for i := 0; i < len(path); i++ { + if path[i] == '\\' { + i++ + } else if path[i] == '.' { + if i == len(path)-1 { + return + } + if path[i+1] == '#' { + i += 2 + if i == len(path) { + return + } + if path[i] == '[' || path[i] == '(' { + var start, end byte + if path[i] == '[' { + start, end = '[', ']' + } else { + start, end = '(', ')' + } + // inside selector, balance brackets + i++ + depth := 1 + for ; i < len(path); i++ { + if path[i] == '\\' { + i++ + } else if path[i] == start { + depth++ + } else if path[i] == end { + depth-- + if depth == 0 { + break + } + } else if path[i] == '"' { + // inside selector string, balance quotes + i++ + for ; i < len(path); i++ { + if path[i] == '\\' { + i++ + } else if path[i] == '"' { + break + } + } + } + } + } + } + } else if path[i] == '|' { + return path[:i], path[i+1:], true + } + } + return +} + +// ForEachLine iterates through lines of JSON as specified by the JSON Lines +// format (http://jsonlines.org/). +// Each line is returned as a GJSON Result. +func ForEachLine(json string, iterator func(line Result) bool) { + var res Result + var i int + for { + i, res, _ = parseAny(json, i, true) + if !res.Exists() { + break + } + if !iterator(res) { + return + } + } +} + +type subSelector struct { + name string + path string +} + +// parseSubSelectors returns the subselectors belonging to a '[path1,path2]' or +// '{"field1":path1,"field2":path2}' type subSelection. It's expected that the +// first character in path is either '[' or '{', and has already been checked +// prior to calling this function. +func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) { + modifer := 0 + depth := 1 + colon := 0 + start := 1 + i := 1 + pushSel := func() { + var sel subSelector + if colon == 0 { + sel.path = path[start:i] + } else { + sel.name = path[start:colon] + sel.path = path[colon+1 : i] + } + sels = append(sels, sel) + colon = 0 + start = i + 1 + } + for ; i < len(path); i++ { + switch path[i] { + case '\\': + i++ + case '@': + if modifer == 0 && i > 0 && (path[i-1] == '.' || path[i-1] == '|') { + modifer = i + } + case ':': + if modifer == 0 && colon == 0 && depth == 1 { + colon = i + } + case ',': + if depth == 1 { + pushSel() + } + case '"': + i++ + loop: + for ; i < len(path); i++ { + switch path[i] { + case '\\': + i++ + case '"': + break loop + } + } + case '[', '(', '{': + depth++ + case ']', ')', '}': + depth-- + if depth == 0 { + pushSel() + path = path[i+1:] + return sels, path, true + } + } + } + return +} + +// nameOfLast returns the name of the last component +func nameOfLast(path string) string { + for i := len(path) - 1; i >= 0; i-- { + if path[i] == '|' || path[i] == '.' { + if i > 0 { + if path[i-1] == '\\' { + continue + } + } + return path[i+1:] + } + } + return path +} + +func isSimpleName(component string) bool { + for i := 0; i < len(component); i++ { + if component[i] < ' ' { + return false + } + switch component[i] { + case '[', ']', '{', '}', '(', ')', '#', '|': + return false + } + } + return true +} + +func appendJSONString(dst []byte, s string) []byte { + for i := 0; i < len(s); i++ { + if s[i] < ' ' || s[i] == '\\' || s[i] == '"' || s[i] > 126 { + d, _ := json.Marshal(s) + return append(dst, string(d)...) + } + } + dst = append(dst, '"') + dst = append(dst, s...) + dst = append(dst, '"') + return dst +} + +type parseContext struct { + json string + value Result + pipe string + piped bool + calcd bool + lines bool +} + +// Get searches json for the specified path. +// A path is in dot syntax, such as "name.last" or "age". +// When the value is found it's returned immediately. +// +// A path is a series of keys searated by a dot. +// A key may contain special wildcard characters '*' and '?'. +// To access an array value use the index as the key. +// To get the number of elements in an array or to access a child path, use +// the '#' character. +// The dot and wildcard character can be escaped with '\'. +// +// { +// "name": {"first": "Tom", "last": "Anderson"}, +// "age":37, +// "children": ["Sara","Alex","Jack"], +// "friends": [ +// {"first": "James", "last": "Murphy"}, +// {"first": "Roger", "last": "Craig"} +// ] +// } +// "name.last" >> "Anderson" +// "age" >> 37 +// "children" >> ["Sara","Alex","Jack"] +// "children.#" >> 3 +// "children.1" >> "Alex" +// "child*.2" >> "Jack" +// "c?ildren.0" >> "Sara" +// "friends.#.first" >> ["James","Roger"] +// +// This function expects that the json is well-formed, and does not validate. +// Invalid json will not panic, but it may return back unexpected results. +// If you are consuming JSON from an unpredictable source then you may want to +// use the Valid function first. +func Get(json, path string) Result { + if len(path) > 1 { + if !DisableModifiers { + if path[0] == '@' { + // possible modifier + var ok bool + var npath string + var rjson string + npath, rjson, ok = execModifier(json, path) + if ok { + path = npath + if len(path) > 0 && (path[0] == '|' || path[0] == '.') { + res := Get(rjson, path[1:]) + res.Index = 0 + return res + } + return Parse(rjson) + } + } + } + if path[0] == '[' || path[0] == '{' { + // using a subselector path + kind := path[0] + var ok bool + var subs []subSelector + subs, path, ok = parseSubSelectors(path) + if ok { + if len(path) == 0 || (path[0] == '|' || path[0] == '.') { + var b []byte + b = append(b, kind) + var i int + for _, sub := range subs { + res := Get(json, sub.path) + if res.Exists() { + if i > 0 { + b = append(b, ',') + } + if kind == '{' { + if len(sub.name) > 0 { + if sub.name[0] == '"' && Valid(sub.name) { + b = append(b, sub.name...) + } else { + b = appendJSONString(b, sub.name) + } + } else { + last := nameOfLast(sub.path) + if isSimpleName(last) { + b = appendJSONString(b, last) + } else { + b = appendJSONString(b, "_") + } + } + b = append(b, ':') + } + var raw string + if len(res.Raw) == 0 { + raw = res.String() + if len(raw) == 0 { + raw = "null" + } + } else { + raw = res.Raw + } + b = append(b, raw...) + i++ + } + } + b = append(b, kind+2) + var res Result + res.Raw = string(b) + res.Type = JSON + if len(path) > 0 { + res = res.Get(path[1:]) + } + res.Index = 0 + return res + } + } + } + } + + var i int + var c = &parseContext{json: json} + if len(path) >= 2 && path[0] == '.' && path[1] == '.' { + c.lines = true + parseArray(c, 0, path[2:]) + } else { + for ; i < len(c.json); i++ { + if c.json[i] == '{' { + i++ + parseObject(c, i, path) + break + } + if c.json[i] == '[' { + i++ + parseArray(c, i, path) + break + } + } + } + if c.piped { + res := c.value.Get(c.pipe) + res.Index = 0 + return res + } + fillIndex(json, c) + return c.value +} + +// GetBytes searches json for the specified path. +// If working with bytes, this method preferred over Get(string(data), path) +func GetBytes(json []byte, path string) Result { + return getBytes(json, path) +} + +// runeit returns the rune from the the \uXXXX +func runeit(json string) rune { + n, _ := strconv.ParseUint(json[:4], 16, 64) + return rune(n) +} + +// unescape unescapes a string +func unescape(json string) string { + var str = make([]byte, 0, len(json)) + for i := 0; i < len(json); i++ { + switch { + default: + str = append(str, json[i]) + case json[i] < ' ': + return string(str) + case json[i] == '\\': + i++ + if i >= len(json) { + return string(str) + } + switch json[i] { + default: + return string(str) + case '\\': + str = append(str, '\\') + case '/': + str = append(str, '/') + case 'b': + str = append(str, '\b') + case 'f': + str = append(str, '\f') + case 'n': + str = append(str, '\n') + case 'r': + str = append(str, '\r') + case 't': + str = append(str, '\t') + case '"': + str = append(str, '"') + case 'u': + if i+5 > len(json) { + return string(str) + } + r := runeit(json[i+1:]) + i += 5 + if utf16.IsSurrogate(r) { + // need another code + if len(json[i:]) >= 6 && json[i] == '\\' && + json[i+1] == 'u' { + // we expect it to be correct so just consume it + r = utf16.DecodeRune(r, runeit(json[i+2:])) + i += 6 + } + } + // provide enough space to encode the largest utf8 possible + str = append(str, 0, 0, 0, 0, 0, 0, 0, 0) + n := utf8.EncodeRune(str[len(str)-8:], r) + str = str[:len(str)-8+n] + i-- // backtrack index by one + } + } + } + return string(str) +} + +// Less return true if a token is less than another token. +// The caseSensitive paramater is used when the tokens are Strings. +// The order when comparing two different type is: +// +// Null < False < Number < String < True < JSON +// +func (t Result) Less(token Result, caseSensitive bool) bool { + if t.Type < token.Type { + return true + } + if t.Type > token.Type { + return false + } + if t.Type == String { + if caseSensitive { + return t.Str < token.Str + } + return stringLessInsensitive(t.Str, token.Str) + } + if t.Type == Number { + return t.Num < token.Num + } + return t.Raw < token.Raw +} + +func stringLessInsensitive(a, b string) bool { + for i := 0; i < len(a) && i < len(b); i++ { + if a[i] >= 'A' && a[i] <= 'Z' { + if b[i] >= 'A' && b[i] <= 'Z' { + // both are uppercase, do nothing + if a[i] < b[i] { + return true + } else if a[i] > b[i] { + return false + } + } else { + // a is uppercase, convert a to lowercase + if a[i]+32 < b[i] { + return true + } else if a[i]+32 > b[i] { + return false + } + } + } else if b[i] >= 'A' && b[i] <= 'Z' { + // b is uppercase, convert b to lowercase + if a[i] < b[i]+32 { + return true + } else if a[i] > b[i]+32 { + return false + } + } else { + // neither are uppercase + if a[i] < b[i] { + return true + } else if a[i] > b[i] { + return false + } + } + } + return len(a) < len(b) +} + +// parseAny parses the next value from a json string. +// A Result is returned when the hit param is set. +// The return values are (i int, res Result, ok bool) +func parseAny(json string, i int, hit bool) (int, Result, bool) { + var res Result + var val string + for ; i < len(json); i++ { + if json[i] == '{' || json[i] == '[' { + i, val = parseSquash(json, i) + if hit { + res.Raw = val + res.Type = JSON + } + return i, res, true + } + if json[i] <= ' ' { + continue + } + switch json[i] { + case '"': + i++ + var vesc bool + var ok bool + i, val, vesc, ok = parseString(json, i) + if !ok { + return i, res, false + } + if hit { + res.Type = String + res.Raw = val + if vesc { + res.Str = unescape(val[1 : len(val)-1]) + } else { + res.Str = val[1 : len(val)-1] + } + } + return i, res, true + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + i, val = parseNumber(json, i) + if hit { + res.Raw = val + res.Type = Number + res.Num, _ = strconv.ParseFloat(val, 64) + } + return i, res, true + case 't', 'f', 'n': + vc := json[i] + i, val = parseLiteral(json, i) + if hit { + res.Raw = val + switch vc { + case 't': + res.Type = True + case 'f': + res.Type = False + } + return i, res, true + } + } + } + return i, res, false +} + +var ( // used for testing + testWatchForFallback bool + testLastWasFallback bool +) + +// GetMany searches json for the multiple paths. +// The return value is a Result array where the number of items +// will be equal to the number of input paths. +func GetMany(json string, path ...string) []Result { + res := make([]Result, len(path)) + for i, path := range path { + res[i] = Get(json, path) + } + return res +} + +// GetManyBytes searches json for the multiple paths. +// The return value is a Result array where the number of items +// will be equal to the number of input paths. +func GetManyBytes(json []byte, path ...string) []Result { + res := make([]Result, len(path)) + for i, path := range path { + res[i] = GetBytes(json, path) + } + return res +} + +func validpayload(data []byte, i int) (outi int, ok bool) { + for ; i < len(data); i++ { + switch data[i] { + default: + i, ok = validany(data, i) + if !ok { + return i, false + } + for ; i < len(data); i++ { + switch data[i] { + default: + return i, false + case ' ', '\t', '\n', '\r': + continue + } + } + return i, true + case ' ', '\t', '\n', '\r': + continue + } + } + return i, false +} +func validany(data []byte, i int) (outi int, ok bool) { + for ; i < len(data); i++ { + switch data[i] { + default: + return i, false + case ' ', '\t', '\n', '\r': + continue + case '{': + return validobject(data, i+1) + case '[': + return validarray(data, i+1) + case '"': + return validstring(data, i+1) + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return validnumber(data, i+1) + case 't': + return validtrue(data, i+1) + case 'f': + return validfalse(data, i+1) + case 'n': + return validnull(data, i+1) + } + } + return i, false +} +func validobject(data []byte, i int) (outi int, ok bool) { + for ; i < len(data); i++ { + switch data[i] { + default: + return i, false + case ' ', '\t', '\n', '\r': + continue + case '}': + return i + 1, true + case '"': + key: + if i, ok = validstring(data, i+1); !ok { + return i, false + } + if i, ok = validcolon(data, i); !ok { + return i, false + } + if i, ok = validany(data, i); !ok { + return i, false + } + if i, ok = validcomma(data, i, '}'); !ok { + return i, false + } + if data[i] == '}' { + return i + 1, true + } + i++ + for ; i < len(data); i++ { + switch data[i] { + default: + return i, false + case ' ', '\t', '\n', '\r': + continue + case '"': + goto key + } + } + return i, false + } + } + return i, false +} +func validcolon(data []byte, i int) (outi int, ok bool) { + for ; i < len(data); i++ { + switch data[i] { + default: + return i, false + case ' ', '\t', '\n', '\r': + continue + case ':': + return i + 1, true + } + } + return i, false +} +func validcomma(data []byte, i int, end byte) (outi int, ok bool) { + for ; i < len(data); i++ { + switch data[i] { + default: + return i, false + case ' ', '\t', '\n', '\r': + continue + case ',': + return i, true + case end: + return i, true + } + } + return i, false +} +func validarray(data []byte, i int) (outi int, ok bool) { + for ; i < len(data); i++ { + switch data[i] { + default: + for ; i < len(data); i++ { + if i, ok = validany(data, i); !ok { + return i, false + } + if i, ok = validcomma(data, i, ']'); !ok { + return i, false + } + if data[i] == ']' { + return i + 1, true + } + } + case ' ', '\t', '\n', '\r': + continue + case ']': + return i + 1, true + } + } + return i, false +} +func validstring(data []byte, i int) (outi int, ok bool) { + for ; i < len(data); i++ { + if data[i] < ' ' { + return i, false + } else if data[i] == '\\' { + i++ + if i == len(data) { + return i, false + } + switch data[i] { + default: + return i, false + case '"', '\\', '/', 'b', 'f', 'n', 'r', 't': + case 'u': + for j := 0; j < 4; j++ { + i++ + if i >= len(data) { + return i, false + } + if !((data[i] >= '0' && data[i] <= '9') || + (data[i] >= 'a' && data[i] <= 'f') || + (data[i] >= 'A' && data[i] <= 'F')) { + return i, false + } + } + } + } else if data[i] == '"' { + return i + 1, true + } + } + return i, false +} +func validnumber(data []byte, i int) (outi int, ok bool) { + i-- + // sign + if data[i] == '-' { + i++ + } + // int + if i == len(data) { + return i, false + } + if data[i] == '0' { + i++ + } else { + for ; i < len(data); i++ { + if data[i] >= '0' && data[i] <= '9' { + continue + } + break + } + } + // frac + if i == len(data) { + return i, true + } + if data[i] == '.' { + i++ + if i == len(data) { + return i, false + } + if data[i] < '0' || data[i] > '9' { + return i, false + } + i++ + for ; i < len(data); i++ { + if data[i] >= '0' && data[i] <= '9' { + continue + } + break + } + } + // exp + if i == len(data) { + return i, true + } + if data[i] == 'e' || data[i] == 'E' { + i++ + if i == len(data) { + return i, false + } + if data[i] == '+' || data[i] == '-' { + i++ + } + if i == len(data) { + return i, false + } + if data[i] < '0' || data[i] > '9' { + return i, false + } + i++ + for ; i < len(data); i++ { + if data[i] >= '0' && data[i] <= '9' { + continue + } + break + } + } + return i, true +} + +func validtrue(data []byte, i int) (outi int, ok bool) { + if i+3 <= len(data) && data[i] == 'r' && data[i+1] == 'u' && + data[i+2] == 'e' { + return i + 3, true + } + return i, false +} +func validfalse(data []byte, i int) (outi int, ok bool) { + if i+4 <= len(data) && data[i] == 'a' && data[i+1] == 'l' && + data[i+2] == 's' && data[i+3] == 'e' { + return i + 4, true + } + return i, false +} +func validnull(data []byte, i int) (outi int, ok bool) { + if i+3 <= len(data) && data[i] == 'u' && data[i+1] == 'l' && + data[i+2] == 'l' { + return i + 3, true + } + return i, false +} + +// Valid returns true if the input is valid json. +// +// if !gjson.Valid(json) { +// return errors.New("invalid json") +// } +// value := gjson.Get(json, "name.last") +// +func Valid(json string) bool { + _, ok := validpayload(stringBytes(json), 0) + return ok +} + +// ValidBytes returns true if the input is valid json. +// +// if !gjson.Valid(json) { +// return errors.New("invalid json") +// } +// value := gjson.Get(json, "name.last") +// +// If working with bytes, this method preferred over ValidBytes(string(data)) +// +func ValidBytes(json []byte) bool { + _, ok := validpayload(json, 0) + return ok +} + +func parseUint(s string) (n uint64, ok bool) { + var i int + if i == len(s) { + return 0, false + } + for ; i < len(s); i++ { + if s[i] >= '0' && s[i] <= '9' { + n = n*10 + uint64(s[i]-'0') + } else { + return 0, false + } + } + return n, true +} + +func parseInt(s string) (n int64, ok bool) { + var i int + var sign bool + if len(s) > 0 && s[0] == '-' { + sign = true + i++ + } + if i == len(s) { + return 0, false + } + for ; i < len(s); i++ { + if s[i] >= '0' && s[i] <= '9' { + n = n*10 + int64(s[i]-'0') + } else { + return 0, false + } + } + if sign { + return n * -1, true + } + return n, true +} + +const minUint53 = 0 +const maxUint53 = 4503599627370495 +const minInt53 = -2251799813685248 +const maxInt53 = 2251799813685247 + +func floatToUint(f float64) (n uint64, ok bool) { + n = uint64(f) + if float64(n) == f && n >= minUint53 && n <= maxUint53 { + return n, true + } + return 0, false +} + +func floatToInt(f float64) (n int64, ok bool) { + n = int64(f) + if float64(n) == f && n >= minInt53 && n <= maxInt53 { + return n, true + } + return 0, false +} + +// execModifier parses the path to find a matching modifier function. +// then input expects that the path already starts with a '@' +func execModifier(json, path string) (pathOut, res string, ok bool) { + name := path[1:] + var hasArgs bool + for i := 1; i < len(path); i++ { + if path[i] == ':' { + pathOut = path[i+1:] + name = path[1:i] + hasArgs = len(pathOut) > 0 + break + } + if path[i] == '|' { + pathOut = path[i:] + name = path[1:i] + break + } + if path[i] == '.' { + pathOut = path[i:] + name = path[1:i] + break + } + } + if fn, ok := modifiers[name]; ok { + var args string + if hasArgs { + var parsedArgs bool + switch pathOut[0] { + case '{', '[', '"': + res := Parse(pathOut) + if res.Exists() { + args = squash(pathOut) + pathOut = pathOut[len(args):] + parsedArgs = true + } + } + if !parsedArgs { + idx := strings.IndexByte(pathOut, '|') + if idx == -1 { + args = pathOut + pathOut = "" + } else { + args = pathOut[:idx] + pathOut = pathOut[idx:] + } + } + } + return pathOut, fn(json, args), true + } + return pathOut, res, false +} + +// unwrap removes the '[]' or '{}' characters around json +func unwrap(json string) string { + json = trim(json) + if len(json) >= 2 && json[0] == '[' || json[0] == '{' { + json = json[1 : len(json)-1] + } + return json +} + +// DisableModifiers will disable the modifier syntax +var DisableModifiers = false + +var modifiers = map[string]func(json, arg string) string{ + "pretty": modPretty, + "ugly": modUgly, + "reverse": modReverse, + "this": modThis, + "flatten": modFlatten, + "join": modJoin, + "valid": modValid, +} + +// AddModifier binds a custom modifier command to the GJSON syntax. +// This operation is not thread safe and should be executed prior to +// using all other gjson function. +func AddModifier(name string, fn func(json, arg string) string) { + modifiers[name] = fn +} + +// ModifierExists returns true when the specified modifier exists. +func ModifierExists(name string, fn func(json, arg string) string) bool { + _, ok := modifiers[name] + return ok +} + +// @pretty modifier makes the json look nice. +func modPretty(json, arg string) string { + if len(arg) > 0 { + opts := *pretty.DefaultOptions + Parse(arg).ForEach(func(key, value Result) bool { + switch key.String() { + case "sortKeys": + opts.SortKeys = value.Bool() + case "indent": + opts.Indent = value.String() + case "prefix": + opts.Prefix = value.String() + case "width": + opts.Width = int(value.Int()) + } + return true + }) + return bytesString(pretty.PrettyOptions(stringBytes(json), &opts)) + } + return bytesString(pretty.Pretty(stringBytes(json))) +} + +// @this returns the current element. Can be used to retrieve the root element. +func modThis(json, arg string) string { + return json +} + +// @ugly modifier removes all whitespace. +func modUgly(json, arg string) string { + return bytesString(pretty.Ugly(stringBytes(json))) +} + +// @reverse reverses array elements or root object members. +func modReverse(json, arg string) string { + res := Parse(json) + if res.IsArray() { + var values []Result + res.ForEach(func(_, value Result) bool { + values = append(values, value) + return true + }) + out := make([]byte, 0, len(json)) + out = append(out, '[') + for i, j := len(values)-1, 0; i >= 0; i, j = i-1, j+1 { + if j > 0 { + out = append(out, ',') + } + out = append(out, values[i].Raw...) + } + out = append(out, ']') + return bytesString(out) + } + if res.IsObject() { + var keyValues []Result + res.ForEach(func(key, value Result) bool { + keyValues = append(keyValues, key, value) + return true + }) + out := make([]byte, 0, len(json)) + out = append(out, '{') + for i, j := len(keyValues)-2, 0; i >= 0; i, j = i-2, j+1 { + if j > 0 { + out = append(out, ',') + } + out = append(out, keyValues[i+0].Raw...) + out = append(out, ':') + out = append(out, keyValues[i+1].Raw...) + } + out = append(out, '}') + return bytesString(out) + } + return json +} + +// @flatten an array with child arrays. +// [1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,[6,7]] +// The {"deep":true} arg can be provide for deep flattening. +// [1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,6,7] +// The original json is returned when the json is not an array. +func modFlatten(json, arg string) string { + res := Parse(json) + if !res.IsArray() { + return json + } + var deep bool + if arg != "" { + Parse(arg).ForEach(func(key, value Result) bool { + if key.String() == "deep" { + deep = value.Bool() + } + return true + }) + } + var out []byte + out = append(out, '[') + var idx int + res.ForEach(func(_, value Result) bool { + if idx > 0 { + out = append(out, ',') + } + if value.IsArray() { + if deep { + out = append(out, unwrap(modFlatten(value.Raw, arg))...) + } else { + out = append(out, unwrap(value.Raw)...) + } + } else { + out = append(out, value.Raw...) + } + idx++ + return true + }) + out = append(out, ']') + return bytesString(out) +} + +// @join multiple objects into a single object. +// [{"first":"Tom"},{"last":"Smith"}] -> {"first","Tom","last":"Smith"} +// The arg can be "true" to specify that duplicate keys should be preserved. +// [{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":37,"age":41} +// Without preserved keys: +// [{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":41} +// The original json is returned when the json is not an object. +func modJoin(json, arg string) string { + res := Parse(json) + if !res.IsArray() { + return json + } + var preserve bool + if arg != "" { + Parse(arg).ForEach(func(key, value Result) bool { + if key.String() == "preserve" { + preserve = value.Bool() + } + return true + }) + } + var out []byte + out = append(out, '{') + if preserve { + // Preserve duplicate keys. + var idx int + res.ForEach(func(_, value Result) bool { + if !value.IsObject() { + return true + } + if idx > 0 { + out = append(out, ',') + } + out = append(out, unwrap(value.Raw)...) + idx++ + return true + }) + } else { + // Deduplicate keys and generate an object with stable ordering. + var keys []Result + kvals := make(map[string]Result) + res.ForEach(func(_, value Result) bool { + if !value.IsObject() { + return true + } + value.ForEach(func(key, value Result) bool { + k := key.String() + if _, ok := kvals[k]; !ok { + keys = append(keys, key) + } + kvals[k] = value + return true + }) + return true + }) + for i := 0; i < len(keys); i++ { + if i > 0 { + out = append(out, ',') + } + out = append(out, keys[i].Raw...) + out = append(out, ':') + out = append(out, kvals[keys[i].String()].Raw...) + } + } + out = append(out, '}') + return bytesString(out) +} + +// @valid ensures that the json is valid before moving on. An empty string is +// returned when the json is not valid, otherwise it returns the original json. +func modValid(json, arg string) string { + if !Valid(json) { + return "" + } + return json +} + +// getBytes casts the input json bytes to a string and safely returns the +// results as uniquely allocated data. This operation is intended to minimize +// copies and allocations for the large json string->[]byte. +func getBytes(json []byte, path string) Result { + var result Result + if json != nil { + // unsafe cast to string + result = Get(*(*string)(unsafe.Pointer(&json)), path) + // safely get the string headers + rawhi := *(*reflect.StringHeader)(unsafe.Pointer(&result.Raw)) + strhi := *(*reflect.StringHeader)(unsafe.Pointer(&result.Str)) + // create byte slice headers + rawh := reflect.SliceHeader{Data: rawhi.Data, Len: rawhi.Len} + strh := reflect.SliceHeader{Data: strhi.Data, Len: strhi.Len} + if strh.Data == 0 { + // str is nil + if rawh.Data == 0 { + // raw is nil + result.Raw = "" + } else { + // raw has data, safely copy the slice header to a string + result.Raw = string(*(*[]byte)(unsafe.Pointer(&rawh))) + } + result.Str = "" + } else if rawh.Data == 0 { + // raw is nil + result.Raw = "" + // str has data, safely copy the slice header to a string + result.Str = string(*(*[]byte)(unsafe.Pointer(&strh))) + } else if strh.Data >= rawh.Data && + int(strh.Data)+strh.Len <= int(rawh.Data)+rawh.Len { + // Str is a substring of Raw. + start := int(strh.Data - rawh.Data) + // safely copy the raw slice header + result.Raw = string(*(*[]byte)(unsafe.Pointer(&rawh))) + // substring the raw + result.Str = result.Raw[start : start+strh.Len] + } else { + // safely copy both the raw and str slice headers to strings + result.Raw = string(*(*[]byte)(unsafe.Pointer(&rawh))) + result.Str = string(*(*[]byte)(unsafe.Pointer(&strh))) + } + } + return result +} + +// fillIndex finds the position of Raw data and assigns it to the Index field +// of the resulting value. If the position cannot be found then Index zero is +// used instead. +func fillIndex(json string, c *parseContext) { + if len(c.value.Raw) > 0 && !c.calcd { + jhdr := *(*reflect.StringHeader)(unsafe.Pointer(&json)) + rhdr := *(*reflect.StringHeader)(unsafe.Pointer(&(c.value.Raw))) + c.value.Index = int(rhdr.Data - jhdr.Data) + if c.value.Index < 0 || c.value.Index >= len(json) { + c.value.Index = 0 + } + } +} + +func stringBytes(s string) []byte { + return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ + Data: (*reflect.StringHeader)(unsafe.Pointer(&s)).Data, + Len: len(s), + Cap: len(s), + })) +} + +func bytesString(b []byte) string { + return *(*string)(unsafe.Pointer(&b)) +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/go.mod" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/go.mod" new file mode 100644 index 0000000000000000000000000000000000000000..d851688cc05a02559330369f42c92b4faf3e7926 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/go.mod" @@ -0,0 +1,8 @@ +module github.com/tidwall/gjson + +go 1.12 + +require ( + github.com/tidwall/match v1.0.1 + github.com/tidwall/pretty v1.0.0 +) diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/go.sum" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/go.sum" new file mode 100644 index 0000000000000000000000000000000000000000..a4a2d872cffbacbd5350108ae7a6eb6c4e325838 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/go.sum" @@ -0,0 +1,4 @@ +github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= +github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/logo.png" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/logo.png" new file mode 100644 index 0000000000000000000000000000000000000000..17a8bbe9d651e5d79cbd59a3645a152443440ad6 Binary files /dev/null and "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/gjson/logo.png" differ diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/match/.travis.yml" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/match/.travis.yml" new file mode 100644 index 0000000000000000000000000000000000000000..4f2ee4d9733890ec7e7fc5348fe33ac145cfd332 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/match/.travis.yml" @@ -0,0 +1 @@ +language: go diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/match/LICENSE" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/match/LICENSE" new file mode 100644 index 0000000000000000000000000000000000000000..58f5819a4380fea7a84a9ebdecffc5c68b0a41eb --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/match/LICENSE" @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2016 Josh Baker + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/match/README.md" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/match/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..2aa5bc38ba1167ba8460a126ce4ad7ac2a42e7e0 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/match/README.md" @@ -0,0 +1,32 @@ +Match +===== +Build Status +GoDoc + +Match is a very simple pattern matcher where '*' matches on any +number characters and '?' matches on any one character. + +Installing +---------- + +``` +go get -u github.com/tidwall/match +``` + +Example +------- + +```go +match.Match("hello", "*llo") +match.Match("jello", "?ello") +match.Match("hello", "h*o") +``` + + +Contact +------- +Josh Baker [@tidwall](http://twitter.com/tidwall) + +License +------- +Redcon source code is available under the MIT [License](/LICENSE). diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/match/match.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/match/match.go" new file mode 100644 index 0000000000000000000000000000000000000000..fcfe998b5b434b2da622138a4377dd3093f4f8a4 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/match/match.go" @@ -0,0 +1,181 @@ +// Match provides a simple pattern matcher with unicode support. +package match + +import "unicode/utf8" + +// Match returns true if str matches pattern. This is a very +// simple wildcard match where '*' matches on any number characters +// and '?' matches on any one character. + +// pattern: +// { term } +// term: +// '*' matches any sequence of non-Separator characters +// '?' matches any single non-Separator character +// c matches character c (c != '*', '?', '\\') +// '\\' c matches character c +// +func Match(str, pattern string) bool { + if pattern == "*" { + return true + } + return deepMatch(str, pattern) +} +func deepMatch(str, pattern string) bool { + for len(pattern) > 0 { + if pattern[0] > 0x7f { + return deepMatchRune(str, pattern) + } + switch pattern[0] { + default: + if len(str) == 0 { + return false + } + if str[0] > 0x7f { + return deepMatchRune(str, pattern) + } + if str[0] != pattern[0] { + return false + } + case '?': + if len(str) == 0 { + return false + } + case '*': + return deepMatch(str, pattern[1:]) || + (len(str) > 0 && deepMatch(str[1:], pattern)) + } + str = str[1:] + pattern = pattern[1:] + } + return len(str) == 0 && len(pattern) == 0 +} + +func deepMatchRune(str, pattern string) bool { + var sr, pr rune + var srsz, prsz int + + // read the first rune ahead of time + if len(str) > 0 { + if str[0] > 0x7f { + sr, srsz = utf8.DecodeRuneInString(str) + } else { + sr, srsz = rune(str[0]), 1 + } + } else { + sr, srsz = utf8.RuneError, 0 + } + if len(pattern) > 0 { + if pattern[0] > 0x7f { + pr, prsz = utf8.DecodeRuneInString(pattern) + } else { + pr, prsz = rune(pattern[0]), 1 + } + } else { + pr, prsz = utf8.RuneError, 0 + } + // done reading + for pr != utf8.RuneError { + switch pr { + default: + if srsz == utf8.RuneError { + return false + } + if sr != pr { + return false + } + case '?': + if srsz == utf8.RuneError { + return false + } + case '*': + return deepMatchRune(str, pattern[prsz:]) || + (srsz > 0 && deepMatchRune(str[srsz:], pattern)) + } + str = str[srsz:] + pattern = pattern[prsz:] + // read the next runes + if len(str) > 0 { + if str[0] > 0x7f { + sr, srsz = utf8.DecodeRuneInString(str) + } else { + sr, srsz = rune(str[0]), 1 + } + } else { + sr, srsz = utf8.RuneError, 0 + } + if len(pattern) > 0 { + if pattern[0] > 0x7f { + pr, prsz = utf8.DecodeRuneInString(pattern) + } else { + pr, prsz = rune(pattern[0]), 1 + } + } else { + pr, prsz = utf8.RuneError, 0 + } + // done reading + } + + return srsz == 0 && prsz == 0 +} + +var maxRuneBytes = func() []byte { + b := make([]byte, 4) + if utf8.EncodeRune(b, '\U0010FFFF') != 4 { + panic("invalid rune encoding") + } + return b +}() + +// Allowable parses the pattern and determines the minimum and maximum allowable +// values that the pattern can represent. +// When the max cannot be determined, 'true' will be returned +// for infinite. +func Allowable(pattern string) (min, max string) { + if pattern == "" || pattern[0] == '*' { + return "", "" + } + + minb := make([]byte, 0, len(pattern)) + maxb := make([]byte, 0, len(pattern)) + var wild bool + for i := 0; i < len(pattern); i++ { + if pattern[i] == '*' { + wild = true + break + } + if pattern[i] == '?' { + minb = append(minb, 0) + maxb = append(maxb, maxRuneBytes...) + } else { + minb = append(minb, pattern[i]) + maxb = append(maxb, pattern[i]) + } + } + if wild { + r, n := utf8.DecodeLastRune(maxb) + if r != utf8.RuneError { + if r < utf8.MaxRune { + r++ + if r > 0x7f { + b := make([]byte, 4) + nn := utf8.EncodeRune(b, r) + maxb = append(maxb[:len(maxb)-n], b[:nn]...) + } else { + maxb = append(maxb[:len(maxb)-n], byte(r)) + } + } + } + } + return string(minb), string(maxb) +} + +// IsPattern returns true if the string is a pattern. +func IsPattern(str string) bool { + for i := 0; i < len(str); i++ { + if str[i] == '*' || str[i] == '?' { + return true + } + } + return false +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/pretty/.travis.yml" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/pretty/.travis.yml" new file mode 100644 index 0000000000000000000000000000000000000000..4f2ee4d9733890ec7e7fc5348fe33ac145cfd332 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/pretty/.travis.yml" @@ -0,0 +1 @@ +language: go diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/pretty/LICENSE" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/pretty/LICENSE" new file mode 100644 index 0000000000000000000000000000000000000000..993b83f230f3455d3e98b14d511ab5554ccb1e92 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/pretty/LICENSE" @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Josh Baker + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/pretty/README.md" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/pretty/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..d2b8864d506414b4da209aac460f56a9c9147bb8 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/pretty/README.md" @@ -0,0 +1,124 @@ +# Pretty +[![Build Status](https://img.shields.io/travis/tidwall/pretty.svg?style=flat-square)](https://travis-ci.org/tidwall/prettty) +[![Coverage Status](https://img.shields.io/badge/coverage-100%25-brightgreen.svg?style=flat-square)](http://gocover.io/github.com/tidwall/pretty) +[![GoDoc](https://img.shields.io/badge/api-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/tidwall/pretty) + + +Pretty is a Go package that provides [fast](#performance) methods for formatting JSON for human readability, or to compact JSON for smaller payloads. + +Getting Started +=============== + +## Installing + +To start using Pretty, install Go and run `go get`: + +```sh +$ go get -u github.com/tidwall/pretty +``` + +This will retrieve the library. + +## Pretty + +Using this example: + +```json +{"name": {"first":"Tom","last":"Anderson"}, "age":37, +"children": ["Sara","Alex","Jack"], +"fav.movie": "Deer Hunter", "friends": [ + {"first": "Janet", "last": "Murphy", "age": 44} + ]} +``` + +The following code: +```go +result = pretty.Pretty(example) +``` + +Will format the json to: + +```json +{ + "name": { + "first": "Tom", + "last": "Anderson" + }, + "age": 37, + "children": ["Sara", "Alex", "Jack"], + "fav.movie": "Deer Hunter", + "friends": [ + { + "first": "Janet", + "last": "Murphy", + "age": 44 + } + ] +} +``` + +## Color + +Color will colorize the json for outputing to the screen. + +```json +result = pretty.Color(json, nil) +``` + +Will add color to the result for printing to the terminal. +The second param is used for a customizing the style, and passing nil will use the default `pretty.TerminalStyle`. + +## Ugly + +The following code: +```go +result = pretty.Ugly(example) +``` + +Will format the json to: + +```json +{"name":{"first":"Tom","last":"Anderson"},"age":37,"children":["Sara","Alex","Jack"],"fav.movie":"Deer Hunter","friends":[{"first":"Janet","last":"Murphy","age":44}]}``` +``` + + +## Customized output + +There's a `PrettyOptions(json, opts)` function which allows for customizing the output with the following options: + +```go +type Options struct { + // Width is an max column width for single line arrays + // Default is 80 + Width int + // Prefix is a prefix for all lines + // Default is an empty string + Prefix string + // Indent is the nested indentation + // Default is two spaces + Indent string + // SortKeys will sort the keys alphabetically + // Default is false + SortKeys bool +} +``` +## Performance + +Benchmarks of Pretty alongside the builtin `encoding/json` Indent/Compact methods. +``` +BenchmarkPretty-8 1000000 1283 ns/op 720 B/op 2 allocs/op +BenchmarkUgly-8 3000000 426 ns/op 240 B/op 1 allocs/op +BenchmarkUglyInPlace-8 5000000 340 ns/op 0 B/op 0 allocs/op +BenchmarkJSONIndent-8 300000 4628 ns/op 1069 B/op 4 allocs/op +BenchmarkJSONCompact-8 1000000 2469 ns/op 758 B/op 4 allocs/op +``` + +*These benchmarks were run on a MacBook Pro 15" 2.8 GHz Intel Core i7 using Go 1.7.* + +## Contact +Josh Baker [@tidwall](http://twitter.com/tidwall) + +## License + +Pretty source code is available under the MIT [License](/LICENSE). + diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/pretty/pretty.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/pretty/pretty.go" new file mode 100644 index 0000000000000000000000000000000000000000..0a922d039d77b4d3349b9f7f00cb1cbe43901bad --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/github.com/tidwall/pretty/pretty.go" @@ -0,0 +1,432 @@ +package pretty + +import ( + "sort" +) + +// Options is Pretty options +type Options struct { + // Width is an max column width for single line arrays + // Default is 80 + Width int + // Prefix is a prefix for all lines + // Default is an empty string + Prefix string + // Indent is the nested indentation + // Default is two spaces + Indent string + // SortKeys will sort the keys alphabetically + // Default is false + SortKeys bool +} + +// DefaultOptions is the default options for pretty formats. +var DefaultOptions = &Options{Width: 80, Prefix: "", Indent: " ", SortKeys: false} + +// Pretty converts the input json into a more human readable format where each +// element is on it's own line with clear indentation. +func Pretty(json []byte) []byte { return PrettyOptions(json, nil) } + +// PrettyOptions is like Pretty but with customized options. +func PrettyOptions(json []byte, opts *Options) []byte { + if opts == nil { + opts = DefaultOptions + } + buf := make([]byte, 0, len(json)) + if len(opts.Prefix) != 0 { + buf = append(buf, opts.Prefix...) + } + buf, _, _, _ = appendPrettyAny(buf, json, 0, true, + opts.Width, opts.Prefix, opts.Indent, opts.SortKeys, + 0, 0, -1) + if len(buf) > 0 { + buf = append(buf, '\n') + } + return buf +} + +// Ugly removes insignificant space characters from the input json byte slice +// and returns the compacted result. +func Ugly(json []byte) []byte { + buf := make([]byte, 0, len(json)) + return ugly(buf, json) +} + +// UglyInPlace removes insignificant space characters from the input json +// byte slice and returns the compacted result. This method reuses the +// input json buffer to avoid allocations. Do not use the original bytes +// slice upon return. +func UglyInPlace(json []byte) []byte { return ugly(json, json) } + +func ugly(dst, src []byte) []byte { + dst = dst[:0] + for i := 0; i < len(src); i++ { + if src[i] > ' ' { + dst = append(dst, src[i]) + if src[i] == '"' { + for i = i + 1; i < len(src); i++ { + dst = append(dst, src[i]) + if src[i] == '"' { + j := i - 1 + for ; ; j-- { + if src[j] != '\\' { + break + } + } + if (j-i)%2 != 0 { + break + } + } + } + } + } + } + return dst +} + +func appendPrettyAny(buf, json []byte, i int, pretty bool, width int, prefix, indent string, sortkeys bool, tabs, nl, max int) ([]byte, int, int, bool) { + for ; i < len(json); i++ { + if json[i] <= ' ' { + continue + } + if json[i] == '"' { + return appendPrettyString(buf, json, i, nl) + } + if (json[i] >= '0' && json[i] <= '9') || json[i] == '-' { + return appendPrettyNumber(buf, json, i, nl) + } + if json[i] == '{' { + return appendPrettyObject(buf, json, i, '{', '}', pretty, width, prefix, indent, sortkeys, tabs, nl, max) + } + if json[i] == '[' { + return appendPrettyObject(buf, json, i, '[', ']', pretty, width, prefix, indent, sortkeys, tabs, nl, max) + } + switch json[i] { + case 't': + return append(buf, 't', 'r', 'u', 'e'), i + 4, nl, true + case 'f': + return append(buf, 'f', 'a', 'l', 's', 'e'), i + 5, nl, true + case 'n': + return append(buf, 'n', 'u', 'l', 'l'), i + 4, nl, true + } + } + return buf, i, nl, true +} + +type pair struct { + kstart, kend int + vstart, vend int +} + +type byKey struct { + sorted bool + json []byte + pairs []pair +} + +func (arr *byKey) Len() int { + return len(arr.pairs) +} +func (arr *byKey) Less(i, j int) bool { + key1 := arr.json[arr.pairs[i].kstart+1 : arr.pairs[i].kend-1] + key2 := arr.json[arr.pairs[j].kstart+1 : arr.pairs[j].kend-1] + return string(key1) < string(key2) +} +func (arr *byKey) Swap(i, j int) { + arr.pairs[i], arr.pairs[j] = arr.pairs[j], arr.pairs[i] + arr.sorted = true +} + +func appendPrettyObject(buf, json []byte, i int, open, close byte, pretty bool, width int, prefix, indent string, sortkeys bool, tabs, nl, max int) ([]byte, int, int, bool) { + var ok bool + if width > 0 { + if pretty && open == '[' && max == -1 { + // here we try to create a single line array + max := width - (len(buf) - nl) + if max > 3 { + s1, s2 := len(buf), i + buf, i, _, ok = appendPrettyObject(buf, json, i, '[', ']', false, width, prefix, "", sortkeys, 0, 0, max) + if ok && len(buf)-s1 <= max { + return buf, i, nl, true + } + buf = buf[:s1] + i = s2 + } + } else if max != -1 && open == '{' { + return buf, i, nl, false + } + } + buf = append(buf, open) + i++ + var pairs []pair + if open == '{' && sortkeys { + pairs = make([]pair, 0, 8) + } + var n int + for ; i < len(json); i++ { + if json[i] <= ' ' { + continue + } + if json[i] == close { + if pretty { + if open == '{' && sortkeys { + buf = sortPairs(json, buf, pairs) + } + if n > 0 { + nl = len(buf) + buf = append(buf, '\n') + } + if buf[len(buf)-1] != open { + buf = appendTabs(buf, prefix, indent, tabs) + } + } + buf = append(buf, close) + return buf, i + 1, nl, open != '{' + } + if open == '[' || json[i] == '"' { + if n > 0 { + buf = append(buf, ',') + if width != -1 && open == '[' { + buf = append(buf, ' ') + } + } + var p pair + if pretty { + nl = len(buf) + buf = append(buf, '\n') + if open == '{' && sortkeys { + p.kstart = i + p.vstart = len(buf) + } + buf = appendTabs(buf, prefix, indent, tabs+1) + } + if open == '{' { + buf, i, nl, _ = appendPrettyString(buf, json, i, nl) + if sortkeys { + p.kend = i + } + buf = append(buf, ':') + if pretty { + buf = append(buf, ' ') + } + } + buf, i, nl, ok = appendPrettyAny(buf, json, i, pretty, width, prefix, indent, sortkeys, tabs+1, nl, max) + if max != -1 && !ok { + return buf, i, nl, false + } + if pretty && open == '{' && sortkeys { + p.vend = len(buf) + if p.kstart > p.kend || p.vstart > p.vend { + // bad data. disable sorting + sortkeys = false + } else { + pairs = append(pairs, p) + } + } + i-- + n++ + } + } + return buf, i, nl, open != '{' +} +func sortPairs(json, buf []byte, pairs []pair) []byte { + if len(pairs) == 0 { + return buf + } + vstart := pairs[0].vstart + vend := pairs[len(pairs)-1].vend + arr := byKey{false, json, pairs} + sort.Sort(&arr) + if !arr.sorted { + return buf + } + nbuf := make([]byte, 0, vend-vstart) + for i, p := range pairs { + nbuf = append(nbuf, buf[p.vstart:p.vend]...) + if i < len(pairs)-1 { + nbuf = append(nbuf, ',') + nbuf = append(nbuf, '\n') + } + } + return append(buf[:vstart], nbuf...) +} + +func appendPrettyString(buf, json []byte, i, nl int) ([]byte, int, int, bool) { + s := i + i++ + for ; i < len(json); i++ { + if json[i] == '"' { + var sc int + for j := i - 1; j > s; j-- { + if json[j] == '\\' { + sc++ + } else { + break + } + } + if sc%2 == 1 { + continue + } + i++ + break + } + } + return append(buf, json[s:i]...), i, nl, true +} + +func appendPrettyNumber(buf, json []byte, i, nl int) ([]byte, int, int, bool) { + s := i + i++ + for ; i < len(json); i++ { + if json[i] <= ' ' || json[i] == ',' || json[i] == ':' || json[i] == ']' || json[i] == '}' { + break + } + } + return append(buf, json[s:i]...), i, nl, true +} + +func appendTabs(buf []byte, prefix, indent string, tabs int) []byte { + if len(prefix) != 0 { + buf = append(buf, prefix...) + } + if len(indent) == 2 && indent[0] == ' ' && indent[1] == ' ' { + for i := 0; i < tabs; i++ { + buf = append(buf, ' ', ' ') + } + } else { + for i := 0; i < tabs; i++ { + buf = append(buf, indent...) + } + } + return buf +} + +// Style is the color style +type Style struct { + Key, String, Number [2]string + True, False, Null [2]string + Append func(dst []byte, c byte) []byte +} + +func hexp(p byte) byte { + switch { + case p < 10: + return p + '0' + default: + return (p - 10) + 'a' + } +} + +// TerminalStyle is for terminals +var TerminalStyle = &Style{ + Key: [2]string{"\x1B[94m", "\x1B[0m"}, + String: [2]string{"\x1B[92m", "\x1B[0m"}, + Number: [2]string{"\x1B[93m", "\x1B[0m"}, + True: [2]string{"\x1B[96m", "\x1B[0m"}, + False: [2]string{"\x1B[96m", "\x1B[0m"}, + Null: [2]string{"\x1B[91m", "\x1B[0m"}, + Append: func(dst []byte, c byte) []byte { + if c < ' ' && (c != '\r' && c != '\n' && c != '\t' && c != '\v') { + dst = append(dst, "\\u00"...) + dst = append(dst, hexp((c>>4)&0xF)) + return append(dst, hexp((c)&0xF)) + } + return append(dst, c) + }, +} + +// Color will colorize the json. The style parma is used for customizing +// the colors. Passing nil to the style param will use the default +// TerminalStyle. +func Color(src []byte, style *Style) []byte { + if style == nil { + style = TerminalStyle + } + apnd := style.Append + if apnd == nil { + apnd = func(dst []byte, c byte) []byte { + return append(dst, c) + } + } + type stackt struct { + kind byte + key bool + } + var dst []byte + var stack []stackt + for i := 0; i < len(src); i++ { + if src[i] == '"' { + key := len(stack) > 0 && stack[len(stack)-1].key + if key { + dst = append(dst, style.Key[0]...) + } else { + dst = append(dst, style.String[0]...) + } + dst = apnd(dst, '"') + for i = i + 1; i < len(src); i++ { + dst = apnd(dst, src[i]) + if src[i] == '"' { + j := i - 1 + for ; ; j-- { + if src[j] != '\\' { + break + } + } + if (j-i)%2 != 0 { + break + } + } + } + if key { + dst = append(dst, style.Key[1]...) + } else { + dst = append(dst, style.String[1]...) + } + } else if src[i] == '{' || src[i] == '[' { + stack = append(stack, stackt{src[i], src[i] == '{'}) + dst = apnd(dst, src[i]) + } else if (src[i] == '}' || src[i] == ']') && len(stack) > 0 { + stack = stack[:len(stack)-1] + dst = apnd(dst, src[i]) + } else if (src[i] == ':' || src[i] == ',') && len(stack) > 0 && stack[len(stack)-1].kind == '{' { + stack[len(stack)-1].key = !stack[len(stack)-1].key + dst = apnd(dst, src[i]) + } else { + var kind byte + if (src[i] >= '0' && src[i] <= '9') || src[i] == '-' { + kind = '0' + dst = append(dst, style.Number[0]...) + } else if src[i] == 't' { + kind = 't' + dst = append(dst, style.True[0]...) + } else if src[i] == 'f' { + kind = 'f' + dst = append(dst, style.False[0]...) + } else if src[i] == 'n' { + kind = 'n' + dst = append(dst, style.Null[0]...) + } else { + dst = apnd(dst, src[i]) + } + if kind != 0 { + for ; i < len(src); i++ { + if src[i] <= ' ' || src[i] == ',' || src[i] == ':' || src[i] == ']' || src[i] == '}' { + i-- + break + } + dst = apnd(dst, src[i]) + } + if kind == '0' { + dst = append(dst, style.Number[1]...) + } else if kind == 't' { + dst = append(dst, style.True[1]...) + } else if kind == 'f' { + dst = append(dst, style.False[1]...) + } else if kind == 'n' { + dst = append(dst, style.Null[1]...) + } + } + } + } + return dst +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/modules.txt" "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/modules.txt" new file mode 100644 index 0000000000000000000000000000000000000000..46126c4721243fe336d55ad28c5188a4ef648e15 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goProject/vendor/modules.txt" @@ -0,0 +1,10 @@ +# github.com/shopspring/decimal v1.2.0 +## explicit +github.com/shopspring/decimal +# github.com/tidwall/gjson v1.6.0 +## explicit +github.com/tidwall/gjson +# github.com/tidwall/match v1.0.1 +github.com/tidwall/match +# github.com/tidwall/pretty v1.0.0 +github.com/tidwall/pretty diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/.gitignore" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/.gitignore" new file mode 100644 index 0000000000000000000000000000000000000000..73f69e0958611ac6e00bde95641f6699030ad235 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/.gitignore" @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/goStudy.iml" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/goStudy.iml" new file mode 100644 index 0000000000000000000000000000000000000000..c956989b29ad0767edc6cf3a202545927c3d1e76 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/goStudy.iml" @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/misc.xml" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/misc.xml" new file mode 100644 index 0000000000000000000000000000000000000000..28a804d8932aba40f168fd757a74cb718a955a1a --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/misc.xml" @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/modules.xml" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/modules.xml" new file mode 100644 index 0000000000000000000000000000000000000000..cccf7dc254a8daf3179264397d8cea31293d2646 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/modules.xml" @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/vcs.xml" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/vcs.xml" new file mode 100644 index 0000000000000000000000000000000000000000..c2365ab11f9ba6b763735c8fd976420234bb3521 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/.idea/vcs.xml" @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/10_timeDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/10_timeDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..1b114dbfc52b3915823842a5e2e7001dcdffa62f --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/10_timeDemo.go" @@ -0,0 +1,69 @@ +package main + +import ( + "fmt" + "time" +) + +func main() { + timeObj := time.Now() + year := timeObj.Year() + month := timeObj.Month() + day := timeObj.Day() + + fmt.Printf("%d-%02d-%02d \n", year, month, day) + + /** + 时间类型有一个自带的方法 Format进行格式化 + 需要注意的是Go语言中格式化时间模板不是长久的 Y-m-d H:M:S + 而是使用Go的诞生时间 2006年1月2日 15点04分 (记忆口诀:2006 1 2 3 4 5) + */ + timeObj2 := time.Now() + fmt.Println(timeObj2.Format("2006-01-02 03:04:05")) + + /** + 获取当前时间戳 + */ + timeObj3 := time.Now() + // 获取秒时间戳 + unixTime := timeObj3.Unix() + // 获取毫秒时间戳 + unixNaTime := timeObj3.UnixNano() + fmt.Println(unixTime) + fmt.Println(unixNaTime) + + // 时间戳转换年月日时分秒(一个参数是秒,另一个参数是毫秒) + var timeObj4 = time.Unix(1595289901, 0) + var timeStr = timeObj4.Format("2006-01-02 15:04:05") + fmt.Println(timeStr) + + // 日期字符串转换成时间戳 + var timeStr2 = "2020-07-21 08:10:05"; + var tmp = "2006-01-02 15:04:05" + timeObj5, _ := time.ParseInLocation(tmp, timeStr2, time.Local) + fmt.Println(timeObj5.Unix()) + + // 时间相加 + now := time.Now() + // 当前时间加1个小时后 + later := now.Add(time.Hour) + fmt.Println(later) + + // 定时器, 定义一个1秒间隔的定时器 + ticker := time.NewTicker(time.Second) + n := 0 + for i := range ticker.C { + fmt.Println(i) + n++ + if n>5 { + ticker.Stop() + return + } + } + + for { + time.Sleep(time.Second) + fmt.Println("一秒后") + } + +} \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/11_pointerDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/11_pointerDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..ad97f719c328df0a6070589bd2ee364e1690ed80 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/11_pointerDemo.go" @@ -0,0 +1,24 @@ +package main + +import "fmt" + +func main() { + var a = 10 + fmt.Printf("a的值: %v,a的类型: %T,a的地址: %p \n", a, a, &a) + + var b = 10 + // p的值就是b的地址 + var p = &b + fmt.Println(b, " ", p) + + // 指针取值 + var c = 20 + var d = &c + fmt.Println(*d) + // c对应地址的值,改成30 + *d = 30 + // c已经变成30了 + fmt.Println(c) + + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/11_pointerDemo2.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/11_pointerDemo2.go" new file mode 100644 index 0000000000000000000000000000000000000000..8d398cad4dc355b02c2b84091bfb6c64c1563003 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/11_pointerDemo2.go" @@ -0,0 +1,40 @@ +package main + +import "fmt" + +func fn4(x int) { + x = 10 +} +func fn5(x *int) { + *x = 20 +} +func main() { + x := 5 + fn4(x) + fmt.Println(x) + fn5(&x) + fmt.Println(x) + + // 引用数据类型map、slice等,必须使用make分配空间,才能够使用 + var userInfo = make(map[string]string) + userInfo["userName"] = "zhangsan" + fmt.Println(userInfo) + + var array = make([]int, 4, 4) + array[0] = 1 + fmt.Println(array) + + // 指针变量初始化 + //var a *int + //*a = 100 + //fmt.Println(a) + + // 使用new关键字创建指针 + aPoint := new(int) + bPoint := new(bool) + fmt.Printf("%T \n", aPoint) + fmt.Printf("%T \n", bPoint) + fmt.Println(*aPoint) + fmt.Println(*bPoint) + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..1f807b10a279d08dce17f8eeb8efb55e6e83ee70 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo.go" @@ -0,0 +1,60 @@ +package main + +import "fmt" + +/** + 定义一个人结构体 + */ +type Person struct { + name string + age int + sex string + + +} +func main() { + // 实例化结构体 + var person Person + person.name = "张三" + person.age = 20 + person.sex = "男" + fmt.Printf("%#v", person) + + // 第二种方式实例化 + var person2 = new(Person) + person2.name = "李四" + person2.age = 30 + person2.sex = "女" + fmt.Printf("%#v", person2) + + // 第三种方式实例化 + var person3 = &Person{} + person3.name = "赵四" + person3.age = 28 + person3.sex = "男" + fmt.Printf("%#v", person3) + + // 第四种方式初始化 + var person4 = Person{ + name: "张三", + age: 10, + sex: "女", + } + fmt.Printf("%#v", person4) + + // 第五种方式初始化 + var person5 = &Person{ + name: "孙五", + age: 10, + sex: "女", + } + fmt.Printf("%#v", person5) + + var person6 = Person{ + "张三", + 5, + "女", + } + fmt.Println(person6) + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo2.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo2.go" new file mode 100644 index 0000000000000000000000000000000000000000..491f77fe7cbb70366181b6a758eb52ca7d31c916 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo2.go" @@ -0,0 +1,36 @@ +package main + +import "fmt" + +/** + 定义一个人结构体 + */ +type Person struct { + name string + age int + sex string +} + +// 定义一个结构体方法 +func (p Person) PrintInfo() { + fmt.Print(" 姓名: ", p.name) + fmt.Print(" 年龄: ", p.age) + fmt.Print(" 性别: ", p.sex) + fmt.Println() +} +func (p *Person) SetInfo(name string, age int, sex string) { + p.name = name + p.age = age + p.sex = sex +} + +func main() { + var person = Person{ + "张三", + 18, + "女", + } + person.PrintInfo() + person.SetInfo("李四", 18, "男") + person.PrintInfo() +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo3.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo3.go" new file mode 100644 index 0000000000000000000000000000000000000000..53329859199057140e413d1149988208c8bf56ab --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo3.go" @@ -0,0 +1,34 @@ +package main + +import "fmt" + +/** + 定义一个人结构体 + */ +type Person struct { + name string + age int + hobby []string + mapValue map[string]string +} + +func main() { + // 结构体的匿名字段 + var person = Person{} + person.name = "张三" + person.age = 10 + + // 给切片申请内存空间 + person.hobby = make([]string, 4, 4) + person.hobby[0] = "睡觉" + person.hobby[1] = "吃饭" + person.hobby[2] = "打豆豆" + + // 给map申请存储空间 + person.mapValue = make(map[string]string) + person.mapValue["address"] = "北京" + person.mapValue["phone"] = "123456789" + + // 加入#打印完整信息 + fmt.Printf("%#v", person) +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo4.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo4.go" new file mode 100644 index 0000000000000000000000000000000000000000..475b4e1a34dc58007d80d687a4f2c7a0ef811816 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo4.go" @@ -0,0 +1,36 @@ +package main + +import "fmt" + +// 结构体嵌套 + +// 用户结构体 +type User struct { + userName string + password string + sex string + age int + address Address // User结构体嵌套Address结构体 +} + +// 收货地址结构体 +type Address struct { + name string + phone string + city string +} + +func main() { + var u User + u.userName = "moguBlog" + u.password = "123456" + u.sex = "男" + u.age = 18 + + var address Address + address.name = "张三" + address.phone = "110" + address.city = "北京" + u.address = address + fmt.Printf("%#v", u) +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo5.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo5.go" new file mode 100644 index 0000000000000000000000000000000000000000..812f2f97904d7977eb966cbe11db61d195188ab5 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructDemo5.go" @@ -0,0 +1,31 @@ +package main +import "fmt" + +// 结构体的继承 +// 用户结构体 +type Animal struct { + name string +} +func (a Animal) run() { + fmt.Printf("%v 在运动 \n", a.name) +} +// 子结构体 +type Dog struct { + age int + // 通过结构体嵌套,完成继承 + Animal +} +func (dog Dog) wang() { + fmt.Printf("%v 在汪汪汪 \n", dog.name) +} + +func main() { + var dog = Dog{ + age: 10, + Animal: Animal{ + name: "阿帕奇", + }, + } + dog.run(); + dog.wang(); +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructJsonDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructJsonDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..5e4192fb7d6a65a9cc7d22e6b3e6dc09d0a9c8eb --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructJsonDemo.go" @@ -0,0 +1,39 @@ +package main + +import ( + "encoding/json" + "fmt" +) + +// 结构体和Json互相转换 + +// 定义一个学生结构体,注意结构体的首字母必须大写,代表公有,否则将无法转换 +type Student struct { + ID string + Gender string + Name string + Sno string +} +func main() { + var s1 = Student{ + ID: "12", + Gender: "男", + Name: "李四", + Sno: "s001", + } + // 结构体转换成Json + jsonByte, _ := json.Marshal(s1) + jsonStr := string(jsonByte) + fmt.Println(jsonStr) + + // Json字符串转换成结构体 + var str = `{"ID":"12","Gender":"男","Name":"李四","Sno":"s001"}` + var s2 = Student{} + // 第一个是需要传入byte类型的数据,第二参数需要传入转换的地址 + err := json.Unmarshal([]byte(str), &s2) + if err != nil { + fmt.Printf("转换失败 \n") + } else { + fmt.Printf("%#v \n", s2) + } +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructJsonDemo2.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructJsonDemo2.go" new file mode 100644 index 0000000000000000000000000000000000000000..a8358c923b867b602c2660e9ad29bd03f7cc3252 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructJsonDemo2.go" @@ -0,0 +1,39 @@ +package main + +import ( + "encoding/json" + "fmt" +) + +// 结构体标签 + +// 定义一个Student体,使用结构体标签 +type Student2 struct { + Id string `json:"id"` // 通过指定tag实现json序列化该字段的key + Gender string `json:"gender"` + Name string `json:"name"` + Sno string `json:"sno"` +} +func main() { + var s1 = Student2{ + Id: "12", + Gender: "男", + Name: "李四", + Sno: "s001", + } + // 结构体转换成Json + jsonByte, _ := json.Marshal(s1) + jsonStr := string(jsonByte) + fmt.Println(jsonStr) + + // Json字符串转换成结构体 + var str = `{"Id":"12","Gender":"男","Name":"李四","Sno":"s001"}` + var s2 = Student2{} + // 第一个是需要传入byte类型的数据,第二参数需要传入转换的地址 + err := json.Unmarshal([]byte(str), &s2) + if err != nil { + fmt.Printf("转换失败 \n") + } else { + fmt.Printf("%#v \n", s2) + } +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructJsonDemo3.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructJsonDemo3.go" new file mode 100644 index 0000000000000000000000000000000000000000..0e52ac181badb9a3920ef892a5156a6fb49aec33 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_StructJsonDemo3.go" @@ -0,0 +1,45 @@ +package main + +import ( + "encoding/json" + "fmt" +) + +// 嵌套结构体 到 Json的互相转换 + +// 定义一个Student结构体 +type Student3 struct { + Id int + Gender string + Name string +} + +// 定义一个班级结构体 +type Class struct { + Title string + Students []Student3 +} + +func main() { + var class = Class{ + Title: "1班", + Students: make([]Student3, 0), + } + for i := 0; i < 10; i++ { + s := Student3{ + Id: i + 1, + Gender: "男", + Name: fmt.Sprintf("stu_%v", i + 1), + } + class.Students = append(class.Students, s) + } + fmt.Printf("%#v \n", class) + + // 转换成Json字符串 + strByte, err := json.Marshal(class) + if err != nil { + fmt.Println("打印失败") + } else { + fmt.Println(string(strByte)) + } +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_TypeDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_TypeDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..985219d79513cda5954a88b949f856cc204d30da --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/12_TypeDemo.go" @@ -0,0 +1,16 @@ +package main + +import "fmt" + +type myInt int +func fun(x int, y int)int { + return x + y +} +func (m myInt) PrintInfo() { + fmt.Println("我是自定义类型里面的自定义方法") +} +func main() { + var a myInt = 10 + fmt.Printf("%v %T \n", a, a) + a.PrintInfo() +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..14089562fc5172782130ed05783adb50f432448b --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo.go" @@ -0,0 +1,48 @@ +package main + +import "fmt" + +func main() { + //// 声明一个传递整型的管道 + //var ch1 chan int + //// 声明一个传递布尔类型的管道 + //var ch2 chan bool + //// 声明一个传递int切片的管道 + //var ch3 chan []int + // + //// 创建一个能存储10个int类型的数据管道 + //ch1 = make(chan int, 10) + //// 创建一个能存储4个bool类型的数据管道 + //ch2 = make(chan bool, 4) + //// 创建一个能存储3个[]int切片类型的管道 + //ch3 = make(chan []int, 3) + + + // 创建管道 + ch := make(chan int, 3) + + // 给管道里面存储数据 + ch <- 10 + ch <- 21 + ch <- 32 + + // 获取管道里面的内容 + a := <- ch + fmt.Println("打印出管道的值:", a) + fmt.Println("打印出管道的值:", <- ch) + fmt.Println("打印出管道的值:", <- ch) + + // 管道的值、容量、长度 + fmt.Printf("地址:%v 容量:%v 长度:%v \n", ch, cap(ch), len(ch)) + + // 管道的类型 + fmt.Printf("%T \n", ch) + + // 管道阻塞(当没有数据的时候取,会出现阻塞,同时当管道满了,继续存也会) + <- ch // 没有数据取,出现阻塞 + ch <- 10 + ch <- 10 + ch <- 10 + ch <- 10 // 管道满了,继续存,也出现阻塞 + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo2.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo2.go" new file mode 100644 index 0000000000000000000000000000000000000000..63d3b682097192082229f0bd9cd1b00b57371c22 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo2.go" @@ -0,0 +1,26 @@ +package main + +import "fmt" + +func main() { + + // 创建管道 + ch := make(chan int, 10) + // 循环写入值 + for i := 0; i < 10; i++ { + ch <- i + } + // 关闭管道 + close(ch) + + // for range循环遍历管道的值(管道没有key) + for value := range ch { + fmt.Println(value) + } + // 通过上述的操作,能够打印值,但是出出现一个deadlock的死锁错误,也就说我们需要关闭管道 + + for i := 0; i < 10; i++ { + fmt.Println(<- ch) + } + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo3.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo3.go" new file mode 100644 index 0000000000000000000000000000000000000000..05778ae431028561ae651f549dc474a3f9f040f4 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo3.go" @@ -0,0 +1,35 @@ +package main + +import ( + "fmt" + "sync" + "time" +) + +func write(ch chan int) { + for i := 0; i < 10; i++ { + fmt.Println("写入:", i) + ch <- i + time.Sleep(time.Microsecond * 10) + } + wg.Done() +} +func read(ch chan int) { + for i := 0; i < 10; i++ { + fmt.Println("读取:", <- ch) + time.Sleep(time.Microsecond * 10) + } + wg.Done() +} +var wg sync.WaitGroup +func main() { + ch := make(chan int, 10) + wg.Add(1) + go write(ch) + wg.Add(1) + go read(ch) + + // 等待 + wg.Wait() + fmt.Println("主线程执行完毕") +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo4.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo4.go" new file mode 100644 index 0000000000000000000000000000000000000000..db295bcddd2babd62df3403df3f89c5480974474 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo4.go" @@ -0,0 +1,89 @@ +package main + +import ( + "fmt" + "sync" +) + +// 想intChan中放入 1~ 120000个数 +func putNum(intChan chan int) { + for i := 3; i < 120000; i++ { + intChan <- i + } + wg.Done() + close(intChan) +} + +// cong intChan取出数据,并判断是否为素数,如果是的话,就把得到的素数放到primeChan中 +func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) { + for value := range intChan { + var flag = true + for i := 2; i < value; i++ { + if value % i == 0 { + flag = false + break + } + } + if flag { + // 是素数 + primeChan <- value + break + } + } + + // 这里需要关闭 primeChan,因为后面需要遍历输出 primeChan + exitChan <- true + + wg.Done() +} + +// 打印素数 +func printPrime(primeChan chan int) { + for value := range primeChan { + fmt.Println(value) + } + wg.Done() +} + + +var wg sync.WaitGroup +func main() { + // 写入数字 + intChan := make(chan int, 1000) + + // 存放素数 + primeChan := make(chan int, 1000) + + // 存放 primeChan退出状态 + exitChan := make(chan bool, 16) + + // 开启写值的协程 + wg.Add(1) + go putNum(intChan) + + // 开启计算素数的协程 + for i := 0; i < 16; i++ { + wg.Add(1) + go primeNum(intChan, primeChan, exitChan) + } + + // 开启打印的协程 + wg.Add(1) + go printPrime(primeChan) + + // 匿名自运行函数 + wg.Add(1) + go func() { + for i := 0; i < 16; i++ { + // 如果exitChan 没有完成16次遍历,将会等待 + <- exitChan + } + // 关闭primeChan + close(primeChan) + wg.Done() + }() + + wg.Wait() + fmt.Println("主线程执行完毕") + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo5.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo5.go" new file mode 100644 index 0000000000000000000000000000000000000000..f576ee2bfadbaef053ac0a52e35275d9c80a933f --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_ChannelDemo5.go" @@ -0,0 +1,59 @@ +package main + +import "fmt" + +func sayHello() { + for i := 0; i < 10; i++ { + fmt.Println("hello") + } +} +func errTest() { + // 捕获异常 + defer func() { + if err := recover(); err != nil { + fmt.Println("errTest发生错误") + } + }() + var myMap map[int]string + myMap[0] = "10" +} +func main() { + + //// 定义一种可读可写的管道 + //var ch = make(chan int, 2) + //ch <- 10 + //<- ch + // + //// 管道声明为只写管道,只能够写入,不能读 + //var ch2 = make(chan<- int, 2) + //ch2 <- 10 + // + //// 声明一个只读管道 + //var ch3 = make(<-chan int, 2) + //<- ch3 + + intChan := make(chan int, 10) + intChan <- 10 + intChan <- 12 + intChan <- 13 + stringChan := make(chan int, 10) + stringChan <- 20 + stringChan <- 23 + stringChan <- 24 + + // 每次循环的时候,会随机中一个chan中读取,其中for是死循环 + for { + select { + case v:= <- intChan: + fmt.Println("从initChan中读取数据:", v) + case v:= <- stringChan: + fmt.Println("从stringChan中读取数据:", v) + default: + fmt.Println("所有的数据获取完毕") + return + } + } + + + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_goroutineDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_goroutineDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..538b41d0fcb75931d13e94d5bb3f5f03a32518da --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_goroutineDemo.go" @@ -0,0 +1,51 @@ +package main + +import ( + "fmt" + "sync" +) + +// 定义一个协程计数器 +var wg sync.WaitGroup + +func test() { + // 这是主进程执行的 + for i := 0; i < 1000; i++ { + fmt.Println("test1 你好golang", i) + //time.Sleep(time.Millisecond * 100) + } + // 协程计数器减1 + wg.Done() +} + +func test2() { + // 这是主进程执行的 + for i := 0; i < 1000; i++ { + fmt.Println("test2 你好golang", i) + //time.Sleep(time.Millisecond * 100) + } + // 协程计数器减1 + wg.Done() +} + + + +func main() { + + // 通过go关键字,就可以直接开启一个协程 + wg.Add(1) + go test() + + // 协程计数器加1 + wg.Add(1) + go test2() + + // 这是主进程执行的 + for i := 0; i < 1000; i++ { + fmt.Println("main 你好golang", i) + //time.Sleep(time.Millisecond * 100) + } + // 等待所有的协程执行完毕 + wg.Wait() + fmt.Println("主线程退出") +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_goroutineDemo2.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_goroutineDemo2.go" new file mode 100644 index 0000000000000000000000000000000000000000..b9bba806831953370313f0fd8425bad98c45d184 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_goroutineDemo2.go" @@ -0,0 +1,32 @@ +package main + +import ( + "fmt" + "runtime" + "sync" +) + +func test(num int) { + for i := 0; i < 10; i++ { + fmt.Printf("协程(%v)打印的第%v条数据 \n", num, i) + } + // 协程计数器减1 + vg.Done() +} + +var vg sync.WaitGroup + +func main() { + // 获取cpu个数 + npmCpu := runtime.NumCPU() + fmt.Println("cup的个数:", npmCpu) + // 设置允许使用的CPU数量 + runtime.GOMAXPROCS(runtime.NumCPU() - 1) + + for i := 0; i < 10; i++ { + go test(i) + vg.Add(1) + } + vg.Wait() + fmt.Println("主线程退出") +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_lockDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_lockDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..2ed6269a7f5289961926b6030774dd5d388da572 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/15_lockDemo.go" @@ -0,0 +1,29 @@ +package main + +import ( + "fmt" + "sync" + "time" +) + +var count = 0 +var wg sync.WaitGroup +var mutex sync.Mutex + +func test() { + // 加锁 + mutex.Lock() + count++ + fmt.Println("the count is : ", count) + time.Sleep(time.Millisecond) + wg.Done() + // 解锁 + mutex.Unlock() +} +func main() { + for i := 0; i < 20; i++ { + wg.Add(1) + go test() + } + time.Sleep(time.Second * 10) +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/16_StructReflectDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/16_StructReflectDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..21c231498476a350f2ab43f37dd442a1315ef6e5 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/16_StructReflectDemo.go" @@ -0,0 +1,103 @@ +package main + +import ( + "fmt" + "reflect" +) + +// 学生结构体 +type Student4 struct { + Name string `json: "name"` + Age int `json: "age"` + Score int `json: "score"` +} + +func (s Student4)GetInfo()string { + var str = fmt.Sprintf("姓名:%v 年龄:%v 成绩:%v", s.Name, s.Age, s.Score) + return str +} +func (s *Student4)SetInfo(name string, age int, score int) { + s.Name = name + s.Age = age + s.Score = score +} +func (s Student4)PrintStudent() { + fmt.Println("打印学生") +} +// 打印结构体中的字段 +func PrintStructField(s interface{}) { + t := reflect.TypeOf(s) + // 判断传递过来的是否是结构体 + if t.Kind() != reflect.Struct && t.Elem().Kind() != reflect.Struct { + fmt.Println("请传入结构体类型!") + return + } + + // 通过类型变量里面的Field可以获取结构体的字段 + field0 := t.Field(0) // 获取第0个字段 + fmt.Printf("%#v \n", field0) + fmt.Println("字段名称:", field0.Name) + fmt.Println("字段类型:", field0.Type) + fmt.Println("字段Tag:", field0.Tag.Get("json")) + + // 通过类型变量里面的FieldByName可以获取结构体的字段中 + field1, ok := t.FieldByName("Age") + if ok { + fmt.Println("字段名称:", field1.Name) + fmt.Println("字段类型:", field1.Type) + fmt.Println("字段Tag:", field1.Tag) + } + + // 通过类型变量里面的NumField获取该结构体有几个字段 + var fieldCount = t.NumField() + fmt.Println("结构体有:", fieldCount, " 个属性") + + // 获取结构体属性对应的值 + v := reflect.ValueOf(s) + nameValue := v.FieldByName("Name") + fmt.Println("nameValue:", nameValue) +} + +// 打印执行方法 +func PrintStructFn(s interface{}) { + t := reflect.TypeOf(s) + // 判断传递过来的是否是结构体 + if t.Kind() != reflect.Struct && t.Elem().Kind() != reflect.Struct { + fmt.Println("请传入结构体类型!") + return + } + // 通过类型变量里面的Method,可以获取结构体的方法 + method0 := t.Method(0) + // 获取第一个方法, 这个是和ACSII相关 + fmt.Println(method0.Name) + + // 通过类型变量获取这个结构体有多少方法 + methodCount := t.NumMethod() + fmt.Println("拥有的方法", methodCount) + + // 通过值变量 执行方法(注意需要使用值变量,并且要注意参数) + v := reflect.ValueOf(s) + // 通过值变量来获取参数 + v.MethodByName("PrintStudent").Call(nil) + + // 手动传参 + var params []reflect.Value + params = append(params, reflect.ValueOf("张三")) + params = append(params, reflect.ValueOf(23)) + params = append(params, reflect.ValueOf(99)) + // 执行setInfo方法 + v.MethodByName("SetInfo").Call(params) + + // 通过值变量来获取参数 + v.MethodByName("PrintStudent").Call(nil) +} +func main() { + + student := Student4{ + "张三", + 18, + 95, + } + PrintStructField(student) + PrintStructFn(&student) +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/16_reflectDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/16_reflectDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..520834f6ddfe0c7fa255b9cc7ad96deb009430d9 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/16_reflectDemo.go" @@ -0,0 +1,45 @@ +package main + +import ( + "fmt" + "reflect" +) + +func reflectFun(x interface{}) { + v := reflect.TypeOf(x) + fmt.Println(v) + fmt.Println("类型名称", v.Name()) + fmt.Println("类型种类", v.Kind()) +} +func reflectValue(x interface{}) { + b,_ := x.(int) + var num = 10 + b + fmt.Println(num) +} +func reflectValue2(x interface{}) { + // 通过反射来获取变量的原始值 + v := reflect.ValueOf(x) + fmt.Println(v) + // 获取到V的int类型 + var n = v.Int() + 12 + fmt.Println(n) + + kind := v.Kind() + switch kind { + case reflect.Int: + fmt.Println("我是int类型") + case reflect.Float64: + fmt.Println("我是float64类型") + default: + fmt.Println("我是其它类型") + } + +} +func main() { + reflectFun(10) + reflectFun(10.01) + reflectFun("abc") + reflectFun(true) + + reflectValue2(10) +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/17_fileCopyDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/17_fileCopyDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..dbdf86be2243e1ec97c5eaf1e383fb2de89049bf --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/17_fileCopyDemo.go" @@ -0,0 +1,17 @@ +package main + +import ( + "fmt" + "io/ioutil" +) + +func main() { + // 读取文件 + byteStr, err := ioutil.ReadFile("./main/test.txt") + if err != nil { + fmt.Println("读取文件出错") + return + } + // 写入指定的文件 + ioutil.WriteFile("./main/test2.txt", byteStr, 777) +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/17_fileDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/17_fileDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..19e0bd23cbea5b87626dc1f9c59b95167a0ef95e --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/17_fileDemo.go" @@ -0,0 +1,30 @@ +package main + +import ( + "fmt" + "io" + "os" +) + +func main() { + // 读取文件 方法1 + file, err := os.Open("./main/test.txt") + // 关闭文件流 + defer file.Close(); + if err != nil { + fmt.Println("打开文件出错") + } + // 读取文件里面的内容 + var tempSlice = make([]byte, 1024) + var strSlice []byte + for { + n, err := file.Read(tempSlice) + if err == io.EOF { + fmt.Printf("读取完毕") + break + } + fmt.Printf("读取到了%v 个字节 \n", n) + strSlice := append(strSlice, tempSlice...) + fmt.Println(string(strSlice)) + } +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/17_fileDemo2.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/17_fileDemo2.go" new file mode 100644 index 0000000000000000000000000000000000000000..26416d749b8401cf236d26464b5a7c92616a1cb3 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/17_fileDemo2.go" @@ -0,0 +1,45 @@ +package main + +import ( + "bufio" + "fmt" + "io" + "io/ioutil" + "os" +) + +func main() { + // 读取文件 方法2 + file, err := os.Open("./main/test.txt") + // 关闭文件流 + defer file.Close(); + if err != nil { + fmt.Println("打开文件出错") + } + // 通过创建bufio来读取 + reader := bufio.NewReader(file) + var fileStr string + var count int = 0 + for { + // 相当于读取一行 + str, err := reader.ReadString('\n') + if err == io.EOF { + // 读取完成的时候,也会有内容 + fileStr += str + fmt.Println("读取结束", count) + break + } + if err != nil { + fmt.Println(err) + break + } + count ++ + fileStr += str + } + fmt.Println(fileStr) + + + // 通过IOUtil读取 + byteStr, _ := ioutil.ReadFile("./main/test.txt") + fmt.Println(string(byteStr)) +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/17_fileDemo3.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/17_fileDemo3.go" new file mode 100644 index 0000000000000000000000000000000000000000..cf10f2ba210b1984364386065fa7d890a4e09ee4 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/17_fileDemo3.go" @@ -0,0 +1,27 @@ +package main + +import ( + "bufio" + "io/ioutil" + "os" +) + +func main() { + // 打开文件 + file, _ := os.OpenFile("./main/test.txt", os.O_CREATE | os.O_RDWR | os.O_APPEND, 777) + defer file.Close() + str := "啦啦啦 \r\n" + file.WriteString(str) + + // 通过bufio写入 + writer := bufio.NewWriter(file) + // 先将数据写入缓存 + writer.WriteString("你好,我是通过writer写入的 \r\n") + // 将缓存中的内容写入文件 + writer.Flush() + + // 第三种方式,通过ioutil + str2 := "hello" + ioutil.WriteFile("./main/test.txt", []byte(str2), 777) + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/6_ArrayDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/6_ArrayDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..106dfb2c5a1ac3479930378ae03be1f7e1599f3f --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/6_ArrayDemo.go" @@ -0,0 +1,71 @@ +package main + +import "fmt" + +func main() { + // 数组的长度是类型的一部分 + var arr1 [3]int + var arr2 [4]string + fmt.Printf("%T, %T \n", arr1, arr2) + + // 数组的初始化 第一种方法 + var arr3 [3]int + arr3[0] = 1 + arr3[1] = 2 + arr3[2] = 3 + fmt.Println(arr3) + + // 第二种初始化数组的犯法 + var arr4 = [4]int {10, 20, 30, 40} + fmt.Println(arr4) + + // 第三种数组初始化方法,自动推断数组长度 + var arr5 = [...]int{1, 2} + fmt.Println(arr5) + + // 第四种初始化数组的方法,指定下标 + a := [...]int{1:1, 3:5} + fmt.Println(a) + + for i := 0; i < len(a); i++ { + fmt.Print(a[i], " ") + } + + for _, value := range a { + fmt.Print(value, " ") + } + + fmt.Println() + // 值类型 引用类型 + // 基本数据类型和数组都是值类型 + var aa = 10 + bb := aa + aa = 20 + fmt.Println(aa, bb) + + // 数组 + var array1 = [...]int {1, 2, 3} + array2 := array1 + array2[0] = 3 + fmt.Println(array1, array2) + + // 切片定义 + var array3 = []int{1,2,3} + array4 := array3 + array4[0] = 3 + fmt.Println(array3, array4) + + // 二维数组 + var array5 = [...][2]int{{1,2},{2,3}} + for i := 0; i < len(array5); i++ { + for j := 0; j < len(array5[0]); j++ { + fmt.Println(array5[i][j]) + } + } + + for _, item := range array5 { + for _, item2 := range item { + fmt.Println(item2) + } + } +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/7_sliceDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/7_sliceDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..1db967e4ecb55936caaf9c76715fb5e1d5d0c8b2 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/7_sliceDemo.go" @@ -0,0 +1,76 @@ +package main + +import "fmt" + +func main() { + // 声明切片,把长度去除就是切片 + var slice = []int{1,2,3} + fmt.Println(slice) + + var slice2 [] int + fmt.Println(slice2 == nil) + + for i := 0; i < len(slice); i++ { + fmt.Print(slice[i], " ") + } + fmt.Println() + // 基于数组定义切片 + a := [5]int {55,56,57,58,59} + // 获取数组所有值,返回的是一个切片 + b := a[:] + // 从数组获取指定的切片 + c := a[1:4] + // 获取 下标3之前的数据(不包括3) + d := a[:3] + // 获取下标3以后的数据(包括3) + e := a[3:] + + fmt.Println(a) + fmt.Println(b) + fmt.Println(c) + fmt.Println(d) + fmt.Println(e) + + // 长度和容量 + s := []int {2,3,5,7,11,13} + fmt.Printf("长度%d 容量%d\n", len(s), cap(s)) + + ss := s[2:] + fmt.Printf("长度%d 容量%d\n", len(ss), cap(ss)) + + sss := s[2:4] + fmt.Printf("长度%d 容量%d\n", len(sss), cap(sss)) + + // make()函数创建切片 + fmt.Println() + var slices = make([]int, 4, 8) + //[0 0 0 0] + fmt.Println(slices) + // 长度:4, 容量8 + fmt.Printf("长度:%d, 容量%d \n", len(slices), cap(slices)) + + // 切片扩容 + slices2 := []int{1,2,3,4} + slices2 = append(slices2, 5) + fmt.Println(slices2) + + // 合并切片 + slices3 := []int{6,7,8} + slices2 = append(slices2, slices3...) + fmt.Println(slices2) + + // copy函数,我们知道切片 + var slices4 = []int{1,2,3,4} + var slices5 = make([]int, len(slices4), len(slices4)) + copy(slices5, slices4) + slices5[0] = 4 + fmt.Println(slices4) + fmt.Println(slices5) + + // 删除切片中的值 + var slices6 = []int {0,1,2,3,4,5,6,7,8,9} + // 删除下标为1的值 + slices6 = append(slices6[:1], slices6[2:]...) + fmt.Println(slices6) + +} \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/8_MapDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/8_MapDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..fd6e17fb094ebcd570928d71dff44c556e4f6a0f --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/8_MapDemo.go" @@ -0,0 +1,77 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + // 创建方式1 + var userInfo = make(map[string]string) + userInfo["userName"] = "zhangsan" + userInfo["age"] = "20" + userInfo["sex"] = "男" + fmt.Println(userInfo) + fmt.Println(userInfo["userName"]) + + // 创建方式2,map也支持声明的时候填充元素 + var userInfo2 = map[string]string{ + "username": "张三", + "age": "21", + "sex": "女", + } + fmt.Println(userInfo2) + + // 遍历map + for key, value := range userInfo2 { + fmt.Println("key:", key, " value:", value) + } + + // 判断是否存在,如果存在 ok = true,否则 ok = false + value, ok := userInfo2["username2"] + fmt.Println(value, ok) + + // 删除map数据里面的key,以及对应的值 + delete(userInfo2, "sex") + fmt.Println(userInfo2) + + // 切片在中存放map + var userInfoList = make([]map[string]string, 3, 3) + var user = map[string]string{ + "userName": "张安", + "age": "15", + } + var user2 = map[string]string{ + "userName": "张2", + "age": "15", + } + var user3 = map[string]string{ + "userName": "张3", + "age": "15", + } + userInfoList[0] = user + userInfoList[1] = user2 + userInfoList[2] = user3 + fmt.Println(userInfoList) + + for _, item := range userInfoList { + fmt.Println(item) + } + + // 将map类型的值 + var userinfo = make(map[string][]string) + userinfo["hobby"] = []string {"吃饭", "睡觉", "敲代码"} + fmt.Println(userinfo) + + // 写一个程序,统计一个字符串中每个单词出现的次数。比如 "how do you do" + var str = "how do you do" + array := strings.Split(str, " ") + fmt.Println(array) + countMap := make(map[string]int) + for _, item := range array { + countMap[item]++ + } + fmt.Println(countMap) + + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/9_FileDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/9_FileDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..b34aab65f0c4e15dc5dd638017eac60fbb92310d --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/9_FileDemo.go" @@ -0,0 +1,31 @@ +package main + +import ( + "errors" + "fmt" +) + +func readFile(fileName string) error { + if fileName == "main.go" { + return nil + } else { + return errors.New("读取文件失败") + } +} + +func myFn () { + defer func() { + e := recover() + if e != nil { + fmt.Println("给管理员发送邮件") + } + }() + err := readFile("XXX.go") + if err != nil { + panic(err) + } +} + +func main() { + myFn() +} \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/9_FunctionDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/9_FunctionDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..84d12510088a3c16350fd92e47479ad7296eb7bb --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/9_FunctionDemo.go" @@ -0,0 +1,139 @@ +package main + +import "fmt" + +// 求两个数的和 +func sumFn(x int, y int) (int){ + return x + y +} +func sunFn2(x ...int) int { + sum := 0 + for _, num := range x { + sum = sum + num + } + return sum +} + +// 可变参数必须在后面 +func sunFn3(x ...int ) int { + sum := 0 + for _, num := range x { + sum = sum + num + } + return sum +} + +// 方法多返回值 +func sunFn4(x int, y int)(sum int, sub int) { + sum = x + y + sub = x -y + return +} + +/** + 传递两个参数和一个方法 + */ +func sunFn (a int, b int, sum func(int, int)int) int { + return sum(a, b) +} + +// 返回一个方法 +type calcType func(int, int)int +func do(o string) calcType { + switch o { + case "+": + return func(i int, i2 int) int { + return i + i2 + } + case "-": + return func(i int, i2 int) int { + return i - i2 + } + case "*": + return func(i int, i2 int) int { + return i * i2 + } + case "/": + return func(i int, i2 int) int { + return i / i2 + } + default: + return nil + + } +} + +// 闭包的写法:函数里面嵌套一个函数,最后返回里面的函数就形成了闭包 +func adder() func() int { + var i = 10 + return func() int { + return i + 1 + } +} + +func adder2() func(y int) int { + var i = 10 + return func(y int) int { + i = i + y + return i + } +} + +func fn1() { + fmt.Println("fn1") +} + +func fn2() { + // 使用recover监听异常 + defer func() { + err := recover() + if err != nil { + fmt.Println(err) + } + }() + panic("抛出一个异常") +} + + +func main() { + //fmt.Println(sumFn(12,2)) + //fmt.Println(sunFn2(1, 2, 3, 4, 5, 7)) + //fmt.Println(sunFn(1, 2, sumFn)) + // + //add := do("+") + //fmt.Println(add(1,5)) + // + //func () { + // fmt.Println("匿名自执行函数") + //}() + // + //var fn = adder() + //fmt.Println(fn()) + //fmt.Println(fn()) + //fmt.Println(fn()) + // + // + //var fn2 = adder2() + //fmt.Println(fn2(10)) + //fmt.Println(fn2(10)) + //fmt.Println(fn2(10)) + // + //// defer函数 + //fmt.Println("1") + //defer fmt.Println("2") + //defer fmt.Println("3") + //fmt.Println("4") + + //fmt.Println("开始") + //defer func() { + // fmt.Println("1") + // fmt.Println("2") + //}() + //fmt.Println("结束") + + + fn1() + fn2() + fmt.Println("结束") + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/StringDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/StringDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..abcc4015601ce80e957f6e33e05f246eed016d16 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/StringDemo.go" @@ -0,0 +1,49 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + var str = "hello world" + var length = len(str) // 长度为11 + fmt.Println("字符串的长度为:" , length) + + // 中文占三个字符,所以长度为6 + var str2 = "你好" + fmt.Println("文字的长度为:", len(str2)) + + fmt.Println("拼接字符串~~~") + str3 := "你好" + str4 := "golang" + str5 := fmt.Sprintf("%v-%v", str3, str4) + fmt.Println(str5) + + fmt.Println("切割字符串") + str6 := "hello world" + arr := strings.Split(str6, " ") + fmt.Println(arr) + + fmt.Println("拼接字符串") + newStr := strings.Join(arr, "*") + fmt.Println(newStr) + + fmt.Println("判断字符串是否包含某个字符串") + var str7 = "abcdefg" + var str8 = "abc" + var isContains bool = strings.Contains(str7, str8) + fmt.Println(isContains) + + fmt.Println("前缀/后缀判断") + isPrefix := strings.HasPrefix(str7, "abc") + fmt.Println("是否包含指定前缀判断", isPrefix) + + isSuffix := strings.HasSuffix(str8, "bcd") + fmt.Println("是否包含指定后缀", isSuffix) + + fmt.Println("测试Index的位置") + index := strings.Index(str7, "abc") + fmt.Println("得到的位置:", index) + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/byteDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/byteDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..4a226b07f8403ed03ed2ee9938897e26fe93be8e --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/byteDemo.go" @@ -0,0 +1,64 @@ +package main + +import "fmt" + +func main() { + var a byte = 'a' + // 输出的是ASCII码值,也就是说当我们直接输出byte(字符)的时候,输出的是这个字符对应的码值 + fmt.Println(a) + // 输出的是字符 + fmt.Printf("%c", a) + + // for循环打印字符串里面的字符 + // 通过len来循环的,相当于打印的是ASCII码 + s := "你好 golang" + for i := 0; i < len(s); i++ { + fmt.Printf("%v(%c)\t", s[i], s[i]) + } + + // 通过rune打印的是 utf-8字符 + for index, v := range s { + fmt.Println(index, v) + } + + // 字符串转换 + + // byte类型 + s1 := "big" + byteS1 := []byte(s1) + byteS1[0] = 'p' + fmt.Println(string(byteS1)) + + // rune类型 + s2 := "你好golang" + byteS2 := []rune(s2) + byteS2[0] = '我' + fmt.Println(string(byteS2)) + + // 整型和浮点型之间转换 + var aa int8 = 20 + var bb int16 = 40 + fmt.Println(int16(aa) + bb) + + // 整型和浮点型之间转换 + var cc int8 = 20 + var dd float32 = 40 + fmt.Println(float32(cc) + dd) + + // 字符串类型转换 + var i int = 20 + var f float64 = 12.456 + var t bool = true + var b byte = 'a' + str1 := fmt.Sprintf("%d", i) + fmt.Printf("类型:%v-%T \n", str1, str1) + + str2 := fmt.Sprintf("%f", f) + fmt.Printf("类型:%v-%T \n", str2, str2) + + str3 := fmt.Sprintf("%t", t) + fmt.Printf("类型:%v-%T \n", str3, str3) + + str4 := fmt.Sprintf("%c", b) + fmt.Printf("类型:%v-%T \n", str4, str4) +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/controlDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/controlDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..d42d9b850aab3737feead54a7d256228f2ab14bb --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/controlDemo.go" @@ -0,0 +1,88 @@ +package main + +import "fmt" + +func main() { + var num = 10 + if num == 10 { + fmt.Println("hello == 10") + } else if(num > 10) { + fmt.Println("hello > 10") + } else { + fmt.Println("hello < 10") + } + + if num2:= 10; num2>=10 { + fmt.Println("hello >=10") + } + + for i := 0; i < 10; i++ { + fmt.Printf("%v ", i+1) + } + + // 打印所有的偶数 + for i := 0; i < 50; i++ { + if i%2 == 0 { + fmt.Print(i , "\t") + } + } + fmt.Println() + sum := 0 + for i := 0; i < 100; i++ { + sum += i + } + fmt.Println("1+...+100:", sum) + + var str = "你好golang" + for key, value := range str { + fmt.Printf("%v - %c ", key, value) + } + fmt.Println() + var array = []string{"php", "java", "node", "golang"} + for index, value := range array { + fmt.Printf("%v %s ", index, value) + } + + fmt.Println() + extname := ".txt" + switch extname { + case ".html": { + fmt.Println(".html") + break + } + case ".txt",".doc": { + fmt.Println("传递来的是文档") + break + } + case ".js": { + fmt.Println(".js") + } + default: { + fmt.Println("其它后缀") + } + } + + var i = 0 + for { + if i == 10{ + fmt.Println("跳出循环") + break + } + i++ + fmt.Println(i) + } + + var n = 20 + if n > 24 { + fmt.Println("成年人") + } else { + goto lable3 + } + + fmt.Println("aaa") + fmt.Println("bbb") +lable3: + fmt.Println("ccc") + fmt.Println("ddd") + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/exec.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/exec.go" new file mode 100644 index 0000000000000000000000000000000000000000..6e1256540db98526c0dab220114066264347e9ea --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/exec.go" @@ -0,0 +1,29 @@ +package main + +import "fmt" + +func main() { + fmt.Println("hello") + fmt.Print("A", "B", "C") + fmt.Println() + var a = 10 + fmt.Printf("%d", a) + + var name = "zhangsan1" + var name2 string = "zhangsan2" + name3 := "zhangsan3" + + fmt.Println(name) + fmt.Println(name2) + fmt.Println(name3) + fmt.Printf("name1=%v name2=%v name3=%v", name, name2, name3) + + var a1, a2 string + a1 = "123" + a2 = "123" + fmt.Printf(a1) + fmt.Printf(a2) + + const pi = 3.14 + const pp = 3.33333 +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/floatDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/floatDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..0afa6cd8f241937138f7650c3061da43a3c15bfe --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/floatDemo.go" @@ -0,0 +1,9 @@ +package main + +import "fmt" + +func main() { + var num1 float64 = 3.1 + var num2 float64 = 4.1 + fmt.Println(num1, num2) +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/hello.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/hello.go" new file mode 100644 index 0000000000000000000000000000000000000000..f291bc4012aca4af707228cbbbcf53a33b0a6c0b --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/hello.go" @@ -0,0 +1,9 @@ +package main + +import "fmt" + +func main() { + var num = 10 + fmt.Println("hello \t world!", num) + fmt.Println("hello world!") +} \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/man3.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/man3.go" new file mode 100644 index 0000000000000000000000000000000000000000..5bab0b8c7bc0651050ec163d1f52db79d77bb180 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/man3.go" @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" + "math" + "unsafe" +) + +func main() { + var num int = 10 + fmt.Printf("num = %v num 是 %T", num, num) + fmt.Println() + var num2 = 12 + fmt.Println(unsafe.Sizeof(num2)) + + var a1 int16 = 10 + var a2 int32 = 12 + var a3 = int32(a1) + a2 + fmt.Println(a3) + + var n1 int16 = 130 + fmt.Println(int8(n1)) + + fmt.Println("不同类型的输出") + var number = 17 + // 原样输出 + fmt.Printf("%v\n", number) + // 十进制输出 + fmt.Printf("%d\n", number) + // 以八进制输出 + fmt.Printf("%o\n", number) + // 以二进制输出 + fmt.Printf("%b\n", number) + // 以十六进制输出 + fmt.Printf("%x\n", number) + + fmt.Println("浮点类型") + var pi = math.Pi + // 打印浮点类型,默认小数点6位 + fmt.Printf("%f\n", pi) + // 打印浮点类型,打印小数点后2位 + fmt.Printf("%.2f\n", pi) + +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/sortDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/sortDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..2ae81c39cb99868eae82b0c236c2adb5e19515e4 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/sortDemo.go" @@ -0,0 +1,50 @@ +package main + +import ( + "fmt" + "sort" +) + +func main() { + + // 编写冒泡排序 + var numSlice = []int{9,8,4,5,1,7} + for i := 0; i < len(numSlice); i++ { + flag := false + for j := 0; j < len(numSlice) - i - 1; j++ { + if numSlice[j] > numSlice[j+1] { + var temp = numSlice[j+1] + numSlice[j+1] = numSlice[j] + numSlice[j] = temp + flag = true + } + } + if !flag { + break + } + } + fmt.Println(numSlice) + + // 编写选择排序 + var numSlice2 = []int{9,8,4,5,1,7} + for i := 0; i < len(numSlice2); i++ { + for j := i + 1; j < len(numSlice2); j++ { + if numSlice2[i] > numSlice2[j] { + var temp = numSlice2[i] + numSlice2[i] = numSlice2[j] + numSlice2[j] = temp + } + } + } + fmt.Println(numSlice2) + + // 调用sort方法 + var numSlice3 = []int{9,8,4,5,1,7} + sort.Ints(numSlice3) + fmt.Println(numSlice3) + + // 逆序排列 + var numSlice4 = []int{9,8,4,5,1,7} + sort.Sort(sort.Reverse(sort.IntSlice(numSlice4))) + fmt.Println(numSlice4) +} diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/strconvDemo.go" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/strconvDemo.go" new file mode 100644 index 0000000000000000000000000000000000000000..97e3dd8425a9a19ce9f2bc0e94ec02225d6a617e --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/strconvDemo.go" @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" + "strconv" +) + +func main() { + // int类型转换str类型 + var num1 int64 = 20 + s1 := strconv.FormatInt(num1, 10) + fmt.Printf("转换:%v - %T", s1, s1) + + // float类型转换成string类型 + var num2 float64 = 3.1415926 + + /* + 参数1:要转换的值 + 参数2:格式化类型 'f'表示float,'b'表示二进制,‘e’表示 十进制 + 参数3:表示保留的小数点,-1表示不对小数点格式化 + 参数4:格式化的类型,传入64位 或者 32位 + */ + s2 := strconv.FormatFloat(num2, 'f', -1, 64) + fmt.Printf("转换:%v-%T", s2, s2) + + fmt.Println("字符串转换") + str := "10" + // 第一个参数:需要转换的数,第二个参数:进制, 参数三:32位或64位 + strconv.ParseInt(str, 10, 64) + + // 转换成float类型 + str2 := "3.141592654" + strconv.ParseFloat(str2, 10) + + + + +} \ No newline at end of file diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/test.txt" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/test.txt" new file mode 100644 index 0000000000000000000000000000000000000000..d33c837e4f8d2aa8d41d3285a6b674f497486209 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/test.txt" @@ -0,0 +1,7 @@ +啦啦啦 +气不错 +t file +i am test file +i am test file啦啦啦 +啦啦啦 +啦啦啦 diff --git "a/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/test2.txt" "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/test2.txt" new file mode 100644 index 0000000000000000000000000000000000000000..d33c837e4f8d2aa8d41d3285a6b674f497486209 --- /dev/null +++ "b/Golang/Golang\345\237\272\347\241\200/Code/goStudy/main/test2.txt" @@ -0,0 +1,7 @@ +啦啦啦 +气不错 +t file +i am test file +i am test file啦啦啦 +啦啦啦 +啦啦啦 diff --git "a/Golang/Golang\350\277\233\351\230\266/10_Flag\345\214\205\347\232\204\347\224\250\346\263\225/README.md" "b/Golang/Golang\350\277\233\351\230\266/10_Flag\345\214\205\347\232\204\347\224\250\346\263\225/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..4546270b78f3eee5a95f0744dbe7a23ec7e009bc --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/10_Flag\345\214\205\347\232\204\347\224\250\346\263\225/README.md" @@ -0,0 +1,183 @@ +# Flag包的用法 + +Go语言内置的`flag`包实现了命令行参数的解析,`flag`包使得开发命令行工具更为简单。 + +## os.Args + +如果你只是简单的想要获取命令行参数,可以像下面的代码示例一样使用`os.Args`来获取命令行参数。 + +```go +package main + +import ( + "fmt" + "os" +) + +//os.Args demo +func main() { + //os.Args是一个[]string + if len(os.Args) > 0 { + for index, arg := range os.Args { + fmt.Printf("args[%d]=%v\n", index, arg) + } + } +} +``` + +将上面的代码执行`go build -o "args_demo"`编译之后,执行: + +```bash +$ ./args_demo a b c d +args[0]=./args_demo +args[1]=a +args[2]=b +args[3]=c +args[4]=d +``` + +`os.Args`是一个存储命令行参数的字符串切片,它的第一个元素是执行文件的名称。 + +## flag包基本使用 + +本文介绍了flag包的常用函数和基本用法,更详细的内容请查看[官方文档](https://studygolang.com/pkgdoc)。 + +### 导入flag包 + +```go +import flag +``` + +### flag参数类型 + +flag包支持的命令行参数类型有`bool`、`int`、`int64`、`uint`、`uint64`、`float` `float64`、`string`、`duration`。 + +| flag参数 | 有效值 | +| :----------: | :----------------------------------------------------------: | +| 字符串flag | 合法字符串 | +| 整数flag | 1234、0664、0x1234等类型,也可以是负数。 | +| 浮点数flag | 合法浮点数 | +| bool类型flag | 1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False。 | +| 时间段flag | 任何合法的时间段字符串。如”300ms”、”-1.5h”、”2h45m”。 合法的单位有”ns”、”us” /“µs”、”ms”、”s”、”m”、”h”。 | + +## 定义命令行flag参数 + +有以下两种常用的定义命令行`flag`参数的方法。 + +### flag.Type() + +基本格式如下: + +`flag.Type(flag名, 默认值, 帮助信息)*Type` 例如我们要定义姓名、年龄、婚否三个命令行参数,我们可以按如下方式定义: + +```go +name := flag.String("name", "张三", "姓名") +age := flag.Int("age", 18, "年龄") +married := flag.Bool("married", false, "婚否") +delay := flag.Duration("d", 0, "时间间隔") +``` + +需要注意的是,此时`name`、`age`、`married`、`delay`均为对应类型的指针。 + +### flag.TypeVar() + +基本格式如下: `flag.TypeVar(Type指针, flag名, 默认值, 帮助信息)` 例如我们要定义姓名、年龄、婚否三个命令行参数,我们可以按如下方式定义: + +```go +var name string +var age int +var married bool +var delay time.Duration +flag.StringVar(&name, "name", "张三", "姓名") +flag.IntVar(&age, "age", 18, "年龄") +flag.BoolVar(&married, "married", false, "婚否") +flag.DurationVar(&delay, "d", 0, "时间间隔") +``` + +## flag.Parse() + +通过以上两种方法定义好命令行flag参数后,需要通过调用`flag.Parse()`来对命令行参数进行解析。 + +支持的命令行参数格式有以下几种: + +- `-flag xxx` (使用空格,一个`-`符号) +- `--flag xxx` (使用空格,两个`-`符号) +- `-flag=xxx` (使用等号,一个`-`符号) +- `--flag=xxx` (使用等号,两个`-`符号) + +其中,布尔类型的参数必须使用等号的方式指定。 + +Flag解析在第一个非flag参数(单个”-“不是flag参数)之前停止,或者在终止符”–“之后停止。 + +## flag其他函数 + +```go +flag.Args() ////返回命令行参数后的其他参数,以[]string类型 +flag.NArg() //返回命令行参数后的其他参数个数 +flag.NFlag() //返回使用的命令行参数个数 +``` + +## 完整示例 + +### 定义 + +```go +func main() { + //定义命令行参数方式1 + var name string + var age int + var married bool + var delay time.Duration + flag.StringVar(&name, "name", "张三", "姓名") + flag.IntVar(&age, "age", 18, "年龄") + flag.BoolVar(&married, "married", false, "婚否") + flag.DurationVar(&delay, "d", 0, "延迟的时间间隔") + + //解析命令行参数 + flag.Parse() + fmt.Println(name, age, married, delay) + //返回命令行参数后的其他参数 + fmt.Println(flag.Args()) + //返回命令行参数后的其他参数个数 + fmt.Println(flag.NArg()) + //返回使用的命令行参数个数 + fmt.Println(flag.NFlag()) +} +``` + +### 使用 + +命令行参数使用提示: + +```bash +$ ./flag_demo -help +Usage of ./flag_demo: + -age int + 年龄 (default 18) + -d duration + 时间间隔 + -married + 婚否 + -name string + 姓名 (default "张三") +``` + +正常使用命令行flag参数: + +```bash +$ ./flag_demo -name 沙河娜扎 --age 28 -married=false -d=1h30m +沙河娜扎 28 false 1h30m0s +[] +0 +4 +``` + +使用非flag命令行参数: + +```bash +$ ./flag_demo a b c +张三 18 false 0s +[a b c] +3 +0 +``` \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/11_Go\346\223\215\344\275\234\346\225\260\346\215\256\345\272\223/README.md" "b/Golang/Golang\350\277\233\351\230\266/11_Go\346\223\215\344\275\234\346\225\260\346\215\256\345\272\223/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..9a8c87c2a7488683a77b9c33e68846e6071132ad --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/11_Go\346\223\215\344\275\234\346\225\260\346\215\256\345\272\223/README.md" @@ -0,0 +1,620 @@ +# Go操作MySQL数据库 + +## 来源 + +http://moguit.cn/#/info?blogUid=3d1cc9ce434aeaf2187692eb0feea294 + +https://www.liwenzhou.com/posts/Go/go_mysql/ + +## 前言 + +常见的数据库有 + +- SqlLite +- MySQL +- SQLServer +- postgreSQL +- Oracle + +MySQL主流的关系型数据库,类似的还有postgreSQL + +关系型数据库:用表来存储一类的数据 + +表结构设计的三大范式:《漫画数据库》 + +## MySQL知识点 + +### SQL语句 + +DDL:操作数据库的 + +DML:表的增删改查 + +DCL:用户及权限 + +### 存储引擎 + +MySQL支持插件式的存储引擎 + +常见的存储引擎:MyISAM和InnoDB + +#### MyISAM: + +- 查询快 +- 只支持表锁 +- 不支持事务 + +#### InnoDB + +- 整体速度快 +- 支持表锁和行锁 + +### 事务 + +把多个SQL操作当成是一个整体 + +### 事务的特点 + +ACID就是事务的特性 + +- 原子性:事务要么成功要么失败,没有中间操作 +- 一致性:数据库的完整性没有被破坏 +- 隔离性:事务之间是相互隔离的 +- 持久性:事务操作完成后,是持久化到数据库的,不会再次改变 + +### 索引 + +索引的原理是:B树和B+树 + +索引的类型和索引的命中 + +### 其它内容 + +分库分表 + +SQL注入 + +SQL慢查询优化 + +MySQL主从 + +MySQL读写分离 + +## Go操作数据库 + +Go语言中的`database/sql`包提供了保证SQL或类SQL数据库的泛用接口,并不提供具体的数据库驱动。使用`database/sql`包时必须注入(至少)一个数据库驱动。 + +我们常用的数据库基本上都有完整的第三方实现。例如:[MySQL驱动](https://github.com/go-sql-driver/mysql) + +### database/sql + +原生支持连接池,是并发安全的 + +这个标准库没有具体的实现,只是列出一些需要第三方库实现的具体内容 + +### 下载依赖 + +首先我们需要使用go mod命令初始化项目 + +```bash +go mod init GoAdvanceCode +``` + +执行完成后,会在项目的根目录下生成一个go.mod的文件,以后我们添加的依赖,就会在这里显示出来 + +然后下载数据库依赖 + +```bash +go get -u github.com/go-sql-driver/mysql +``` + +`go get`包的路径就是下载第三方的依赖,将第三方的依赖默认保存在 `$GOPATH/src` + +### 使用MySQL驱动 + + 导入刚刚引入的包 + +```go +package main +import ( + "database/sql" + "fmt" + _"github.com/go-sql-driver/mysql" +) + +// 定义一个全局的DB,是一个连接池对象 +var db *sql.DB + +func initDB()(err error) { + // 连接数据库 + dsn := "root:root@tcp(127.0.0.1:3306)/mogu_demo" + + // 连接MySQL数据库(注意不能使用 := ) + db, err = sql.Open("mysql", dsn) + if err != nil { + fmt.Printf("open %s failed, err: %v \n", dsn, err) + return + } + + // 尝试连接数据库 + err = db.Ping() + if err != nil { + fmt.Printf("open %s failed, err: %v, \n", dsn, err) + return + } + fmt.Println("连接数据库成功") + return +} + +type user struct { + id string + name string + age int +} + +// 查询操作 +func query() { + sqlStr := "select id, name, age from user where id > ?" + rows, err := db.Query(sqlStr, 0) + if err != nil { + fmt.Println() + fmt.Printf("query failed, err:%v\n", err) + return + } + // 非常重要:关闭rows释放持有的数据库链接 + defer rows.Close() + + // 循环读取结果集中的数据 + for rows.Next() { + var u user + err := rows.Scan(&u.id, &u.name, &u.age) + if err != nil { + fmt.Printf("scan failed, err:%v\n", err) + return + } + fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age) + } +} + +// Go连接MySQL +func main() { + err := initDB() + if err != nil { + fmt.Println("数据库初始化失败") + } + + // 查询单条记录 + query() + +} +``` + +其中`sql.DB`是表示连接的数据库对象(结构体实例),它保存了连接数据库相关的所有信息。它内部维护着一个具有零到多个底层连接的连接池,它可以安全地被多个goroutine同时使用。 + +### SetMaxOpenConns + +```go +func (db *DB) SetMaxOpenConns(n int) +``` + +`SetMaxOpenConns`设置与数据库建立连接的最大数目。 如果n大于0且小于最大闲置连接数,会将最大闲置连接数减小到匹配最大开启连接数的限制。 如果n<=0,不会限制最大开启连接数,默认为0(无限制)。 + +> 需要注意的是,我们再查询完成后,需要使用Scan进行连接的释放 +> +> ```go +> // 调用Scan才会释放我们的连接 +> err := rows.Scan(&u.id, &u.name, &u.age) +> if err != nil { +> fmt.Printf("scan failed, err:%v\n", err) +> return +> } +> ``` + +### SetMaxIdleConns + +```go +func (db *DB) SetMaxIdleConns(n int) +``` + +SetMaxIdleConns设置连接池中的最大闲置连接数。 如果n大于最大开启连接数,则新的最大闲置连接数会减小到匹配最大开启连接数的限制。 如果n<=0,不会保留闲置连接。 + +## CRUD + +### 建库建表 + +我们先在MySQL中创建一个名为`sql_test`的数据库 + +```sql +CREATE DATABASE sql_test; +``` + +进入该数据库: + +```sql +use sql_test; +``` + +执行以下命令创建一张用于测试的数据表: + +```sql +CREATE TABLE `user` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `name` VARCHAR(20) DEFAULT '', + `age` INT(11) DEFAULT '0', + PRIMARY KEY(`id`) +)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; +``` + +### 查询 + +为了方便查询,我们事先定义好一个结构体来存储user表的数据。 + +```go +type user struct { + id int + age int + name string +} +``` + +#### 单行查询 + +单行查询`db.QueryRow()`执行一次查询,并期望返回最多一行结果(即Row)。QueryRow总是返回非nil的值,直到返回值的Scan方法被调用时,才会返回被延迟的错误。(如:未找到结果) + +```go +func (db *DB) QueryRow(query string, args ...interface{}) *Row +``` + +具体示例代码: + +```go +// 查询单条数据示例 +func queryRowDemo() { + sqlStr := "select id, name, age from user where id=?" + var u user + // 非常重要:确保QueryRow之后调用Scan方法,否则持有的数据库链接不会被释放 + err := db.QueryRow(sqlStr, 1).Scan(&u.id, &u.name, &u.age) + if err != nil { + fmt.Printf("scan failed, err:%v\n", err) + return + } + fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age) +} +``` + +#### 多行查询 + +多行查询`db.Query()`执行一次查询,返回多行结果(即Rows),一般用于执行select命令。参数args表示query中的占位参数。 + +```go +func (db *DB) Query(query string, args ...interface{}) (*Rows, error) +``` + +具体示例代码: + +```go +// 查询多条数据示例 +func queryMultiRowDemo() { + sqlStr := "select id, name, age from user where id > ?" + rows, err := db.Query(sqlStr, 0) + if err != nil { + fmt.Printf("query failed, err:%v\n", err) + return + } + // 非常重要:关闭rows释放持有的数据库链接 + defer rows.Close() + + // 循环读取结果集中的数据 + for rows.Next() { + var u user + err := rows.Scan(&u.id, &u.name, &u.age) + if err != nil { + fmt.Printf("scan failed, err:%v\n", err) + return + } + fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age) + } +} +``` + +### 插入数据 + +插入、更新和删除操作都使用`Exec`方法。 + +```go +func (db *DB) Exec(query string, args ...interface{}) (Result, error) +``` + +Exec执行一次命令(包括查询、删除、更新、插入等),返回的Result是对已执行的SQL命令的总结。参数args表示query中的占位参数。 + +具体插入数据示例代码如下: + +```go +// 插入数据 +func insertRowDemo() { + sqlStr := "insert into user(name, age) values (?,?)" + ret, err := db.Exec(sqlStr, "王五", 38) + if err != nil { + fmt.Printf("insert failed, err:%v\n", err) + return + } + theID, err := ret.LastInsertId() // 新插入数据的id + if err != nil { + fmt.Printf("get lastinsert ID failed, err:%v\n", err) + return + } + fmt.Printf("insert success, the id is %d.\n", theID) +} +``` + +### 更新数据 + +具体更新数据示例代码如下: + +```go +// 更新数据 +func updateRowDemo() { + sqlStr := "update user set age=? where id = ?" + ret, err := db.Exec(sqlStr, 39, 3) + if err != nil { + fmt.Printf("update failed, err:%v\n", err) + return + } + n, err := ret.RowsAffected() // 操作影响的行数 + if err != nil { + fmt.Printf("get RowsAffected failed, err:%v\n", err) + return + } + fmt.Printf("update success, affected rows:%d\n", n) +} +``` + +### 删除数据 + +具体删除数据的示例代码如下: + +```go +// 删除数据 +func deleteRowDemo() { + sqlStr := "delete from user where id = ?" + ret, err := db.Exec(sqlStr, 3) + if err != nil { + fmt.Printf("delete failed, err:%v\n", err) + return + } + n, err := ret.RowsAffected() // 操作影响的行数 + if err != nil { + fmt.Printf("get RowsAffected failed, err:%v\n", err) + return + } + fmt.Printf("delete success, affected rows:%d\n", n) +} +``` + +## MySQL预处理 + +### 什么是预处理? + +普通SQL语句执行过程: + +1. 客户端对SQL语句进行占位符替换得到完整的SQL语句。 +2. 客户端发送完整SQL语句到MySQL服务端 +3. MySQL服务端执行完整的SQL语句并将结果返回给客户端。 + +预处理执行过程: + +1. 把SQL语句分成两部分,命令部分与数据部分。 +2. 先把命令部分发送给MySQL服务端,MySQL服务端进行SQL预处理。 +3. 然后把数据部分发送给MySQL服务端,MySQL服务端对SQL语句进行占位符替换。 +4. MySQL服务端执行完整的SQL语句并将结果返回给客户端。 + +### 为什么要预处理? + +1. 优化MySQL服务器重复执行SQL的方法,可以提升服务器性能,提前让服务器编译,一次编译多次执行,节省后续编译的成本。 +2. 避免SQL注入问题。 + +### Go实现MySQL预处理 + +`database/sql`中使用下面的`Prepare`方法来实现预处理操作。 + +```go +func (db *DB) Prepare(query string) (*Stmt, error) +``` + +`Prepare`方法会先将sql语句发送给MySQL服务端,返回一个准备好的状态用于之后的查询和命令。返回值可以同时执行多个查询和命令。 + +查询操作的预处理示例代码如下: + +```go +// 预处理查询示例 +func prepareQueryDemo() { + sqlStr := "select id, name, age from user where id > ?" + stmt, err := db.Prepare(sqlStr) + if err != nil { + fmt.Printf("prepare failed, err:%v\n", err) + return + } + defer stmt.Close() + rows, err := stmt.Query(0) + if err != nil { + fmt.Printf("query failed, err:%v\n", err) + return + } + defer rows.Close() + // 循环读取结果集中的数据 + for rows.Next() { + var u user + err := rows.Scan(&u.id, &u.name, &u.age) + if err != nil { + fmt.Printf("scan failed, err:%v\n", err) + return + } + fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age) + } +} +``` + +插入、更新和删除操作的预处理十分类似,这里以插入操作的预处理为例: + +```go +// 预处理插入示例 +func prepareInsertDemo() { + sqlStr := "insert into user(name, age) values (?,?)" + stmt, err := db.Prepare(sqlStr) + if err != nil { + fmt.Printf("prepare failed, err:%v\n", err) + return + } + defer stmt.Close() + _, err = stmt.Exec("小王子", 18) + if err != nil { + fmt.Printf("insert failed, err:%v\n", err) + return + } + _, err = stmt.Exec("沙河娜扎", 18) + if err != nil { + fmt.Printf("insert failed, err:%v\n", err) + return + } + fmt.Println("insert success.") +} +``` + +### SQL注入问题 + +**我们任何时候都不应该自己拼接SQL语句!** + +这里我们演示一个自行拼接SQL语句的示例,编写一个根据name字段查询user表的函数如下: + +```go +// sql注入示例 +func sqlInjectDemo(name string) { + sqlStr := fmt.Sprintf("select id, name, age from user where name='%s'", name) + fmt.Printf("SQL:%s\n", sqlStr) + var u user + err := db.QueryRow(sqlStr).Scan(&u.id, &u.name, &u.age) + if err != nil { + fmt.Printf("exec failed, err:%v\n", err) + return + } + fmt.Printf("user:%#v\n", u) +} +``` + +此时以下输入字符串都可以引发SQL注入问题: + +```go +sqlInjectDemo("xxx' or 1=1#") +sqlInjectDemo("xxx' union select * from user #") +sqlInjectDemo("xxx' and (select count(*) from user) <10 #") +``` + +**补充:**不同的数据库中,SQL语句使用的占位符语法不尽相同。 + +| 数据库 | 占位符语法 | +| :--------: | :----------: | +| MySQL | `?` | +| PostgreSQL | `$1`, `$2`等 | +| SQLite | `?` 和`$1` | +| Oracle | `:name` | + +## Go实现MySQL事务 + +### 什么是事务? + +事务:一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元),同时这个完整的业务需要执行多次的DML(insert、update、delete)语句共同联合完成。A转账给B,这里面就需要执行两次update操作。 + +在MySQL中只有使用了`Innodb`数据库引擎的数据库或表才支持事务。事务处理可以用来维护数据库的完整性,保证成批的SQL语句要么全部执行,要么全部不执行。 + +### 事务的ACID + +通常事务必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。 + +| 条件 | 解释 | +| :----: | :----------------------------------------------------------: | +| 原子性 | 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。 | +| 一致性 | 在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。 | +| 隔离性 | 数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。 | +| 持久性 | 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。 | + +### 事务相关方法 + +Go语言中使用以下三个方法实现MySQL中的事务操作。 开始事务 + +```go +func (db *DB) Begin() (*Tx, error) +``` + +提交事务 + +```go +func (tx *Tx) Commit() error +``` + +回滚事务 + +```go +func (tx *Tx) Rollback() error +``` + +### 事务示例 + +下面的代码演示了一个简单的事务操作,该事物操作能够确保两次更新操作要么同时成功要么同时失败,不会存在中间状态。 + +```go +// 事务操作示例 +func transactionDemo() { + tx, err := db.Begin() // 开启事务 + if err != nil { + if tx != nil { + tx.Rollback() // 回滚 + } + fmt.Printf("begin trans failed, err:%v\n", err) + return + } + sqlStr1 := "Update user set age=30 where id=?" + ret1, err := tx.Exec(sqlStr1, 2) + if err != nil { + tx.Rollback() // 回滚 + fmt.Printf("exec sql1 failed, err:%v\n", err) + return + } + affRow1, err := ret1.RowsAffected() + if err != nil { + tx.Rollback() // 回滚 + fmt.Printf("exec ret1.RowsAffected() failed, err:%v\n", err) + return + } + + sqlStr2 := "Update user set age=40 where id=?" + ret2, err := tx.Exec(sqlStr2, 3) + if err != nil { + tx.Rollback() // 回滚 + fmt.Printf("exec sql2 failed, err:%v\n", err) + return + } + affRow2, err := ret2.RowsAffected() + if err != nil { + tx.Rollback() // 回滚 + fmt.Printf("exec ret1.RowsAffected() failed, err:%v\n", err) + return + } + + fmt.Println(affRow1, affRow2) + if affRow1 == 1 && affRow2 == 1 { + fmt.Println("事务提交啦...") + tx.Commit() // 提交事务 + } else { + tx.Rollback() + fmt.Println("事务回滚啦...") + } + + fmt.Println("exec trans success!") +} +``` + +[更强大、更好用的sqlx库](https://www.liwenzhou.com/posts/Go/sqlx/) + +## 练习题 + +1. 结合`net/http`和`database/sql`实现一个使用MySQL存储用户信息的注册及登陆的简易web程序。 \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/12_sqlx\345\272\223\347\232\204\344\275\277\347\224\250/README.md" "b/Golang/Golang\350\277\233\351\230\266/12_sqlx\345\272\223\347\232\204\344\275\277\347\224\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..852544b67bdc753452b1c77c1cd135f5c8aca2be --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/12_sqlx\345\272\223\347\232\204\344\275\277\347\224\250/README.md" @@ -0,0 +1,456 @@ +# sqlx的使用 + +在项目中我们通常可能会使用`database/sql`连接MySQL数据库。本文借助使用`sqlx`实现批量插入数据的例子,介绍了`sqlx`中可能被你忽视了的`sqlx.In`和`DB.NamedExec`方法。 + +## sqlx介绍 + +在项目中我们通常可能会使用`database/sql`连接MySQL数据库。`sqlx`可以认为是Go语言内置`database/sql`的超集,它在优秀的内置`database/sql`基础上提供了一组扩展。这些扩展中除了大家常用来查询的`Get(dest interface{}, ...) error`和`Select(dest interface{}, ...) error`外还有很多其他强大的功能。 + +## 安装sqlx + +```go +go get github.com/jmoiron/sqlx +``` + +## 基本使用 + +### 连接数据库 + +```go +var db *sqlx.DB + +type user struct { + ID string + Name string + Age int +} + +func initDB() (err error) { + dsn := "user:password@tcp(127.0.0.1:3306)/sql_test?charset=utf8mb4&parseTime=True" + // 也可以使用MustConnect连接不成功就panic + db, err = sqlx.Connect("mysql", dsn) + if err != nil { + fmt.Printf("connect DB failed, err:%v\n", err) + return + } + db.SetMaxOpenConns(20) + db.SetMaxIdleConns(10) + return +} +``` + +### 查询 + +查询单行数据示例代码如下: + +```go +// 查询单条数据示例 +func queryRowDemo() { + sqlStr := "select id, name, age from user where id=?" + var u user + // 需要传递指针,因为要修改里面的值 + err := db.Get(&u, sqlStr, 1) + if err != nil { + fmt.Printf("get failed, err:%v\n", err) + return + } + fmt.Printf("id:%d name:%s age:%d\n", u.ID, u.Name, u.Age) +} +``` + +查询多行数据示例代码如下: + +```go +// 查询多条数据示例 +func queryMultiRowDemo() { + sqlStr := "select id, name, age from user where id > ?" + var users []user + err := db.Select(&users, sqlStr, 0) + if err != nil { + fmt.Printf("query failed, err:%v\n", err) + return + } + fmt.Printf("users:%#v\n", users) +} +``` + +### 插入、更新和删除 + +sqlx中的exec方法与原生sql中的exec使用基本一致: + +```go +// 插入数据 +func insertRowDemo() { + sqlStr := "insert into user(name, age) values (?,?)" + ret, err := db.Exec(sqlStr, "沙河小王子", 19) + if err != nil { + fmt.Printf("insert failed, err:%v\n", err) + return + } + theID, err := ret.LastInsertId() // 新插入数据的id + if err != nil { + fmt.Printf("get lastinsert ID failed, err:%v\n", err) + return + } + fmt.Printf("insert success, the id is %d.\n", theID) +} + +// 更新数据 +func updateRowDemo() { + sqlStr := "update user set age=? where id = ?" + ret, err := db.Exec(sqlStr, 39, 6) + if err != nil { + fmt.Printf("update failed, err:%v\n", err) + return + } + n, err := ret.RowsAffected() // 操作影响的行数 + if err != nil { + fmt.Printf("get RowsAffected failed, err:%v\n", err) + return + } + fmt.Printf("update success, affected rows:%d\n", n) +} + +// 删除数据 +func deleteRowDemo() { + sqlStr := "delete from user where id = ?" + ret, err := db.Exec(sqlStr, 6) + if err != nil { + fmt.Printf("delete failed, err:%v\n", err) + return + } + n, err := ret.RowsAffected() // 操作影响的行数 + if err != nil { + fmt.Printf("get RowsAffected failed, err:%v\n", err) + return + } + fmt.Printf("delete success, affected rows:%d\n", n) +} +``` + +### NamedExec + +`DB.NamedExec`方法用来绑定SQL语句与结构体或map中的同名字段。 + +```go +func insertUserDemo()(err error){ + sqlStr := "INSERT INTO user (name,age) VALUES (:name,:age)" + _, err = db.NamedExec(sqlStr, + map[string]interface{}{ + "name": "七米", + "age": 28, + }) + return +} +``` + +### NamedQuery + +与`DB.NamedExec`同理,这里是支持查询。 + +```go +func namedQuery(){ + sqlStr := "SELECT * FROM user WHERE name=:name" + // 使用map做命名查询 + rows, err := db.NamedQuery(sqlStr, map[string]interface{}{"name": "七米"}) + if err != nil { + fmt.Printf("db.NamedQuery failed, err:%v\n", err) + return + } + defer rows.Close() + for rows.Next(){ + var u user + err := rows.StructScan(&u) + if err != nil { + fmt.Printf("scan failed, err:%v\n", err) + continue + } + fmt.Printf("user:%#v\n", u) + } + + u := user{ + Name: "七米", + } + // 使用结构体命名查询,根据结构体字段的 db tag进行映射 + rows, err = db.NamedQuery(sqlStr, u) + if err != nil { + fmt.Printf("db.NamedQuery failed, err:%v\n", err) + return + } + defer rows.Close() + for rows.Next(){ + var u user + err := rows.StructScan(&u) + if err != nil { + fmt.Printf("scan failed, err:%v\n", err) + continue + } + fmt.Printf("user:%#v\n", u) + } +} +``` + +### 事务操作 + +对于事务操作,我们可以使用`sqlx`中提供的`db.Beginx()`和`tx.Exec()`方法。示例代码如下: + +```go +func transactionDemo2()(err error) { + tx, err := db.Beginx() // 开启事务 + if err != nil { + fmt.Printf("begin trans failed, err:%v\n", err) + return err + } + defer func() { + if p := recover(); p != nil { + tx.Rollback() + panic(p) // re-throw panic after Rollback + } else if err != nil { + fmt.Println("rollback") + tx.Rollback() // err is non-nil; don't change it + } else { + err = tx.Commit() // err is nil; if Commit returns error update err + fmt.Println("commit") + } + }() + + sqlStr1 := "Update user set age=20 where id=?" + + rs, err := tx.Exec(sqlStr1, 1) + if err!= nil{ + return err + } + n, err := rs.RowsAffected() + if err != nil { + return err + } + if n != 1 { + return errors.New("exec sqlStr1 failed") + } + sqlStr2 := "Update user set age=50 where i=?" + rs, err = tx.Exec(sqlStr2, 5) + if err!=nil{ + return err + } + n, err = rs.RowsAffected() + if err != nil { + return err + } + if n != 1 { + return errors.New("exec sqlStr1 failed") + } + return err +} +``` + +## sqlx.In + +`sqlx.In`是`sqlx`提供的一个非常方便的函数。 + +### sqlx.In的批量插入示例 + +#### 表结构 + +为了方便演示插入数据操作,这里创建一个`user`表,表结构如下: + +```sql +CREATE TABLE `user` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `name` VARCHAR(20) DEFAULT '', + `age` INT(11) DEFAULT '0', + PRIMARY KEY(`id`) +)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; +``` + +#### 结构体 + +定义一个`user`结构体,字段通过tag与数据库中user表的列一致。 + +```go +type User struct { + Name string `db:"name"` + Age int `db:"age"` +} +``` + +#### bindvars(绑定变量) + +查询占位符`?`在内部称为**bindvars(查询占位符)**,它非常重要。你应该始终使用它们向数据库发送值,因为它们可以防止SQL注入攻击。`database/sql`不尝试对查询文本进行任何验证;它与编码的参数一起按原样发送到服务器。除非驱动程序实现一个特殊的接口,否则在执行之前,查询是在服务器上准备的。因此`bindvars`是特定于数据库的: + +- MySQL中使用`?` +- PostgreSQL使用枚举的`$1`、`$2`等bindvar语法 +- SQLite中`?`和`$1`的语法都支持 +- Oracle中使用`:name`的语法 + +`bindvars`的一个常见误解是,它们用来在sql语句中插入值。它们其实仅用于参数化,不允许更改SQL语句的结构。例如,使用`bindvars`尝试参数化列或表名将不起作用: + +```go +// ?不能用来插入表名(做SQL语句中表名的占位符) +db.Query("SELECT * FROM ?", "mytable") + +// ?也不能用来插入列名(做SQL语句中列名的占位符) +db.Query("SELECT ?, ? FROM people", "name", "location") +``` + +#### 自己拼接语句实现批量插入 + +比较笨,但是很好理解。就是有多少个User就拼接多少个`(?, ?)`。 + +```go +// BatchInsertUsers 自行构造批量插入的语句 +func BatchInsertUsers(users []*User) error { + // 存放 (?, ?) 的slice + valueStrings := make([]string, 0, len(users)) + // 存放values的slice + valueArgs := make([]interface{}, 0, len(users) * 2) + // 遍历users准备相关数据 + for _, u := range users { + // 此处占位符要与插入值的个数对应 + valueStrings = append(valueStrings, "(?, ?)") + valueArgs = append(valueArgs, u.Name) + valueArgs = append(valueArgs, u.Age) + } + // 自行拼接要执行的具体语句 + stmt := fmt.Sprintf("INSERT INTO user (name, age) VALUES %s", + strings.Join(valueStrings, ",")) + _, err := DB.Exec(stmt, valueArgs...) + return err +} +``` + +#### 使用sqlx.In实现批量插入 + +前提是需要我们的结构体实现`driver.Valuer`接口: + +```go +func (u User) Value() (driver.Value, error) { + return []interface{}{u.Name, u.Age}, nil +} +``` + +使用`sqlx.In`实现批量插入代码如下: + +```go +// BatchInsertUsers2 使用sqlx.In帮我们拼接语句和参数, 注意传入的参数是[]interface{} +func BatchInsertUsers2(users []interface{}) error { + query, args, _ := sqlx.In( + "INSERT INTO user (name, age) VALUES (?), (?), (?)", + users..., // 如果arg实现了 driver.Valuer, sqlx.In 会通过调用 Value()来展开它 + ) + fmt.Println(query) // 查看生成的querystring + fmt.Println(args) // 查看生成的args + _, err := DB.Exec(query, args...) + return err +} +``` + +#### 使用NamedExec实现批量插入 + +**注意** :该功能目前有人已经推了[#285 PR](https://github.com/jmoiron/sqlx/pull/285),但是作者还没有发`release`,所以想要使用下面的方法实现批量插入需要暂时使用`master`分支的代码: + +在项目目录下执行以下命令下载并使用`master`分支代码: + +```bash +go get github.com/jmoiron/sqlx@master +``` + +使用`NamedExec`实现批量插入的代码如下: + +```go +// BatchInsertUsers3 使用NamedExec实现批量插入 +func BatchInsertUsers3(users []*User) error { + _, err := DB.NamedExec("INSERT INTO user (name, age) VALUES (:name, :age)", users) + return err +} +``` + +把上面三种方法综合起来试一下: + +```go +func main() { + err := initDB() + if err != nil { + panic(err) + } + defer DB.Close() + u1 := User{Name: "七米", Age: 18} + u2 := User{Name: "q1mi", Age: 28} + u3 := User{Name: "小王子", Age: 38} + + // 方法1 + users := []*User{&u1, &u2, &u3} + err = BatchInsertUsers(users) + if err != nil { + fmt.Printf("BatchInsertUsers failed, err:%v\n", err) + } + + // 方法2 + users2 := []interface{}{u1, u2, u3} + err = BatchInsertUsers2(users2) + if err != nil { + fmt.Printf("BatchInsertUsers2 failed, err:%v\n", err) + } + + // 方法3 + users3 := []*User{&u1, &u2, &u3} + err = BatchInsertUsers3(users3) + if err != nil { + fmt.Printf("BatchInsertUsers3 failed, err:%v\n", err) + } +} +``` + +### sqlx.In的查询示例 + +关于`sqlx.In`这里再补充一个用法,在`sqlx`查询语句中实现In查询和FIND_IN_SET函数。即实现`SELECT * FROM user WHERE id in (3, 2, 1);`和`SELECT * FROM user WHERE id in (3, 2, 1) ORDER BY FIND_IN_SET(id, '3,2,1');`。 + +#### in查询 + +查询id在给定id集合中的数据。 + +```go +// QueryByIDs 根据给定ID查询 +func QueryByIDs(ids []int)(users []User, err error){ + // 动态填充id + query, args, err := sqlx.In("SELECT name, age FROM user WHERE id IN (?)", ids) + if err != nil { + return + } + // sqlx.In 返回带 `?` bindvar的查询语句, 我们使用Rebind()重新绑定它 + query = DB.Rebind(query) + + err = DB.Select(&users, query, args...) + return +} +``` + +#### in查询和FIND_IN_SET函数 + +查询id在给定id集合的数据并维持给定id集合的顺序。 + +```go +// QueryAndOrderByIDs 按照指定id查询并维护顺序 +func QueryAndOrderByIDs(ids []int)(users []User, err error){ + // 动态填充id + strIDs := make([]string, 0, len(ids)) + for _, id := range ids { + strIDs = append(strIDs, fmt.Sprintf("%d", id)) + } + query, args, err := sqlx.In("SELECT name, age FROM user WHERE id IN (?) ORDER BY FIND_IN_SET(id, ?)", ids, strings.Join(strIDs, ",")) + if err != nil { + return + } + + // sqlx.In 返回带 `?` bindvar的查询语句, 我们使用Rebind()重新绑定它 + query = DB.Rebind(query) + + err = DB.Select(&users, query, args...) + return +} +``` + +当然,在这个例子里面你也可以先使用`IN`查询,然后通过代码按给定的ids对查询结果进行排序。 + +参考链接: + +[Illustrated guide to SQLX](http://jmoiron.github.io/sqlx/) \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/13_Go\346\223\215\344\275\234Redis/README.md" "b/Golang/Golang\350\277\233\351\230\266/13_Go\346\223\215\344\275\234Redis/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..8630f7600e9488e4b773bec18adef440b64bf36d --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/13_Go\346\223\215\344\275\234Redis/README.md" @@ -0,0 +1,365 @@ +# Go操作Redis + +## 来源 + +https://www.liwenzhou.com/posts/Go/go_redis/ + +- cache缓存 +- 简单的队列 +- 排行榜 + +## 介绍 + +Redis是一个开源的内存数据库,Redis提供了多种不同类型的数据结构,很多业务场景下的问题都可以很自然地映射到这些数据结构上。除此之外,通过复制、持久化和客户端分片等特性,我们可以很方便地将Redis扩展成一个能够包含数百GB数据、每秒处理上百万次请求的系统。 + +## Redis支持的数据结构 + +Redis支持诸如字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、带范围查询的排序集合(sorted sets)、位图(bitmaps)、hyperloglogs、带半径查询和流的地理空间索引等数据结构(geospatial indexes)。 + +## Redis应用场景 + +- 缓存系统,减轻主数据库(MySQL)的压力。 +- 计数场景,比如微博、抖音中的关注数和粉丝数。 +- 热门排行榜,需要排序的场景特别适合使用ZSET。 +- 利用LIST可以实现队列的功能。 + +## Redis与Memcached比较 + +Memcached的值只支持简单的字符串,Redis支持更丰富的数据结构,Redis的性能比Memcached好很多,Redis支持RDB持久化和AOF持久化,Redis支持master/slave模式。 + +## 准备Redis环境 + +这里直接使用Docker启动一个redis环境,方便学习使用。 + +docker启动一个名为redis507的5.0.7版本的redis server示例: + +```bash +docker run --name redis507 -p 6379:6379 -d redis:5.0.7 +``` + +**注意:**此处的版本、容器名和端口号请根据自己需要设置。 + +启动一个redis-cli连接上面的redis server: + +```bash +docker run -it --network host --rm redis:5.0.7 redis-cli +``` + +## go-redis库 安装 + +区别于另一个比较常用的Go语言redis client库:[redigo](https://github.com/gomodule/redigo),我们这里采用https://github.com/go-redis/redis连接Redis数据库并进行操作,因为`go-redis`支持连接哨兵及集群模式的Redis。 + +使用以下命令下载并安装: + +```bash +go get -u github.com/go-redis/redis +``` + +## 连接 + +### 普通连接 + +```go +// 声明一个全局的rdb变量 +var rdb *redis.Client + +// 初始化连接 +func initClient() (err error) { + rdb = redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + Password: "", // no password set + DB: 0, // use default DB + }) + + _, err = rdb.Ping().Result() + if err != nil { + return err + } + return nil +} +``` + +### 连接Redis哨兵模式 + +```go +func initClient()(err error){ + rdb := redis.NewFailoverClient(&redis.FailoverOptions{ + MasterName: "master", + SentinelAddrs: []string{"x.x.x.x:26379", "xx.xx.xx.xx:26379", "xxx.xxx.xxx.xxx:26379"}, + }) + _, err = rdb.Ping().Result() + if err != nil { + return err + } + return nil +} +``` + +### 连接Redis集群 + +```go +func initClient()(err error){ + rdb := redis.NewClusterClient(&redis.ClusterOptions{ + Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"}, + }) + _, err = rdb.Ping().Result() + if err != nil { + return err + } + return nil +} +``` + +## 基本使用 + +### set/get示例 + +```go +func redisExample() { + err := rdb.Set("score", 100, 0).Err() + if err != nil { + fmt.Printf("set score failed, err:%v\n", err) + return + } + + val, err := rdb.Get("score").Result() + if err != nil { + fmt.Printf("get score failed, err:%v\n", err) + return + } + fmt.Println("score", val) + + val2, err := rdb.Get("name").Result() + if err == redis.Nil { + fmt.Println("name does not exist") + } else if err != nil { + fmt.Printf("get name failed, err:%v\n", err) + return + } else { + fmt.Println("name", val2) + } +} +``` + +### zset示例 + +```go +func redisExample2() { + zsetKey := "language_rank" + languages := []redis.Z{ + redis.Z{Score: 90.0, Member: "Golang"}, + redis.Z{Score: 98.0, Member: "Java"}, + redis.Z{Score: 95.0, Member: "Python"}, + redis.Z{Score: 97.0, Member: "JavaScript"}, + redis.Z{Score: 99.0, Member: "C/C++"}, + } + // ZADD + num, err := rdb.ZAdd(zsetKey, languages...).Result() + if err != nil { + fmt.Printf("zadd failed, err:%v\n", err) + return + } + fmt.Printf("zadd %d succ.\n", num) + + // 把Golang的分数加10 + newScore, err := rdb.ZIncrBy(zsetKey, 10.0, "Golang").Result() + if err != nil { + fmt.Printf("zincrby failed, err:%v\n", err) + return + } + fmt.Printf("Golang's score is %f now.\n", newScore) + + // 取分数最高的3个 + ret, err := rdb.ZRevRangeWithScores(zsetKey, 0, 2).Result() + if err != nil { + fmt.Printf("zrevrange failed, err:%v\n", err) + return + } + for _, z := range ret { + fmt.Println(z.Member, z.Score) + } + + // 取95~100分的 + op := redis.ZRangeBy{ + Min: "95", + Max: "100", + } + ret, err = rdb.ZRangeByScoreWithScores(zsetKey, op).Result() + if err != nil { + fmt.Printf("zrangebyscore failed, err:%v\n", err) + return + } + for _, z := range ret { + fmt.Println(z.Member, z.Score) + } +} +``` + +输出结果如下: + +```bash +$ ./06redis_demo +zadd 0 succ. +Golang's score is 100.000000 now. +Golang 100 +C/C++ 99 +Java 98 +JavaScript 97 +Java 98 +C/C++ 99 +Golang 100 +``` + +### Pipeline + +`Pipeline` 主要是一种网络优化。它本质上意味着客户端缓冲一堆命令并一次性将它们发送到服务器。这些命令不能保证在事务中执行。这样做的好处是节省了每个命令的网络往返时间(RTT)。 + +`Pipeline` 基本示例如下: + +```go +pipe := rdb.Pipeline() + +incr := pipe.Incr("pipeline_counter") +pipe.Expire("pipeline_counter", time.Hour) + +_, err := pipe.Exec() +fmt.Println(incr.Val(), err) +``` + +上面的代码相当于将以下两个命令一次发给redis server端执行,与不使用`Pipeline`相比能减少一次RTT。 + +```bash +INCR pipeline_counter +EXPIRE pipeline_counts 3600 +``` + +也可以使用`Pipelined`: + +```go +var incr *redis.IntCmd +_, err := rdb.Pipelined(func(pipe redis.Pipeliner) error { + incr = pipe.Incr("pipelined_counter") + pipe.Expire("pipelined_counter", time.Hour) + return nil +}) +fmt.Println(incr.Val(), err) +``` + +在某些场景下,当我们有多条命令要执行时,就可以考虑使用pipeline来优化。 + +### 事务 + +Redis是单线程的,因此单个命令始终是原子的,但是来自不同客户端的两个给定命令可以依次执行,例如在它们之间交替执行。但是,`Multi/exec`能够确保在`multi/exec`两个语句之间的命令之间没有其他客户端正在执行命令。 + +在这种场景我们需要使用`TxPipeline`。`TxPipeline`总体上类似于上面的`Pipeline`,但是它内部会使用`MULTI/EXEC`包裹排队的命令。例如: + +```go +pipe := rdb.TxPipeline() + +incr := pipe.Incr("tx_pipeline_counter") +pipe.Expire("tx_pipeline_counter", time.Hour) + +_, err := pipe.Exec() +fmt.Println(incr.Val(), err) +``` + +上面代码相当于在一个RTT下执行了下面的redis命令: + +```bash +MULTI +INCR pipeline_counter +EXPIRE pipeline_counts 3600 +EXEC +``` + +还有一个与上文类似的`TxPipelined`方法,使用方法如下: + +```go +var incr *redis.IntCmd +_, err := rdb.TxPipelined(func(pipe redis.Pipeliner) error { + incr = pipe.Incr("tx_pipelined_counter") + pipe.Expire("tx_pipelined_counter", time.Hour) + return nil +}) +fmt.Println(incr.Val(), err) +``` + +### Watch + +在某些场景下,我们除了要使用`MULTI/EXEC`命令外,还需要配合使用`WATCH`命令。在用户使用`WATCH`命令监视某个键之后,直到该用户执行`EXEC`命令的这段时间里,如果有其他用户抢先对被监视的键进行了替换、更新、删除等操作,那么当用户尝试执行`EXEC`的时候,事务将失败并返回一个错误,用户可以根据这个错误选择重试事务或者放弃事务。 + +```go +Watch(fn func(*Tx) error, keys ...string) error +``` + +Watch方法接收一个函数和一个或多个key作为参数。基本使用示例如下: + +```go +// 监视watch_count的值,并在值不变的前提下将其值+1 +key := "watch_count" +err = client.Watch(func(tx *redis.Tx) error { + n, err := tx.Get(key).Int() + if err != nil && err != redis.Nil { + return err + } + _, err = tx.Pipelined(func(pipe redis.Pipeliner) error { + pipe.Set(key, n+1, 0) + return nil + }) + return err +}, key) +``` + +最后看一个官方文档中使用GET和SET命令以事务方式递增Key的值的示例: + +```go +const routineCount = 100 + +increment := func(key string) error { + txf := func(tx *redis.Tx) error { + // 获得当前值或零值 + n, err := tx.Get(key).Int() + if err != nil && err != redis.Nil { + return err + } + + // 实际操作(乐观锁定中的本地操作) + n++ + + // 仅在监视的Key保持不变的情况下运行 + _, err = tx.Pipelined(func(pipe redis.Pipeliner) error { + // pipe 处理错误情况 + pipe.Set(key, n, 0) + return nil + }) + return err + } + + for retries := routineCount; retries > 0; retries-- { + err := rdb.Watch(txf, key) + if err != redis.TxFailedErr { + return err + } + // 乐观锁丢失 + } + return errors.New("increment reached maximum number of retries") +} + +var wg sync.WaitGroup +wg.Add(routineCount) +for i := 0; i < routineCount; i++ { + go func() { + defer wg.Done() + + if err := increment("counter3"); err != nil { + fmt.Println("increment error:", err) + } + }() +} +wg.Wait() + +n, err := rdb.Get("counter3").Int() +fmt.Println("ended with", n, err) +``` + +更多详情请查阅[文档](https://godoc.org/github.com/go-redis/redis)。 \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/README.md" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..4764cfdb49294e2c95a2dd99da0c40bd5429ab1e --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/README.md" @@ -0,0 +1,471 @@ +# Go操作消息队列 + +NSQ是目前比较流行的一个分布式的消息队列,本文主要介绍了NSQ及Go语言如何操作NSQ。 + +使用消息队列的主要目的,异步、解耦、削峰 + +## NSQ介绍 + +[NSQ](https://nsq.io/)是Go语言编写的一个开源的实时分布式内存消息队列,其性能十分优异。 NSQ的优势有以下优势: + +1. NSQ提倡分布式和分散的拓扑,没有单点故障,支持容错和高可用性,并提供可靠的消息交付保证 +2. NSQ支持横向扩展,没有任何集中式代理。 +3. NSQ易于配置和部署,并且内置了管理界面。 + +## NSQ的应用场景 + +通常来说,消息队列都适用以下场景。 + +### 异步处理 + +参照下图利用消息队列把业务流程中的非关键流程异步化,从而显著降低业务请求的响应时间。![nsq应用场景1](images/nsq1.png) + +### 应用解耦 + +通过使用消息队列将不同的业务逻辑解耦,降低系统间的耦合,提高系统的健壮性。后续有其他业务要使用订单数据可直接订阅消息队列,提高系统的灵活性。![nsq应用场景1](images/nsq2.png) + +### 流量削峰 + +类似秒杀(大秒)等场景下,某一时间可能会产生大量的请求,使用消息队列能够为后端处理请求提供一定的缓冲区,保证后端服务的稳定性。![nsq应用场景1](images/nsq3.png) + +## 安装 + +[官方下载页面](https://nsq.io/deployment/installing.html)根据自己的平台下载并解压即可。 + +![image-20200901105947668](images/image-20200901105947668.png) + +## NSQ组件 + +### nsqd + +nsqd是一个守护进程,它接收、排队并向客户端发送消息。 + +启动`nsqd`,指定`-broadcast-address=127.0.0.1`来配置广播地址 + +```go +./nsqd -broadcast-address=127.0.0.1 +``` + +如果是在搭配`nsqlookupd`使用的模式下需要还指定`nsqlookupd`地址: + +```bash +./nsqd -broadcast-address=127.0.0.1 -lookupd-tcp-address=127.0.0.1:4160 +``` + +最后我们还需要启动图形化的界面 nsqadmin + +```bash +nsqadmin -lookupd-http-address=127.0.0.1:4161 +``` + +然后在启动成功后,在浏览器输入 127.0.0.1:4171,即可进入图形化界面 + +![image-20200901125118515](images/image-20200901125118515.png) + +如果是部署了多个`nsqlookupd`节点的集群,那还可以指定多个`-lookupd-tcp-address`。 + +`nsqdq`相关配置项如下: + +```go +-auth-http-address value + : to query auth server (may be given multiple times) +-broadcast-address string + address that will be registered with lookupd (defaults to the OS hostname) (default "PROSNAKES.local") +-config string + path to config file +-data-path string + path to store disk-backed messages +-deflate + enable deflate feature negotiation (client compression) (default true) +-e2e-processing-latency-percentile value + message processing time percentiles (as float (0, 1.0]) to track (can be specified multiple times or comma separated '1.0,0.99,0.95', default none) +-e2e-processing-latency-window-time duration + calculate end to end latency quantiles for this duration of time (ie: 60s would only show quantile calculations from the past 60 seconds) (default 10m0s) +-http-address string + : to listen on for HTTP clients (default "0.0.0.0:4151") +-http-client-connect-timeout duration + timeout for HTTP connect (default 2s) +-http-client-request-timeout duration + timeout for HTTP request (default 5s) +-https-address string + : to listen on for HTTPS clients (default "0.0.0.0:4152") +-log-prefix string + log message prefix (default "[nsqd] ") +-lookupd-tcp-address value + lookupd TCP address (may be given multiple times) +-max-body-size int + maximum size of a single command body (default 5242880) +-max-bytes-per-file int + number of bytes per diskqueue file before rolling (default 104857600) +-max-deflate-level int + max deflate compression level a client can negotiate (> values == > nsqd CPU usage) (default 6) +-max-heartbeat-interval duration + maximum client configurable duration of time between client heartbeats (default 1m0s) +-max-msg-size int + maximum size of a single message in bytes (default 1048576) +-max-msg-timeout duration + maximum duration before a message will timeout (default 15m0s) +-max-output-buffer-size int + maximum client configurable size (in bytes) for a client output buffer (default 65536) +-max-output-buffer-timeout duration + maximum client configurable duration of time between flushing to a client (default 1s) +-max-rdy-count int + maximum RDY count for a client (default 2500) +-max-req-timeout duration + maximum requeuing timeout for a message (default 1h0m0s) +-mem-queue-size int + number of messages to keep in memory (per topic/channel) (default 10000) +-msg-timeout string + duration to wait before auto-requeing a message (default "1m0s") +-node-id int + unique part for message IDs, (int) in range [0,1024) (default is hash of hostname) (default 616) +-snappy + enable snappy feature negotiation (client compression) (default true) +-statsd-address string + UDP : of a statsd daemon for pushing stats +-statsd-interval string + duration between pushing to statsd (default "1m0s") +-statsd-mem-stats + toggle sending memory and GC stats to statsd (default true) +-statsd-prefix string + prefix used for keys sent to statsd (%s for host replacement) (default "nsq.%s") +-sync-every int + number of messages per diskqueue fsync (default 2500) +-sync-timeout duration + duration of time per diskqueue fsync (default 2s) +-tcp-address string + : to listen on for TCP clients (default "0.0.0.0:4150") +-tls-cert string + path to certificate file +-tls-client-auth-policy string + client certificate auth policy ('require' or 'require-verify') +-tls-key string + path to key file +-tls-min-version value + minimum SSL/TLS version acceptable ('ssl3.0', 'tls1.0', 'tls1.1', or 'tls1.2') (default 769) +-tls-required + require TLS for client connections (true, false, tcp-https) +-tls-root-ca-file string + path to certificate authority file +-verbose + enable verbose logging +-version + print version string +-worker-id + do NOT use this, use --node-id +``` + +### nsqlookupd + +nsqlookupd是维护所有nsqd状态、提供服务发现的守护进程。它能为消费者查找特定`topic`下的nsqd提供了运行时的自动发现服务。 它不维持持久状态,也不需要与任何其他nsqlookupd实例协调以满足查询。因此根据你系统的冗余要求尽可能多地部署`nsqlookupd`节点。它们消耗的资源很少,可以与其他服务共存。我们的建议是为每个数据中心运行至少3个集群。 + +`nsqlookupd`相关配置项如下: + +```bash +-broadcast-address string + address of this lookupd node, (default to the OS hostname) (default "PROSNAKES.local") +-config string + path to config file +-http-address string + : to listen on for HTTP clients (default "0.0.0.0:4161") +-inactive-producer-timeout duration + duration of time a producer will remain in the active list since its last ping (default 5m0s) +-log-prefix string + log message prefix (default "[nsqlookupd] ") +-tcp-address string + : to listen on for TCP clients (default "0.0.0.0:4160") +-tombstone-lifetime duration + duration of time a producer will remain tombstoned if registration remains (default 45s) +-verbose + enable verbose logging +-version + print version string +``` + +### nsqadmin + +一个实时监控集群状态、执行各种管理任务的Web管理平台。 启动`nsqadmin`,指定`nsqlookupd`地址: + +```bash +./nsqadmin -lookupd-http-address=127.0.0.1:4161 +``` + +我们可以使用浏览器打开`http://127.0.0.1:4171/`访问如下管理界面。![nsqadmin管理界面](images/nsqadmin0.png) + +`nsqadmin`相关的配置项如下: + +```go +-allow-config-from-cidr string + A CIDR from which to allow HTTP requests to the /config endpoint (default "127.0.0.1/8") +-config string + path to config file +-graphite-url string + graphite HTTP address +-http-address string + : to listen on for HTTP clients (default "0.0.0.0:4171") +-http-client-connect-timeout duration + timeout for HTTP connect (default 2s) +-http-client-request-timeout duration + timeout for HTTP request (default 5s) +-http-client-tls-cert string + path to certificate file for the HTTP client +-http-client-tls-insecure-skip-verify + configure the HTTP client to skip verification of TLS certificates +-http-client-tls-key string + path to key file for the HTTP client +-http-client-tls-root-ca-file string + path to CA file for the HTTP client +-log-prefix string + log message prefix (default "[nsqadmin] ") +-lookupd-http-address value + lookupd HTTP address (may be given multiple times) +-notification-http-endpoint string + HTTP endpoint (fully qualified) to which POST notifications of admin actions will be sent +-nsqd-http-address value + nsqd HTTP address (may be given multiple times) +-proxy-graphite + proxy HTTP requests to graphite +-statsd-counter-format string + The counter stats key formatting applied by the implementation of statsd. If no formatting is desired, set this to an empty string. (default "stats.counters.%s.count") +-statsd-gauge-format string + The gauge stats key formatting applied by the implementation of statsd. If no formatting is desired, set this to an empty string. (default "stats.gauges.%s") +-statsd-interval duration + time interval nsqd is configured to push to statsd (must match nsqd) (default 1m0s) +-statsd-prefix string + prefix used for keys sent to statsd (%s for host replacement, must match nsqd) (default "nsq.%s") +-version + print version string +``` + +## NSQ架构 + +### NSQ工作模式 + +![nsq架构设计](images/nsq4.png) + +### Topic和Channel + +每个nsqd实例旨在一次处理多个数据流。这些数据流称为`“topics”`,一个`topic`具有1个或多个`“channels”`。每个`channel`都会收到`topic`所有消息的副本,实际上下游的服务是通过对应的`channel`来消费`topic`消息。 + +`topic`和`channel`不是预先配置的。`topic`在首次使用时创建,方法是将其发布到指定`topic`,或者订阅指定`topic`上的`channel`。`channel`是通过订阅指定的`channel`在第一次使用时创建的。 + +`topic`和`channel`都相互独立地缓冲数据,防止缓慢的消费者导致其他`chennel`的积压(同样适用于`topic`级别)。 + +`channel`可以并且通常会连接多个客户端。假设所有连接的客户端都处于准备接收消息的状态,则每条消息将被传递到随机客户端。例如: + +![nsq架构设计](images/nsq5.gif)总而言之,消息是从`topic -> channel`(每个channel接收该topic的所有消息的副本)多播的,但是从`channel -> consumers`均匀分布(每个消费者接收该channel的一部分消息)。 + +### NSQ接收和发送消息流程 + +![nsq架构设计](images/nsq6.png) + +- input Chan:就是go语言中的通道 +- In-Memory Chan:是内存的通道,负责将消息进行持久化 +- Output Chan: + +## NSQ特性 + +- 消息默认不持久化,可以配置成持久化模式。nsq采用的方式时内存+硬盘的模式,当内存到达一定程度时就会将数据持久化到硬盘。 + - 如果将`--mem-queue-size`设置为0,所有的消息将会存储到磁盘。 + - 服务器重启时也会将当时在内存中的消息持久化。 +- 每条消息至少传递一次。 +- 消息不保证有序。 + +## Go操作NSQ + +官方提供了Go语言版的客户端:[go-nsq](https://github.com/nsqio/go-nsq),更多客户端支持请查看[CLIENT LIBRARIES](https://nsq.io/clients/client_libraries.html)。 + +### 启动 + +首先进入bin目录下,打开cmd,输入 + +```bash +nsqlookupd +``` + +然后就开启了nsq服务,端口号是4160 + +![image-20200901110859477](images/image-20200901110859477.png) + +然后我们在启动一个cmd界面,输入下面的代码,启动nsqd,nsqd是一个守护进程,它用于接收、排队并向客户端发送消息,启动nsqd,指定 `-broadcast-address=127.0.0.1` 来配置广播地址 + +```bash +nsqd -broadcast-address=127.0.0.1 +``` + +如果是在搭配 `nsqlookupd`,使用的模式下需要还指定`nsqlookupd`的地址 + +```bash +nsqd -broadcast-address=127.0.0.1 -lookupd-tcp-address=127.0.0.1:4160 +``` + +启动成功的图片如下所示 + +![image-20200901111133414](images/image-20200901111133414.png) + + + +### 安装 + +```bash +go get -u github.com/nsqio/go-nsq +``` + +### 生产者 + +一个简单的生产者示例代码如下: + +```go +// nsq_producer/main.go +package main + +import ( + "bufio" + "fmt" + "os" + "strings" + + "github.com/nsqio/go-nsq" +) + +// NSQ Producer Demo + +var producer *nsq.Producer + +// 初始化生产者 +func initProducer(str string) (err error) { + config := nsq.NewConfig() + producer, err = nsq.NewProducer(str, config) + if err != nil { + fmt.Printf("create producer failed, err:%v\n", err) + return err + } + return nil +} + +func main() { + nsqAddress := "127.0.0.1:4150" + err := initProducer(nsqAddress) + if err != nil { + fmt.Printf("init producer failed, err:%v\n", err) + return + } + + reader := bufio.NewReader(os.Stdin) // 从标准输入读取 + for { + data, err := reader.ReadString('\n') + if err != nil { + fmt.Printf("read string from stdin failed, err:%v\n", err) + continue + } + data = strings.TrimSpace(data) + if strings.ToUpper(data) == "Q" { // 输入Q退出 + break + } + // 向 'topic_demo' publish 数据 + err = producer.Publish("topic_demo", []byte(data)) + if err != nil { + fmt.Printf("publish msg to nsq failed, err:%v\n", err) + continue + } + } +} +``` + +将上面的代码编译执行,然后在终端输入两条数据`123`和`456`: + +```bash +$ ./nsq_producer +123 +2018/10/22 18:41:20 INF 1 (127.0.0.1:4150) connecting to nsqd +456 +``` + +使用浏览器打开`http://127.0.0.1:4171/`可以查看到类似下面的页面: 在下面这个页面能看到当前的`topic`信息:![nsqadmin界面1](images/nsqadmin1.png) + +点击页面上的`topic_demo`就能进入一个展示更多详细信息的页面,在这个页面上我们可以查看和管理`topic`,同时能够看到目前在`LWZMBP:4151 (127.0.01:4151)`这个`nsqd`上有2条message。又因为没有消费者接入所以暂时没有创建`channel`。![nsqadmin界面2](images/nsqadmin2.png) + +在`/nodes`这个页面我们能够很方便的查看当前接入`lookupd`的`nsqd`节点。![nsqadmin界面3](images/nsqadmin3.png) + +这个`/counter`页面显示了处理的消息数量,因为我们没有接入消费者,所以处理的消息数量为0。![images/nsqadmin4.png) + +在`/lookup`界面支持创建`topic`和`channel`。![nsqadmin界面5](images/nsqadmin5.png) + +### 消费者 + +一个简单的消费者示例代码如下: + +```go +// nsq_consumer/main.go +package main + +import ( + "fmt" + "os" + "os/signal" + "syscall" + "time" + + "github.com/nsqio/go-nsq" +) + +// NSQ Consumer Demo + +// MyHandler 是一个消费者类型 +type MyHandler struct { + Title string +} + +// HandleMessage 是需要实现的处理消息的方法 +func (m *MyHandler) HandleMessage(msg *nsq.Message) (err error) { + fmt.Printf("%s recv from %v, msg:%v\n", m.Title, msg.NSQDAddress, string(msg.Body)) + return +} + +// 初始化消费者 +func initConsumer(topic string, channel string, address string) (err error) { + config := nsq.NewConfig() + config.LookupdPollInterval = 15 * time.Second + c, err := nsq.NewConsumer(topic, channel, config) + if err != nil { + fmt.Printf("create consumer failed, err:%v\n", err) + return + } + consumer := &MyHandler{ + Title: "沙河1号", + } + c.AddHandler(consumer) + + // if err := c.ConnectToNSQD(address); err != nil { // 直接连NSQD + if err := c.ConnectToNSQLookupd(address); err != nil { // 通过lookupd查询 + return err + } + return nil + +} + +func main() { + err := initConsumer("topic_demo", "first", "127.0.0.1:4161") + if err != nil { + fmt.Printf("init consumer failed, err:%v\n", err) + return + } + c := make(chan os.Signal) // 定义一个信号的通道 + signal.Notify(c, syscall.SIGINT) // 转发键盘中断信号到c + <-c // 阻塞 +} +``` + +将上面的代码保存之后编译执行,就能够获取之前我们publish的两条消息了: + +```bash +$ ./nsq_consumer +2018/10/22 18:49:06 INF 1 [topic_demo/first] querying nsqlookupd http://127.0.0.1:4161/lookup?topic=topic_demo +2018/10/22 18:49:06 INF 1 [topic_demo/first] (127.0.0.1:4150) connecting to nsqd +沙河1号 recv from 127.0.0.1:4150, msg:123 +沙河1号 recv from 127.0.0.1:4150, msg:456 +``` + +同时在nsqadmin的`/counter`页面查看到处理的数据数量为2。![nsqadmin界面5](images/nsqadmin6.png) + +关于`go-nsq`的更多内容请阅读[go-nsq的官方文档](https://godoc.org/github.com/nsqio/go-nsq)。 \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/image-20200901105947668.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/image-20200901105947668.png" new file mode 100644 index 0000000000000000000000000000000000000000..31d5b66403cbc70e29914f5640bb000bbf9ddc9a Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/image-20200901105947668.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/image-20200901110859477.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/image-20200901110859477.png" new file mode 100644 index 0000000000000000000000000000000000000000..6ad174bc5e38efc80f0b7ead6d3bf87001875006 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/image-20200901110859477.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/image-20200901111133414.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/image-20200901111133414.png" new file mode 100644 index 0000000000000000000000000000000000000000..0ac75988c419e1ea4a0f18d66629e07bec99ea0a Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/image-20200901111133414.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/image-20200901125118515.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/image-20200901125118515.png" new file mode 100644 index 0000000000000000000000000000000000000000..e53702cfec311c2dd6a0427bad79ff8f4debd234 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/image-20200901125118515.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq1.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq1.png" new file mode 100644 index 0000000000000000000000000000000000000000..30c98b03e75fd96fa23b20307508ef8bc191ec65 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq1.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq2.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq2.png" new file mode 100644 index 0000000000000000000000000000000000000000..32644ccfec026a5402ba50e02e6a9d444ec2504e Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq2.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq3.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq3.png" new file mode 100644 index 0000000000000000000000000000000000000000..71d40987541a87437c1cb2af11dcda29e6c2471e Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq3.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq4.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq4.png" new file mode 100644 index 0000000000000000000000000000000000000000..836f786bfb106c4ee3b5f0f405b7d8610ee16e3f Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq4.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq5.gif" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq5.gif" new file mode 100644 index 0000000000000000000000000000000000000000..6dacc125b343ac1af67431164123a1df86eb2cac Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq5.gif" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq6.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq6.png" new file mode 100644 index 0000000000000000000000000000000000000000..b006ff0875254db81ef3999607fdf42d3522e6f8 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsq6.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin0.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin0.png" new file mode 100644 index 0000000000000000000000000000000000000000..c5126fa49f9516c724d521157e1f324f4b8bde31 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin0.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin1.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin1.png" new file mode 100644 index 0000000000000000000000000000000000000000..ccc78503bf7c654f4fc072c646145e145649458d Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin1.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin2.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin2.png" new file mode 100644 index 0000000000000000000000000000000000000000..28db5149e2847b47aedac2a95acafd115b0f61ec Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin2.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin3.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin3.png" new file mode 100644 index 0000000000000000000000000000000000000000..3a76ddebc35168da044cf1fe1407c3f3b9c75c78 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin3.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin4.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin4.png" new file mode 100644 index 0000000000000000000000000000000000000000..4b3059dc823928b00186321b1df4f7151db6522b Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin4.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin5.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin5.png" new file mode 100644 index 0000000000000000000000000000000000000000..b3c388beed01940eb2aea9d1a58283b74ae80341 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin5.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin6.png" "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin6.png" new file mode 100644 index 0000000000000000000000000000000000000000..b9debaf82ad7de2821f27c6621ad72fb7b9ef14e Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/14_Go\346\223\215\344\275\234\346\266\210\346\201\257\351\230\237\345\210\227/images/nsqadmin6.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/15_Go\347\232\204\344\276\235\350\265\226\347\256\241\347\220\206GoModule/README.md" "b/Golang/Golang\350\277\233\351\230\266/15_Go\347\232\204\344\276\235\350\265\226\347\256\241\347\220\206GoModule/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..077d811f3bc8775ece7768dd737d431674fa3f02 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/15_Go\347\232\204\344\276\235\350\265\226\347\256\241\347\220\206GoModule/README.md" @@ -0,0 +1,215 @@ +# Go的依赖管理Go Module + +## 来源 + +https://www.liwenzhou.com/posts/Go/go_dependency/ + +## 历史遗留问题 + +如果是使用Go1.11和Go1.12版本,需要手动开启Go module支持 + +![image-20200906202108891](images/image-20200906202108891.png) + +## 为什么需要依赖管理 + +最早的时候,Go所依赖的所有的第三方库都放在GOPATH这个目录下面。这就导致了同一个库只能保存一个版本的代码。如果不同的项目依赖同一个第三方的库的不同版本,应该怎么解决? + +## godep + +Go语言从v1.5开始开始引入`vendor`模式,如果项目目录下有vendor目录,那么go工具链会优先使用`vendor`内的包进行编译、测试等。 + +`godep`是一个通过vender模式实现的Go语言的第三方依赖管理工具,类似的还有由社区维护准官方包管理工具`dep`。 + +### 安装 + +执行以下命令安装`godep`工具。 + +```go +go get github.com/tools/godep +``` + +### 基本命令 + +安装好godep之后,在终端输入`godep`查看支持的所有命令。 + +```bash +godep save 将依赖项输出并复制到Godeps.json文件中 +godep go 使用保存的依赖项运行go工具 +godep get 下载并安装具有指定依赖项的包 +godep path 打印依赖的GOPATH路径 +godep restore 在GOPATH中拉取依赖的版本 +godep update 更新选定的包或go版本 +godep diff 显示当前和以前保存的依赖项集之间的差异 +godep version 查看版本信息 +``` + +使用`godep help [command]`可以看看具体命令的帮助信息。 + +### 使用godep + +在项目目录下执行`godep save`命令,会在当前项目中创建`Godeps`和`vender`两个文件夹。 + +其中`Godeps`文件夹下有一个`Godeps.json`的文件,里面记录了项目所依赖的包信息。 `vender`文件夹下是项目依赖的包的源代码文件。 + +### vender机制 + +Go1.5版本之后开始支持,能够控制Go语言程序编译时依赖包搜索路径的优先级。 + +例如查找项目的某个依赖包,首先会在项目根目录下的`vender`文件夹中查找,如果没有找到就会去`$GOAPTH/src`目录下查找。 + +### godep开发流程 + +1. 保证程序能够正常编译 +2. 执行`godep save`保存当前项目的所有第三方依赖的版本信息和代码 +3. 提交Godeps目录和vender目录到代码库。 +4. 如果要更新依赖的版本,可以直接修改`Godeps.json`文件中的对应项 + +## go module + +`go module`是Go1.11版本之后官方推出的版本管理工具,并且从Go1.13版本开始,`go module`将是Go语言默认的依赖管理工具。 + +### GO111MODULE + +要启用`go module`支持首先要设置环境变量`GO111MODULE`,通过它可以开启或关闭模块支持,它有三个可选值:`off`、`on`、`auto`,默认值是`auto`。 + +1. `GO111MODULE=off`禁用模块支持,编译时会从`GOPATH`和`vendor`文件夹中查找包。 +2. `GO111MODULE=on`启用模块支持,编译时会忽略`GOPATH`和`vendor`文件夹,只根据 `go.mod`下载依赖。 +3. `GO111MODULE=auto`,当项目在`$GOPATH/src`外且项目根目录有`go.mod`文件时,开启模块支持。 + +简单来说,设置`GO111MODULE=on`之后就可以使用`go module`了,以后就没有必要在GOPATH中创建项目了,并且还能够很好的管理项目依赖的第三方包信息。 + +使用 go module 管理依赖后会在项目根目录下生成两个文件`go.mod`和`go.sum`。 + +### GOPROXY + +Go1.11之后设置GOPROXY命令为: + +```bash +export GOPROXY=https://goproxy.cn +``` + +Go1.13之后`GOPROXY`默认值为`https://proxy.golang.org`,在国内是无法访问的,所以十分建议大家设置GOPROXY,这里我推荐使用[goproxy.cn](https://studygolang.com/topics/10014)。 + +```bash +go env -w GOPROXY=https://goproxy.cn,direct +``` + +### go mod命令 + +常用的`go mod`命令如下: + +``` +go mod download 下载依赖的module到本地cache(默认为$GOPATH/pkg/mod目录) +go mod edit 编辑go.mod文件 +go mod graph 打印模块依赖图 +go mod init 初始化当前文件夹, 创建go.mod文件 +go mod tidy 增加缺少的module,删除无用的module +go mod vendor 将依赖复制到vendor下 +go mod verify 校验依赖 +go mod why 解释为什么需要依赖 +``` + +### go.mod + +go.mod文件记录了项目所有的依赖信息,其结构大致如下: + +```sh +module github.com/Q1mi/studygo/blogger + +go 1.12 + +require ( + github.com/DeanThompson/ginpprof v0.0.0-20190408063150-3be636683586 + github.com/gin-gonic/gin v1.4.0 + github.com/go-sql-driver/mysql v1.4.1 + github.com/jmoiron/sqlx v1.2.0 + github.com/satori/go.uuid v1.2.0 + google.golang.org/appengine v1.6.1 // indirect +) +``` + +其中, + +- `module`用来定义包名 +- `require`用来定义依赖包及版本 +- `indirect`表示间接引用 + +#### 依赖的版本 + +go mod支持语义化版本号,比如`go get foo@v1.2.3`,也可以跟git的分支或tag,比如`go get foo@master`,当然也可以跟git提交哈希,比如`go get foo@e3702bed2`。关于依赖的版本支持以下几种格式: + +```go +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 +gopkg.in/vmihailenco/msgpack.v2 v2.9.1 +gopkg.in/yaml.v2 <=v2.2.1 +github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e +latest +``` + +#### replace + +在国内访问golang.org/x的各个包都需要翻墙,你可以在go.mod中使用replace替换成github上对应的库。 + +```go +replace ( + golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac => github.com/golang/crypto v0.0.0-20180820150726-614d502a4dac + golang.org/x/net v0.0.0-20180821023952-922f4815f713 => github.com/golang/net v0.0.0-20180826012351-8a410e7b638d + golang.org/x/text v0.3.0 => github.com/golang/text v0.3.0 +) +``` + +### go get + +在项目中执行`go get`命令可以下载依赖包,并且还可以指定下载的版本。 + +1. 运行`go get -u`将会升级到最新的次要版本或者修订版本(x.y.z, z是修订版本号, y是次要版本号) +2. 运行`go get -u=patch`将会升级到最新的修订版本 +3. 运行`go get package@version`将会升级到指定的版本号version + +如果下载所有依赖可以使用`go mod download`命令。 + +### 整理依赖 + +我们在代码中删除依赖代码后,相关的依赖库并不会在`go.mod`文件中自动移除。这种情况下我们可以使用`go mod tidy`命令更新`go.mod`中的依赖关系。 + +### go mod edit + +#### 格式化 + +因为我们可以手动修改go.mod文件,所以有些时候需要格式化该文件。Go提供了一下命令: + +```bash +go mod edit -fmt +``` + +#### 添加依赖项 + +```bash +go mod edit -require=golang.org/x/text +``` + +#### 移除依赖项 + +如果只是想修改`go.mod`文件中的内容,那么可以运行`go mod edit -droprequire=package path`,比如要在`go.mod`中移除`golang.org/x/text`包,可以使用如下命令: + +```bash +go mod edit -droprequire=golang.org/x/text +``` + +关于`go mod edit`的更多用法可以通过`go help mod edit`查看。 + +## 在项目中使用go module + +### 既有项目 + +如果需要对一个已经存在的项目启用`go module`,可以按照以下步骤操作: + +1. 在项目目录下执行`go mod init`,生成一个`go.mod`文件。 +2. 执行`go get`,查找并记录当前项目的依赖,同时生成一个`go.sum`记录每个依赖库的版本和哈希值。 + +### 新项目 + +对于一个新创建的项目,我们可以在项目文件夹下按照以下步骤操作: + +1. 执行`go mod init 项目名`命令,在当前项目文件夹下创建一个`go.mod`文件。 +2. 手动编辑`go.mod`中的require依赖项或执行`go get`自动发现、维护依赖。 \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/15_Go\347\232\204\344\276\235\350\265\226\347\256\241\347\220\206GoModule/images/image-20200906202108891.png" "b/Golang/Golang\350\277\233\351\230\266/15_Go\347\232\204\344\276\235\350\265\226\347\256\241\347\220\206GoModule/images/image-20200906202108891.png" new file mode 100644 index 0000000000000000000000000000000000000000..c73bc0769f1c5f4d4ee4c9754771cb3dc0165021 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/15_Go\347\232\204\344\276\235\350\265\226\347\256\241\347\220\206GoModule/images/image-20200906202108891.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/16_GoContext\347\232\204\344\275\277\347\224\250/README.md" "b/Golang/Golang\350\277\233\351\230\266/16_GoContext\347\232\204\344\275\277\347\224\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..3bb844ab138056e26ddd77225ecb03d91ace2f49 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/16_GoContext\347\232\204\344\275\277\347\224\250/README.md" @@ -0,0 +1,602 @@ +# Go Context的使用 + +在 Go http包的Server中,每一个请求在都有一个对应的 goroutine 去处理。请求处理函数通常会启动额外的 goroutine 用来访问后端服务,比如数据库和RPC服务。用来处理一个请求的 goroutine 通常需要访问一些与请求特定的数据,比如终端用户的身份认证信息、验证相关的token、请求的截止时间。 当一个请求被取消或超时时,所有用来处理该请求的 goroutine 都应该迅速退出,然后系统才能释放这些 goroutine 占用的资源。 + +## 来源 + +https://www.liwenzhou.com/posts/Go/go_context/ + +## 为什么需要Context + +### 基本示例 + +```go +package main + +import ( + "fmt" + "sync" + + "time" +) + +var wg sync.WaitGroup + +// 初始的例子 + +func worker() { + for { + fmt.Println("worker") + time.Sleep(time.Second) + } + // 如何接收外部命令实现退出 + wg.Done() +} + +func main() { + wg.Add(1) + go worker() + // 如何优雅的实现结束子goroutine + wg.Wait() + fmt.Println("over") +} +``` + +### 全局变量方式 + +```go +package main + +import ( + "fmt" + "sync" + + "time" +) + +var wg sync.WaitGroup +var exit bool + +// 全局变量方式存在的问题: +// 1. 使用全局变量在跨包调用时不容易统一 +// 2. 如果worker中再启动goroutine,就不太好控制了。 + +func worker() { + for { + fmt.Println("worker") + time.Sleep(time.Second) + if exit { + break + } + } + wg.Done() +} + +func main() { + wg.Add(1) + go worker() + time.Sleep(time.Second * 3) // sleep3秒以免程序过快退出 + exit = true // 修改全局变量实现子goroutine的退出 + wg.Wait() + fmt.Println("over") +} +``` + +### 通道方式 + +```go +package main + +import ( + "fmt" + "sync" + + "time" +) + +var wg sync.WaitGroup + +// 管道方式存在的问题: +// 1. 使用全局变量在跨包调用时不容易实现规范和统一,需要维护一个共用的channel + +func worker(exitChan chan struct{}) { +LOOP: + for { + fmt.Println("worker") + time.Sleep(time.Second) + select { + case <-exitChan: // 等待接收上级通知 + break LOOP + default: + } + } + wg.Done() +} + +func main() { + var exitChan = make(chan struct{}) + wg.Add(1) + go worker(exitChan) + time.Sleep(time.Second * 3) // sleep3秒以免程序过快退出 + exitChan <- struct{}{} // 给子goroutine发送退出信号 + close(exitChan) + wg.Wait() + fmt.Println("over") +} +``` + +### 官方版的方案 + +```go +package main + +import ( + "context" + "fmt" + "sync" + + "time" +) + +var wg sync.WaitGroup + +func worker(ctx context.Context) { +LOOP: + for { + fmt.Println("worker") + time.Sleep(time.Second) + select { + case <-ctx.Done(): // 等待上级通知 + break LOOP + default: + } + } + wg.Done() +} + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + wg.Add(1) + go worker(ctx) + time.Sleep(time.Second * 3) + cancel() // 通知子goroutine结束 + wg.Wait() + fmt.Println("over") +} +``` + +当子goroutine又开启另外一个goroutine时,只需要将ctx传入即可: + +```go +package main + +import ( + "context" + "fmt" + "sync" + + "time" +) + +var wg sync.WaitGroup + +func worker(ctx context.Context) { + go worker2(ctx) +LOOP: + for { + fmt.Println("worker") + time.Sleep(time.Second) + select { + case <-ctx.Done(): // 等待上级通知 + break LOOP + default: + } + } + wg.Done() +} + +func worker2(ctx context.Context) { +LOOP: + for { + fmt.Println("worker2") + time.Sleep(time.Second) + select { + case <-ctx.Done(): // 等待上级通知 + break LOOP + default: + } + } +} +func main() { + ctx, cancel := context.WithCancel(context.Background()) + wg.Add(1) + go worker(ctx) + time.Sleep(time.Second * 3) + cancel() // 通知子goroutine结束 + wg.Wait() + fmt.Println("over") +} +``` + +## Context初识 + +Go1.7加入了一个新的标准库`context`,它定义了`Context`类型,专门用来简化 对于处理单个请求的多个 goroutine 之间与请求域的数据、取消信号、截止时间等相关操作,这些操作可能涉及多个 API 调用。 + +对服务器传入的请求应该创建上下文,而对服务器的传出调用应该接受上下文。它们之间的函数调用链必须传递上下文,或者可以使用`WithCancel`、`WithDeadline`、`WithTimeout`或`WithValue`创建的派生上下文。当一个上下文被取消时,它派生的所有上下文也被取消。 + +## Context接口 + +`context.Context`是一个接口,该接口定义了四个需要实现的方法。具体签名如下: + +```go +type Context interface { + Deadline() (deadline time.Time, ok bool) + Done() <-chan struct{} + Err() error + Value(key interface{}) interface{} +} +``` + +其中: + +- `Deadline`方法需要返回当前`Context`被取消的时间,也就是完成工作的截止时间(deadline); + +- `Done`方法需要返回一个`Channel`,这个Channel会在当前工作完成或者上下文被取消之后关闭,多次调用`Done`方法会返回同一个Channel; + +- ``` + Err + ``` + + 方法会返回当前 + + ``` + Context + ``` + + 结束的原因,它只会在 + + ``` + Done + ``` + + 返回的Channel被关闭时才会返回非空的值; + + - 如果当前`Context`被取消就会返回`Canceled`错误; + - 如果当前`Context`超时就会返回`DeadlineExceeded`错误; + +- `Value`方法会从`Context`中返回键对应的值,对于同一个上下文来说,多次调用`Value` 并传入相同的`Key`会返回相同的结果,该方法仅用于传递跨API和进程间跟请求域的数据; + +### Background()和TODO() + +Go内置两个函数:`Background()`和`TODO()`,这两个函数分别返回一个实现了`Context`接口的`background`和`todo`。我们代码中最开始都是以这两个内置的上下文对象作为最顶层的`partent context`,衍生出更多的子上下文对象。 + +`Background()`主要用于main函数、初始化以及测试代码中,作为Context这个树结构的最顶层的Context,也就是根Context。 + +`TODO()`,它目前还不知道具体的使用场景,如果我们不知道该使用什么Context的时候,可以使用这个。 + +`background`和`todo`本质上都是`emptyCtx`结构体类型,是一个不可取消,没有设置截止时间,没有携带任何值的Context。 + +## With系列函数 + +此外,`context`包中还定义了四个With系列函数。 + +### WithCancel + +`WithCancel`的函数签名如下: + +```go +func WithCancel(parent Context) (ctx Context, cancel CancelFunc) +``` + +`WithCancel`返回带有新Done通道的父节点的副本。当调用返回的cancel函数或当关闭父上下文的Done通道时,将关闭返回上下文的Done通道,无论先发生什么情况。 + +取消此上下文将释放与其关联的资源,因此代码应该在此上下文中运行的操作完成后立即调用cancel。 + +```go +func gen(ctx context.Context) <-chan int { + dst := make(chan int) + n := 1 + go func() { + for { + select { + case <-ctx.Done(): + return // return结束该goroutine,防止泄露 + case dst <- n: + n++ + } + } + }() + return dst + } +func main() { + // context.Background:传递的是根节点 + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() // 当我们取完需要的整数后调用cancel,相当于向ctx里面添加值 + + // 遍历chan + for n := range gen(ctx) { + fmt.Println(n) + if n == 5 { + break + } + } +} +``` + +上面的示例代码中,`gen`函数在单独的goroutine中生成整数并将它们发送到返回的通道。 gen的调用者在使用生成的整数之后需要取消上下文,以免`gen`启动的内部goroutine发生泄漏。 + +### WithDeadline + +`WithDeadline`的函数签名如下: + +```go +func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) +``` + +返回父上下文的副本,并将deadline调整为不迟于d。如果父上下文的deadline已经早于d,则WithDeadline(parent, d)在语义上等同于父上下文。当截止日过期时,当调用返回的cancel函数时,或者当父上下文的Done通道关闭时,返回上下文的Done通道将被关闭,以最先发生的情况为准。 + +取消此上下文将释放与其关联的资源,因此代码应该在此上下文中运行的操作完成后立即调用cancel。 + +```go +func main() { + // 设置过期时间50毫秒 + d := time.Now().Add(50 * time.Millisecond) + ctx, cancel := context.WithDeadline(context.Background(), d) + + // 尽管ctx会过期,但在任何情况下调用它的cancel函数都是很好的实践。 + // 如果不这样做,可能会使上下文及其父类存活的时间超过必要的时间。 + defer cancel() + + select { + case <-time.After(1 * time.Second): + fmt.Println("overslept") + case <-ctx.Done(): + fmt.Println(ctx.Err()) + } +} +``` + +上面的代码中,定义了一个50毫秒之后过期的deadline,然后我们调用`context.WithDeadline(context.Background(), d)`得到一个上下文(ctx)和一个取消函数(cancel),然后使用一个select让主程序陷入等待:等待1秒后打印`overslept`退出或者等待ctx过期后退出。 因为ctx50秒后就过期,所以`ctx.Done()`会先接收到值,上面的代码会打印ctx.Err()取消原因。 + +### WithTimeout + +`WithTimeout`的函数签名如下: + +```go +func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) +``` + +`WithTimeout`返回`WithDeadline(parent, time.Now().Add(timeout))`。 + +取消此上下文将释放与其相关的资源,因此代码应该在此上下文中运行的操作完成后立即调用cancel,通常用于数据库或者网络连接的超时控制。具体示例如下: + +```go +package main + +import ( + "context" + "fmt" + "sync" + + "time" +) + +// context.WithTimeout + +var wg sync.WaitGroup + +func worker(ctx context.Context) { +LOOP: + for { + fmt.Println("db connecting ...") + time.Sleep(time.Millisecond * 10) // 假设正常连接数据库耗时10毫秒 + select { + case <-ctx.Done(): // 50毫秒后自动调用 + break LOOP + default: + } + } + fmt.Println("worker done!") + wg.Done() +} + +func main() { + // 设置一个50毫秒的超时 + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50) + wg.Add(1) + go worker(ctx) + time.Sleep(time.Second * 5) + cancel() // 通知子goroutine结束 + wg.Wait() + fmt.Println("over") +} +``` + +### WithValue + +`WithValue`函数能够将请求作用域的数据与 Context 对象建立关系。声明如下: + +```go +func WithValue(parent Context, key, val interface{}) Context +``` + +`WithValue`返回父节点的副本,其中与key关联的值为val。 + +仅对API和进程间传递请求域的数据使用上下文值,而不是使用它来传递可选参数给函数。 + +所提供的键必须是可比较的,并且不应该是`string`类型或任何其他内置类型,以避免使用上下文在包之间发生冲突。`WithValue`的用户应该为键定义自己的类型。为了避免在分配给interface{}时进行分配,上下文键通常具有具体类型`struct{}`。或者,导出的上下文关键变量的静态类型应该是指针或接口。 + +```go +package main + +import ( + "context" + "fmt" + "sync" + + "time" +) + +// context.WithValue + +type TraceCode string + +var wg sync.WaitGroup + +func worker(ctx context.Context) { + key := TraceCode("TRACE_CODE") + // .(string) 是类型断言 + traceCode, ok := ctx.Value(key).(string) // 在子goroutine中获取trace code + if !ok { + fmt.Println("invalid trace code") + } +LOOP: + for { + fmt.Printf("worker, trace code:%s\n", traceCode) + time.Sleep(time.Millisecond * 10) // 假设正常连接数据库耗时10毫秒 + select { + case <-ctx.Done(): // 50毫秒后自动调用 + break LOOP + default: + } + } + fmt.Println("worker done!") + wg.Done() +} + +func main() { + // 设置一个50毫秒的超时 + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50) + // 在系统的入口中设置trace code传递给后续启动的goroutine实现日志数据聚合 + ctx = context.WithValue(ctx, TraceCode("TRACE_CODE"), "12512312234") + wg.Add(1) + go worker(ctx) + time.Sleep(time.Second * 5) + cancel() // 通知子goroutine结束 + wg.Wait() + fmt.Println("over") +} +``` + +## 使用Context的注意事项 + +- 推荐以参数的方式显示传递Context +- 以Context作为参数的函数方法,应该把Context作为第一个参数。 +- 给一个函数方法传递Context的时候,不要传递nil,如果不知道传递什么,就使用context.TODO() +- Context的Value相关方法应该传递请求域的必要数据,不应该用于传递可选参数 +- Context是线程安全的,可以放心的在多个goroutine中传递 + +## 客户端超时取消示例 + +调用服务端API时如何在客户端实现超时控制? + +### server端 + +```go +// context_timeout/server/main.go +package main + +import ( + "fmt" + "math/rand" + "net/http" + + "time" +) + +// server端,随机出现慢响应 + +func indexHandler(w http.ResponseWriter, r *http.Request) { + number := rand.Intn(2) + if number == 0 { + time.Sleep(time.Second * 10) // 耗时10秒的慢响应 + fmt.Fprintf(w, "slow response") + return + } + fmt.Fprint(w, "quick response") +} + +func main() { + http.HandleFunc("/", indexHandler) + err := http.ListenAndServe(":8000", nil) + if err != nil { + panic(err) + } +} +``` + +### client端 + +```go +// context_timeout/client/main.go +package main + +import ( + "context" + "fmt" + "io/ioutil" + "net/http" + "sync" + "time" +) + +// 客户端 + +type respData struct { + resp *http.Response + err error +} + +func doCall(ctx context.Context) { + transport := http.Transport{ + // 请求频繁可定义全局的client对象并启用长链接 + // 请求不频繁使用短链接 + DisableKeepAlives: true, } + client := http.Client{ + Transport: &transport, + } + + respChan := make(chan *respData, 1) + req, err := http.NewRequest("GET", "http://127.0.0.1:8000/", nil) + if err != nil { + fmt.Printf("new requestg failed, err:%v\n", err) + return + } + req = req.WithContext(ctx) // 使用带超时的ctx创建一个新的client request + var wg sync.WaitGroup + wg.Add(1) + defer wg.Wait() + go func() { + resp, err := client.Do(req) + fmt.Printf("client.do resp:%v, err:%v\n", resp, err) + rd := &respData{ + resp: resp, + err: err, + } + respChan <- rd + wg.Done() + }() + + select { + case <-ctx.Done(): + //transport.CancelRequest(req) + fmt.Println("call api timeout") + case result := <-respChan: + fmt.Println("call server api success") + if result.err != nil { + fmt.Printf("call server api failed, err:%v\n", result.err) + return + } + defer result.resp.Body.Close() + data, _ := ioutil.ReadAll(result.resp.Body) + fmt.Printf("resp:%v\n", string(data)) + } +} + +func main() { + // 定义一个100毫秒的超时 + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*100) + defer cancel() // 调用cancel释放子goroutine资源 + doCall(ctx) +} +``` \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/README.md" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..d0a817a97ffa97bce7d3e75d584d323a3b09ae15 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/README.md" @@ -0,0 +1,747 @@ +# 日志收集项目架构设计及Kafka介绍 + +## 项目背景 + +每个业务系统都有日志,当系统出现问题时,需要通过日志信息来定位和解决问题。当系统机器比较少时,登陆到服务器上查看即可满足当系统机器规模巨大,登陆到机器上查看几乎不现实(分布式的系统,一个系统部署在十几台机器上) + +## 解决方案 + +把机器上的日志实时收集,统一存储到中心系统。再对这些日志建立索引,通过搜索即可快速找到对应的日志记录。通过提供一个界面友好的web页面实现日志展示与检索。 + +## 面临的问题 + +实时日志量非常大,每天处理几十亿条。日志准实时收集,延迟控制在分钟级别。系统的架构设计能够支持水平扩展。 + +## 业界方案 + +### ELK + +![image-20200906204717091](images/image-20200906204717091.png) + +- AppServer:跑业务的服务器 +- Logstash Agent: +- Elastic Search Cluster +- Kibana Server:数据可视化 +- Browser:浏览器 + +### ELK方案的问题 + +- 运维成本高,每增加一个日志收集项,都需要手动修改配置 + - 使用etcd来管理被收集的日志项 +- 监控缺失,无法精准获取logstash的状态 +- 无法做到定制化开发与维护 + +## 日志收集系统架构设计 + +### 架构设计 + +![image-20200906205046296](images/image-20200906205046296.png) + +通过etcd做一个配置中心的概念,它是用go写的,是可以用来替代Zookeeper的 + +LogAgent收集日志,然后将其发送到Kafka中,Kafka既可以作为消息队列,也可以做到消息的存储组件 + +然后Log transfer就将Kafka中的日志记录取出来,进行处理,然后写入到ElasticSearch中,然后将对应的日志 + +最后通过Kibana进行可视化展示,SysAgent是用来采集系统的日志信息(或者使用 普罗米修斯) + +### 组件介绍 + +- LogAgent:日志收集客户端,用来收集服务器上的日志 +- Kafka:高吞吐量的分布式队列(Linkin开发,Apache顶级开源项目) +- ElasticSearch:开源的搜索引擎,提供基于HTTP RESTful的web接口 +- Kibana:开源的ES数据分析和可视化工具 +- Hadoop:分布式计算框架,能够对大量数据进行分布式处理的平台 +- Storm:一个免费并开源的分布式实时计算框架 + +### 将学到的技能 + +- 服务端agent开发 +- 后端服务组件开发 +- Kafka和Zookeeper的使用 +- ES和Kibana使用 +- etcd的使用(配置中心,配置共享) + +## 消息队列的通信模型 + +### 点对点模式 queue + +消息生产者发送到queue中,然后消息消费者从queue中取出并消费信息,一条消息被消费以后,queue中就没有了,不存在重复消费的问题 + +### 发布/订阅 topic + +消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。和点对点方式不同,发布到topic的消息会被所有的订阅者消费(类似于关注了微信公众号的人都能收到推送的文章)。 + +补充:发布订阅模式下,当发布者消息量很大时,显然单个订阅者的处理能力是不足的。实际上现实场景中多个订阅者节点组成一个订阅组负载均衡消费topic消息即分组订阅,这样订阅者很容易实现消费能力线扩展。可以看成是一个topic下有多个Queue,每个Queue是点对点的方式,Queue之间是发布订阅方式。 + +## Kafka + +Apache Kafka由著名职业社交公司Linkedin开发,最初是被设计用来解决LinkedIn公司内部海量日志传输问题,Kafka使用Scala语言编写,于2011年开源并进入Apache孵化器,2012年10月正式毕业,现在为Apache顶级项目 + +### 介绍 + +Kafka是一个分布式数据流平台,可以运行在单台服务器上,也可以在多台服务器上部署形成集群。它提供了发布和订阅功能,使用这可以发送数据到Kafka中,也可以从Kafka中读取数据(以便进行后续处理)。Kafka具有高吞吐、低延迟、高容错等特点。 + +![image-20200906213002928](images/image-20200906213002928.png) + +### Kafka的架构图 + +![image-20200906213058075](images/image-20200906213058075.png) + +- Producer:Producer即生产者,消息的产生者,是消息的入口。 +- kafka cluster:kafka集群,一台或多台服务器组成 + - Broker:Broker是指部署了Kafka实例的服务器节点。每个服务器上有一个或多个kafka的实例,我们姑且认为每个broker对应一台服务器。每个kafka集群内的broker都有一个不重复的编号,如图中的broker-0、broker-1等… + - Topic:消息的主题,可以理解为消息的分类,kafka的数据就保存在topic。在每个broker上都可以创建多个topic。实际应用中通常是一个业务线建一个topic。 + - Partition:Topic的分区,每个topic可以有多个分区,分区的作用是做负载,提高kafka的吞吐量。同一个topic在不同的分区的数据是不重复的,partition的表现形式就是一个一个的文件夹! + - Replication:每一个分区都有多个副本,副本的作用是做备胎。当主分区(Leader)故障的时候会选择一个备胎(Follower)上位,成为Leader。在kafka中默认副本的最大数量是10个,且副本的数量不能大于Broker的数量,follower和leader绝对是在不同的机器,同一机器对同一个分区也只可能存放一个副本(包括自己)。 +- Consumer:消费者,即消息的消费方,是消息的出口。 + +### 工作流程 + +我们看上面的架构图中,produce就是生产者,是数据的入口。Producer在写入数据的时候会把数据写入到Leader中,不会直接将数据写入follower!那leader怎么找呢?写入流程又是怎么样的呢?我们看下图 + +![image-20200906214046688](images/image-20200906214046688.png) + +- 生产者从Kafka集群获取分区leader信息 +- 生产者将消息发送给leader +- leader将消息写入本地磁盘 +- follower从leader拉取消息数据 +- follower将消息写入本地磁盘后向leader发送ACK +- leader收到所有的follower的ACK之后向生产者发送ACK + +### 选择partition的原则 + +那在kafka中,如果某低opic有多个partition,producer又怎么知道该将数据发往哪个partition呢? +kafka中有几个原则: + +- partition在写入的时候可以指定需要写入的partition,如果有指定,则写入对应的partition。 +- 如果没有指定partition,但是设置了数据的key,则会根据key的值hash出一个partition。 +- 如果既没指定partition,又没有设置key,则会采用轮询方式,即每次取一小段时间的数据写入某个partition,下一小段的时间写入下一个partition。 + +### ACK应答机制 + +producer在向kafka写入消息的时候,可以设置参数来确定是否确认kafka接收到数据,这个参数可设置的值为0、1、all。 + +- 0:代表producer往集群发送数据不需要等到集群的返回,不确保消息发送成功。安全性最低但是效I率最高。 +- 1:代表producer往集群发送数据只要leader应答就可以发送下一条,只确保leader发送成功。 +- all:代表producer往集群发送数据需要所有的follower都完成从leader的同步才会发送下一条,确保leader发送成功和所有的副本都完成备份。安全性最高,但是效率最低。 + +最后要注意的是,如果往不存在的topic写数据,kafka会自动创建topic,partition和replication的数量默认配置都是1。 + +### Topic和数据日志 + +topic是同一类别的消息记录(record)的集合。在kafka中,一个主题通常有多个订阅者。对于每个主题、Kafka集群维护了一个分区数据日志文件结构如下: + +![image-20200908223706657](images/image-20200908223706657.png) + +每个partition都是一个有序并且不可变的消息记录集合。当新的数据写入时,就被追加到partition的末尾。在每个partition中,每条消息都会被分配一个顺序的唯一标识,这个标识被称为offset,即偏移量。注意,kafka只保证在他同一个partition内部消息是有序的,在不同partition之间,并不能保证消息有序。 + +Kafka可以配置一个保留期限,用来标识日志会在Kafka集群中保留多长时间。Kafka集群会保留在保留期限内所有发布的消息,不管这些消息是否被消费过,比如保留期限设置为两天,那么数据被发布到Kafka集群的两天以内,所有的这些数据都可以被消费,当超过两天,这些数据将会被清空。以便为后续的数据腾出空间,由于Kafka会将数据进行持久化存储(即写入到硬盘上),所以保留的数据大小可以设置为一个比较大的值。 + +### Partition结构 + +Partition在服务器上的表现形式就是一个一个的文件夹,每个partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件、.log文件、.timeindex文件三个文件,其中.log文件就是实际存储message的地方,而.index和.timeindex文件为索引文件,用于检索消息。 + +### 消费数据 + +多个消费者实例可以组成一个消费者组,并用一个标签来标识这个消费者组。一个消费者组中的不同消费者实例可以运行在不同的进程甚至不同的服务器上。 + +如果所有的消费者实例都在同一个消费者组中,那么消息记录会被很好的均衡的发送到每个消费者实例。 + +如果所有的消费者实例都在不同的消费者组,那么每一条消息记录会被广播到每一个消费者实例。 + +![image-20200908225045929](images/image-20200908225045929.png) + +上面是kafka集群,下面就是消费者组 + +举个例子,如上图所示一个两个节点的Kafka集群上拥有一个四个partition(PO-P3)的topic。有两个消费者组都在消费这个topic中的数据,消费者组A有两个消费者实例,消费者组B有四个消费者实例。 + +从图中我们可以看到,在同一个消费者组中,每个消费者实例可以消费多个分区,但是每个分区最多只能被消费者组中的一个实例消费。也就是说,如果有一个4个分区的主题,那么消费者组中最多只能有4个消费者实例去消费,多出来的都不会被分配到分区。其实这也很好理解,如果允许两个消费者实例同时消费同一个分区,那么就无法记录这个分区被这个消费者组消费的offset了。如果在消费者组中动态的上线或下线消费者,那么Kafka集群会自动调整分区与消费者实例间的对应关系。 + +### 使用场景 + +上面介绍了Kafka的一些基本概念和原理,那么Kafka可以做什么呢?目前主流使用场景基本如下: + +#### 消息队列(MQ) + +在系统架构设计中,经常会使用消息队列(Message Queue)——MQ。MQ是一种跨进程的通信机制,用于上下游的消息传递,使用MQ可以使上下游解耦,消息发送上游只需要依赖MQ,逻辑上和物理上都不需要依赖其他下游服务。MQ的常见使用场景如流量削峰、数据驱动的任务依赖等等。在MQ领域,除了Kafka外还有传统的消息队列如ActiveMQ和RabbitMQ等。 + +#### 追踪网站活动 + +Kafka最出就是被设计用来进行网站活动(比如PV、UV、搜索记录等)的追踪。可以将不同的活动放入不同的主题,供后续的实时计算、实时监控等程序使用,也可以将数据导入到数据仓库中进行后续的离线处理和生成报表等。 + +#### Metrics + + Kafka 经常被用来传输监控数据。主要用来聚合分布式应用程序的统计数据,将数据集中后进行统一的分析和展示等。 + +#### 日志聚合 + +很多人使用Kafka作为日志聚合的解决方案。日志聚合通常指将不同服务器上的日志收集起来并放入一个日志中心,比如一台文件服务器或者HDFS中的一个目录,供后续进行分析处理。相比于Flume和Scribe等日志聚合工具,Kafka具有更出色的性能。 + +## Kafka安装和启动 + +### 下载 + +下载地址:https://www.apache.org/dyn/closer.cgi?path=/kafka/2.6.0/kafka_2.12-2.6.0.tgz + +### 安装 + +将下载好的压缩包解压到本地,注意Kafka需要先安装JDK环境 + +![image-20200909081800184](images/image-20200909081800184.png) + +### 修改配置 + +我们首先找到Kafka的配置文件 server.properties + +![image-20200909083413345](images/image-20200909083413345.png) + +然后修改日志存放位置 + +```bash +############################# Log Basics ############################# + +# A comma separated list of directories under which to store log files +log.dirs=D:/tmp/kafka-logs +``` + +### 启动 + +修改完成后,我们即可启动Kafka了,kafka默认端口号是9092 + +然后到 bin\windows目录下,输入下面的脚本 + +```bash + .\kafka-server-start.bat ..\..\config\server.properties +``` + +Kafka启动成功 + +![image-20200909083907053](images/image-20200909083907053.png) + +## Zookeeper启动 + +注意,我们安装的Kafka里面,就包含了所需的Zookeeper配置文件,因此我们只需要修改配置即可 + +![image-20200909082146945](images/image-20200909082146945.png) + +找到Zookeeper.properties配置文件,修改数据目录 + +![image-20200909083551746](images/image-20200909083551746.png) + +修改完成后,我们到 bin\windows目录下 + +![image-20200909083106755](images/image-20200909083106755.png) + +启动脚本 + +```bash + .\zookeeper-server-start.bat ..\..\config\zookeeper.properties +``` + +启动完成后,将占用 2181端口号 + +![image-20200909083149805](images/image-20200909083149805.png) + +## LogAgent的工作流程 + +![image-20200906205046296](images/image-20200906205046296.png) + +- 读日志 +- 往kafka中写日志 + +首先我们需要下载tailf,使用下面的命令 + +```bash +go get github.com/hpcloud/tail +``` + +然后编写测试样例 + +```go +package main + +import ( + "fmt" + "github.com/hpcloud/tail" + "time" +) + +// tailf的用法 +func main() { + // 需要记录的日志文件 + fileName := "./my.log" + + // + config := tail.Config{ + ReOpen: true, // 重新打开,日志文件到了一定大小,就会分裂 + Follow: true, // 是否跟随 + Location: &tail.SeekInfo{Offset: 0, Whence: 2}, // 从文件的哪个位置开始读 + MustExist: false, // 是否必须存在,如果不存在是否报错 + Poll: true, // + } + + tails, err := tail.TailFile(fileName, config) + if err != nil { + fmt.Println("tail file failed, err:", err) + return + } + + var( + line *tail.Line + ok bool + ) + for { + // 从tails中一行一行的读取 + line, ok = <- tails.Lines + if !ok { + fmt.Println("tail file close reopen, filename:%s\n", tails.Filename) + time.Sleep(time.Second) + continue + } + fmt.Println("line", line.Text) + } +} + +``` + +但是我们在启动的时候,又出错了 + +```bash +cannot find module providing package gopkg.in/fsnotify.v1 +``` + +我们定位到源码目录,因为 opkg.in/fsnotify.v1的包改名了,所以我们需要修改两个文件,inotify.go 和 inotify_tracker.go + +![image-20200909095258325](images/image-20200909095258325.png) + +将里面出错的文件,替换成下面的这个文件即可 + +### log agent开发 + +#### 下载安装 + +```bash +go get github.com/Shopify/sarama +``` + +sarama V1.20之后的版本加入了zstd压缩算法,需要用到cgo,在Windows平台编译时会提示类似如下错误: + +```bash +exec: "gcc":executable file not found in %PATH% +``` + +所以在Windows平台请使用v1.19版本的sarama,因此我们需要使用下面命令创建一个go.mod文件 + +```bash +go mod init kafkaDemo +``` + +然后在文件里面配置一下版本号 v1.19.0 + +```mod + +go 1.14 + +require ( + github.com/Shopify/sarama v1.19.0 +) +``` + +然后在项目的目录下,下载依赖 + +```bash +go mod download +``` + +下载完成后,我们就可以写测试代码了 + +```bash +package main + +import ( + "fmt" + "github.com/Shopify/sarama" +) + +// 基于sarama第三方库开发的Kafka client +func main() { + config := sarama.NewConfig() + + // tailf包使用,发送完数据需要 leader 和 follow都确定 + config.Producer.RequiredAcks = sarama.WaitForAll + // 新选出一个partition + config.Producer.Partitioner = sarama.NewRandomPartitioner + // 成功交付的消息将在 success channel返回 + config.Producer.Return.Successes = true + + msg := &sarama.ProducerMessage{} + msg.Topic = "web_log" + msg.Value = sarama.StringEncoder("this is a test log") + // 连接kafka,可以连接一个集群 + client, err := sarama.NewSyncProducer([]string{"127.0.0.1:9092"}, config) + if err != nil { + fmt.Println("producer closed, err: ", err) + } + fmt.Println("连接kafka成功!") + // 定义延迟关闭 + defer client.Close() + + // 发送消息 + pid, offset, err := client.SendMessage(msg) + if err != nil { + fmt.Println("send msg failed, err:", err) + return + } + fmt.Printf("pid:%v offset:%v \n", pid, offset) +} +``` + +## LogAgent编码 + +首先我们需要创建一个 kafka.go 用来初始化kafka和发送消息到kafka + +```go +package kafka + +import ( + "fmt" + "github.com/Shopify/sarama" +) + +// 专门往kafka写日志的模块 + +var ( + // 声明一个全局连接kafka的生产者 + client sarama.SyncProducer +) + +// 初始化client +func Init()(err error) { + config := sarama.NewConfig() + + // tailf包使用,发送完数据需要 leader 和 follow都确定 + config.Producer.RequiredAcks = sarama.WaitForAll + // 新选出一个partition + config.Producer.Partitioner = sarama.NewRandomPartitioner + // 成功交付的消息将在 success channel返回 + config.Producer.Return.Successes = true + + msg := &sarama.ProducerMessage{} + msg.Topic = "web_log" + msg.Value = sarama.StringEncoder("this is a test log") + // 连接kafka,可以连接一个集群 + client, err = sarama.NewSyncProducer([]string{"127.0.0.1:9092"}, config) + if err != nil { + fmt.Println("producer closed, err: ", err) + } + fmt.Println("Kafka初始化成功") + return err +} + +// 发送消息到Kafka +func SendToKafka(topic, data string) { + msg := &sarama.ProducerMessage{} + msg.Topic = topic + msg.Value = sarama.StringEncoder(data) + // 发送到kafka + pid, offset, err := client.SendMessage(msg) + if err != nil { + fmt.Println("send msg failed, err:", err) + return + } + fmt.Println("发送消息:", data) + fmt.Printf("发送成功~ pid:%v offset:%v \n", pid, offset) +} +``` + +然后我们在创建一个 taillog.go文件,用来记录日志 + +```go +package taillog + +import ( + "fmt" + "github.com/hpcloud/tail" +) + +// 定义全局对象 +var ( + // 声明一个全局连接kafka的生产者 + tailObj *tail.Tail +) + +// 专门从日志文件收集日志的模块 +func Init(fileName string)(err error ){ + + // 定义配置文件 + config := tail.Config{ + ReOpen: true, // 重新打开,日志文件到了一定大小,就会分裂 + Follow: true, // 是否跟随 + Location: &tail.SeekInfo{Offset: 0, Whence: 2}, // 从文件的哪个位置开始读 + MustExist: false, // 是否必须存在,如果不存在是否报错 + Poll: true, // + } + + tailObj, err = tail.TailFile(fileName, config) + if err != nil { + fmt.Println("tail file failed, err:", err) + return + } + return err +} + +// 读取日志,返回一个只读的chan +func ReadChan() <-chan *tail.Line { + return tailObj.Lines +} +``` + +最后我们创建main.go作为启动类 + +```go +package main + +import ( + "LogDemo/kafka" + "LogDemo/taillog" + "fmt" + "time" +) + +// logAgent入口程序 +func run() { + // 1.读取日志 + for { + select { + case line := <-taillog.ReadChan(): + { + // 2.发送到kafka + kafka.SendToKafka("web_log", line.Text) + } + default: + time.Sleep(1 * time.Second) + } + } +} + +func main() { + // 1. 初始化kafka连接 + err := kafka.Init() + if err != nil { + fmt.Printf("init Kafka failed, err:%v \n", err) + return + } + // 2. 打开日志文件,准备收集 + err = taillog.Init("./my.log") + if err != nil { + fmt.Printf("Init taillog failed, err: %v \n", err) + return + } + + // 3.执行业务逻辑 + run() +} +``` + +最后我们启动main.go,然后往文件里面插入内容,然后就会将日志记录发送到kafka中 + +![image-20200909210434742](images/image-20200909210434742.png) + +最后通过下面的脚本,来进行kafka的消息的消费 + +```bash + .\kafka-console-consumer.bat --bootstrap-server=127.0.0.1:9092 --topic=web_log --from-beginning +``` + +然后就开始消费kafka中的消息 + +![image-20200909210448475](images/image-20200909210448475.png) + +### 存在的问题 + +上述的代码还存在硬编码的问题,我们将通过配置文件将一些信息配置出来,这样能够提高代码的扩展性,这里我们用的是ini文件,创建一个 config.ini文件,填入配置信息 + +```ini +[kafka] +address=127.0.0.1:9092 +topic=web_log + +[taillog] +path:=./my.log +``` + +### 引入依赖 + +我们需要使用go-ini的依赖,来对我们的配置文件进行解析 ,[go-ini官网](https://github.com/go-ini/ini) + +首先下载依赖 + +```bash +go get gopkg.in/ini.v1 +``` + +然后通过下面的方式进行读取 + +```go +// 0. 加载配置文件 +cfg, err := ini.Load("./conf/config.ini") +if err != nil { + fmt.Printf("Fail to read file: %v", err) + os.Exit(1) +} + +// 典型读取操作,默认分区可以使用空字符串表示 +fmt.Println("kafka address:", cfg.Section("kafka").Key("address").String()) +fmt.Println("kafka topic:", cfg.Section("kafka").Key("topic").String()) +fmt.Println("taillog path:", cfg.Section("taillog").Key("path").String()) +``` + +优化后的main.go如下所示 + +```go +package main + +import ( + "LogDemo/kafka" + "LogDemo/taillog" + "fmt" + "gopkg.in/ini.v1" + "os" + "time" +) + +// logAgent入口程序 +func run() { + // 1.读取日志 + for { + select { + case line := <-taillog.ReadChan(): + { + // 2.发送到kafka + kafka.SendToKafka("web_log", line.Text) + } + default: + time.Sleep(1 * time.Second) + } + } +} + +func main() { + // 0. 加载配置文件 + cfg, err := ini.Load("./conf/config.ini") + if err != nil { + fmt.Printf("Fail to read file: %v", err) + os.Exit(1) + } + + // 典型读取操作,默认分区可以使用空字符串表示 + fmt.Println("kafka address:", cfg.Section("kafka").Key("address").String()) + fmt.Println("kafka topic:", cfg.Section("kafka").Key("topic").String()) + fmt.Println("taillog path:", cfg.Section("taillog").Key("path").String()) + + // 1. 初始化kafka连接 + address := []string{cfg.Section("kafka").Key("address").String()} + topic := cfg.Section("taillog").Key("path").String() + err = kafka.Init(address, topic) + if err != nil { + fmt.Printf("init Kafka failed, err:%v \n", err) + return + } + // 2. 打开日志文件,准备收集 + err = taillog.Init(cfg.Section("taillog").Key("path").String()) + if err != nil { + fmt.Printf("Init taillog failed, err: %v \n", err) + return + } + // 3.执行业务逻辑 + run() +} +``` + +### 最终版本 + +上述的方式,还是存在一些问题,就是配置信息不能传递,只能在main方法里面,那么我们可以在定义一个结构体,conf.go + +```go +package conf + +type AppConf struct { + KafkaConf `ini:"kafka"` + TaillogConf `ini:"taillog"` +} +type KafkaConf struct { + Address string `ini:"address"` + Topic string `ini:"topic"` +} + +type TaillogConf struct { + FileName string `ini:"filename"` +} +``` + +然后原来的main.go改为 + +```go +package main + +import ( + "LogDemo/conf" + "LogDemo/kafka" + "LogDemo/taillog" + "fmt" + "gopkg.in/ini.v1" + "time" +) + +var ( + cfg = new(conf.AppConf) +) + +// logAgent入口程序 +func run() { + // 1.读取日志 + for { + select { + case line := <-taillog.ReadChan(): + { + // 2.发送到kafka + kafka.SendToKafka(cfg.Topic, line.Text) + } + default: + time.Sleep(1 * time.Second) + } + } +} + +func main() { + // 0. 加载配置文件 + // 方式2 + err := ini.MapTo(&cfg, "./conf/config.ini") + if err != nil { + fmt.Printf("load ini failed, err: %v \n", err) + return + } + fmt.Println("读取到的配置信息", cfg) + + // 1. 初始化kafka连接 + address := []string{cfg.Address} + topic := cfg.Topic + err = kafka.Init(address, topic) + if err != nil { + fmt.Printf("init Kafka failed, err:%v \n", err) + return + } + // 2. 打开日志文件,准备收集 + err = taillog.Init(cfg.FileName) + if err != nil { + fmt.Printf("Init taillog failed, err: %v \n", err) + return + } + // 3.执行业务逻辑 + run() +} +``` + + + diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906204717091.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906204717091.png" new file mode 100644 index 0000000000000000000000000000000000000000..189ee6cac441646cf43367e763db68d8e2ce8032 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906204717091.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906205046296.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906205046296.png" new file mode 100644 index 0000000000000000000000000000000000000000..40df41d9db86c22b42d51c24b7a587d7be3ddee2 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906205046296.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906213002928.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906213002928.png" new file mode 100644 index 0000000000000000000000000000000000000000..4eb886c7e2b1e85a8727badd485bc25c262c7339 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906213002928.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906213058075.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906213058075.png" new file mode 100644 index 0000000000000000000000000000000000000000..41b6bcffa049420e99861ef6b8acf9a8970db163 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906213058075.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906214046688.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906214046688.png" new file mode 100644 index 0000000000000000000000000000000000000000..bbc860fcaafba9dc1efe9d9c2c7dbdf84d68ef59 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200906214046688.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200908223706657.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200908223706657.png" new file mode 100644 index 0000000000000000000000000000000000000000..6be88aafa192cb6af2c0d123d3c42834b02e6dd1 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200908223706657.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200908225045929.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200908225045929.png" new file mode 100644 index 0000000000000000000000000000000000000000..321b692a5f7eac58c02d93e7d7be9d976800d8a1 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200908225045929.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909081800184.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909081800184.png" new file mode 100644 index 0000000000000000000000000000000000000000..7e66b1c86b9200a92ec4ca78882b9565bf9ca462 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909081800184.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909082146945.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909082146945.png" new file mode 100644 index 0000000000000000000000000000000000000000..d182c47bda60d6ae41f4036d5a1237afd109af5c Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909082146945.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909082325420.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909082325420.png" new file mode 100644 index 0000000000000000000000000000000000000000..ba5582cae4a8758a1da40c5822279d33d31e2c69 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909082325420.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083106755.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083106755.png" new file mode 100644 index 0000000000000000000000000000000000000000..f66822edf44f9abbe17c00f5b3a418755777295b Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083106755.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083149805.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083149805.png" new file mode 100644 index 0000000000000000000000000000000000000000..f3c8d5138879de8c0765e977f450abb653673516 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083149805.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083413345.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083413345.png" new file mode 100644 index 0000000000000000000000000000000000000000..049fc8b421a5cc1739a53fd948030dc8ddbfd030 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083413345.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083551746.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083551746.png" new file mode 100644 index 0000000000000000000000000000000000000000..bd58448453bebb30603dc16f64fd49c2af6dfd25 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083551746.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083907053.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083907053.png" new file mode 100644 index 0000000000000000000000000000000000000000..bd36ca27d064e279d38b60e87483eacfd5097a6e Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909083907053.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909095208527.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909095208527.png" new file mode 100644 index 0000000000000000000000000000000000000000..01061ea263bf401ec4ab54b2adac151b4efb4347 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909095208527.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909095258325.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909095258325.png" new file mode 100644 index 0000000000000000000000000000000000000000..85456a4413df3acb9308363eb16adb10d733c3e4 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909095258325.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909210434742.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909210434742.png" new file mode 100644 index 0000000000000000000000000000000000000000..a04b9895f3da2727bf84d2b79b122c98a7068e86 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909210434742.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909210448475.png" "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909210448475.png" new file mode 100644 index 0000000000000000000000000000000000000000..54ff44d00685fe3a056fcfce3fecf7fbadde27bd Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/17_\346\227\245\345\277\227\346\224\266\351\233\206\351\241\271\347\233\256\346\236\266\346\236\204\350\256\276\350\256\241\345\217\212Kafka\344\273\213\347\273\215/images/image-20200909210448475.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/README.md" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..2d3dfe2f54c7dd20e197b1bcc98126595650d916 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/README.md" @@ -0,0 +1,298 @@ +# etcd介绍 + +### 前言 + +etcd:目前比较火的开源库,docker和k8s都是使用的它 + +目标:使用etcd优化日志收集项目 + +## 介绍 + +etcd是使用Go语言开发的一个开源的、高可用的分布式key-value存储系统,可以用于配置共享和服务的注册和发现,类似项目有Zookeeper和consul + +etcd具有以下特点 + +- 完全复制:集群中的每个节点都可以使用完整的存档 +- 高可用性:Etcd可用于避免硬件的单点故障或网络问题(选择出另外的leader) +- 一致性:每次读取都会返回跨多主机的最新写入 +- 简单:包括一个定义良好、面向用户的API(gRPC) +- 安全:实现了带有可选的客户端证书身份验证的自动化TLS +- 快速:每秒10000次写入的基准速度 +- 可靠:使用 **Raft** 算法实现了强一致性,高可用的服务存储目录 + - Raft协议:选举、日志复制机制、异常处理(脑裂)、Zookeeper的zad协议的区别 + +## etcd应用场景 + +### 服务发现 + +服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务,要如何才能找到对方并建立连接。本质上来说,服务发现就是想要了解集群中是否有进程在监听udp或tcp端口,并且通过名字就可以查找和连接。 + +![image-20200910161600037](images/image-20200910161600037.png) + +### 配置中心 + +将一些配置信息放到etcd上进行集中管理。这类场景的使用方式通常是这样的:应用启动的时候,主动从etcd获取一次配置信息,同时,在etcd节点上注册一个Watcher并等待,以后每次配置有更新的时候,etcd都会实时通知订阅者,以此达到获取最新配置信息的目的。 + +### 分布式锁 + +因为etcd使用Raft算法保持了数据的强一致性,某次操作存储到集群中的值必然是全局一致性的,所以很容易实现分布式锁。锁服务有两种使用方式,一种是保持独占,二是控制时序。 + +- 保持独占即所有获取锁的用户最终只有一个可以得到。etcd为此提供了一套实现分布式锁原子操作CAS(CompareAndSwap)的API。通过设置preExist值,可以保证在多个节点同时去创建某个目录时,只有一个成功,而创建成功的用户就可以认为是获得了锁。 +- 控制时序,即所有想要获得锁的用户都会被安排执行,但是获得锁的顺序也是全局唯一的,同时决定了执行顺序。etcd为此也提供了一套API(自动创建有序键),对一个目录建值时指定为POST动作,这样etcd会自动在目录下生成一个当前最大的键值。此时这些键的值就是客户端的时序,而这些键中的存储的值可以代表客户端的编号。 + +![image-20200910212441132](images/image-20200910212441132.png) + +上图就是三个同时来竞争锁,最后只有一个获取到了锁 + +## 为什么使用etcd而不用Zookeeper? + +### Zookeeper存在的问题 + +etcd 实现的这些功能,ZooKeeper都能实现。那么为什么要用etcd 而非直接使用ZooKeeper呢?相较之下,ZooKeeper有如下缺点: + +- **复杂**:ZooKeeper的部署维护复杂,管理员需要掌握一系列的知识和技能;而Paxos 强一致性算法也是素来以复杂难懂而闻名于世;另外,ZooKeeper的使用也比较复杂,需要安装客户端,官方只提供了Java和C两种语言的接口。 +- **Java编写**:这里不是对Java有偏见,而是Java本身就偏向于重型应用,它会引入大量的依赖。而运维人员则普遍希望保持强一致、高可用的机器集群尽可能简单,维护起来也不易出错。 +- **发展缓慢**:Apache 基金会项目特有的"Apache Way”在开源界饱受争议,其中一大原因就是由于基金会庞大的结构以及松散的管理导致项目发展缓慢。 + +### etcd的优势 + +而etcd作为一个后起之秀,其优点也很明显 + +**简单**:使用Go语言编写部署简单;使用HTTP作为接口使用简单;使用Raft 算法保证强一致性让用户易于理解。 + +**数据持久化**:etcd 默认数据一更新就进行持久化。 + +**安全**:etcd 支持SSL客户端安全认证。 + +最后,etcd作为一个年轻的项目,真正告诉迭代和开发中,这既是一个优点,也是一个缺点。优点是它的未来具有无限的可能性,缺点是无法得到大项目长时间使用的检验。然而,目前CoreOS、Kubernetes 和CloudFoundry等知名项目均在生产环境中使用了etcd,所以总的来说,etcd值得你去尝试。 + +## etcd架构 + +![image-20200910212915543](images/image-20200910212915543.png) + +从etcd的架构图中我们可以看到,etcd主要分为四个部分 + +- HTTP Server:用于处理用户发送的API请求以及其他etcd节点的同步与心跳信息请求 +- Store:用于处理etcd支持的各类功能的事务,包括数据索引、节点状态变更、监控与反馈、事件处理与执行等等,是etcd对用户提供的大多数API功能的具体实现 +- Raft:Raft强一致性算法的具体实现,是etcd的核心 +- WAL:Write Ahead Log(预写式日志),是etcd的数据存储方式。除了在内存中存有所有数据的状态以及节点的索引以外,etcd就通过WAL进行持久化存储。WAL中,所有的数据提交前都会实现记录日志。Snapshot是为了防止数据过多而进行的状态快照;Entry表示存储的具体日志内容。 + +### etcd集群 + +etcd作为一个高可用键值存储系统,天生就是为集群化而设计的,由于Raft算法在做决策时需要多数节点投票,所以etcd一般部署集群推荐奇数个节点,推荐的数量为3、5或者7个节点构成一个集群。 + +## 搭建一个3节点集群示例 + +在每个etcd节点指定集群成员,为了区分不同的集群最好同时配置一个独一无二的token。 + +下面是提前定义好的集群信息,其中n1、n2和n3表示3个不同的etcd节点。 + +![image-20200910215834659](images/image-20200910215834659.png) + +在n1这台机器上执行以下命令来启动etcd: + +![image-20200910220236723](images/image-20200910220236723.png) + +在n2这台机器上执行以下命令启动etcd: + +![image-20200910220304923](images/image-20200910220304923.png) + +在n3这台机器上执行以下命令启动etcd: + +![image-20200910220323979](images/image-20200910220323979.png) + +etcd官网提供了一个公网访问的etcd存储地址,你可以通过如下命令得到etcd服务的目录,并把它作为-discovery参数使用 + +## etcd部署 + +### 下载 + +找到对应的 **Github官网**,到相应的releases,找到windows平台的压缩包进行下载 + +![image-20200911084346199](images/image-20200911084346199.png) + +解压完成后的目录 + +![image-20200911084441272](images/image-20200911084441272.png) + +### 启动 + +双击etcd.exe就是启动了etcd。其它平台解压之后在bin目录下找etcd可执行文件。 + +默认会在2379端口监听客户端通信,在2380端口监听节点间的通信。 + +![image-20200911084639443](images/image-20200911084639443.png) + +etcdctl.ext可以理解为一个客户端或者本机etcd的控制端 + +### 连接 + +默认的etcdctrl使用的是v2版本的命令,我们需要设置环境变量ETCDCTL_API=3来使用v3版本的API,而默认的也就是环境变量为ETCDCTL_API=2是使用v2版本的API + +修改环境变量指定使用API的版本 + +```bash +SET_ETCDCTL_API=3 +``` + +### 简单使用 + +#### put:设置 + +```bash +.\etcdctl.exe --endpoints=http://127.0.0.1:2379 put baodelu "dsb" +``` + +![image-20200911085617469](images/image-20200911085617469.png) + +显示设置成功~ + +#### get:获取 + +```bash +.\etcdctl.exe --endpoints=http://127.0.0.1:2379 get baodelu +``` + +#### del:删除 + +```bash +.\etcdctl.exe --endpoints=http://127.0.0.1:2379 del baodelu +``` + +## Go操作etcd + +### 安装依赖 + +这里使用官方的 etcd/clientv3包来连接etcd并进行相关操作 + +```bash +go get go.etcd.io/etcd/clientv3 +``` + +### put和get操作 + +put命令用来设置键值对数据,get命令用来根据key获取值 + +```go +package main + +import ( + "context" + "fmt" + "go.etcd.io/etcd/clientv3" + "time" +) + +func main() { + cli, err := clientv3.New(clientv3.Config { + Endpoints: []string{"127.0.0.1:2379"}, // etcd的节点,可以传入多个 + DialTimeout: 5*time.Second, // 连接超时时间 + }) + + if err != nil { + fmt.Printf("connect to etcd failed, err: %v \n", err) + return + } + fmt.Println("connect to etcd success") + + // 延迟关闭 + defer cli.Close() + + // put操作 设置1秒超时 + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + _, err = cli.Put(ctx, "moxi", "lalala") + cancel() + if err != nil { + fmt.Printf("put to etcd failed, err:%v \n", err) + return + } + + // get操作,设置1秒超时 + ctx, cancel = context.WithTimeout(context.Background(), time.Second) + resp, err := cli.Get(ctx, "q1mi") + cancel() + if err != nil { + fmt.Printf("get from etcd failed, err:%v \n", err) + return + } + fmt.Println(resp) +} +``` + +### 错误实例 + +在我们运行代码的时候,突然出错了,undefined: resolver.BuildOption + +经过排查,是因为 google.golang.org/grpc 1.26后的版本不支持clientv3的 + +所以我们只能将其改成1.26版本的就可以了,具体操作需要在go.mod上加上以下代码 + +```bash +replace google.golang.org/grpc => google.golang.org/grpc v1.26.0 +``` + +![image-20200911092218954](images/image-20200911092218954.png) + +### watch + +使用watch可以做服务的热更新 + +```go +import ( + "context" + "fmt" + "go.etcd.io/etcd/clientv3" + "time" +) +// etcd 的watch操作 +func main() { + cli, err := clientv3.New(clientv3.Config { + Endpoints: []string{"127.0.0.1:2379"}, // etcd的节点,可以传入多个 + DialTimeout: 5*time.Second, // 连接超时时间 + }) + + if err != nil { + fmt.Printf("connect to etcd failed, err: %v \n", err) + return + } + fmt.Println("connect to etcd success") + defer cli.Close() + + // watch + // 派一个哨兵,一直监视着 moxi 这个key的变化(新增,修改,删除),返回一个只读的chan + ch := cli.Watch(context.Background(), "moxi") + + // 从通道中尝试获取值(监视的信息) + for wresp := range ch{ + for _, evt := range wresp.Events{ + fmt.Printf("Type:%v key:%v value:%v \n", evt.Type, evt.Kv.Key, evt.Kv.Value) + } + } +} +``` + +然后我们往etcd中插入数据的时候 + +![image-20200911115618754](images/image-20200911115618754.png) + +我们的代码就会监听到数据的变化 + +![image-20200911115648301](images/image-20200911115648301.png) + +## 使用etcd优化日志项目 + + + +## logagent根据etcd的配置创建多个tailtask + + + +**见代码部分 18_LogAgent** + + + +etcd底层如何实现watch给客户端发通知(websocket) + + + +## logagent根据IP拉取配置 \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910161600037.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910161600037.png" new file mode 100644 index 0000000000000000000000000000000000000000..4f3a4338e2f6c39a8a14db0bec7cfed28a404b54 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910161600037.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910212441132.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910212441132.png" new file mode 100644 index 0000000000000000000000000000000000000000..8f2350e9d6a051ae24eb5a49099a4364340b715f Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910212441132.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910212915543.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910212915543.png" new file mode 100644 index 0000000000000000000000000000000000000000..4bd473f2eb8fe223d39f7c85b11732f4ad64f42d Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910212915543.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910215834659.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910215834659.png" new file mode 100644 index 0000000000000000000000000000000000000000..8e73d16881a825070816c5fe3c2f162347d2eec3 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910215834659.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910220236723.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910220236723.png" new file mode 100644 index 0000000000000000000000000000000000000000..fb314c92f1fc42c62d05537ced0cb6b1176983ff Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910220236723.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910220304923.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910220304923.png" new file mode 100644 index 0000000000000000000000000000000000000000..7d75b60bbceed6168f43926b42156338e2acb657 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910220304923.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910220323979.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910220323979.png" new file mode 100644 index 0000000000000000000000000000000000000000..5fca2f4a5ac78c54925a055328566f7c9a7dad8a Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200910220323979.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911084346199.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911084346199.png" new file mode 100644 index 0000000000000000000000000000000000000000..319401f80bd80bc4627b395a3e646c5f69657bba Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911084346199.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911084441272.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911084441272.png" new file mode 100644 index 0000000000000000000000000000000000000000..6fed11205bc91ed1ad980fce3a5907b49152d70f Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911084441272.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911084639443.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911084639443.png" new file mode 100644 index 0000000000000000000000000000000000000000..8092643d33e8ff5eee28fb0d3597eb28db29a9dc Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911084639443.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911085617469.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911085617469.png" new file mode 100644 index 0000000000000000000000000000000000000000..4c96d3d8381434080b706231046ac145bbaff9a2 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911085617469.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911092218954.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911092218954.png" new file mode 100644 index 0000000000000000000000000000000000000000..131151a2e2cad8139933256944e0d9fb6ec3a3e3 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911092218954.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911115618754.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911115618754.png" new file mode 100644 index 0000000000000000000000000000000000000000..abad8477d5eafc413c10200b53ebc1b19f425883 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911115618754.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911115648301.png" "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911115648301.png" new file mode 100644 index 0000000000000000000000000000000000000000..ff132fee72a0c96e4d9bbc48ef954424f9c27bd5 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/18_etcd\344\273\213\347\273\215/images/image-20200911115648301.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/README.md" "b/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..da5ad491c0b7e88eec61389f32859d2e5c728cb2 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/README.md" @@ -0,0 +1,243 @@ +# ES介绍和使用 + +## 来源 + +https://www.liwenzhou.com/posts/Go/go_elasticsearch/ + +## 今日内容 + +### Logtransfer + +从Kafka里面把日志取出来,写入ES,使用Kibana做可视化展示 + +### 系统监控 + +psutil:采集系统信息的,写入到influxDB,使用 Grafana做展示 + +promethenus监控:采集性能指标数据,保存起来,使用grafana做展示 + +### ElasticSearch + +Elasticsearch(ES)是一个基于Lucene构建的开源、分布式、RESTful接口的全文搜索引擎。Elasticsearch还是一个分布式文档数据库,其中每个字段均可被索引,而且每个字段的数据均可被搜索,ES能够横向扩展至数以百计的服务器存储以及处理PB级的数据。可以在极短的时间内存储、搜索和分析大量的数据。通常作为具有复杂搜索场景情况下的核心发动机。 + +### Kibana + +图形化展示 + +## ElasticSearch安装 + +去官网下载 [ElasticSearch](https://www.elastic.co/cn/elasticsearch/) ,下载完成后,到bin目录,双击启动 + +![image-20200912213519915](images/image-20200912213519915.png) + +启动完成后,访问下面的URL + +```bash +http://127.0.0.1:9200/ +``` + +即可看到ElasticSearch的信息 + +![image-20200912213600553](images/image-20200912213600553.png) + +## ES API + +以下示例使用`curl`演示。 + +### 查看健康状态 + +```bash +curl -X GET 127.0.0.1:9200/_cat/health?v +``` + +输出: + +```bash +epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent +1564726309 06:11:49 elasticsearch yellow 1 1 3 3 0 0 1 0 - 75.0% +``` + +### 查询当前es集群中所有的indices + +```bash +curl -X GET 127.0.0.1:9200/_cat/indices?v +``` + +输出: + +```bash +health status index uuid pri rep docs.count docs.deleted store.size pri.store.size +green open .kibana_task_manager LUo-IxjDQdWeAbR-SYuYvQ 1 0 2 0 45.5kb 45.5kb +green open .kibana_1 PLvyZV1bRDWex05xkOrNNg 1 0 4 1 23.9kb 23.9kb +yellow open user o42mIpDeSgSWZ6eARWUfKw 1 1 0 0 283b 283b +``` + +### 创建索引 + +```bash +curl -X PUT 127.0.0.1:9200/www +``` + +![image-20200912214032188](images/image-20200912214032188.png) + +输出: + +```bash +{"acknowledged":true,"shards_acknowledged":true,"index":"www"} +``` + +### 删除索引 + +```bash +curl -X DELETE 127.0.0.1:9200/www +``` + +![image-20200912214108846](images/image-20200912214108846.png) + +输出: + +```bash +{"acknowledged":true} +``` + +### 插入记录 + +```bash +curl -H "ContentType:application/json" -X POST 127.0.0.1:9200/user/person -d ' +{ + "name": "dsb", + "age": 9000, + "married": true +}' +``` + +![image-20200912214440400](images/image-20200912214440400.png) + +输出: + +```bash +{ + "_index": "user", + "_type": "person", + "_id": "MLcwUWwBvEa8j5UrLZj4", + "_version": 1, + "result": "created", + "_shards": { + "total": 2, + "successful": 1, + "failed": 0 + }, + "_seq_no": 3, + "_primary_term": 1 +} +``` + +也可以使用PUT方法,但是需要传入id + +```bash +curl -H "ContentType:application/json" -X PUT 127.0.0.1:9200/user/person/4 -d ' +{ + "name": "sb", + "age": 9, + "married": false +}' +``` + +### 检索 + +Elasticsearch的检索语法比较特别,使用GET方法携带JSON格式的查询条件。 + +全检索: + +```bash +curl -X GET 127.0.0.1:9200/user/person/_search +``` + +按条件检索: + +```bash +curl -H "ContentType:application/json" -X PUT 127.0.0.1:9200/user/person/4 -d ' +{ + "query":{ + "match": {"name": "sb"} + } +}' +``` + +ElasticSearch默认一次最多返回10条结果,可以像下面的示例通过size字段来设置返回结果的数目。 + +```bash +curl -H "ContentType:application/json" -X PUT 127.0.0.1:9200/user/person/4 -d ' +{ + "query":{ + "match": {"name": "sb"}, + "size": 2 + } +}' +``` + +## Go操作Elasticsearch + +### elastic client + +我们使用第三方库https://github.com/olivere/elastic来连接ES并进行操作。 + +注意下载与你的ES相同版本的client,例如我们这里使用的ES是7.2.1的版本,那么我们下载的client也要与之对应为`github.com/olivere/elastic/v7`。 + +```bash +# 初始化mod +go mod init es +# 下载依赖 +go get github.com/olivere/elastic/v7 +``` + +使用`go.mod`来管理依赖: + +```go +require ( + github.com/olivere/elastic/v7 v7.0.4 +) +``` + +简单示例: + +```go +package main + +import ( + "context" + "fmt" + + "github.com/olivere/elastic/v7" +) + +// Elasticsearch demo + +type Person struct { + Name string `json:"name"` + Age int `json:"age"` + Married bool `json:"married"` +} + +func main() { + client, err := elastic.NewClient(elastic.SetURL("http://192.168.1.7:9200")) + if err != nil { + // Handle error + panic(err) + } + + fmt.Println("connect to es success") + p1 := Person{Name: "rion", Age: 22, Married: false} + put1, err := client.Index(). + Index("user"). + BodyJson(p1). + Do(context.Background()) + if err != nil { + // Handle error + panic(err) + } + fmt.Printf("Indexed user %s to index %s, type %s\n", put1.Id, put1.Index, put1.Type) +} +``` + +更多使用详见文档:https://godoc.org/github.com/olivere/elastic \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912213519915.png" "b/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912213519915.png" new file mode 100644 index 0000000000000000000000000000000000000000..f9f058d14383a695f6fade91959da92b3f8d4ad2 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912213519915.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912213600553.png" "b/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912213600553.png" new file mode 100644 index 0000000000000000000000000000000000000000..0f01eea74e40e8f1ddc6c214c3e5298df3f5eb9a Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912213600553.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912214032188.png" "b/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912214032188.png" new file mode 100644 index 0000000000000000000000000000000000000000..34058846c47640959510345fd0d22ad18800e180 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912214032188.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912214108846.png" "b/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912214108846.png" new file mode 100644 index 0000000000000000000000000000000000000000..83a5e147c7a50338594e6e56abdfcd30cd9e7fd3 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912214108846.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912214440400.png" "b/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912214440400.png" new file mode 100644 index 0000000000000000000000000000000000000000..cb7fb2e707c84e35ec05a29ad71ea3cff6e6d447 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/19_ES\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200912214440400.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/20_Kafka\346\266\210\350\264\271\347\244\272\344\276\213/README.md" "b/Golang/Golang\350\277\233\351\230\266/20_Kafka\346\266\210\350\264\271\347\244\272\344\276\213/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..015307477cbba1014be57e0d8df0e1f9046598ab --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/20_Kafka\346\266\210\350\264\271\347\244\272\344\276\213/README.md" @@ -0,0 +1,182 @@ +# Kafka消费示例 + +Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据,具有高性能、持久化、多副本备份、横向扩展等特点。本文介绍了如何使用Go语言发送和接收kafka消息。 + +## 来源 + +https://www.liwenzhou.com/posts/Go/go_kafka/ + +## 启动Kafka + +上一篇博客中,讲了kafka的安装和启动 + +```bash +# 启动Zookeeper + .\zookeeper-server-start.bat ..\..\config\zookeeper.properties + +# 启动kafka + .\kafka-server-start.bat ..\..\config\server.properties +``` + +## sarama + +Go语言中连接kafka使用第三方库:[github.com/Shopify/sarama](https://github.com/Shopify/sarama)。 + +### 下载及安装 + +```bash +go get github.com/Shopify/sarama +``` + +### 注意事项 + +`sarama` v1.20之后的版本加入了`zstd`压缩算法,需要用到cgo,在Windows平台编译时会提示类似如下错误: + +```bash +# github.com/DataDog/zstd +exec: "gcc":executable file not found in %PATH% +``` + +所以在Windows平台请使用v1.19版本的sarama。 + +## 连接kafka发送消息 + +```go +package main + +import ( + "fmt" + + "github.com/Shopify/sarama" +) + +// 基于sarama第三方库开发的kafka client + +func main() { + config := sarama.NewConfig() + config.Producer.RequiredAcks = sarama.WaitForAll // 发送完数据需要leader和follow都确认 + config.Producer.Partitioner = sarama.NewRandomPartitioner // 新选出一个partition + config.Producer.Return.Successes = true // 成功交付的消息将在success channel返回 + + // 构造一个消息 + msg := &sarama.ProducerMessage{} + msg.Topic = "web_log" + msg.Value = sarama.StringEncoder("this is a test log") + // 连接kafka + client, err := sarama.NewSyncProducer([]string{"192.168.1.7:9092"}, config) + if err != nil { + fmt.Println("producer closed, err:", err) + return + } + defer client.Close() + // 发送消息 + pid, offset, err := client.SendMessage(msg) + if err != nil { + fmt.Println("send msg failed, err:", err) + return + } + fmt.Printf("pid:%v offset:%v\n", pid, offset) +} +``` + +## 连接kafka消费消息 + +```go +package main + +import ( + "fmt" + + "github.com/Shopify/sarama" +) + +// kafka consumer + +func main() { + consumer, err := sarama.NewConsumer([]string{"127.0.0.1:9092"}, nil) + if err != nil { + fmt.Printf("fail to start consumer, err:%v\n", err) + return + } + partitionList, err := consumer.Partitions("web_log") // 根据topic取到所有的分区 + if err != nil { + fmt.Printf("fail to get list of partition:err%v\n", err) + return + } + fmt.Println(partitionList) + for partition := range partitionList { // 遍历所有的分区 + // 针对每个分区创建一个对应的分区消费者 + pc, err := consumer.ConsumePartition("web_log", int32(partition), sarama.OffsetNewest) + if err != nil { + fmt.Printf("failed to start consumer for partition %d,err:%v\n", partition, err) + return + } + defer pc.AsyncClose() + // 异步从每个分区消费信息 + go func(sarama.PartitionConsumer) { + for msg := range pc.Messages() { + fmt.Printf("Partition:%d Offset:%d Key:%v Value:%v", msg.Partition, msg.Offset, msg.Key, msg.Value) + } + }(pc) + } +} +``` + +## LogTransfer实现 + +参考源码 20_LogTransfer + +LogTransfer的主要功能,就是将kafka中的日志信息取出来,然后发送到ElasticSearch中,下面我们就需要编码实现以下过程 + +### 文件结构 + +LogTransfer首先包含多个模块 + +- kafka:用于kafka操作相关 +- es:用于es操作相关 +- conf:配置相关 +- + +### Conf模块 + +conf模块是配置模块,用于进行LogTransfer的配置 + +#### cfg.ini + +我们使用ini管理配置信息 + +```bash +[kafka] +address=127.0.0.1:9092 +topic=web_log + +[es] +address=127.0.0.1:9200 +``` + +#### cfg.go + +然后定义配置类的结构体 + +```bash +package conf + +type LogTransferCfg struct { + KafkaCfg `ini:"kafka"` // 这个对应ini文件中的 [kafka] + EsCfg `ini:"es"` // 这个对应ini文件中的 [es] +} + +// Kafka配置类 +type KafkaCfg struct { + Address string `ini:"address"` + Topic string `ini:"topic"` +} + +// Es配置类 +type EsCfg struct { + Address string `ini:"address"` +} +``` + +### main函数 + diff --git "a/Golang/Golang\350\277\233\351\230\266/21_Kibana\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/README.md" "b/Golang/Golang\350\277\233\351\230\266/21_Kibana\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..f90c41763a6977a48612cd73e7b098a5b04d1832 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/21_Kibana\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/README.md" @@ -0,0 +1,32 @@ +# Kibana介绍和使用 + +## 注意 + +Kibana和ElasticSearch配合使用的时候,需要确保两者的版本号一直,不然可能出现无法正常使用的问题 + +## 下载 + +[官网](https://www.elastic.co/cn/kibana)下载Kibana,下载完成后,解压缩文件,修改对应的配置 + +![image-20200913152910693](images/image-20200913152910693.png) + +找到 config/kibana.yml,然后修改下面的配置信息,因为kibana + +```bash +# Specifies locale to be used for all localizable strings, dates and number formats. +i18n.locale: "zh-CN" +``` + +## 启动 + +修改配置完成后,找到 bin/kibana.bat,双击启动即可 + +![image-20200913154215143](images/image-20200913154215143.png) + +启动完成后,访问下面的URL进入到管理页面 + +```bash +http://127.0.0.1:5601 +``` + +![image-20200913155139167](images/image-20200913155139167.png) \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/21_Kibana\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200913152910693.png" "b/Golang/Golang\350\277\233\351\230\266/21_Kibana\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200913152910693.png" new file mode 100644 index 0000000000000000000000000000000000000000..147bda9dc411c45b65949ba6f4fc9e0be55d9ff5 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/21_Kibana\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200913152910693.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/21_Kibana\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200913154215143.png" "b/Golang/Golang\350\277\233\351\230\266/21_Kibana\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200913154215143.png" new file mode 100644 index 0000000000000000000000000000000000000000..ee185f475c0e4666e033f4fb52625a1a6336f694 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/21_Kibana\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200913154215143.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/21_Kibana\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200913155139167.png" "b/Golang/Golang\350\277\233\351\230\266/21_Kibana\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200913155139167.png" new file mode 100644 index 0000000000000000000000000000000000000000..81ff5caf9a8f61a31c9da412895b07bbf296607f Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/21_Kibana\344\273\213\347\273\215\345\222\214\344\275\277\347\224\250/images/image-20200913155139167.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/README.md" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..bd605be11ac0efda5e900d0d731cdf3f5655554d --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/README.md" @@ -0,0 +1,107 @@ +# Prometheus和Grafana介绍 + +## 系统监控 + +[gopsutil](https://www.liwenzhou.com/posts/Go/go_gopsutil/):做系统监控信息的采集,写入influxDb,使用grafana作展示 + +prometheus:采集性能指标数据,使用grafana作展示 + +## Prometheus + +[普罗米修斯](https://github.com/prometheus/prometheus):专用于服务监控,主动去拉取数据 + +![image-20200913185216706](images/image-20200913185216706.png) + +- Jobs/Exporters:任务,监控项 +- Serveice Discovery:服务发现 +- Short-lived jobs:短期存活的任务 + +### 下载普罗米修斯 + +去Github的[官网](https://github.com/prometheus/prometheus/releases/tag/v2.21.0)下载 + +![image-20200913190154123](images/image-20200913190154123.png) + +下载完成后解压即可 + +![image-20200913190213569](images/image-20200913190213569.png) + +双击 prometheus.exe启动,然后访问下面的地址 + +```bash +http://localhost:9090/graph +``` + +进入到prometheus的图形化页面 + +![image-20200913190307310](images/image-20200913190307310.png) + +### 使用 + +![image-20200913190408222](images/image-20200913190408222.png) + +就能够看到我们的图形化信息了 + +![image-20200913190444467](images/image-20200913190444467.png) + +通过上图我们发现,使用 prometheus的图形化界面好像不太美观,所以就引出了下面的 [grafana](https://grafana.com/) + +## grafana + +grafana是采用go语言编写的,非常美观的图形化展示,我们找到[官网下载](https://grafana.com/grafana/download?platform=windows),选择window环境 + +![image-20200913190726155](images/image-20200913190726155.png) + +解压后的目录,如下所示 + +![image-20200913190824928](images/image-20200913190824928.png) + +我们进入bin目录,找到 grafana-server.exe 然后启动 【首次启动比较慢,需要建立数据库】,启动成功后,访问下面的地址 + +```bash +http://127.0.0.1:3000 +``` + +即可进入到grafana的图形化页面了 + +![image-20200913191017753](images/image-20200913191017753.png) + +然后输入admin admin 登录即可 + +![image-20200913191249800](images/image-20200913191249800.png) + +然后选择普罗米修斯 + +![image-20200913191312189](images/image-20200913191312189.png) + +然后输入url保存 + +![image-20200913191338347](images/image-20200913191338347.png) + +然后导入我们的普罗米修斯的仪表盘 + +![image-20200913191444113](images/image-20200913191444113.png) + +然后到Home目录下,选择 new board + +![image-20200913191803694](images/image-20200913191803694.png) + +选择刚刚的import 的 仪表信息 + +![image-20200913191822529](images/image-20200913191822529.png) + +这样就生成了我们的仪表信息了 + +![image-20200913191854680](images/image-20200913191854680.png) + +或者可以选择另外一个样式 + +![image-20200913192017515](images/image-20200913192017515.png) + +## 结语 + +如果我们要监控其它的一些服务,比如redis、mysql、Memcache等等,需要自己到官网下载对应的包 + +https://prometheus.io/download/ + +![image-20200913192232698](images/image-20200913192232698.png) \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913185216706.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913185216706.png" new file mode 100644 index 0000000000000000000000000000000000000000..473debdb96a52499265865f36c195f2c72bb7df2 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913185216706.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190154123.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190154123.png" new file mode 100644 index 0000000000000000000000000000000000000000..06ec3cc3d3b24f9562eb51cdd898a00fd0c43d19 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190154123.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190213569.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190213569.png" new file mode 100644 index 0000000000000000000000000000000000000000..79c8a43d1ba6938ccf4abe7b47bd3ef8aae5060f Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190213569.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190307310.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190307310.png" new file mode 100644 index 0000000000000000000000000000000000000000..2d5b2a8022f5898014cb6d057a806583d9e91a4a Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190307310.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190408222.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190408222.png" new file mode 100644 index 0000000000000000000000000000000000000000..281b0373247d1527be50ffd185f1ccf8f667f03b Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190408222.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190444467.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190444467.png" new file mode 100644 index 0000000000000000000000000000000000000000..eda9e03520f8712d906cfa07b93a4a81f2806cce Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190444467.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190726155.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190726155.png" new file mode 100644 index 0000000000000000000000000000000000000000..abb80f8dcc7a0a9923d8c765d2df8470eae25986 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190726155.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190824928.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190824928.png" new file mode 100644 index 0000000000000000000000000000000000000000..17fb7e7b1515c560f2ac2174e3122b67ff5000da Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913190824928.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191017753.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191017753.png" new file mode 100644 index 0000000000000000000000000000000000000000..bc4d49d98c30bf27646c12062fa54dd73ecadb56 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191017753.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191249800.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191249800.png" new file mode 100644 index 0000000000000000000000000000000000000000..3db9cdd6fc759a379b380408f42110cf36677de3 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191249800.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191312189.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191312189.png" new file mode 100644 index 0000000000000000000000000000000000000000..8981f44a9db10fae400e5f6510bd091a3bc462ea Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191312189.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191338347.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191338347.png" new file mode 100644 index 0000000000000000000000000000000000000000..535301fe445a7ce607de2828124aa0805cab4352 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191338347.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191444113.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191444113.png" new file mode 100644 index 0000000000000000000000000000000000000000..9da4838962d3449e40319d1fcf567ef09994dd73 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191444113.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191803694.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191803694.png" new file mode 100644 index 0000000000000000000000000000000000000000..c86000ec435973769241bcf7db4698fc5b3eb4b6 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191803694.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191822529.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191822529.png" new file mode 100644 index 0000000000000000000000000000000000000000..ac51480797a6c4ac4e040afebd063c304d664cae Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191822529.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191854680.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191854680.png" new file mode 100644 index 0000000000000000000000000000000000000000..552c3968069a2c14df653da4d18d9db087f0939f Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913191854680.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913192017515.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913192017515.png" new file mode 100644 index 0000000000000000000000000000000000000000..08e97cb4df07be17a79b161e6fce8fa8b20203d4 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913192017515.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913192232698.png" "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913192232698.png" new file mode 100644 index 0000000000000000000000000000000000000000..d84762f155d65bf4bd90e53b6b149c279879f4e2 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/22_Prometheus\345\222\214Grafana\344\273\213\347\273\215/images/image-20200913192232698.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/4_Golang\345\271\266\345\217\221\347\274\226\347\250\213/README.md" "b/Golang/Golang\350\277\233\351\230\266/4_Golang\345\271\266\345\217\221\347\274\226\347\250\213/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..1c4511a0ed52c895d02519cf5872314351e1cc17 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/4_Golang\345\271\266\345\217\221\347\274\226\347\250\213/README.md" @@ -0,0 +1,103 @@ +# Go并发编程 + +## 参考 + +https://www.liwenzhou.com/posts/Go/14_concurrence/ + +## 并行与并发 + +并发:同一时间段内执行多个任务(你在用微信和两个女朋友聊天) + +并行:同一时刻执行多个任务(你和你朋友都在用微信和女朋友聊天) + +Go语言的并发通过goroutine 实现。goroutine类似于线程,属于用户态的线程,我们可以根据需要创建成千上万个goroutine 并发工作。goroutine 是由Go语言的运行时(runtime)调度完成,而线程是由操作系统调度完成。 +Go语言还提供channel 在多个goroutine间进行通信。goroutine和channel 是Go语言秉承CSP(Communicating Sequential Process)并发模式的重要实现基础。 + +> 用户态:表示程序执行用户自己写的程序时 +> +> 内核态:表示程序执行操作系统层面的程序时 +> +> 我们学习go的并发,就是学习goroutine 和 channel + +## Goroutine + +在java/c++中我们要实现并发编程的时候,我们通常需要自己维护一个线程池,并且需要自己去包装一个又一个的任务,同时需要自己去调度线程执行任务并维护上下文切换,这一切通常会耗费程序员大量的心智。那么能不能有一种机制,程序员只需要定义很多个任务,让系统去帮助我们把这些任务分配到CPU上实现并发执行呢? + +Go语言中的goroutine就是一种机制,goroutine的概念类似于线程,但goroutine是由Go的运行时(runtime)调度和管理的。Go程序会智能地将goroutine中的任务合理分配给每个CPU,Go语言之所以被称为现代化的编程语言,就是因为它在语言层面已经内置了调度和上下文切换的机制。 + +在Go语言编程中你不需要去自己写进程、线程、协程,你的技能包里只有一个技能- goroutine,当你需要让某个任务并发执行的时候,你只需要把这个任务包装成一个函数、开启一个goroutine去执行这个函数就可以了,就是这么简单粗暴 + +### 使用Goroutine + +Go语言中goroutine非常简单,只需要在调用函数的时候,在前面加上go关键字,就可以为一个函数创建一个goroutine + +一个goroutine必定对应一个函数,可以创建多个goroutine去执行相同的函数 + +### 启动goroutine + +启动goroutine的方式非常简单,只需要在调用的函数(普通函数和匿名函数)前面加上一个`go`关键字。 + +举个例子如下: + +```go +func hello() { + fmt.Println("Hello Goroutine!") +} +func main() { + hello() + fmt.Println("main goroutine done!") +} +``` + +当main()函数返回的时候该`goroutine`就结束了,所有在`main()`函数中启动的`goroutine`会一同结束,`main`函数所在的`goroutine`就像是权利的游戏中的夜王,其他的`goroutine`都是异鬼,夜王一死它转化的那些异鬼也就全部GG了 + +所以我们要想办法让main函数等一等hello函数,最简单粗暴的方式就是`time.Sleep`了 + +```go +func main() { + go hello() // 启动另外一个goroutine去执行hello函数 + fmt.Println("main goroutine done!") + time.Sleep(time.Second) +} +``` + +### 启动多个goroutine + +在Go语言中实现并发就是这样简单,我们还可以启动多个`goroutine`。让我们再来一个例子:(这里使用了`sync.WaitGroup`来实现goroutine的同步) + +```go +var wg sync.WaitGroup + +func hello(i int) { + defer wg.Done() // goroutine结束就登记-1 + fmt.Println("Hello Goroutine!", i) +} +func main() { + + for i := 0; i < 10; i++ { + wg.Add(1) // 启动一个goroutine就登记+1 + go hello(i) + } + wg.Wait() // 等待所有登记的goroutine都结束 +} +``` + +### goroutine什么时候结束? + + goroutine对应的函数结束了,goroutine就结束了吗,也就是说当我们的main函数执行结束了,那么main函数对应的goroutine也结束了。 + +## goroutine与线程 + +### 可增长的栈 + +OS线程(操作系统线程)一般都有固定的栈内存(通常为2MB),一个`goroutine`的栈在其生命周期开始时只有很小的栈(典型情况下2KB),`goroutine`的栈不是固定的,他可以按需增大和缩小,`goroutine`的栈大小限制可以达到1GB,虽然极少会用到这么大。所以在Go语言中一次创建十万左右的`goroutine`也是可以的 + +### Goroutine调度 + +`GPM`是Go语言运行时(runtime)层面的实现,是go语言自己实现的一套调度系统。区别于操作系统调度OS线程。 + +- `G`很好理解,就是个goroutine的,里面除了存放本goroutine信息外 还有与所在P的绑定等信息。 +- `P`管理着一组goroutine队列,P里面会存储当前goroutine运行的上下文环境(函数指针,堆栈地址及地址边界),P会对自己管理的goroutine队列做一些调度(比如把占用CPU时间较长的goroutine暂停、运行后续的goroutine等等)当自己的队列消费完了就去全局队列里取,如果全局队列里也消费完了会去其他P的队列里抢任务。 +- `M(machine)`是Go运行时(runtime)对操作系统内核线程的虚拟, M与内核线程一般是一一映射的关系, 一个groutine最终是要放到M上执行的; + +单从线程调度讲,Go语言相比起其他语言的优势在于OS线程是由OS内核来调度的,`goroutine`则是由Go运行时(runtime)自己的调度器调度的,这个调度器使用一个称为m:n调度的技术(复用/调度m个goroutine到n个OS线程)。 其一大特点是goroutine的调度是在用户态下完成的, 不涉及内核态与用户态之间的频繁切换,包括内存的分配与释放,都是在用户态维护着一块大的内存池, 不直接调用系统的malloc函数(除非内存池需要改变),成本比调度OS线程低很多。 另一方面充分利用了多核的硬件资源,近似的把若干goroutine均分在物理线程上, 再加上本身goroutine的超轻量,以上种种保证了go调度方面的性能。 \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/README.md" "b/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..55c1359c1f3ec7c6ae346fcf094b7b971c8014b4 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/README.md" @@ -0,0 +1,462 @@ +# 互联网协议 + +## 来源 + +https://www.liwenzhou.com/posts/Go/15_socket/ + +## 前言 + +现在我们几乎每天都在使用互联网,我们前面已经学习了如何编写Go语言程序,但是如何才能让我们的程序通过网络互相通信呢?本章我们就一起来学习下Go语言中的网络编程。 关于网络编程其实是一个很庞大的领域,本文只是简单的演示了如何使用net包进行TCP和UDP通信。如需了解更详细的网络编程请自行检索和阅读专业资料。 + +## 互联网协议介绍 + +互联网的核心是一系列协议,总称为”互联网协议”(Internet Protocol Suite),正是这一些协议规定了电脑如何连接和组网。我们理解了这些协议,就理解了互联网的原理。由于这些协议太过庞大和复杂,没有办法在这里一概而全,只能介绍一下我们日常开发中接触较多的几个协议。 + +### 互联网分层模型 + +互联网的逻辑实现被分为好几层。每一层都有自己的功能,就像建筑物一样,每一层都靠下一层支持。用户接触到的只是最上面的那一层,根本不会感觉到下面的几层。要理解互联网就需要自下而上理解每一层的实现的功能。 + +![osi七层模型](images/osi.png) + +如上图所示,互联网按照不同的模型划分会有不用的分层,但是不论按照什么模型去划分,越往上的层越靠近用户,越往下的层越靠近硬件。在软件开发中我们使用最多的是上图中将互联网划分为五个分层的模型。 + +接下来我们一层一层的自底向上介绍一下每一层。 + +### 物理层 + +我们的电脑要与外界互联网通信,需要先把电脑连接网络,我们可以用双绞线、光纤、无线电波等方式。这就叫做”实物理层”,它就是把电脑连接起来的物理手段。它主要规定了网络的一些电气特性,作用是负责传送0和1的电信号。 + +### 数据链路层 + +单纯的0和1没有任何意义,所以我们使用者会为其赋予一些特定的含义,规定解读电信号的方式:例如:多少个电信号算一组?每个信号位有何意义?这就是”数据链接层”的功能,它在”物理层”的上方,确定了物理层传输的0和1的分组方式及代表的意义。早期的时候,每家公司都有自己的电信号分组方式。逐渐地,一种叫做”以太网”(Ethernet)的协议,占据了主导地位。 + +以太网规定,一组电信号构成一个数据包,叫做”帧”(Frame)。每一帧分成两个部分:标头(Head)和数据(Data)。其中”标头”包含数据包的一些说明项,比如发送者、接受者、数据类型等等;”数据”则是数据包的具体内容。”标头”的长度,固定为18字节。”数据”的长度,最短为46字节,最长为1500字节。因此,整个”帧”最短为64字节,最长为1518字节。如果数据很长,就必须分割成多个帧进行发送。 + +那么,发送者和接受者是如何标识呢?以太网规定,连入网络的所有设备都必须具有”网卡”接口。数据包必须是从一块网卡,传送到另一块网卡。网卡的地址,就是数据包的发送地址和接收地址,这叫做MAC地址。每块网卡出厂的时候,都有一个全世界独一无二的MAC地址,长度是48个二进制位,通常用12个十六进制数表示。前6个十六进制数是厂商编号,后6个是该厂商的网卡流水号。有了MAC地址,就可以定位网卡和数据包的路径了。 + +我们会通过ARP协议来获取接受方的MAC地址,有了MAC地址之后,如何把数据准确的发送给接收方呢?其实这里以太网采用了一种很”原始”的方式,它不是把数据包准确送到接收方,而是向本网络内所有计算机都发送,让每台计算机读取这个包的”标头”,找到接收方的MAC地址,然后与自身的MAC地址相比较,如果两者相同,就接受这个包,做进一步处理,否则就丢弃这个包。这种发送方式就叫做”广播”(broadcasting)。 + +### 网络层 + +按照以太网协议的规则我们可以依靠MAC地址来向外发送数据。理论上依靠MAC地址,你电脑的网卡就可以找到身在世界另一个角落的某台电脑的网卡了,但是这种做法有一个重大缺陷就是以太网采用广播方式发送数据包,所有成员人手一”包”,不仅效率低,而且发送的数据只能局限在发送者所在的子网络。也就是说如果两台计算机不在同一个子网络,广播是传不过去的。这种设计是合理且必要的,因为如果互联网上每一台计算机都会收到互联网上收发的所有数据包,那是不现实的。 + +因此,必须找到一种方法区分哪些MAC地址属于同一个子网络,哪些不是。如果是同一个子网络,就采用广播方式发送,否则就采用”路由”方式发送。这就导致了”网络层”的诞生。它的作用是引进一套新的地址,使得我们能够区分不同的计算机是否属于同一个子网络。这套地址就叫做”网络地址”,简称”网址”。 + +“网络层”出现以后,每台计算机有了两种地址,一种是MAC地址,另一种是网络地址。两种地址之间没有任何联系,MAC地址是绑定在网卡上的,网络地址则是网络管理员分配的。网络地址帮助我们确定计算机所在的子网络,MAC地址则将数据包送到该子网络中的目标网卡。因此,从逻辑上可以推断,必定是先处理网络地址,然后再处理MAC地址。 + +规定网络地址的协议,叫做IP协议。它所定义的地址,就被称为IP地址。目前,广泛采用的是IP协议第四版,简称IPv4。IPv4这个版本规定,网络地址由32个二进制位组成,我们通常习惯用分成四段的十进制数表示IP地址,从0.0.0.0一直到255.255.255.255。 + +根据IP协议发送的数据,就叫做IP数据包。IP数据包也分为”标头”和”数据”两个部分:”标头”部分主要包括版本、长度、IP地址等信息,”数据”部分则是IP数据包的具体内容。IP数据包的”标头”部分的长度为20到60字节,整个数据包的总长度最大为65535字节。 + +### 传输层 + +有了MAC地址和IP地址,我们已经可以在互联网上任意两台主机上建立通信。但问题是同一台主机上会有许多程序都需要用网络收发数据,比如QQ和浏览器这两个程序都需要连接互联网并收发数据,我们如何区分某个数据包到底是归哪个程序的呢?也就是说,我们还需要一个参数,表示这个数据包到底供哪个程序(进程)使用。这个参数就叫做”端口”(port),它其实是每一个使用网卡的程序的编号。每个数据包都发到主机的特定端口,所以不同的程序就能取到自己所需要的数据。 + +“端口”是0到65535之间的一个整数,正好16个二进制位。0到1023的端口被系统占用,用户只能选用大于1023的端口。有了IP和端口我们就能实现唯一确定互联网上一个程序,进而实现网络间的程序通信。 + +我们必须在数据包中加入端口信息,这就需要新的协议。最简单的实现叫做UDP协议,它的格式几乎就是在数据前面,加上端口号。UDP数据包,也是由”标头”和”数据”两部分组成:”标头”部分主要定义了发出端口和接收端口,”数据”部分就是具体的内容。UDP数据包非常简单,”标头”部分一共只有8个字节,总长度不超过65,535字节,正好放进一个IP数据包。 + +UDP协议的优点是比较简单,容易实现,但是缺点是可靠性较差,一旦数据包发出,无法知道对方是否收到。为了解决这个问题,提高网络可靠性,TCP协议就诞生了。TCP协议能够确保数据不会遗失。它的缺点是过程复杂、实现困难、消耗较多的资源。TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会超过IP数据包的长度,以确保单个TCP数据包不必再分割。 + +### 应用层 + +应用程序收到”传输层”的数据,接下来就要对数据进行解包。由于互联网是开放架构,数据来源五花八门,必须事先规定好通信的数据格式,否则接收方根本无法获得真正发送的数据内容。”应用层”的作用就是规定应用程序使用的数据格式,例如我们TCP协议之上常见的Email、HTTP、FTP等协议,这些协议就组成了互联网协议的应用层。 + +如下图所示,发送方的HTTP数据经过互联网的传输过程中会依次添加各层协议的标头信息,接收方收到数据包之后再依次根据协议解包得到数据。 + +![HTTP数据传输图解](images/httptcpip.png) + +## socket编程 + +Socket是BSD UNIX的进程通信机制,通常也称作”套接字”,用于描述IP地址和端口,是一个通信链的句柄。Socket可以理解为TCP/IP网络的API,它定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。电脑上运行的应用程序通常通过”套接字”向网络发出请求或者应答网络请求。 + +> Socket把底层的内容给屏蔽掉了,我们只需要关注于Socket的API层面,即可完成网络通信 + +### socket图解 + +`Socket`是应用层与TCP/IP协议族通信的中间软件抽象层。在设计模式中,`Socket`其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在`Socket`后面,对用户来说只需要调用Socket规定的相关函数,让`Socket`去组织符合指定的协议数据然后进行通信。 + +![socket图解](images/socket.png) + +## Go语言实现TCP通信 + +### TCP协议 + +TCP/IP(Transmission Control Protocol/Internet Protocol) 即传输控制协议/网间协议,是一种面向连接(连接导向)的、可靠的、基于字节流的传输层(Transport layer)通信协议,因为是面向连接的协议,数据像水流一样传输,会存在黏包问题。 + +### TCP服务端 + +一个TCP服务端可以同时连接很多个客户端,例如世界各地的用户使用自己电脑上的浏览器访问淘宝网。因为Go语言中创建多个goroutine实现并发非常方便和高效,所以我们可以每建立一次链接就创建一个goroutine去处理。 + +TCP服务端程序的处理流程: + +1. 监听端口 +2. 接收客户端请求建立链接 +3. 创建goroutine处理链接。 + +我们使用Go语言的net包实现的TCP服务端代码如下: + +```go +// 用于接收请求的方法 +func processConn(conn net.Conn) { + // 与客户端通信 + var tmp [128]byte + // 使用for循环监听消息 + for { + n, err := conn.Read(tmp[:]) + if err != nil { + fmt.Println("read from conn failed, err:", err) + return + } + fmt.Println(conn, string(tmp[:n])) + } +} +func main() { + // 本地端口启动服务 + listen, err := net.Listen("tcp", "127.0.0.1:20000") + if err!= nil { + fmt.Println("start server on failed ", err) + } + + // for循环监听 + for { + // 等待别人来建立连接 + conn, err := listen.Accept() + if err != nil { + fmt.Println("accept failed, err: ", err) + return + } + go processConn(conn) + } +} +``` + +### TCP客户端 + +```go +func getInput() string { + //使用os.Stdin开启输入流 + //函数原型 func NewReader(rd io.Reader) *Reader + //NewReader创建一个具有默认大小缓冲、从r读取的*Reader 结构见官方文档 + in := bufio.NewReader(os.Stdin) + //in.ReadLine函数具有三个返回值 []byte bool error + //分别为读取到的信息 是否数据太长导致缓冲区溢出 是否读取失败 + str, _, err := in.ReadLine() + if err != nil { + return err.Error() + } + return string(str) +} + +// tcp client +func main() { + // 与server端建立连接 + conn, err := net.Dial("tcp", "127.0.0.1:20000") + if err != nil { + fmt.Println("dial 127.0.0.1:20000 failed, err:", err) + return + } + // 发送数据 + conn.Write([]byte(getInput())) + + // 关闭流 + defer conn.Close() +} +``` + +## TCP黏包 + +### 黏包实例 + +服务端代码如下: + +```go +// socket_stick/server/main.go +func process(conn net.Conn) { + defer conn.Close() + reader := bufio.NewReader(conn) + var buf [1024]byte + for { + n, err := reader.Read(buf[:]) + if err == io.EOF { + break + } + if err != nil { + fmt.Println("read from client failed, err:", err) + break + } + recvStr := string(buf[:n]) + fmt.Println("收到client发来的数据:", recvStr) + } +} + +func main() { + + listen, err := net.Listen("tcp", "127.0.0.1:30000") + if err != nil { + fmt.Println("listen failed, err:", err) + return + } + defer listen.Close() + for { + conn, err := listen.Accept() + if err != nil { + fmt.Println("accept failed, err:", err) + continue + } + go process(conn) + } +} +``` + +客户端代码如下: + +```go +// socket_stick/client/main.go + +func main() { + conn, err := net.Dial("tcp", "127.0.0.1:30000") + if err != nil { + fmt.Println("dial failed, err", err) + return + } + defer conn.Close() + + // 连续发送20次的hello到服务器 + for i := 0; i < 20; i++ { + msg := `Hello, Hello. How are you?` + conn.Write([]byte(msg)) + } +} +``` + +将上面的代码保存后,分别编译。先启动服务端再启动客户端,可以看到服务端输出结果如下: + +```bash +收到client发来的数据: Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you? +收到client发来的数据: Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you? +收到client发来的数据: Hello, Hello. How are you?Hello, Hello. How are you? +收到client发来的数据: Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you? +收到client发来的数据: Hello, Hello. How are you?Hello, Hello. How are you? +``` + +客户端分10次发送的数据,在服务端并没有成功的输出10次,而是多条数据 粘 到了一起。 + + + +1. + +### 为什么会出现粘包 + +主要原因就是tcp数据传递模式是流模式,在保持长连接的时候可以进行多次的收和发。 + +“粘包”可发生在发送端也可发生在接收端: + +1. 由Nagle算法造成的发送端的粘包:Nagle算法是一种改善网络传输效率的算法。简单来说就是当我们提交一段数据给TCP发送时,TCP并不立刻发送此段数据,而是等待一小段时间看看在等待期间是否还有要发送的数据,若有则会一次把这两段数据发送出去。 +2. 接收端接收不及时造成的接收端粘包:TCP会把接收到的数据存在自己的缓冲区中,然后通知应用层取数据。当应用层由于某些原因不能及时的把TCP的数据取出来,就会造成TCP缓冲区中存放了几段数据。 + +### 解决办法 + +出现”粘包”的关键在于接收方不确定将要传输的数据包的大小,因此我们可以对数据包进行封包和拆包的操作。 + +封包:封包就是给一段数据加上包头,这样一来数据包就分为包头和包体两部分内容了(过滤非法包时封包会加入”包尾”内容)。包头部分的长度是固定的,并且它存储了包体的长度,根据包头长度固定以及包头中含有包体长度的变量就能正确的拆分出一个完整的数据包。 + +我们可以自己定义一个协议,比如数据包的前4个字节为包头,里面存储的是发送的数据的长度。 + +```go +// socket_stick/proto/proto.go +package proto + +import ( + "bufio" + "bytes" + "encoding/binary" +) + +// Encode 将消息编码 +func Encode(message string) ([]byte, error) { + // 读取消息的长度,转换成int32类型(占4个字节) + var length = int32(len(message)) + var pkg = new(bytes.Buffer) + // 写入消息头 + err := binary.Write(pkg, binary.LittleEndian, length) + if err != nil { + return nil, err + } + // 写入消息实体 + err = binary.Write(pkg, binary.LittleEndian, []byte(message)) + if err != nil { + return nil, err + } + return pkg.Bytes(), nil +} + +// Decode 解码消息 +func Decode(reader *bufio.Reader) (string, error) { + // 读取消息的长度 + lengthByte, _ := reader.Peek(4) // 读取前4个字节的数据 + lengthBuff := bytes.NewBuffer(lengthByte) + var length int32 + err := binary.Read(lengthBuff, binary.LittleEndian, &length) + if err != nil { + return "", err + } + // Buffered返回缓冲中现有的可读取的字节数。 + if int32(reader.Buffered()) < length+4 { + return "", err + } + + // 读取真正的消息数据 + pack := make([]byte, int(4+length)) + _, err = reader.Read(pack) + if err != nil { + return "", err + } + return string(pack[4:]), nil +} +``` + +> 引申知识点:大端和小端 + +![image-20200815105512405](images/image-20200815105512405.png) + +接下来在服务端和客户端分别使用上面定义的`proto`包的`Decode`和`Encode`函数处理数据。 + +服务端代码如下: + +```go +// socket_stick/server2/main.go + +func process(conn net.Conn) { + defer conn.Close() + reader := bufio.NewReader(conn) + for { + msg, err := proto.Decode(reader) + if err == io.EOF { + return + } + if err != nil { + fmt.Println("decode msg failed, err:", err) + return + } + fmt.Println("收到client发来的数据:", msg) + } +} + +func main() { + + listen, err := net.Listen("tcp", "127.0.0.1:30000") + if err != nil { + fmt.Println("listen failed, err:", err) + return + } + defer listen.Close() + for { + conn, err := listen.Accept() + if err != nil { + fmt.Println("accept failed, err:", err) + continue + } + go process(conn) + } +} +``` + +客户端代码如下: + +```go +// socket_stick/client2/main.go + +func main() { + conn, err := net.Dial("tcp", "127.0.0.1:30000") + if err != nil { + fmt.Println("dial failed, err", err) + return + } + defer conn.Close() + for i := 0; i < 20; i++ { + msg := `Hello, Hello. How are you?` + data, err := proto.Encode(msg) + if err != nil { + fmt.Println("encode msg failed, err:", err) + return + } + conn.Write(data) + } +} +``` + +## Go语言实现UDP通信 + +### UDP协议 + +UDP协议(User Datagram Protocol)中文名称是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联)参考模型中一种**无连接**的传输层协议,不需要建立连接就能直接进行数据发送和接收,属于不可靠的、没有时序的通信,但是UDP协议的实时性比较好,通常用于视频直播相关领域。 + +### UDP服务端 + +使用Go语言的`net`包实现的UDP服务端代码如下: + +```go +// UDP/server/main.go + +// UDP server端 +func main() { + listen, err := net.ListenUDP("udp", &net.UDPAddr{ + IP: net.IPv4(0, 0, 0, 0), + Port: 30000, + }) + if err != nil { + fmt.Println("listen failed, err:", err) + return + } + defer listen.Close() + for { + var data [1024]byte + n, addr, err := listen.ReadFromUDP(data[:]) // 接收数据 + if err != nil { + fmt.Println("read udp failed, err:", err) + continue + } + fmt.Printf("data:%v addr:%v count:%v\n", string(data[:n]), addr, n) + _, err = listen.WriteToUDP(data[:n], addr) // 发送数据 + if err != nil { + fmt.Println("write to udp failed, err:", err) + continue + } + } +} +``` + +### UDP客户端 + +使用Go语言的`net`包实现的UDP客户端代码如下: + +```go +// UDP 客户端 +func main() { + // 拨号连接 + socket, err := net.DialUDP("udp", nil, &net.UDPAddr{ + IP: net.IPv4(0, 0, 0, 0), + Port: 30000, + }) + if err != nil { + fmt.Println("连接服务端失败,err:", err) + return + } + defer socket.Close() + sendData := []byte("Hello server") + _, err = socket.Write(sendData) // 发送数据 + if err != nil { + fmt.Println("发送数据失败,err:", err) + return + } + data := make([]byte, 4096) + n, remoteAddr, err := socket.ReadFromUDP(data) // 接收数据 + if err != nil { + fmt.Println("接收数据失败,err:", err) + return + } + fmt.Printf("recv:%v addr:%v count:%v\n", string(data[:n]), remoteAddr, n) +} +``` + diff --git "a/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/images/httptcpip.png" "b/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/images/httptcpip.png" new file mode 100644 index 0000000000000000000000000000000000000000..9703d701cf853487c4a26ecd4b475745f28d50cf Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/images/httptcpip.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/images/image-20200815105512405.png" "b/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/images/image-20200815105512405.png" new file mode 100644 index 0000000000000000000000000000000000000000..6cf685e4580a7b80265663a1fbf01bc10293fcd2 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/images/image-20200815105512405.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/images/osi.png" "b/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/images/osi.png" new file mode 100644 index 0000000000000000000000000000000000000000..079b1d8b2b4ecba68f3442eb78ef975e3e165d54 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/images/osi.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/images/socket.png" "b/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/images/socket.png" new file mode 100644 index 0000000000000000000000000000000000000000..109f8012a5f20fe643f0ca6bb80341af15ac51d7 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/5_\344\272\222\350\201\224\347\275\221\345\215\217\350\256\256\344\273\213\347\273\215/images/socket.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/6_HTTP\350\257\267\346\261\202/README.md" "b/Golang/Golang\350\277\233\351\230\266/6_HTTP\350\257\267\346\261\202/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..2fb012c46e58ae33d42b1ea8db8ae11fffe13885 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/6_HTTP\350\257\267\346\261\202/README.md" @@ -0,0 +1,288 @@ +# HTTP请求 + +## 本次内容 + +- context +- 单元测试(给函数做单元测试) +- pprof调试工具(go语言内置工具) + - 可以看到代码的cpu和运行时的一些信息 + - 能看到一些图表信息,如内存占用、cpu占用等 + +## 内容回顾 + +https://www.liwenzhou.com/posts/Go/14_concurrence/ + +### 锁 + +sync.Mutex,底层是一个结构体,是值类型。给参数传递参数的时候,要传指针 + +两个方法 + +```go +var lock sync.Mutex +lock.lock() // 加锁 +lock.unlock() //解锁 +``` + +为什么要上锁?? + +防止多个goroutine同一时刻操作同一个资源。 + +### 读写互斥锁 + +应用场景:适用于读多写少的场景下,也就是支持并发读,单个写 + +特点 + +- 读的goroutine来了获取的是读锁,后续的goroutine能读不能写 +- 写的goroutine来了获取的是写锁,后续的goroutine不管是读还是写都要等待获取获取锁 + +使用 + +```go +var rwLock sync.RWMutex +rwLock.RLock() // 获取读锁 +rwLock.Runlock() // 释放锁 + +rwLock.Lock() // 获取写锁 +rwLock.unlock() // 释放写锁 +``` + +### 等待组 + +`sync.waitgroup`,用来等goroutine执行完在继续,是一个结构体,值类型,给函数传参数的时候要传指针 + +```go +var wg sync.WaitGroup + +wg.add(1) // 起几个goroutine就加几个数 +wg.Done() // 在goroutine对应的函数中,函数要结束的时候调用,表示goroutine完成,计数器减1 +wg.Wait() // 阻塞,等待所有的goroutine都结束 +``` + +### Sync.Once + +某些函数只需要执行 一次的时候,就可以使用 `sync.Once` + +比如blog加载图片那个例子 + +```go +var once sync.Once +once.Do() //接收一个没有参数也乜有返回值的函数,如有需要可以使用闭包 +``` + +### sync.Map + +使用场景:并发操作一个map的时候,内置的map不是并发安全的 + +而sync.map是一个开箱即用(不需要make初始化)的并发安全的map + +```go +var syncMap sync.Map +syncMap[key] = value //原生map +syncMap.Store(key, value) // 存储 +syncMap.LoadOrStore() // 获取 +syncMap.Delete() +syncMap.Range() +``` + +### 原子操作 + +Go语言内置了一些针对内置的基本数据类型的一些并发安全的操作 + +```go +var i int64 = 10 +atomic.AddInt64(&i, 1) +``` + +### 网络编程 + +互联网的协议 + +OSI七层模型:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层 + +TCP/IP协议:应用层、传输层、网络层、数据链路层、物理层 + +![image-20200817170306666](images/image-20200817170306666.png) + +## Http服务端 + +Go语言内置的`net/http` 包提供了HTTP客户端和服务端的实现 + +### HTTP协议 + +超文本传输协议(HTTP,Hyper Text Transfer Protocol)是互联网上应用最为广泛的一种网络传输协议,所有的wWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。 + +### HTTP客户端 + +使用`net/http`包编写一个简单的发送HTTP请求的Client端,代码如下: + +```go +package main + +import "net/http" + +func f1(w http.ResponseWriter, r *http.Request) { + str := "hello 沙河!" + w.Write([]byte(str)) +} + +func main() { + http.HandleFunc("/posts/Go/15_socket/", f1) + http.ListenAndServe("127.0.0.1:9090", nil) +} +``` + +我们制作了一个最简单的api接口,最后返回的是我们的hello 沙河! + +![image-20200817172803104](images/image-20200817172803104.png) + +我们也可以通过读取文件中的内容,然后进行显示 + +```go +func f1(w http.ResponseWriter, r *http.Request) { + index, err := ioutil.ReadFile("./index.html") + if err != nil { + w.Write([]byte(fmt.Sprintf("%v", err))) + } + w.Write([]byte(index)) +} + +func main() { + http.HandleFunc("/index", f1) + http.HandleFunc("/home", f1) + http.HandleFunc("/about", f1) + http.ListenAndServe("127.0.0.1:9090", nil) +} +``` + +### 自定义Server + +要管理服务端的行为,可以创建一个自定义的Server: + +```go +s := &http.Server{ + Addr: ":8080", + Handler: myHandler, + ReadTimeout: 10 * time.Second, + WriteTimeout: 10 * time.Second, + MaxHeaderBytes: 1 << 20, +} +log.Fatal(s.ListenAndServe()) +``` + +### 网站运行运行流程 + +![image-20200817175202590](images/image-20200817175202590.png) + + + +- HTTP:超文本传输协议,规定了浏览器和网站服务器之间通信的规则 + - 规定了浏览器和网站服务器之间通信的规则 + +- HTML:超文本标记语言,学的就是标记的符号,标签 +- CSS:层叠样式表,规定了HTML中标签的具体样式(颜色/背景/大小/位置/浮动...) +- JavaScript:一种跑在浏览器上的编程语言 + +## HTTP客户端 + +我们可以使用http客户端,去请求我们的URL地址,得到我们的内容 + +```go +func main() { + res, err := http.Get("http://127.0.0.1:9090/query?name=zansan&age=10") + if err != nil { + fmt.Println(err) + return + } + + // 从res中把服务端返回的数据读取出来 + b, err := ioutil.ReadAll(res.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(b)) +} +``` + +对于GET请求,参数都放在URL上(query param),请求体上是没有数据的,我们可以通过以下方法来获取 + +```go +func f2(w http.ResponseWriter, r *http.Request) { + fmt.Println(r.URL) + fmt.Println(r.URL.Query()) // 识别URL中的参数 + queryParams := r.URL.Query() + name := queryParams.Get("name") + age := queryParams.Get("age") + fmt.Println("传递来的name:", name) + fmt.Println("传递来的age:", age) + fmt.Println(r.Method) + fmt.Println(ioutil.ReadAll(r.Body)) +} + +func main() { + http.HandleFunc("/query", f2) + http.ListenAndServe("127.0.0.1:9090", nil) +} + +``` + +同时上述的url也支持中文的请求,如下所示 + +```go +res, err := http.Get("http://127.0.0.1:9090/query?name=张三&age=10") +``` + +或者我们可以使用更为复杂的请求方式,可以使用下面的方式 + +```go + data := url.Values{} + urlObj, _ := url.Parse("http://127.0.0.1:9090/query") + data.Set("name", "周林") + data.Set("age", "100") + // 对请求进行编码 + queryStr := data.Encode() + urlObj.RawQuery = queryStr + + req, err := http.NewRequest("GET", urlObj.String(), nil) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(req) +``` + +### 自定义Client + +```go +client := &http.Client{ + CheckRedirect: redirectPolicyFunc, +} +resp, err := client.Get("http://example.com") +// ... +req, err := http.NewRequest("GET", "http://example.com", nil) +// ... +req.Header.Add("If-None-Match", `W/"wyzzy"`) +resp, err := client.Do(req) +``` + +### 自定义Transport + +要管理代理、TLS配置、keep-alive、压缩和其他设置,创建一个Transport: + +```go +tr := &http.Transport{ + TLSClientConfig: &tls.Config{RootCAs: pool}, + DisableCompression: true, +} +client := &http.Client{Transport: tr} +resp, err := client.Get("https://example.com") +``` + +Client和Transport类型都可以安全的被多个goroutine同时使用。出于效率考虑,应该一次建立、尽量重用。 + +## 参考 + +- [Go语言基础之net/http](https://www.liwenzhou.com/posts/Go/go_http/) +- \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/6_HTTP\350\257\267\346\261\202/images/image-20200817170306666.png" "b/Golang/Golang\350\277\233\351\230\266/6_HTTP\350\257\267\346\261\202/images/image-20200817170306666.png" new file mode 100644 index 0000000000000000000000000000000000000000..3f87b70f5f49d89ccbf2f71159cef0b4714bfc4d Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/6_HTTP\350\257\267\346\261\202/images/image-20200817170306666.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/6_HTTP\350\257\267\346\261\202/images/image-20200817172803104.png" "b/Golang/Golang\350\277\233\351\230\266/6_HTTP\350\257\267\346\261\202/images/image-20200817172803104.png" new file mode 100644 index 0000000000000000000000000000000000000000..b9eb099b6d006e6a6ff39e2e8e58e8a70211b2cf Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/6_HTTP\350\257\267\346\261\202/images/image-20200817172803104.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/6_HTTP\350\257\267\346\261\202/images/image-20200817175202590.png" "b/Golang/Golang\350\277\233\351\230\266/6_HTTP\350\257\267\346\261\202/images/image-20200817175202590.png" new file mode 100644 index 0000000000000000000000000000000000000000..c2f70ef672ce24a4bcbb5af05c56c372c46d0bc7 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/6_HTTP\350\257\267\346\261\202/images/image-20200817175202590.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/7_\346\227\245\345\277\227\345\272\223/README.md" "b/Golang/Golang\350\277\233\351\230\266/7_\346\227\245\345\277\227\345\272\223/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..4a01b2fdd4e01b74893dd896e539a8ffd9ae9369 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/7_\346\227\245\345\277\227\345\272\223/README.md" @@ -0,0 +1,244 @@ +# 日志库 + +## 来源 + +https://www.liwenzhou.com/posts/Go/go_log/ + +## 介绍 + +无论是软件开发的调试阶段还是软件上线之后的运行阶段,日志一直都是非常重要的一个环节,我们也应该养成在程序中记录日志的好习惯。 + +Go语言内置的`log`包实现了简单的日志服务。本文介绍了标准库`log`的基本使用。 + +## 使用Logger + +log包定义了Logger类型,该类型提供了一些格式化输出的方法。本包也提供了一个预定义的“标准”logger,可以通过调用函数`Print系列`(Print|Printf|Println)、`Fatal系列`(Fatal|Fatalf|Fatalln)、和`Panic系列`(Panic|Panicf|Panicln)来使用,比自行创建一个logger对象更容易使用。 + +例如,我们可以像下面的代码一样直接通过`log`包来调用上面提到的方法,默认它们会将日志信息打印到终端界面 + +```go +package main + +import ( + "log" +) + +func main() { + log.Println("这是一条很普通的日志。") + v := "很普通的" + log.Printf("这是一条%s日志。\n", v) + log.Fatalln("这是一条会触发fatal的日志。") + log.Panicln("这是一条会触发panic的日志。") +} +``` + +编译并执行上面的代码会得到如下输出: + +```bash +2017/06/19 14:04:17 这是一条很普通的日志。 +2017/06/19 14:04:17 这是一条很普通的日志。 +2017/06/19 14:04:17 这是一条会触发fatal的日志 +``` + +logger会打印每条日志信息的日期、时间,默认输出到系统的标准错误。Fatal系列函数会在写入日志信息后调用os.Exit(1)。Panic系列函数会在写入日志信息后panic。 + +## 日志输出到文件中 + +我们正常的日志文件,是存储在文件中的,因此我们可以使用以下的方式,将日志存储在文件中 + +```go +func main() { + fileObj, err := os.OpenFile("./xx.log", os.O_APPEND | os.O_CREATE | os.O_WRONLY, 0644) + if err != nil { + fmt.Printf("open file failed, err : %v \n", err) + return + } + // 设置log的输出路径 + log.SetOutput(fileObj) + for { + log.Println("这是一条测试日志") + time.Sleep(time.Second * 3) + } +} +``` + +## 日志库的简单实现 + +- 支持往不同的地方输出日志 +- 日志分级别 + - debug + - Trace + - info + - warning + - Error + - Fatal:严重错误 +- 日志要支持开关控制,比如说开发的时候什么级别都能输出,但是上线之后只有INFO级别往下才能输出 +- 日志要有时间、行号、文件名、日志级别、日志信息 +- 日志文件要切割 +- + +```go +package main + +import ( + "errors" + "fmt" + "path" + "runtime" + "strings" + "time" +) + +// 往终端写日志相关内容 + +type LogLevel uint16 + +// 定义日志级别 +const( + UNKNOWN LogLevel = iota // 0 + DEBUG + TRACE + INFO + WARNING + ERROR + FATAL +) + +// Logger日志结构体 +type Logger struct { + Level LogLevel +} + +func parseLogLevel(s string) (LogLevel, error) { + s = strings.ToLower(s) + switch s { + case "debug": + return DEBUG, nil + case "trace": + return TRACE, nil + case "info": + return INFO, nil + case "warning": + return WARNING, nil + case "error": + return ERROR, nil + case "fatal": + return FATAL, nil + default: + err := errors.New("无效的日志级别") + return UNKNOWN, err + } + +} + +func getLogLevelStr(logLevel LogLevel) (string) { + switch logLevel { + case DEBUG: + return "debug" + case TRACE: + return "trace" + case INFO: + return "info" + case WARNING: + return "warning" + case ERROR: + return "error" + case FATAL: + return "fatal" + default: + return "unknown" + } +} + +// 获取函数名、文件名、行号 +// skip表示隔了几层 +func getInfo(skip int)(funcName string, fileName string, lineNo int) { + // pc:函数信息 + // file:文件 + // line:行号,也就是当前行号 + pc, file, line, ok := runtime.Caller(skip) + if !ok { + fmt.Printf("runtime.Caller() failed, err:%v \n") + return + } + funName := runtime.FuncForPC(pc).Name() + + return funName, path.Base(file), line +} + +// Logger构造方法 +func NewLog(levelStr string) Logger { + level, err := parseLogLevel(levelStr) + if err != nil { + panic(err) + } + // 构造了一个Logger对象 + return Logger{ + Level: level, + } +} + +// 判断啥级别的日志可以输出是否输出 +func (l Logger) enable(logLevel LogLevel) bool { + return logLevel >= l.Level +} + +func printLog(lv LogLevel, msg string) { + now := time.Now().Format("2006-01-02 15:04:05") + // 拿到第二层的函数名 + funcName, filePath, lineNo := getInfo(3) + fmt.Printf("[%s] [%s] [%s:%s:%d] %s \n", now, getLogLevelStr(lv),filePath, funcName, lineNo, msg) + +} + +func (l Logger) Debug(msg string) { + if l.enable(DEBUG) { + printLog(DEBUG, msg) + } +} + +func (l Logger) TRACE(msg string) { + if l.enable(TRACE) { + printLog(TRACE, msg) + } +} + +func (l Logger) Info(msg string) { + if l.enable(INFO) { + printLog(INFO, msg) + } +} + +func (l Logger) Warning(msg string) { + + if l.enable(WARNING) { + printLog(WARNING, msg) + } +} + +func (l Logger) Error(msg string) { + if l.enable(ERROR) { + printLog(ERROR, msg) + } +} + +func (l Logger) Fatal(msg string) { + if l.enable(FATAL) { + printLog(FATAL, msg) + } +} + +func main() { + log := NewLog("ERROR") + for { + log.Debug("这是一条DEBUG日志") + log.Info("这是一条INFO日志") + log.Warning("这是一条WARNING日志") + log.Error("这是一条ERROR日志") + log.Fatal("这是一条FATAL日志") + fmt.Println("----------------") + time.Sleep(time.Second) + } +} +``` + diff --git "a/Golang/Golang\350\277\233\351\230\266/8_\345\217\215\345\260\204/README.md" "b/Golang/Golang\350\277\233\351\230\266/8_\345\217\215\345\260\204/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..fbed0ffe6ce84f6e642815ff1ca0027cdfac5fee --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/8_\345\217\215\345\260\204/README.md" @@ -0,0 +1,424 @@ +# 反射 + +## 来源 + +https://www.liwenzhou.com/posts/Go/13_reflect/ + +## 前言 + +反射在我们的编码中可能不太常用到,但是其实很多内部方法都应用了反射技术,例如 + +```go +type person struct { + Name string `json:"name"` + Age int `json:"age"` +} + +func main() { + str := `{"name":"张三", "age":15}` + var p person + json.Unmarshal([]byte(str), &p) + fmt.Println(p.Name, p.Age) +} +``` + +## 变量的内在机制 + +Go语言中的变量是分为两部分的: + +- 类型信息:预先定义好的元信息。 +- 值信息:程序运行过程中可动态变化的。 + +## 反射介绍 + +反射是指在程序运行期对程序本身进行访问和修改的能力。程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分。在运行程序时,程序无法获取自身的信息。 + +支持反射的语言可以在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期获取类型的反射信息,并且有能力修改它们。 + +Go程序在运行期使用reflect包访问程序的反射信息。 + +在上一篇博客中我们介绍了空接口。 空接口可以存储任意类型的变量,那我们如何知道这个空接口保存的数据是什么呢? 反射就是在运行时动态的获取一个变量的类型信息和值信息。 + +## reflect包 + +在Go语言的反射机制中,任何接口值都由是`一个具体类型`和`具体类型的值`两部分组成的(我们在上一篇接口的博客中有介绍相关概念)。 在Go语言中反射的相关功能由内置的reflect包提供,任意接口值在反射中都可以理解为由`reflect.Type`和`reflect.Value`两部分组成,并且reflect包提供了`reflect.TypeOf`和`reflect.ValueOf`两个函数来获取任意对象的Value和Type + +### TypeOf + +在Go语言中,使用`reflect.TypeOf()`函数可以获得任意值的类型对象(reflect.Type),程序通过类型对象可以访问任意值的类型信息。 + +```go +package main + +import ( + "fmt" + "reflect" +) + +func reflectType(x interface{}) { + v := reflect.TypeOf(x) + fmt.Printf("type:%v\n", v) +} +func main() { + var a float32 = 3.14 + reflectType(a) // type:float32 + var b int64 = 100 + reflectType(b) // type:int64 +} +``` + +### type name和type kind + +在反射中关于类型还划分为两种:`类型(Type)`和`种类(Kind)`。因为在Go语言中我们可以使用type关键字构造很多自定义类型,而`种类(Kind)`就是指底层的类型,但在反射中,当需要区分指针、结构体等大品种的类型时,就会用到`种类(Kind)`。 举个例子,我们定义了两个指针类型和两个结构体类型,通过反射查看它们的类型和种类。 + +```go +package main + +import ( + "fmt" + "reflect" +) + +type myInt int64 + +func reflectType(x interface{}) { + t := reflect.TypeOf(x) + fmt.Printf("type:%v kind:%v\n", t.Name(), t.Kind()) +} + +func main() { + var a *float32 // 指针 + var b myInt // 自定义类型 + var c rune // 类型别名 + reflectType(a) // type: kind:ptr + reflectType(b) // type:myInt kind:int64 + reflectType(c) // type:int32 kind:int32 + + type person struct { + name string + age int + } + type book struct{ title string } + var d = person{ + name: "沙河小王子", + age: 18, + } + var e = book{title: "《跟小王子学Go语言》"} + reflectType(d) // type:person kind:struct + reflectType(e) // type:book kind:struct +} +``` + +Go语言的反射中像数组、切片、Map、指针等类型的变量,它们的`.Name()`都是返回`空`。 + +在`reflect`包中定义的Kind类型如下: + +```go +type Kind uint +const ( + Invalid Kind = iota // 非法类型 + Bool // 布尔型 + Int // 有符号整型 + Int8 // 有符号8位整型 + Int16 // 有符号16位整型 + Int32 // 有符号32位整型 + Int64 // 有符号64位整型 + Uint // 无符号整型 + Uint8 // 无符号8位整型 + Uint16 // 无符号16位整型 + Uint32 // 无符号32位整型 + Uint64 // 无符号64位整型 + Uintptr // 指针 + Float32 // 单精度浮点数 + Float64 // 双精度浮点数 + Complex64 // 64位复数类型 + Complex128 // 128位复数类型 + Array // 数组 + Chan // 通道 + Func // 函数 + Interface // 接口 + Map // 映射 + Ptr // 指针 + Slice // 切片 + String // 字符串 + Struct // 结构体 + UnsafePointer // 底层指针 +) +``` + +## ValueOf + +`reflect.ValueOf()`返回的是`reflect.Value`类型,其中包含了原始值的值信息。`reflect.Value`与原始值之间可以互相转换。 + +`reflect.Value`类型提供的获取原始值的方法如下: + +| 方法 | 说明 | +| :----------------------: | :----------------------------------------------------------: | +| Interface() interface {} | 将值以 interface{} 类型返回,可以通过类型断言转换为指定类型 | +| Int() int64 | 将值以 int 类型返回,所有有符号整型均可以此方式返回 | +| Uint() uint64 | 将值以 uint 类型返回,所有无符号整型均可以此方式返回 | +| Float() float64 | 将值以双精度(float64)类型返回,所有浮点数(float32、float64)均可以此方式返回 | +| Bool() bool | 将值以 bool 类型返回 | +| Bytes() []bytes | 将值以字节数组 []bytes 类型返回 | +| String() string | 将值以字符串类型返回 | + +## 通过反射获取值 + +```go +func reflectValue(x interface{}) { + v := reflect.ValueOf(x) + k := v.Kind() + switch k { + case reflect.Int64: + // v.Int()从反射中获取整型的原始值,然后通过int64()强制类型转换 + fmt.Printf("type is int64, value is %d\n", int64(v.Int())) + case reflect.Float32: + // v.Float()从反射中获取浮点型的原始值,然后通过float32()强制类型转换 + fmt.Printf("type is float32, value is %f\n", float32(v.Float())) + case reflect.Float64: + // v.Float()从反射中获取浮点型的原始值,然后通过float64()强制类型转换 + fmt.Printf("type is float64, value is %f\n", float64(v.Float())) + } +} +func main() { + var a float32 = 3.14 + var b int64 = 100 + reflectValue(a) // type is float32, value is 3.140000 + reflectValue(b) // type is int64, value is 100 + // 将int类型的原始值转换为reflect.Value类型 + c := reflect.ValueOf(10) + fmt.Printf("type c :%T\n", c) // type c :reflect.Value +} +``` + +## 通过反射设置变量的值 + +想要在函数中通过反射修改变量的值,需要注意函数参数传递的是值拷贝,必须传递变量地址才能修改变量值。而反射中使用专有的`Elem()`方法来获取指针对应的值。 + +```go +package main + +import ( + "fmt" + "reflect" +) + +func reflectSetValue1(x interface{}) { + v := reflect.ValueOf(x) + if v.Kind() == reflect.Int64 { + v.SetInt(200) //修改的是副本,reflect包会引发panic + } +} +func reflectSetValue2(x interface{}) { + v := reflect.ValueOf(x) + // 反射中使用 Elem()方法获取指针对应的值 + if v.Elem().Kind() == reflect.Int64 { + v.Elem().SetInt(200) + } +} +func main() { + var a int64 = 100 + // reflectSetValue1(a) //panic: reflect: reflect.Value.SetInt using unaddressable value + reflectSetValue2(&a) + fmt.Println(a) +} +``` + +## isNil()和isValid() + +### isNil() + +```go +func (v Value) IsNil() bool +``` + +`IsNil()`报告v持有的值是否为nil。v持有的值的分类必须是通道、函数、接口、映射、指针、切片之一;否则IsNil函数会导致panic。 + +### isValid() + +```go +func (v Value) IsValid() bool +``` + +`IsValid()`返回v是否持有一个值。如果v是Value零值会返回假,此时v除了IsValid、String、Kind之外的方法都会导致panic。 + +### 举个例子 + +`IsNil()`常被用于判断指针是否为空;`IsValid()`常被用于判定返回值是否有效。 + +```go +func main() { + // *int类型空指针 + var a *int + fmt.Println("var a *int IsNil:", reflect.ValueOf(a).IsNil()) + // nil值 + fmt.Println("nil IsValid:", reflect.ValueOf(nil).IsValid()) + // 实例化一个匿名结构体 + b := struct{}{} + // 尝试从结构体中查找"abc"字段 + fmt.Println("不存在的结构体成员:", reflect.ValueOf(b).FieldByName("abc").IsValid()) + // 尝试从结构体中查找"abc"方法 + fmt.Println("不存在的结构体方法:", reflect.ValueOf(b).MethodByName("abc").IsValid()) + // map + c := map[string]int{} + // 尝试从map中查找一个不存在的键 + fmt.Println("map中不存在的键:", reflect.ValueOf(c).MapIndex(reflect.ValueOf("娜扎")).IsValid()) +} +``` + +## 结构体反射 + +### 与结构体相关的方法 + +任意值通过`reflect.TypeOf()`获得反射对象信息后,如果它的类型是结构体,可以通过反射值对象(`reflect.Type`)的`NumField()`和`Field()`方法获得结构体成员的详细信息。 + +`reflect.Type`中与获取结构体成员相关的的方法如下表所示。 + +| 方法 | 说明 | +| :---------------------------------------------------------: | :----------------------------------------------------------: | +| Field(i int) StructField | 根据索引,返回索引对应的结构体字段的信息。 | +| NumField() int | 返回结构体成员字段数量。 | +| FieldByName(name string) (StructField, bool) | 根据给定字符串返回字符串对应的结构体字段的信息。 | +| FieldByIndex(index []int) StructField | 多层成员访问时,根据 []int 提供的每个结构体的字段索引,返回字段的信息。 | +| FieldByNameFunc(match func(string) bool) (StructField,bool) | 根据传入的匹配函数匹配需要的字段。 | +| NumMethod() int | 返回该类型的方法集中方法的数目 | +| Method(int) Method | 返回该类型方法集中的第i个方法 | +| MethodByName(string)(Method, bool) | 根据方法名返回该类型方法集中的方法 | + +### StructField类型 + +`StructField`类型用来描述结构体中的一个字段的信息。 + +`StructField`的定义如下: + +```go +type StructField struct { + // Name是字段的名字。PkgPath是非导出字段的包路径,对导出字段该字段为""。 + // 参见http://golang.org/ref/spec#Uniqueness_of_identifiers + Name string + PkgPath string + Type Type // 字段的类型 + Tag StructTag // 字段的标签 + Offset uintptr // 字段在结构体中的字节偏移量 + Index []int // 用于Type.FieldByIndex时的索引切片 + Anonymous bool // 是否匿名字段 +} +``` + +### 结构体反射示例 + +当我们使用反射得到一个结构体数据之后可以通过索引依次获取其字段信息,也可以通过字段名去获取指定的字段信息。 + +```go +type student struct { + Name string `json:"name"` + Score int `json:"score"` +} + +func main() { + stu1 := student{ + Name: "小王子", + Score: 90, + } + + t := reflect.TypeOf(stu1) + fmt.Println(t.Name(), t.Kind()) // student struct + // 通过for循环遍历结构体的所有字段信息 + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + fmt.Printf("name:%s index:%d type:%v json tag:%v\n", field.Name, field.Index, field.Type, field.Tag.Get("json")) + } + + // 通过字段名获取指定结构体字段信息 + if scoreField, ok := t.FieldByName("Score"); ok { + fmt.Printf("name:%s index:%d type:%v json tag:%v\n", scoreField.Name, scoreField.Index, scoreField.Type, scoreField.Tag.Get("json")) + } +} +``` + +接下来编写一个函数`printMethod(s interface{})`来遍历打印s包含的方法。 + +```go +// 给student添加两个方法 Study和Sleep(注意首字母大写) +func (s student) Study() string { + msg := "好好学习,天天向上。" + fmt.Println(msg) + return msg +} + +func (s student) Sleep() string { + msg := "好好睡觉,快快长大。" + fmt.Println(msg) + return msg +} + +func printMethod(x interface{}) { + t := reflect.TypeOf(x) + v := reflect.ValueOf(x) + + fmt.Println(t.NumMethod()) + for i := 0; i < v.NumMethod(); i++ { + methodType := v.Method(i).Type() + fmt.Printf("method name:%s\n", t.Method(i).Name) + fmt.Printf("method:%s\n", methodType) + // 通过反射调用方法传递的参数必须是 []reflect.Value 类型 + var args = []reflect.Value{} + v.Method(i).Call(args) + } +} +``` + +## 反射是把双刃剑 + +反射是一个强大并富有表现力的工具,能让我们写出更灵活的代码。但是反射不应该被滥用,原因有以下三个。 + +1. 基于反射的代码是极其脆弱的,反射中的类型错误会在真正运行的时候才会引发panic,那很可能是在代码写完的很长时间之后。 +2. 大量使用反射的代码通常难以理解。 +3. 反射的性能低下,基于反射实现的代码通常比正常代码运行速度慢一到两个数量级 + +## 练习题 + +编写代码利用反射实现一个ini文件的解析器程序 + +首先有一个ini文件 + +```ini +[mysql] +address=127.0.0.1 +port=3306 +username=root +password=root +``` + +然后再是一个加载配置的函数,init.go + +```go +package main + +import ( + "fmt" + "reflect" +) + +// ini配置文件解析器 + +// MysqlConfig MySQL配置结构体 +type MysqlConfig struct { + Address string `ini:"address"` + Port int `ini:"port"` + Username string `ini:"username"` + Password string `ini:"password"` +} + +func loadIni(x interface{}) { + v := reflect.ValueOf(x) + fmt.Println(v) +} + +func main() { + var mc MysqlConfig + loadIni(&mc) + fmt.Println(mc.Address, mc.Port, mc.Username, mc.Password) +} +``` + diff --git "a/Golang/Golang\350\277\233\351\230\266/9_\345\215\225\345\205\203\346\265\213\350\257\225/README.md" "b/Golang/Golang\350\277\233\351\230\266/9_\345\215\225\345\205\203\346\265\213\350\257\225/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a62aea308e0d7b03ca94d770893c4c18ff0431ae --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/9_\345\215\225\345\205\203\346\265\213\350\257\225/README.md" @@ -0,0 +1,807 @@ +# 单元测试 + +## 来源 + +单元测试:https://www.liwenzhou.com/posts/Go/16_test/ + +性能测试:https://www.liwenzhou.com/posts/Go/performance_optimisation/ + +## 前言 + +不写测试的开发不是好程序员。我个人非常崇尚TDD(Test Driven Development)的,然而可惜的是国内的程序员都不太关注测试这一部分。 这篇文章主要介绍下在Go语言中如何做单元测试和基准测试。 + +## Go test工具 + +Go语言中的测试依赖`go test`命令。编写测试代码和编写普通的Go代码过程是类似的,并不需要学习新的语法、规则或工具。 + +go test命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内,所有以`_test.go`为后缀名的源代码文件都是`go test`测试的一部分,不会被`go build`编译到最终的可执行文件中。 + +在`*_test.go`文件中有三种类型的函数,单元测试函数、基准测试函数和示例函数。 + +| 类型 | 格式 | 作用 | +| :------: | :-------------------: | :----------------------------: | +| 测试函数 | 函数名前缀为Test | 测试程序的一些逻辑行为是否正确 | +| 基准函数 | 函数名前缀为Benchmark | 测试函数的性能 | +| 示例函数 | 函数名前缀为Example | 为文档提供示例文档 | + +`go test`命令会遍历所有的`*_test.go`文件中符合上述命名规则的函数,然后生成一个临时的main包用于调用相应的测试函数,然后构建并运行、报告测试结果,最后清理测试中生成的临时文件。 + +## 测试函数的格式 + +每个测试函数必须导入`testing`包,测试函数的基本格式(签名)如下: + +```go +func TestName(t *testing.T){ + // ... +} +``` + +测试函数的名字必须以`Test`开头,可选的后缀名必须以大写字母开头,举几个例子: + +```go +func TestAdd(t *testing.T){ ... } +func TestSum(t *testing.T){ ... } +func TestLog(t *testing.T){ ... } +``` + +其中参数`t`用于报告测试失败和附加的日志信息。 `testing.T`的拥有的方法如下: + +```go +func (c *T) Error(args ...interface{}) +func (c *T) Errorf(format string, args ...interface{}) +func (c *T) Fail() +func (c *T) FailNow() +func (c *T) Failed() bool +func (c *T) Fatal(args ...interface{}) +func (c *T) Fatalf(format string, args ...interface{}) +func (c *T) Log(args ...interface{}) +func (c *T) Logf(format string, args ...interface{}) +func (c *T) Name() string +func (t *T) Parallel() +func (t *T) Run(name string, f func(t *T)) bool +func (c *T) Skip(args ...interface{}) +func (c *T) SkipNow() +func (c *T) Skipf(format string, args ...interface{}) +func (c *T) Skipped() bool +``` + +## 测试函数示例 + +就像细胞是构成我们身体的基本单位,一个软件程序也是由很多单元组件构成的。单元组件可以是函数、结构体、方法和最终用户可能依赖的任意东西。总之我们需要确保这些组件是能够正常运行的。单元测试是一些利用各种方法测试单元组件的程序,它会将结果与预期输出进行比较。 + +接下来,我们定义一个`split`的包,包中定义了一个`Split`函数,具体实现如下: + +```go +// split/split.go + +package split + +import "strings" + +// split package with a single split function. + +// Split slices s into all substrings separated by sep and +// returns a slice of the substrings between those separators. +func Split(s, sep string) (result []string) { + i := strings.Index(s, sep) + + for i > -1 { + result = append(result, s[:i]) + s = s[i+1:] + i = strings.Index(s, sep) + } + result = append(result, s) + return +} +``` + +在当前目录下,我们创建一个`split_test.go`的测试文件,并定义一个测试函数如下: + +```go +// split/split_test.go + +package split + +import ( + "reflect" + "testing" +) + +func TestSplit(t *testing.T) { // 测试函数名必须以Test开头,必须接收一个*testing.T类型参数 + got := Split("a:b:c", ":") // 程序输出的结果 + want := []string{"a", "b", "c"} // 期望的结果 + if !reflect.DeepEqual(want, got) { // 因为slice不能比较直接,借助反射包中的方法比较 + t.Errorf("excepted:%v, got:%v", want, got) // 测试失败输出错误提示 + } +} +``` + +此时`split`这个包中的文件如下: + +```bash +split $ ls -l +total 16 +-rw-r--r-- 1 liwenzhou staff 408 4 29 15:50 split.go +-rw-r--r-- 1 liwenzhou staff 466 4 29 16:04 split_test.go +``` + +在`split`包路径下,执行`go test`命令,可以看到输出结果如下: + +```bash +split $ go test +PASS +ok github.com/Q1mi/studygo/code_demo/test_demo/split 0.005s +``` + +一个测试用例有点单薄,我们再编写一个测试使用多个字符切割字符串的例子,在`split_test.go`中添加如下测试函数: + +```go +func TestMoreSplit(t *testing.T) { + got := Split("abcd", "bc") + want := []string{"a", "d"} + if !reflect.DeepEqual(want, got) { + t.Errorf("excepted:%v, got:%v", want, got) + } +} +``` + +再次运行`go test`命令,输出结果如下: + +```bash +split $ go test +--- FAIL: TestMultiSplit (0.00s) + split_test.go:20: excepted:[a d], got:[a cd] +FAIL +exit status 1 +FAIL github.com/Q1mi/studygo/code_demo/test_demo/split 0.006s +``` + +这一次,我们的测试失败了。我们可以为`go test`命令添加`-v`参数,查看测试函数名称和运行时间: + +```bash +split $ go test -v +=== RUN TestSplit +--- PASS: TestSplit (0.00s) +=== RUN TestMoreSplit +--- FAIL: TestMoreSplit (0.00s) + split_test.go:21: excepted:[a d], got:[a cd] +FAIL +exit status 1 +FAIL github.com/Q1mi/studygo/code_demo/test_demo/split 0.005s +``` + +这一次我们能清楚的看到是`TestMoreSplit`这个测试没有成功。 还可以在`go test`命令后添加`-run`参数,它对应一个正则表达式,只有函数名匹配上的测试函数才会被`go test`命令执行。 + +```bash +split $ go test -v -run="More" +=== RUN TestMoreSplit +--- FAIL: TestMoreSplit (0.00s) + split_test.go:21: excepted:[a d], got:[a cd] +FAIL +exit status 1 +FAIL github.com/Q1mi/studygo/code_demo/test_demo/split 0.006s +``` + +现在我们回过头来解决我们程序中的问题。很显然我们最初的`split`函数并没有考虑到sep为多个字符的情况,我们来修复下这个Bug: + +```go +package split + +import "strings" + +// split package with a single split function. + +// Split slices s into all substrings separated by sep and +// returns a slice of the substrings between those separators. +func Split(s, sep string) (result []string) { + i := strings.Index(s, sep) + + for i > -1 { + result = append(result, s[:i]) + s = s[i+len(sep):] // 这里使用len(sep)获取sep的长度 + i = strings.Index(s, sep) + } + result = append(result, s) + return +} +``` + +这一次我们再来测试一下,我们的程序。注意,当我们修改了我们的代码之后不要仅仅执行那些失败的测试函数,我们应该完整的运行所有的测试,保证不会因为修改代码而引入了新的问题。 + +```bash +split $ go test -v +=== RUN TestSplit +--- PASS: TestSplit (0.00s) +=== RUN TestMoreSplit +--- PASS: TestMoreSplit (0.00s) +PASS +ok github.com/Q1mi/studygo/code_demo/test_demo/split 0.006s +``` + +这一次我们的测试都通过了。 + +## 测试组 + +我们现在还想要测试一下`split`函数对中文字符串的支持,这个时候我们可以再编写一个`TestChineseSplit`测试函数,但是我们也可以使用如下更友好的一种方式来添加更多的测试用例。 + +```go +func TestSplit(t *testing.T) { + // 定义一个测试用例类型 + type test struct { + input string + sep string + want []string + } + // 定义一个存储测试用例的切片 + tests := []test{ + {input: "a:b:c", sep: ":", want: []string{"a", "b", "c"}}, + {input: "a:b:c", sep: ",", want: []string{"a:b:c"}}, + {input: "abcd", sep: "bc", want: []string{"a", "d"}}, + {input: "沙河有沙又有河", sep: "沙", want: []string{"河有", "又有河"}}, + } + // 遍历切片,逐一执行测试用例 + for _, tc := range tests { + got := Split(tc.input, tc.sep) + if !reflect.DeepEqual(got, tc.want) { + t.Errorf("excepted:%v, got:%v", tc.want, got) + } + } +} +``` + +我们通过上面的代码把多个测试用例合到一起,再次执行`go test`命令。 + +```bash +split $ go test -v +=== RUN TestSplit +--- FAIL: TestSplit (0.00s) + split_test.go:42: excepted:[河有 又有河], got:[ 河有 又有河] +FAIL +exit status 1 +FAIL github.com/Q1mi/studygo/code_demo/test_demo/split 0.006s +``` + +我们的测试出现了问题,仔细看打印的测试失败提示信息:`excepted:[河有 又有河], got:[ 河有 又有河]`,你会发现`[ 河有 又有河]`中有个不明显的空串,这种情况下十分推荐使用`%#v`的格式化方式。 + +我们修改下测试用例的格式化输出错误提示部分: + +```go +func TestSplit(t *testing.T) { + ... + + for _, tc := range tests { + got := Split(tc.input, tc.sep) + if !reflect.DeepEqual(got, tc.want) { + t.Errorf("excepted:%#v, got:%#v", tc.want, got) + } + } +} +``` + +此时运行`go test`命令后就能看到比较明显的提示信息了: + +```bash +split $ go test -v +=== RUN TestSplit +--- FAIL: TestSplit (0.00s) + split_test.go:42: excepted:[]string{"河有", "又有河"}, got:[]string{"", "河有", "又有河"} +FAIL +exit status 1 +FAIL github.com/Q1mi/studygo/code_demo/test_demo/split 0.006s +``` + +## 子测试 + +看起来都挺不错的,但是如果测试用例比较多的时候,我们是没办法一眼看出来具体是哪个测试用例失败了。我们可能会想到下面的解决办法: + +```go +func TestSplit(t *testing.T) { + type test struct { // 定义test结构体 + input string + sep string + want []string + } + tests := map[string]test{ // 测试用例使用map存储 + "simple": {input: "a:b:c", sep: ":", want: []string{"a", "b", "c"}}, + "wrong sep": {input: "a:b:c", sep: ",", want: []string{"a:b:c"}}, + "more sep": {input: "abcd", sep: "bc", want: []string{"a", "d"}}, + "leading sep": {input: "沙河有沙又有河", sep: "沙", want: []string{"河有", "又有河"}}, + } + for name, tc := range tests { + got := Split(tc.input, tc.sep) + if !reflect.DeepEqual(got, tc.want) { + t.Errorf("name:%s excepted:%#v, got:%#v", name, tc.want, got) // 将测试用例的name格式化输出 + } + } +} +``` + +上面的做法是能够解决问题的。同时Go1.7+中新增了子测试,我们可以按照如下方式使用`t.Run`执行子测试: + +```go +func TestSplit(t *testing.T) { + type test struct { // 定义test结构体 + input string + sep string + want []string + } + tests := map[string]test{ // 测试用例使用map存储 + "simple": {input: "a:b:c", sep: ":", want: []string{"a", "b", "c"}}, + "wrong sep": {input: "a:b:c", sep: ",", want: []string{"a:b:c"}}, + "more sep": {input: "abcd", sep: "bc", want: []string{"a", "d"}}, + "leading sep": {input: "沙河有沙又有河", sep: "沙", want: []string{"河有", "又有河"}}, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { // 使用t.Run()执行子测试 + got := Split(tc.input, tc.sep) + if !reflect.DeepEqual(got, tc.want) { + t.Errorf("excepted:%#v, got:%#v", tc.want, got) + } + }) + } +} +``` + +此时我们再执行`go test`命令就能够看到更清晰的输出内容了: + +```bash +split $ go test -v +=== RUN TestSplit +=== RUN TestSplit/leading_sep +=== RUN TestSplit/simple +=== RUN TestSplit/wrong_sep +=== RUN TestSplit/more_sep +--- FAIL: TestSplit (0.00s) + --- FAIL: TestSplit/leading_sep (0.00s) + split_test.go:83: excepted:[]string{"河有", "又有河"}, got:[]string{"", "河有", "又有河"} + --- PASS: TestSplit/simple (0.00s) + --- PASS: TestSplit/wrong_sep (0.00s) + --- PASS: TestSplit/more_sep (0.00s) +FAIL +exit status 1 +FAIL github.com/Q1mi/studygo/code_demo/test_demo/split 0.006s +``` + +这个时候我们要把测试用例中的错误修改回来: + +```go +func TestSplit(t *testing.T) { + ... + tests := map[string]test{ // 测试用例使用map存储 + "simple": {input: "a:b:c", sep: ":", want: []string{"a", "b", "c"}}, + "wrong sep": {input: "a:b:c", sep: ",", want: []string{"a:b:c"}}, + "more sep": {input: "abcd", sep: "bc", want: []string{"a", "d"}}, + "leading sep": {input: "沙河有沙又有河", sep: "沙", want: []string{"", "河有", "又有河"}}, + } + ... +} +``` + +我们都知道可以通过`-run=RegExp`来指定运行的测试用例,还可以通过`/`来指定要运行的子测试用例, + +例如:`go test -v -run=Split/simple` 只会运行`simple`对应的子测试用例。 + +## 测试覆盖率 + +测试覆盖率是你的代码被测试套件覆盖的百分比。通常我们使用的都是语句的覆盖率,也就是在测试中至少被运行一次的代码占总代码的比例。 + +Go提供内置功能来检查你的代码覆盖率。我们可以使用`go test -cover`来查看测试覆盖率。例如: + +```bash +split $ go test -cover +PASS +coverage: 100.0% of statements +ok github.com/Q1mi/studygo/code_demo/test_demo/split 0.005s +``` + +从上面的结果可以看到我们的测试用例覆盖了100%的代码。 + +Go还提供了一个额外的`-coverprofile`参数,用来将覆盖率相关的记录信息输出到一个文件。例如: + +```bash +split $ go test -cover -coverprofile=c.out +PASS +coverage: 100.0% of statements +ok github.com/Q1mi/studygo/code_demo/test_demo/split 0.005s +``` + +上面的命令会将覆盖率相关的信息输出到当前文件夹下面的`c.out`文件中,然后我们执行`go tool cover -html=c.out`,使用`cover`工具来处理生成的记录信息,该命令会打开本地的浏览器窗口生成一个HTML报告。![Go test cover](images/cover.png)上图中每个用绿色标记的语句块表示被覆盖了,而红色的表示没有被覆盖。 + +# 基准测试 + +## 基准测试函数格式 + +基准测试就是在一定的工作负载之下检测程序性能的一种方法。基准测试的基本格式如下: + +```go +func BenchmarkName(b *testing.B){ + // ... +} +``` + +基准测试以`Benchmark`为前缀,需要一个`*testing.B`类型的参数b,基准测试必须要执行`b.N`次,这样的测试才有对照性,`b.N`的值是系统根据实际情况去调整的,从而保证测试的稳定性。 `testing.B`拥有的方法如下: + +```go +func (c *B) Error(args ...interface{}) +func (c *B) Errorf(format string, args ...interface{}) +func (c *B) Fail() +func (c *B) FailNow() +func (c *B) Failed() bool +func (c *B) Fatal(args ...interface{}) +func (c *B) Fatalf(format string, args ...interface{}) +func (c *B) Log(args ...interface{}) +func (c *B) Logf(format string, args ...interface{}) +func (c *B) Name() string +func (b *B) ReportAllocs() +func (b *B) ResetTimer() +func (b *B) Run(name string, f func(b *B)) bool +func (b *B) RunParallel(body func(*PB)) +func (b *B) SetBytes(n int64) +func (b *B) SetParallelism(p int) +func (c *B) Skip(args ...interface{}) +func (c *B) SkipNow() +func (c *B) Skipf(format string, args ...interface{}) +func (c *B) Skipped() bool +func (b *B) StartTimer() +func (b *B) StopTimer() +``` + +## 基准测试示例 + +我们为split包中的`Split`函数编写基准测试如下: + +```go +func BenchmarkSplit(b *testing.B) { + for i := 0; i < b.N; i++ { + Split("沙河有沙又有河", "沙") + } +} +``` + +基准测试并不会默认执行,需要增加`-bench`参数,所以我们通过执行`go test -bench=Split`命令执行基准测试,输出结果如下: + +```bash +split $ go test -bench=Split +goos: darwin +goarch: amd64 +pkg: github.com/Q1mi/studygo/code_demo/test_demo/split +BenchmarkSplit-8 10000000 203 ns/op +PASS +ok github.com/Q1mi/studygo/code_demo/test_demo/split 2.255s +``` + +其中`BenchmarkSplit-8`表示对Split函数进行基准测试,数字`8`表示`GOMAXPROCS`的值,这个对于并发基准测试很重要。`10000000`和`203ns/op`表示每次调用`Split`函数耗时`203ns`,这个结果是`10000000`次调用的平均值。 + +我们还可以为基准测试添加`-benchmem`参数,来获得内存分配的统计数据。 + +```bash +split $ go test -bench=Split -benchmem +goos: darwin +goarch: amd64 +pkg: github.com/Q1mi/studygo/code_demo/test_demo/split +BenchmarkSplit-8 10000000 215 ns/op 112 B/op 3 allocs/op +PASS +ok github.com/Q1mi/studygo/code_demo/test_demo/split 2.394s +``` + +其中,`112 B/op`表示每次操作内存分配了112字节,`3 allocs/op`则表示每次操作进行了3次内存分配。 我们将我们的`Split`函数优化如下: + +```go +func Split(s, sep string) (result []string) { + result = make([]string, 0, strings.Count(s, sep)+1) + i := strings.Index(s, sep) + for i > -1 { + result = append(result, s[:i]) + s = s[i+len(sep):] // 这里使用len(sep)获取sep的长度 + i = strings.Index(s, sep) + } + result = append(result, s) + return +} +``` + +这一次我们提前使用make函数将result初始化为一个容量足够大的切片,而不再像之前一样通过调用append函数来追加。我们来看一下这个改进会带来多大的性能提升: + +```bash +split $ go test -bench=Split -benchmem +goos: darwin +goarch: amd64 +pkg: github.com/Q1mi/studygo/code_demo/test_demo/split +BenchmarkSplit-8 10000000 127 ns/op 48 B/op 1 allocs/op +PASS +ok github.com/Q1mi/studygo/code_demo/test_demo/split 1.423s +``` + +这个使用make函数提前分配内存的改动,减少了2/3的内存分配次数,并且减少了一半的内存分配。 + +## 性能比较函数 + +上面的基准测试只能得到给定操作的绝对耗时,但是在很多性能问题是发生在两个不同操作之间的相对耗时,比如同一个函数处理1000个元素的耗时与处理1万甚至100万个元素的耗时的差别是多少?再或者对于同一个任务究竟使用哪种算法性能最佳?我们通常需要对两个不同算法的实现使用相同的输入来进行基准比较测试。 + +性能比较函数通常是一个带有参数的函数,被多个不同的Benchmark函数传入不同的值来调用。举个例子如下: + +```go +func benchmark(b *testing.B, size int){/* ... */} +func Benchmark10(b *testing.B){ benchmark(b, 10) } +func Benchmark100(b *testing.B){ benchmark(b, 100) } +func Benchmark1000(b *testing.B){ benchmark(b, 1000) } +``` + +例如我们编写了一个计算斐波那契数列的函数如下: + +```go +// fib.go + +// Fib 是一个计算第n个斐波那契数的函数 +func Fib(n int) int { + if n < 2 { + return n + } + return Fib(n-1) + Fib(n-2) +} +``` + +我们编写的性能比较函数如下: + +```go +// fib_test.go + +func benchmarkFib(b *testing.B, n int) { + for i := 0; i < b.N; i++ { + Fib(n) + } +} + +func BenchmarkFib1(b *testing.B) { benchmarkFib(b, 1) } +func BenchmarkFib2(b *testing.B) { benchmarkFib(b, 2) } +func BenchmarkFib3(b *testing.B) { benchmarkFib(b, 3) } +func BenchmarkFib10(b *testing.B) { benchmarkFib(b, 10) } +func BenchmarkFib20(b *testing.B) { benchmarkFib(b, 20) } +func BenchmarkFib40(b *testing.B) { benchmarkFib(b, 40) } +``` + +运行基准测试: + +```bash +split $ go test -bench=. +goos: darwin +goarch: amd64 +pkg: github.com/Q1mi/studygo/code_demo/test_demo/fib +BenchmarkFib1-8 1000000000 2.03 ns/op +BenchmarkFib2-8 300000000 5.39 ns/op +BenchmarkFib3-8 200000000 9.71 ns/op +BenchmarkFib10-8 5000000 325 ns/op +BenchmarkFib20-8 30000 42460 ns/op +BenchmarkFib40-8 2 638524980 ns/op +PASS +ok github.com/Q1mi/studygo/code_demo/test_demo/fib 12.944s +``` + +这里需要注意的是,默认情况下,每个基准测试至少运行1秒。如果在Benchmark函数返回时没有到1秒,则b.N的值会按1,2,5,10,20,50,…增加,并且函数再次运行。 + +最终的BenchmarkFib40只运行了两次,每次运行的平均值只有不到一秒。像这种情况下我们应该可以使用`-benchtime`标志增加最小基准时间,以产生更准确的结果。例如: + +```bash +split $ go test -bench=Fib40 -benchtime=20s +goos: darwin +goarch: amd64 +pkg: github.com/Q1mi/studygo/code_demo/test_demo/fib +BenchmarkFib40-8 50 663205114 ns/op +PASS +ok github.com/Q1mi/studygo/code_demo/test_demo/fib 33.849s +``` + +这一次`BenchmarkFib40`函数运行了50次,结果就会更准确一些了。 + +使用性能比较函数做测试的时候一个容易犯的错误就是把`b.N`作为输入的大小,例如以下两个例子都是错误的示范: + +```go +// 错误示范1 +func BenchmarkFibWrong(b *testing.B) { + for n := 0; n < b.N; n++ { + Fib(n) + } +} + +// 错误示范2 +func BenchmarkFibWrong2(b *testing.B) { + Fib(b.N) +} +``` + +## 重置时间 + +`b.ResetTimer`之前的处理不会放到执行时间里,也不会输出到报告中,所以可以在之前做一些不计划作为测试报告的操作。例如: + +```go +func BenchmarkSplit(b *testing.B) { + time.Sleep(5 * time.Second) // 假设需要做一些耗时的无关操作 + b.ResetTimer() // 重置计时器 + for i := 0; i < b.N; i++ { + Split("沙河有沙又有河", "沙") + } +} +``` + +## 并行测试 + +`func (b *B) RunParallel(body func(*PB))`会以并行的方式执行给定的基准测试。 + +`RunParallel`会创建出多个`goroutine`,并将`b.N`分配给这些`goroutine`执行, 其中`goroutine`数量的默认值为`GOMAXPROCS`。用户如果想要增加非CPU受限(non-CPU-bound)基准测试的并行性, 那么可以在`RunParallel`之前调用`SetParallelism` 。`RunParallel`通常会与`-cpu`标志一同使用。 + +```go +func BenchmarkSplitParallel(b *testing.B) { + // b.SetParallelism(1) // 设置使用的CPU数 + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + Split("沙河有沙又有河", "沙") + } + }) +} +``` + +执行一下基准测试: + +```bash +split $ go test -bench=. +goos: darwin +goarch: amd64 +pkg: github.com/Q1mi/studygo/code_demo/test_demo/split +BenchmarkSplit-8 10000000 131 ns/op +BenchmarkSplitParallel-8 50000000 36.1 ns/op +PASS +ok github.com/Q1mi/studygo/code_demo/test_demo/split 3.308s +``` + +还可以通过在测试命令后添加`-cpu`参数如`go test -bench=. -cpu 1`来指定使用的CPU数量。 + +# Setup与TearDown + +测试程序有时需要在测试之前进行额外的设置(setup)或在测试之后进行拆卸(teardown)。 + +## TestMain + +通过在`*_test.go`文件中定义`TestMain`函数来可以在测试之前进行额外的设置(setup)或在测试之后进行拆卸(teardown)操作。 + +如果测试文件包含函数:`func TestMain(m *testing.M)`那么生成的测试会先调用 TestMain(m),然后再运行具体测试。`TestMain`运行在主`goroutine`中, 可以在调用 `m.Run`前后做任何设置(setup)和拆卸(teardown)。退出测试的时候应该使用`m.Run`的返回值作为参数调用`os.Exit`。 + +一个使用`TestMain`来设置Setup和TearDown的示例如下: + +```go +func TestMain(m *testing.M) { + fmt.Println("write setup code here...") // 测试之前的做一些设置 + // 如果 TestMain 使用了 flags,这里应该加上flag.Parse() + retCode := m.Run() // 执行测试 + fmt.Println("write teardown code here...") // 测试之后做一些拆卸工作 + os.Exit(retCode) // 退出测试 +} +``` + +需要注意的是:在调用`TestMain`时, `flag.Parse`并没有被调用。所以如果`TestMain` 依赖于command-line标志 (包括 testing 包的标记), 则应该显示的调用`flag.Parse`。 + +## 子测试的Setup与Teardown + +有时候我们可能需要为每个测试集设置Setup与Teardown,也有可能需要为每个子测试设置Setup与Teardown。下面我们定义两个函数工具函数如下: + +```go +// 测试集的Setup与Teardown +func setupTestCase(t *testing.T) func(t *testing.T) { + t.Log("如有需要在此执行:测试之前的setup") + return func(t *testing.T) { + t.Log("如有需要在此执行:测试之后的teardown") + } +} + +// 子测试的Setup与Teardown +func setupSubTest(t *testing.T) func(t *testing.T) { + t.Log("如有需要在此执行:子测试之前的setup") + return func(t *testing.T) { + t.Log("如有需要在此执行:子测试之后的teardown") + } +} +``` + +使用方式如下: + +```go +func TestSplit(t *testing.T) { + type test struct { // 定义test结构体 + input string + sep string + want []string + } + tests := map[string]test{ // 测试用例使用map存储 + "simple": {input: "a:b:c", sep: ":", want: []string{"a", "b", "c"}}, + "wrong sep": {input: "a:b:c", sep: ",", want: []string{"a:b:c"}}, + "more sep": {input: "abcd", sep: "bc", want: []string{"a", "d"}}, + "leading sep": {input: "沙河有沙又有河", sep: "沙", want: []string{"", "河有", "又有河"}}, + } + teardownTestCase := setupTestCase(t) // 测试之前执行setup操作 + defer teardownTestCase(t) // 测试之后执行testdoen操作 + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { // 使用t.Run()执行子测试 + teardownSubTest := setupSubTest(t) // 子测试之前执行setup操作 + defer teardownSubTest(t) // 测试之后执行testdoen操作 + got := Split(tc.input, tc.sep) + if !reflect.DeepEqual(got, tc.want) { + t.Errorf("excepted:%#v, got:%#v", tc.want, got) + } + }) + } +} +``` + +测试结果如下: + +```bash +split $ go test -v +=== RUN TestSplit +=== RUN TestSplit/simple +=== RUN TestSplit/wrong_sep +=== RUN TestSplit/more_sep +=== RUN TestSplit/leading_sep +--- PASS: TestSplit (0.00s) + split_test.go:71: 如有需要在此执行:测试之前的setup + --- PASS: TestSplit/simple (0.00s) + split_test.go:79: 如有需要在此执行:子测试之前的setup + split_test.go:81: 如有需要在此执行:子测试之后的teardown + --- PASS: TestSplit/wrong_sep (0.00s) + split_test.go:79: 如有需要在此执行:子测试之前的setup + split_test.go:81: 如有需要在此执行:子测试之后的teardown + --- PASS: TestSplit/more_sep (0.00s) + split_test.go:79: 如有需要在此执行:子测试之前的setup + split_test.go:81: 如有需要在此执行:子测试之后的teardown + --- PASS: TestSplit/leading_sep (0.00s) + split_test.go:79: 如有需要在此执行:子测试之前的setup + split_test.go:81: 如有需要在此执行:子测试之后的teardown + split_test.go:73: 如有需要在此执行:测试之后的teardown +=== RUN ExampleSplit +--- PASS: ExampleSplit (0.00s) +PASS +ok github.com/Q1mi/studygo/code_demo/test_demo/split 0.006s +``` + +# 示例函数 + +## 示例函数的格式 + +被`go test`特殊对待的第三种函数就是示例函数,它们的函数名以`Example`为前缀。它们既没有参数也没有返回值。标准格式如下: + +```go +func ExampleName() { + // ... +} +``` + +## 示例函数示例 + +下面的代码是我们为`Split`函数编写的一个示例函数: + +```go +func ExampleSplit() { + fmt.Println(split.Split("a:b:c", ":")) + fmt.Println(split.Split("沙河有沙又有河", "沙")) + // Output: + // [a b c] + // [ 河有 又有河] +} +``` + +为你的代码编写示例代码有如下三个用处: + +1. 示例函数能够作为文档直接使用,例如基于web的godoc中能把示例函数与对应的函数或包相关联。 + +2. 示例函数只要包含了`// Output:`也是可以通过`go test`运行的可执行测试。 + + ```bash + split $ go test -run Example + PASS + ok github.com/Q1mi/studygo/code_demo/test_demo/split 0.006s + ``` + +3. 示例函数提供了可以直接运行的示例代码,可以直接在`golang.org`的`godoc`文档服务器上使用`Go Playground`运行示例代码。下图为`strings.ToUpper`函数在Playground的示例函数效果。![Go Playground](images/example.png) + +# 练习题 + +1. 编写一个回文检测函数,并为其编写单元测试和基准测试,根据测试的结果逐步对其进行优化。(回文:一个字符串正序和逆序一样,如“Madam,I’mAdam”、“油灯少灯油”等。) \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/9_\345\215\225\345\205\203\346\265\213\350\257\225/images/cover.png" "b/Golang/Golang\350\277\233\351\230\266/9_\345\215\225\345\205\203\346\265\213\350\257\225/images/cover.png" new file mode 100644 index 0000000000000000000000000000000000000000..98cd6891ea4d2718f97205bff5d8a11ae5c19993 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/9_\345\215\225\345\205\203\346\265\213\350\257\225/images/cover.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/9_\345\215\225\345\205\203\346\265\213\350\257\225/images/example.png" "b/Golang/Golang\350\277\233\351\230\266/9_\345\215\225\345\205\203\346\265\213\350\257\225/images/example.png" new file mode 100644 index 0000000000000000000000000000000000000000..0ba888e5ca7273116044bdcb35ee172c7d389a0d Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/9_\345\215\225\345\205\203\346\265\213\350\257\225/images/example.png" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/.gitignore" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/.gitignore" new file mode 100644 index 0000000000000000000000000000000000000000..73f69e0958611ac6e00bde95641f6699030ad235 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/.gitignore" @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/GoAdvanceCode.iml" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/GoAdvanceCode.iml" new file mode 100644 index 0000000000000000000000000000000000000000..c956989b29ad0767edc6cf3a202545927c3d1e76 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/GoAdvanceCode.iml" @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/misc.xml" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/misc.xml" new file mode 100644 index 0000000000000000000000000000000000000000..28a804d8932aba40f168fd757a74cb718a955a1a --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/misc.xml" @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/modules.xml" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/modules.xml" new file mode 100644 index 0000000000000000000000000000000000000000..147d34e20ed8817c4164d34eda209c669ec1c9cd --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/modules.xml" @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/vcs.xml" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/vcs.xml" new file mode 100644 index 0000000000000000000000000000000000000000..c2365ab11f9ba6b763735c8fd976420234bb3521 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/.idea/vcs.xml" @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/10_OSFlagDemo/10_OSFlagDemo.exe" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/10_OSFlagDemo/10_OSFlagDemo.exe" new file mode 100644 index 0000000000000000000000000000000000000000..8fc880bd9c0e081fef03d86069a55ea9efbf7bde Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/10_OSFlagDemo/10_OSFlagDemo.exe" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/10_OSFlagDemo/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/10_OSFlagDemo/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..0f0faed417c2a350ffd31194c7aa61fc061f1be0 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/10_OSFlagDemo/main.go" @@ -0,0 +1,26 @@ +package main + +import ( + "flag" + "fmt" + "os" +) + +func main() { + // os.Args 获取命令行参数 + fmt.Println(os.Args) + params0 := os.Args[0] + params1 := os.Args[1] + fmt.Println(params0, params1) + + // 创建一个标志位参数 + name := flag.String("name", "张三", "请输入名字") + age := flag.Int("age", 18, "请输入年龄") + + // 使用flag + flag.Parse() + + // 根据地址获取信息 + fmt.Println(*name) + fmt.Println(*age) +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/10_split_string/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/10_split_string/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..f50e087223efb845d6bae466a6ad39f8dffc09a8 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/10_split_string/main.go" @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "strings" +) + +// 切割字符串 +func Split(str string, seq string)[]string { + + var ret [] string + index := strings.Index(str, seq) + for index > 0 { + ret = append(ret, str[:index]) + str = str[index+1:] + index = strings.Index(str, seq) + } + ret = append(ret, str) + return ret +} +func main() { + fmt.Println(Split("abcabcdba", "b")) +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/10_split_string/main_test.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/10_split_string/main_test.go" new file mode 100644 index 0000000000000000000000000000000000000000..0a2b8fe1abdf94889509a6e6de4445faa0019bdc --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/10_split_string/main_test.go" @@ -0,0 +1,17 @@ +package main + +import ( + "reflect" + "testing" +) + +func TestSplit(t *testing.T) { + ret := Split("abc", "b") + want := []string{"a", "c"} + // 判断期望结果和最后结果是否相同 + if !reflect.DeepEqual(ret, want) { + // 测试用例失败了 + t.Error("want: %v but got: %v", want, ret) + } + +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/11_MySQLDemo/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/11_MySQLDemo/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..a874bbdb7f150027012c7320a12ee3dd2ae5ab9e --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/11_MySQLDemo/main.go" @@ -0,0 +1,147 @@ +package main +import ( + "database/sql" + "fmt" + _"github.com/go-sql-driver/mysql" +) + +// 定义一个全局的DB,是一个连接池对象 +var db *sql.DB + +func initDB()(err error) { + // 连接数据库 + dsn := "root:root@tcp(127.0.0.1:3306)/mogu_demo" + + // 连接MySQL数据库(注意不能使用 := ) + db, err = sql.Open("mysql", dsn) + if err != nil { + fmt.Printf("open %s failed, err: %v \n", dsn, err) + return + } + + // 尝试连接数据库 + err = db.Ping() + if err != nil { + fmt.Printf("open %s failed, err: %v, \n", dsn, err) + return + } + // 设置数据库连接池的最大连接数 + db.SetMaxOpenConns(10) + // 设置最大空闲连接数 + db.SetMaxIdleConns(5) + + fmt.Println("连接数据库成功") + return +} + +type user struct { + id string + name string + age int +} + +// 查询单条数据示例 +func queryRowDemo() { + sqlStr := "select id, name, age from user where id=?" + var u user + // 非常重要:确保QueryRow之后调用Scan方法,否则持有的数据库链接不会被释放 + err := db.QueryRow(sqlStr, 1).Scan(&u.id, &u.name, &u.age) + if err != nil { + fmt.Printf("scan failed, err:%v\n", err) + return + } + fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age) +} + +// 查询操作 +func query(id int) { + sqlStr := "select id, name, age from user where id > ?" + rows, err := db.Query(sqlStr, id) + if err != nil { + fmt.Println() + fmt.Printf("query failed, err:%v\n", err) + return + } + // 非常重要:关闭rows释放持有的数据库链接,相当于丢到池子里面 + // 其它的对象才能够从对象中获取 + defer rows.Close() + + // 循环读取结果集中的数据 + for rows.Next() { + var u user + // 调用Scan才会释放我们的连接 + err := rows.Scan(&u.id, &u.name, &u.age) + if err != nil { + fmt.Printf("scan failed, err:%v\n", err) + return + } + fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age) + } +} + +// 插入数据 +func insertRowDemo(id int, userName string, age int) { + sqlStr := "insert into user(id, name, age) values (?,?,?)" + ret, err := db.Exec(sqlStr, id, userName, age) + if err != nil { + fmt.Printf("insert failed, err:%v\n", err) + return + } + theID, err := ret.LastInsertId() // 新插入数据的id + if err != nil { + fmt.Printf("get lastinsert ID failed, err:%v\n", err) + return + } + fmt.Printf("insert success, the id is %d.\n", theID) +} + +// 更新数据 +func updateRowDemo() { + sqlStr := "update user set age=? where id = ?" + ret, err := db.Exec(sqlStr, 39, 3) + if err != nil { + fmt.Printf("update failed, err:%v\n", err) + return + } + n, err := ret.RowsAffected() // 操作影响的行数 + if err != nil { + fmt.Printf("get RowsAffected failed, err:%v\n", err) + return + } + fmt.Printf("update success, affected rows:%d\n", n) +} + +// 删除数据 +func deleteRowDemo() { + sqlStr := "delete from user where id = ?" + ret, err := db.Exec(sqlStr, 3) + if err != nil { + fmt.Printf("delete failed, err:%v\n", err) + return + } + n, err := ret.RowsAffected() // 操作影响的行数 + if err != nil { + fmt.Printf("get RowsAffected failed, err:%v\n", err) + return + } + fmt.Printf("delete success, affected rows:%d\n", n) +} + +// Go连接MySQL +func main() { + err := initDB() + if err != nil { + fmt.Println("数据库初始化失败") + } + + // 查询单条语句 + queryRowDemo() + + // 插入数据 + insertRowDemo(4,"王五", 23) + + // 查询多条语句 + query(0) + + +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/13_RedisDemo/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/13_RedisDemo/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..341c6bf3ffbbf0a269d2af5df74af87ba06db755 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/13_RedisDemo/main.go" @@ -0,0 +1,85 @@ +package main + +import ( + "fmt" + "github.com/go-redis/redis" +) + +// 声明一个全局的rdb变量 +var rdb *redis.Client + +// 初始化连接 +func initClient() (err error) { + // 传入的是Redis的数据库配置结构体 + rdb = redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + Password: "", // no password set + DB: 1, // use default DB + }) + + _, err = rdb.Ping().Result() + if err != nil { + return err + } + + return nil +} + +func redisExample2() { + zsetKey := "language_rank" + languages := []redis.Z{ + redis.Z{Score: 90.0, Member: "Golang"}, + redis.Z{Score: 98.0, Member: "Java"}, + redis.Z{Score: 95.0, Member: "Python"}, + redis.Z{Score: 97.0, Member: "JavaScript"}, + redis.Z{Score: 99.0, Member: "C/C++"}, + } + // ZADD + num, err := rdb.ZAdd(zsetKey, languages...).Result() + if err != nil { + fmt.Printf("zadd failed, err:%v\n", err) + return + } + fmt.Printf("zadd %d succ.\n", num) + + // 把Golang的分数加10 + newScore, err := rdb.ZIncrBy(zsetKey, 10.0, "Golang").Result() + if err != nil { + fmt.Printf("zincrby failed, err:%v\n", err) + return + } + fmt.Printf("Golang's score is %f now.\n", newScore) + + // 取分数最高的3个 + ret, err := rdb.ZRevRangeWithScores(zsetKey, 0, 2).Result() + if err != nil { + fmt.Printf("zrevrange failed, err:%v\n", err) + return + } + for _, z := range ret { + fmt.Println(z.Member, z.Score) + } + + // 取95~100分的 + op := redis.ZRangeBy{ + Min: "95", + Max: "100", + } + ret, err = rdb.ZRangeByScoreWithScores(zsetKey, op).Result() + if err != nil { + fmt.Printf("zrangebyscore failed, err:%v\n", err) + return + } + for _, z := range ret { + fmt.Println(z.Member, z.Score) + } +} + +func main() { + err := initClient() + if err != nil { + fmt.Println("Redis初始化失败,", err) + } else { + fmt.Println("初始化Redis连接成功") + } +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/contextWithDeadline/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/contextWithDeadline/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..d1e56ce0faf93f53036b73f75f5370add0d316f0 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/contextWithDeadline/main.go" @@ -0,0 +1,24 @@ +package main + +import ( + "context" + "fmt" + "time" +) + +func main() { + // 设置 50毫秒返回 + d := time.Now().Add(50 * time.Millisecond) + ctx, cancel := context.WithDeadline(context.Background(), d) + + // 尽管ctx会过期,但在任何情况下,调用它的cancel函数都是很好的实践。 + // 如果不这样做,可能会使上下文及其父类存活的时间超过必要的时间 + defer cancel() + + select { + case <- time.After(1 * time.Second): + fmt.Println("周琳") + case <- ctx.Done(): + fmt.Println(ctx.Err()) + } +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/contextWithTimeout/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/contextWithTimeout/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..9e9253da176bb73eec40cfcb4fed7e2bf251f11c --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/contextWithTimeout/main.go" @@ -0,0 +1,39 @@ +package main + +import ( + "context" + "fmt" + "sync" + + "time" +) + +// context.WithTimeout + +var wg sync.WaitGroup + +func worker(ctx context.Context) { +LOOP: + for { + fmt.Println("db connecting ...") + time.Sleep(time.Millisecond * 10) // 假设正常连接数据库耗时10毫秒 + select { + case <-ctx.Done(): // 50毫秒后自动调用 + break LOOP + default: + } + } + fmt.Println("worker done!") + wg.Done() +} + +func main() { + // 设置一个50毫秒的超时 + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50) + wg.Add(1) + go worker(ctx) + time.Sleep(time.Second * 5) + cancel() // 通知子goroutine结束 + wg.Wait() + fmt.Println("over") +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/demo1/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/demo1/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..2ffb61a16dc7374254218d23328313f2591a03de --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/demo1/main.go" @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "sync" + "time" +) + +// 为什么需要Go context,下面的方式不是非常的优雅,我们有没有什么更好的可以优雅的退出go routine + +var wg sync.WaitGroup +var notify bool +func f() { + defer wg.Done(); + for { + fmt.Println("测试") + // 睡眠500毫秒 + time.Sleep(500 * time.Millisecond) + if notify { + break; + } + } +} + +func main() { + wg.Add(1); + go f() + time.Sleep(5 * time.Second) + notify = true + // 等待wg执行Done方法 + wg.Wait() + fmt.Println("main结束") +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/demo2/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/demo2/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..5e809564b7ce22602a942db84b6385b8ee83c5a4 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/demo2/main.go" @@ -0,0 +1,41 @@ +package main + +import ( + "fmt" + "sync" + "time" +) + +// 利用通道来通知退出 + +var wg sync.WaitGroup +var exitChan chan bool = make(chan bool, 1) +func f() { + defer wg.Done(); + notify := false + for { + if notify { + break + } + fmt.Println("测试") + // 睡眠500毫秒 + time.Sleep(500 * time.Millisecond) + // 多路复用 + select { + case <- exitChan: + notify = true + break + default: + } + } +} + +func main() { + wg.Add(1); + go f() + time.Sleep(5 * time.Second) + exitChan <- true + // 等待wg执行Done方法 + wg.Wait() + fmt.Println("main结束") +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/demo3/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/demo3/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..390f0b4cffffd3efac75449e526ad910900b469f --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/16_GoContext/demo3/main.go" @@ -0,0 +1,37 @@ +package main + +import ( + "context" + "fmt" + "sync" + + "time" +) + +var wg sync.WaitGroup + +func worker(ctx context.Context) { +LOOP: + for { + fmt.Println("worker") + time.Sleep(time.Second) + select { + case <-ctx.Done(): // 等待上级通知 + break LOOP + default: + } + } + wg.Done() +} + +func main() { + // 得到上下文 和 cancel方法 + ctx, cancel := context.WithCancel(context.Background()) + wg.Add(1) + go worker(ctx) + time.Sleep(time.Second * 3) + // 通知子goroutine结束 + cancel() + wg.Wait() + fmt.Println("over") +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/conf/conf.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/conf/conf.go" new file mode 100644 index 0000000000000000000000000000000000000000..858beae1f6e850617f6e2843cb7a3aeaab1c371e --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/conf/conf.go" @@ -0,0 +1,14 @@ +package conf + +type AppConf struct { + KafkaConf `ini:"kafka"` + TaillogConf `ini:"taillog"` +} +type KafkaConf struct { + Address string `ini:"address"` + Topic string `ini:"topic"` +} + +type TaillogConf struct { + FileName string `ini:"filename"` +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/conf/config.ini" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/conf/config.ini" new file mode 100644 index 0000000000000000000000000000000000000000..d00c83d78a04464604db512655304b55a82b2121 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/conf/config.ini" @@ -0,0 +1,6 @@ +[kafka] +address=127.0.0.1:9092 +topic=web_log + +[taillog] +filename=./my.log \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/go.mod" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/go.mod" new file mode 100644 index 0000000000000000000000000000000000000000..4f4f42a15b80b384669992139fe7459409b24c17 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/go.mod" @@ -0,0 +1,18 @@ +module LogDemo + +go 1.14 + +require ( + github.com/Shopify/sarama v1.19.0 + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/eapache/go-resiliency v1.2.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect + github.com/eapache/queue v1.1.0 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/golang/snappy v0.0.1 // indirect + github.com/hpcloud/tail v1.0.0 + github.com/pierrec/lz4 v2.5.2+incompatible // indirect + github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect + gopkg.in/ini.v1 v1.61.0 + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect +) diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/go.sum" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/go.sum" new file mode 100644 index 0000000000000000000000000000000000000000..556ef624a3ff190e5223f1b98bafa506536cc559 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/go.sum" @@ -0,0 +1,25 @@ +github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= +github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +gopkg.in/ini.v1 v1.61.0 h1:LBCdW4FmFYL4s/vDZD1RQYX7oAR6IjujCYgMdbHBR10= +gopkg.in/ini.v1 v1.61.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/kafka/kafka.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/kafka/kafka.go" new file mode 100644 index 0000000000000000000000000000000000000000..d213e86def6899dd1ff145d3e5e7d9afb34f4be0 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/kafka/kafka.go" @@ -0,0 +1,51 @@ +package kafka + +import ( + "fmt" + "github.com/Shopify/sarama" +) + +// 专门往kafka写日志的模块 + +var ( + // 声明一个全局连接kafka的生产者 + client sarama.SyncProducer +) + +// 初始化client +func Init(address []string, topic string)(err error) { + config := sarama.NewConfig() + + // tailf包使用,发送完数据需要 leader 和 follow都确定 + config.Producer.RequiredAcks = sarama.WaitForAll + // 新选出一个partition + config.Producer.Partitioner = sarama.NewRandomPartitioner + // 成功交付的消息将在 success channel返回 + config.Producer.Return.Successes = true + + msg := &sarama.ProducerMessage{} + msg.Topic = topic + msg.Value = sarama.StringEncoder("this is a test log") + // 连接kafka,可以连接一个集群 + client, err = sarama.NewSyncProducer(address, config) + if err != nil { + fmt.Println("producer closed, err: ", err) + } + fmt.Println("Kafka初始化成功") + return err +} + +// 发送消息到Kafka +func SendToKafka(topic, data string) { + msg := &sarama.ProducerMessage{} + msg.Topic = topic + msg.Value = sarama.StringEncoder(data) + // 发送到kafka + pid, offset, err := client.SendMessage(msg) + if err != nil { + fmt.Println("send msg failed, err:", err) + return + } + fmt.Println("发送消息:", data) + fmt.Printf("发送成功~ pid:%v offset:%v \n", pid, offset) +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/kafkaDemo/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/kafkaDemo/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..ca3922570d49650baa44f56d61293202703c342f --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/kafkaDemo/main.go" @@ -0,0 +1,39 @@ +package main + +import ( + "fmt" + "github.com/Shopify/sarama" +) + +// 基于sarama第三方库开发的Kafka client +func main() { + config := sarama.NewConfig() + + // tailf包使用,发送完数据需要 leader 和 follow都确定 + config.Producer.RequiredAcks = sarama.WaitForAll + // 新选出一个partition + config.Producer.Partitioner = sarama.NewRandomPartitioner + // 成功交付的消息将在 success channel返回 + config.Producer.Return.Successes = true + + msg := &sarama.ProducerMessage{} + msg.Topic = "web_log" + msg.Value = sarama.StringEncoder("this is a test log") + // 连接kafka,可以连接一个集群 + client, err := sarama.NewSyncProducer([]string{"127.0.0.1:9092"}, config) + if err != nil { + fmt.Println("producer closed, err: ", err) + return + } + fmt.Println("连接kafka成功!") + // 定义延迟关闭 + defer client.Close() + + // 发送消息 + pid, offset, err := client.SendMessage(msg) + if err != nil { + fmt.Println("send msg failed, err:", err) + return + } + fmt.Printf("pid:%v offset:%v \n", pid, offset) +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..cbee00e3c198afd8489e25edfee4fdba5baac772 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/main.go" @@ -0,0 +1,71 @@ +package main + +import ( + "LogDemo/conf" + "LogDemo/kafka" + "LogDemo/taillog" + "fmt" + "gopkg.in/ini.v1" + "time" +) + +var ( + cfg = new(conf.AppConf) +) + +// logAgent入口程序 +func run() { + // 1.读取日志 + for { + select { + case line := <-taillog.ReadChan(): + { + // 2.发送到kafka + kafka.SendToKafka(cfg.Topic, line.Text) + } + default: + time.Sleep(1 * time.Second) + } + } +} + +func main() { + // 0. 加载配置文件 + + // 方式1 + //cfg, err := ini.Load("./conf/config.ini") + //if err != nil { + // fmt.Printf("Fail to read file: %v", err) + // os.Exit(1) + //} + // + //// 典型读取操作,默认分区可以使用空字符串表示 + //fmt.Println("kafka address:", cfg.Section("kafka").Key("address").String()) + //fmt.Println("kafka topic:", cfg.Section("kafka").Key("topic").String()) + //fmt.Println("taillog path:", cfg.Section("taillog").Key("path").String()) + + // 方式2(传一个可修改的指针) + err := ini.MapTo(&cfg, "./conf/config.ini") + if err != nil { + fmt.Printf("load ini failed, err: %v \n", err) + return + } + fmt.Println("读取到的配置信息", cfg) + + // 1. 初始化kafka连接 + address := []string{cfg.Address} + topic := cfg.Topic + err = kafka.Init(address, topic) + if err != nil { + fmt.Printf("init Kafka failed, err:%v \n", err) + return + } + // 2. 打开日志文件,准备收集 + err = taillog.Init(cfg.FileName) + if err != nil { + fmt.Printf("Init taillog failed, err: %v \n", err) + return + } + // 3.执行业务逻辑 + run() +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/my.log" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/my.log" new file mode 100644 index 0000000000000000000000000000000000000000..e7bbc410aa53e6b2273fa0d3694af8afc6d62416 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/my.log" @@ -0,0 +1,4 @@ +hello +123hello +456123hello +123 diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/tailDemo/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/tailDemo/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..b8d9ed5c46a2f979bdb4435c44692887fd9ed3c1 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/tailDemo/main.go" @@ -0,0 +1,43 @@ +package main + +import ( + "fmt" + "github.com/hpcloud/tail" + "time" +) + +// tailf的用法 +func main() { + // 需要记录的日志文件 + fileName := "./my.log" + + // + config := tail.Config{ + ReOpen: true, // 重新打开,日志文件到了一定大小,就会分裂 + Follow: true, // 是否跟随 + Location: &tail.SeekInfo{Offset: 0, Whence: 2}, // 从文件的哪个位置开始读 + MustExist: false, // 是否必须存在,如果不存在是否报错 + Poll: true, // + } + + tails, err := tail.TailFile(fileName, config) + if err != nil { + fmt.Println("tail file failed, err:", err) + return + } + + var( + line *tail.Line + ok bool + ) + for { + // 从tails中一行一行的读取 + line, ok = <- tails.Lines + if !ok { + fmt.Println("tail file close reopen, filename:%s\n", tails.Filename) + time.Sleep(time.Second) + continue + } + fmt.Println("line", line.Text) + } +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/tailDemo/my.log" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/tailDemo/my.log" new file mode 100644 index 0000000000000000000000000000000000000000..e4d05736b440ba3066a46f8bd8855f66910a9bb3 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/tailDemo/my.log" @@ -0,0 +1,2 @@ +hello +lll diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/taillog/taillog.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/taillog/taillog.go" new file mode 100644 index 0000000000000000000000000000000000000000..6e34db3823f70e11e72e3f71595ff4807fa1e007 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/17_LogDemo/taillog/taillog.go" @@ -0,0 +1,37 @@ +package taillog + +import ( + "fmt" + "github.com/hpcloud/tail" +) + +// 定义全局对象 +var ( + // 声明一个全局连接kafka的生产者 + tailObj *tail.Tail +) + +// 专门从日志文件收集日志的模块 +func Init(fileName string)(err error ){ + + // 定义配置文件 + config := tail.Config{ + ReOpen: true, // 重新打开,日志文件到了一定大小,就会分裂 + Follow: true, // 是否跟随 + Location: &tail.SeekInfo{Offset: 0, Whence: 2}, // 从文件的哪个位置开始读 + MustExist: false, // 是否必须存在,如果不存在是否报错 + Poll: true, // + } + + tailObj, err = tail.TailFile(fileName, config) + if err != nil { + fmt.Println("tail file failed, err:", err) + return + } + return err +} + +// 读取日志,返回一个只读的chan +func ReadChan() <-chan *tail.Line { + return tailObj.Lines +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/Utils/IpUtils.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/Utils/IpUtils.go" new file mode 100644 index 0000000000000000000000000000000000000000..700ce35cd92f167a74d42dc507eb0617e11324c0 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/Utils/IpUtils.go" @@ -0,0 +1,22 @@ +package Utils + +import ( + "fmt" + "net" + "strings" +) + +// 获取本地对外IP +func GetOutboundIP()(ip string, err error) { + // 使用udp的方式拨号 + conn, err := net.Dial("udp", "8.8.8.8:80") + if err != nil { + fmt.Printf("get ip failed, err: %s, \n", err) + return + } + defer conn.Close() + localAddr := conn.LocalAddr().(*net.UDPAddr) + fmt.Println(localAddr.String()) + ip = strings.Split(localAddr.IP.String(), ":")[0] + return +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/conf/conf.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/conf/conf.go" new file mode 100644 index 0000000000000000000000000000000000000000..32159f18f2dc5c2c1c497e1a9a8c0bb9b7cf69fb --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/conf/conf.go" @@ -0,0 +1,17 @@ +package conf + +type AppConf struct { + KafkaConf `ini:"kafka"` + EtcdConf `ini:"etcd"` +} +type KafkaConf struct { + Address string `ini:"address"` + Topic string `ini:"topic"` + ChanMaxSize int `ini:"chan_max_size"` +} +// etcd配置 +type EtcdConf struct { + Address string `ini:"address"` + Key string `ini:"collect_log_key"` + Timeout int `ini:"timeout"` +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/conf/config.ini" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/conf/config.ini" new file mode 100644 index 0000000000000000000000000000000000000000..08610ca00c58417ba13d15383ee9ffe9d8eab3dc --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/conf/config.ini" @@ -0,0 +1,9 @@ +[kafka] +address=127.0.0.1:9092 +topic=web_log +chan_max_size=100000 + +[etcd] +address=127.0.0.1:2379 +timeout=5 +collect_log_key=/logagent/%s/collect_config \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/etcd/etcd.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/etcd/etcd.go" new file mode 100644 index 0000000000000000000000000000000000000000..4f95801aa80c72328eb8da5efb4522d710ebf42b --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/etcd/etcd.go" @@ -0,0 +1,82 @@ +package etcd + +import ( + "context" + "encoding/json" + "fmt" + "go.etcd.io/etcd/clientv3" + "time" +) + +var( + cli *clientv3.Client +) + +// 需要收集的日志的配置信息 +type LogEntry struct { + Path string `json:"path"` // 日志存放的路径 + Topic string `json:"topic"` // 日志要发往Kafka中的哪个topic +} + +// 初始化ETCD的函数 +func Init(addr string, timeOut time.Duration)(err error) { + cli, err = clientv3.New(clientv3.Config { + Endpoints: []string{addr}, // etcd的节点,可以传入多个 + DialTimeout: timeOut, // 连接超时时间 + }) + + if err != nil { + fmt.Printf("connect to etcd failed, err: %v \n", err) + return + } + fmt.Println("connect to etcd success") + return err +} + +// 从ETCD中根据key获取配置项 +func GetConf(key string) (logEntryConf []*LogEntry, err error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + resp, err := cli.Get(ctx, key) + cancel() + if err != nil { + fmt.Println("get from etcd failed, err:%v \n", err) + return + } + for _, ev := range resp.Kvs { + // 打印出key和value + //fmt.Printf("%s:%s \n", ev.Key, ev.Value) + + err = json.Unmarshal(ev.Value, &logEntryConf) + if err != nil { + fmt.Printf("unmarshal etcd value failed, err:%v \n", err) + return + } + } + return +} + +// etcd watch // 派一个哨兵,一直监视着key的变化(新增,修改,删除),返回一个只读的chan +func WatchConf(key string, newConfCh chan <- []*LogEntry) { + ch := cli.Watch(context.Background(), key) + // 从通道中尝试获取值(监视的信息) + for wresp := range ch{ + for _, evt := range wresp.Events{ + fmt.Printf("Type:%v key:%v value:%v \n", evt.Type, string(evt.Kv.Key), string(evt.Kv.Value)) + // 通知taillog.tskMgr + // 先判断操作类型 + var newConf []*LogEntry + // 如果是删除操作 + if evt.Type != clientv3.EventTypeDelete { + // 如果是删除操作,手动传递一个空的配置项 + err := json.Unmarshal(evt.Kv.Value, &newConf) + if err != nil { + fmt.Printf("unmarshal failed, err: %v \n", err) + continue + } + } + // 将newConf传递到通道中 + fmt.Printf("get new conf: %v \n", newConf) + newConfCh <- newConf + } + } +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/etcd_put_get/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/etcd_put_get/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..4d42093f5d047ef13f2b56ac60ee01c88727f052 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/etcd_put_get/main.go" @@ -0,0 +1,35 @@ +package main + +import ( + "context" + "fmt" + "go.etcd.io/etcd/clientv3" + "time" +) + +func main() { + cli, err := clientv3.New(clientv3.Config { + Endpoints: []string{"127.0.0.1:2379"}, // etcd的节点,可以传入多个 + DialTimeout: 5*time.Second, // 连接超时时间 + }) + + if err != nil { + fmt.Printf("connect to etcd failed, err: %v \n", err) + return + } + fmt.Println("connect to etcd success") + + // 延迟关闭 + defer cli.Close() + + // put操作 设置1秒超时 + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + value := `[{"path":"D:/mogu_blog/logs/mysql.log","topic":"web_log"},{"path":"D:/mogu_blog/logs/redis.log","topic":"redis_log"}]` + _, err = cli.Put(ctx, "/logagent/202.193.57.73/collect_config", value) + cancel() + if err != nil { + fmt.Printf("put to etcd failed, err:%v \n", err) + return + } + fmt.Println("设置成功") +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/go.mod" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/go.mod" new file mode 100644 index 0000000000000000000000000000000000000000..ce096edd4652308e27ae7a88cdf804510e8b5d9a --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/go.mod" @@ -0,0 +1,28 @@ +module LogDemo + +go 1.14 + +require ( + github.com/Shopify/sarama v1.19.0 + github.com/coreos/etcd v3.3.25+incompatible // indirect + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/eapache/go-resiliency v1.2.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect + github.com/eapache/queue v1.1.0 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/gogo/protobuf v1.3.1 // indirect + github.com/golang/snappy v0.0.1 // indirect + github.com/google/uuid v1.1.2 // indirect + github.com/hpcloud/tail v1.0.0 + github.com/pierrec/lz4 v2.5.2+incompatible // indirect + github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect + go.etcd.io/etcd v3.3.25+incompatible + go.uber.org/zap v1.16.0 // indirect + google.golang.org/grpc v1.32.0 // indirect + gopkg.in/ini.v1 v1.61.0 + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect +) + +replace google.golang.org/grpc => google.golang.org/grpc v1.26.0 diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/go.sum" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/go.sum" new file mode 100644 index 0000000000000000000000000000000000000000..9516bc12ce37838b3da8e706dea469170848610e --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/go.sum" @@ -0,0 +1,132 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/coreos/etcd v0.5.0-alpha.5 h1:0Qi6Jzjk2CDuuGlIeecpu+em2nrjhOgz2wsIwCmQHmc= +github.com/coreos/etcd v3.3.25+incompatible h1:0GQEw6h3YnuOVdtwygkIfJ+Omx0tZ8/QkVyXI4LkbeY= +github.com/coreos/etcd v3.3.25+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= +github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +go.etcd.io/etcd v0.5.0-alpha.5 h1:VOolFSo3XgsmnYDLozjvZ6JL6AAwIDu1Yx1y+4EYLDo= +go.etcd.io/etcd v3.3.25+incompatible h1:V1RzkZJj9LqsJRy+TUBgpWSbZXITLB819lstuTFoZOY= +go.etcd.io/etcd v3.3.25+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.61.0 h1:LBCdW4FmFYL4s/vDZD1RQYX7oAR6IjujCYgMdbHBR10= +gopkg.in/ini.v1 v1.61.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/kafka/kafka.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/kafka/kafka.go" new file mode 100644 index 0000000000000000000000000000000000000000..57ec4438dbc7258309e34d59f98051a86e52f258 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/kafka/kafka.go" @@ -0,0 +1,81 @@ +package kafka + +import ( + "fmt" + "github.com/Shopify/sarama" + "time" +) + +// 专门往kafka写日志的模块 + +type logData struct { + topic string + data string +} + +var ( + // 声明一个全局连接kafka的生产者 + client sarama.SyncProducer + // 全局的用于存放日志的chan + logDataChan chan *logData +) + +// 初始化client +func Init(address []string, topic string, maxSize int)(err error) { + config := sarama.NewConfig() + + // tailf包使用,发送完数据需要 leader 和 follow都确定 + config.Producer.RequiredAcks = sarama.WaitForAll + // 新选出一个partition + config.Producer.Partitioner = sarama.NewRandomPartitioner + // 成功交付的消息将在 success channel返回 + config.Producer.Return.Successes = true + + msg := &sarama.ProducerMessage{} + msg.Topic = topic + msg.Value = sarama.StringEncoder("this is a test log") + // 连接kafka,可以连接一个集群 + client, err = sarama.NewSyncProducer(address, config) + if err != nil { + fmt.Println("producer closed, err: ", err) + return err + } + // 初始化全局的chan,用来指定最大的大小 + logDataChan = make(chan *logData, maxSize) + + // 开启协程,从logDataChan等待数据过来,然后发送到kafka + go sendToKafka() + fmt.Println("Kafka初始化成功") + return err +} + +// 给外部暴露的一个函数,该函数只把日志数据发送到一个内部的channel中 +func SendToChan(topic, data string) { + msg := &logData{ + topic: topic, + data: data, + } + logDataChan <- msg +} + +// 发送消息到Kafka +func sendToKafka() { + for { + select { + case ld := <-logDataChan: { + msg := &sarama.ProducerMessage{} + msg.Topic = ld.topic + msg.Value = sarama.StringEncoder(ld.data) + // 发送到kafka + pid, offset, err := client.SendMessage(msg) + if err != nil { + fmt.Println("send msg failed, err:", err) + return + } + fmt.Printf("message: %v , pid:%v , offset:%v \n", ld, pid, offset) + } + default: + time.Sleep(time.Millisecond * 50) + } + } +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..88e3a5536bcb0482f63eeeb63f574e38d6a3db25 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/main.go" @@ -0,0 +1,80 @@ +package main + +import ( + "LogDemo/Utils" + "LogDemo/conf" + "LogDemo/etcd" + "LogDemo/kafka" + "LogDemo/taillog" + "fmt" + "gopkg.in/ini.v1" + "sync" + "time" +) + +var ( + cfg = new(conf.AppConf) +) + +func main() { + + // 加载配置文件 + err := ini.MapTo(&cfg, "./conf/config.ini") + if err != nil { + fmt.Printf("load ini failed, err: %v \n", err) + return + } + fmt.Println("读取到的配置信息", cfg) + + // 1. 初始化kafka连接 + address := []string{cfg.KafkaConf.Address} + topic := cfg.Topic + err = kafka.Init(address, topic, cfg.ChanMaxSize) + if err != nil { + fmt.Printf("init Kafka failed, err:%v \n", err) + return + } + fmt.Println("init kafka success.") + + // 初始化etcd + err = etcd.Init(cfg.EtcdConf.Address, time.Duration(cfg.EtcdConf.Timeout) * time.Second) + if err != nil { + fmt.Println("init etcd failed, err:%v \n", err) + return + } + + // 为了实现每个logagent都拉取自己独有的配置,所以要以自己的IP地址作为区分 + ipStr, err := Utils.GetOutboundIP() + if err != nil { + panic(err) + } + etcdConfKey := fmt.Sprintf(cfg.EtcdConf.Key, ipStr) + + // 从etcd中获取日志收集项的配置信息 + logEntryConf, err := etcd.GetConf(etcdConfKey) + if err != nil { + fmt.Println("etcd.GetConf failed, err:%v \n", err) + return + } + fmt.Printf("get conf from etcd success, %v \n", logEntryConf) + + // 派一个哨兵去监视日志收集项的变化(有变化及时通知我的logAgent的热加载配置) + + // 打印出配置 + for index, value := range logEntryConf { + fmt.Printf("index:%v, value:%v \n", index, value) + } + + // 收集日志,发往kafka中【因为NewConfChan访问了tskMgr的NewConfChan,这个channel是在初始化完成时才执行初始化】 + taillog.Init(logEntryConf) + + // 从taillog包中获取对外暴露的通道 + newConfChan := taillog.NewConf() + + // 获取一个等待组 + var wg sync.WaitGroup + wg.Add(1) + // 哨兵发现最新的配置信息会通知上面的那个通道 + go etcd.WatchConf(etcdConfKey, newConfChan) + wg.Wait() +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/my.log" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/my.log" new file mode 100644 index 0000000000000000000000000000000000000000..e7bbc410aa53e6b2273fa0d3694af8afc6d62416 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/my.log" @@ -0,0 +1,4 @@ +hello +123hello +456123hello +123 diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/taillog/taillog.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/taillog/taillog.go" new file mode 100644 index 0000000000000000000000000000000000000000..271933dd79b2bd045a6feb02dfad85f89f49a259 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/taillog/taillog.go" @@ -0,0 +1,76 @@ +package taillog + +import ( + "LogDemo/kafka" + "context" + "fmt" + "github.com/hpcloud/tail" +) + +// TailTask:具体的一个日志收集的任务 +type TailTask struct { + // 收集的哪一个路径下的日志 + path string + // 收集的日志要放到哪个topic下面 + topic string + // 具体的tailObj对象 + instance *tail.Tail + // 为了能显示退出 t.run() + ctx context.Context + cancelFunc context.CancelFunc +} + +// 初始化TailTask +func NewTailTask(path string, topic string)(tailObj *TailTask) { + ctx, cancel := context.WithCancel(context.Background()) + tailObj = &TailTask{ + path: path, + topic: topic, + ctx: ctx, + cancelFunc: cancel, + } + // 根据路径去打开对应的日志 + tailObj.init() + return +} + +func (t *TailTask)init()() { + + // 定义配置文件 + config := tail.Config{ + ReOpen: true, // 重新打开,日志文件到了一定大小,就会分裂 + Follow: true, // 是否跟随 + Location: &tail.SeekInfo{Offset: 0, Whence: 2}, // 从文件的哪个位置开始读 + MustExist: false, // 是否必须存在,如果不存在是否报错 + Poll: true, // + } + var err error + t.instance, err = tail.TailFile(t.path, config) + if err != nil { + fmt.Println("tail file failed, err:", err) + } + // 开启goroutine 去采集日志发送到kafka中【当goroutine执行的函数退出的时候,也就退出了】 + go t.run() +} + +// 采集日志 +func (t *TailTask) run() { + // 从tailObj的通道中一行一行的读取日志数据 【多路复用】 + for { + select { + // 当ctx中的Done通道中,有内容时,代表需要退出了 + case <- t.ctx.Done(): + fmt.Printf("tail task: %s_%s 结束了.... \n", t.path , t.topic) + return + case line := <- t.instance.Lines: + // 发往数据到kafka中 + // 可以优化,先把日志数据发送到一个通道中,然后在kafka的那个包中,有单独的goroutine去取日志数据发送到kafka中 + kafka.SendToChan(t.topic, line.Text) + } + } +} + +// 读取日志,返回一个只读的chan +func (t *TailTask)ReadChan() <-chan *tail.Line { + return t.instance.Lines +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/taillog/taillog_mgr.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/taillog/taillog_mgr.go" new file mode 100644 index 0000000000000000000000000000000000000000..72958de2d5d66fa177fe6935f5eaf16c72a28f6d --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_LogAgent/taillog/taillog_mgr.go" @@ -0,0 +1,95 @@ +package taillog + +import ( + "LogDemo/etcd" + "fmt" + "time" +) + +var tskMgr *tailLogMgr + +// 专门用来管理taillog的,tailTask管理者 +type tailLogMgr struct { + logEntry [] *etcd.LogEntry + // 有多少干活的TailTask,就记录起来 + tskMap map[string]*TailTask + // 等待最新配置过来的通道 + newConfChan chan []*etcd.LogEntry +} + +// 初始化方法 +func Init(logEntryConf []*etcd.LogEntry) { + + tskMgr = &tailLogMgr{ + // 把当前的日志收集项配置信息保存起来 + logEntry: logEntryConf, + tskMap: make(map[string]*TailTask, 16), + newConfChan: make(chan []*etcd.LogEntry), // 无缓冲区的通道 + } + for _, logEntry := range logEntryConf { + // conf是一个LogEntry结构体 + // logEntry.Path:要收集的日志的路径 + tailObj := NewTailTask(logEntry.Path, logEntry.Topic) + + // 初始化的时候,起了多少tailtask都要记下来,为了后续判断方便 + mKey := fmt.Sprintf("%s_%s", logEntry.Path, logEntry.Topic) + tskMgr.tskMap[mKey] = tailObj + } + + // 从NewConfChan中获取最新配置 + go tskMgr.run() +} + +// 监听自己的newConfChan,有了新的配置过来之后,就做处理 +// 1.配置新增、2.配置删除、3.配置变更 +func (t *tailLogMgr)run() { + for { + select{ + case newConf := <- t.newConfChan: + // 1.配置新增、2.配置删除、3.配置变更 + fmt.Println("新的配置来了:", newConf) + for _, conf := range newConf { + // 从tskMap中判断是否有该配置 + mKey := fmt.Sprintf("%s_%s", conf.Path, conf.Topic) + _, ok := t.tskMap[mKey] + if ok { + // 原来就有,不需要操作 + continue + } else { + // 如果不存在,说明是一个新增的操作 + tailObj := NewTailTask(conf.Path, conf.Topic) + tskMgr.tskMap[mKey] = tailObj + } + } + + // 找出原来t.logEntry有,但是newConf中没有,要删掉 + for _, c1 := range t.logEntry { // 从原来的配置中依次拿出配置项 + isDelete := true + for _, c2 := range newConf { // 去新的配置中逐一进行比较 + // 判断原来有,现在是否有,那么什么都不做 + if c2.Path == c1.Path && c2.Topic == c1.Topic { + isDelete = false + continue; + } + } + if isDelete { + // 把c1对应的这个tailObj给停掉 + mk := fmt.Sprintf("%s_%s", c1.Path, c1.Topic) + + // t.tskMap[mk] ==> tailObj + // 调用tailObj中的退出方法 + t.tskMap[mk].cancelFunc() + } + } + + + default: + time.Sleep(time.Second) + } + } +} + +// 向往暴露一个函数,获取tskMgr的newConfChan +func NewConf() chan<- [] *etcd.LogEntry { + return tskMgr.newConfChan +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_etcdDemo/etcd_put_get/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_etcdDemo/etcd_put_get/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..93981b754c4735f6604f1a2b9fc80a3dc1a19204 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_etcdDemo/etcd_put_get/main.go" @@ -0,0 +1,45 @@ +package main + +import ( + "context" + "fmt" + "go.etcd.io/etcd/clientv3" + "time" +) + +func main() { + cli, err := clientv3.New(clientv3.Config { + Endpoints: []string{"127.0.0.1:2379"}, // etcd的节点,可以传入多个 + DialTimeout: 5*time.Second, // 连接超时时间 + }) + + if err != nil { + fmt.Printf("connect to etcd failed, err: %v \n", err) + return + } + fmt.Println("connect to etcd success") + + // 延迟关闭 + defer cli.Close() + + // put操作 设置1秒超时 + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + _, err = cli.Put(ctx, "moxi", "lalala") + cancel() + if err != nil { + fmt.Printf("put to etcd failed, err:%v \n", err) + return + } + + // get操作,设置1秒超时 + ctx, cancel = context.WithTimeout(context.Background(), time.Second) + resp, err := cli.Get(ctx, "q1mi") + cancel() + if err != nil { + fmt.Printf("get from etcd failed, err:%v \n", err) + return + } + for _, ev := range resp.Kvs { + fmt.Printf("%s:%s \n", ev.Key, ev.Value) + } +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_etcdDemo/etcd_watch/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_etcdDemo/etcd_watch/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..6cdab87061ec96aabe4d470e3848b00758059c44 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/18_etcdDemo/etcd_watch/main.go" @@ -0,0 +1,33 @@ +package main + +import ( + "context" + "fmt" + "go.etcd.io/etcd/clientv3" + "time" +) +// etcd 的watch操作 +func main() { + cli, err := clientv3.New(clientv3.Config { + Endpoints: []string{"127.0.0.1:2379"}, // etcd的节点,可以传入多个 + DialTimeout: 5*time.Second, // 连接超时时间 + }) + + if err != nil { + fmt.Printf("connect to etcd failed, err: %v \n", err) + return + } + fmt.Println("connect to etcd success") + defer cli.Close() + + // watch + // 派一个哨兵,一直监视着 moxi 这个key的变化(新增,修改,删除),返回一个只读的chan + ch := cli.Watch(context.Background(), "moxi") + + // 从通道中尝试获取值(监视的信息) + for wresp := range ch{ + for _, evt := range wresp.Events{ + fmt.Printf("Type:%v key:%v value:%v \n", evt.Type, evt.Kv.Key, evt.Kv.Value) + } + } +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/19_ElasticSearch/go.mod" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/19_ElasticSearch/go.mod" new file mode 100644 index 0000000000000000000000000000000000000000..06e018e6b045c311d5cfb779229aef56d181a792 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/19_ElasticSearch/go.mod" @@ -0,0 +1,5 @@ +module es + +go 1.14 + +require github.com/olivere/elastic/v7 v7.0.20 diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/19_ElasticSearch/go.sum" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/19_ElasticSearch/go.sum" new file mode 100644 index 0000000000000000000000000000000000000000..19d930afb15e2a715789df90a7616722e60ec198 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/19_ElasticSearch/go.sum" @@ -0,0 +1,69 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/aws/aws-sdk-go v1.34.13/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/olivere/elastic v1.0.1 h1:UeafjZg+TifCVPhCJNPof0pUHig6vbXuJEbC/A+Ouo0= +github.com/olivere/elastic v6.2.35+incompatible h1:MMklYDy2ySi01s123CB2WLBuDMzFX4qhFcA5tKWJPgM= +github.com/olivere/elastic/v7 v7.0.20 h1:5FFpGPVJlBSlWBOdict406Y3yNTIpVpAiUvdFZeSbAo= +github.com/olivere/elastic/v7 v7.0.20/go.mod h1:Kh7iIsXIBl5qRQOBFoylCsXVTtye3keQU2Y/YbR7HD8= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= +github.com/smartystreets/gunit v1.4.2/go.mod h1:ZjM1ozSIMJlAz/ay4SG8PeKF00ckUp+zMHZXV9/bvak= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/19_ElasticSearch/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/19_ElasticSearch/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..e341556fba051bc88ab055a584dc03c5796700b0 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/19_ElasticSearch/main.go" @@ -0,0 +1,58 @@ +package main + +import ( + "context" + "fmt" + "github.com/olivere/elastic/v7" +) + +// 构造一个student结构体 + +type Student struct { + Name string `json:"name"` + Age int `json:"age"` + Married bool `json:"married"` +} + +func (s *Student)run() *Student { + fmt.Printf("%s在跑...", s.Name) + return s +} + +func (s *Student)play()*Student { + fmt.Printf("%s在玩...", s.Name) + return s +} + +func main() { + + moxi := Student{ + Name: "陌溪", + Age: 9000, + Married: true, + } + moxi.run() + moxi.run() + moxi.play().run() + + + // 使用 elastic库中的NewClient方法 + client, err := elastic.NewClient(elastic.SetURL("http://127.0.0.1:9200")) + if err != nil { + // 抛出异常 + panic(err) + } + fmt.Println("connect to es success") + // 构造一条数据 + p1 := Student{Name: "rion", Age: 22, Married: false} + put1, err := client.Index(). + Index("user"). // 拿到索引库 + BodyJson(p1). // 将对象转换成json + Do(context.Background()) // 插入,同时可以设置context的超时 + + if err != nil { + // Handle error + panic(err) + } + fmt.Printf("Indexed student %s to index %s, type %s\n", put1.Id, put1.Index, put1.Type) +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_KafkaConsumer/go.mod" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_KafkaConsumer/go.mod" new file mode 100644 index 0000000000000000000000000000000000000000..f10a32b6bda456fb63f729495ea521836576afd3 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_KafkaConsumer/go.mod" @@ -0,0 +1,16 @@ +module kafka + +go 1.14 + +require ( + github.com/Shopify/sarama v1.19.0 + github.com/Shopify/toxiproxy v2.1.4+incompatible // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/eapache/go-resiliency v1.2.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect + github.com/eapache/queue v1.1.0 // indirect + github.com/frankban/quicktest v1.10.2 // indirect + github.com/golang/snappy v0.0.1 // indirect + github.com/pierrec/lz4 v2.5.2+incompatible // indirect + github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect +) diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_KafkaConsumer/go.sum" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_KafkaConsumer/go.sum" new file mode 100644 index 0000000000000000000000000000000000000000..6c5976bcd514267d0396673c75ea154c38a1b69b --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_KafkaConsumer/go.sum" @@ -0,0 +1,29 @@ +github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/frankban/quicktest v1.10.2 h1:19ARM85nVi4xH7xPXuc5eM/udya5ieh7b/Sv+d844Tk= +github.com/frankban/quicktest v1.10.2/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= +github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_KafkaConsumer/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_KafkaConsumer/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..efeef193a6ac887122c81444aa7c0914c4742251 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_KafkaConsumer/main.go" @@ -0,0 +1,41 @@ +package main + +import ( + "fmt" + + "github.com/Shopify/sarama" +) + +// Kafka消费者,从Kafka中将数据读出来 + +func main() { + consumer, err := sarama.NewConsumer([]string{"127.0.0.1:9092"}, nil) + if err != nil { + fmt.Printf("fail to start consumer, err:%v\n", err) + return + } + partitionList, err := consumer.Partitions("web_log") // 根据topic取到所有的分区 + if err != nil { + fmt.Printf("fail to get list of partition:err%v\n", err) + return + } + fmt.Println("分区列表", partitionList) + for partition := range partitionList { // 遍历所有的分区 + // 针对每个分区创建一个对应的分区消费者 + pc, err := consumer.ConsumePartition("web_log", int32(partition), sarama.OffsetNewest) + if err != nil { + fmt.Printf("failed to start consumer for partition %d,err:%v\n", partition, err) + return + } + defer pc.AsyncClose() + // 异步从每个分区消费信息 + go func(sarama.PartitionConsumer) { + for msg := range pc.Messages() { + fmt.Printf("Partition:%d Offset:%d Key:%v Value:%v", msg.Partition, msg.Offset, msg.Key, string(msg.Value)) + } + }(pc) + } + select { + + } +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/conf/cfg.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/conf/cfg.go" new file mode 100644 index 0000000000000000000000000000000000000000..2d87310be4bcc6f2de1f766d15a370bee4f26161 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/conf/cfg.go" @@ -0,0 +1,17 @@ +package conf + +type LogTransferCfg struct { + KafkaCfg `ini:"kafka"` // 这个对应ini文件中的 [kafka] + EsCfg `ini:"es"` // 这个对应ini文件中的 [es] +} + +// Kafka配置类 +type KafkaCfg struct { + Address string `ini:"address"` + Topic string `ini:"topic"` +} + +// Es配置类 +type EsCfg struct { + Address string `ini:"address"` +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/conf/cfg.ini" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/conf/cfg.ini" new file mode 100644 index 0000000000000000000000000000000000000000..55691de9bc263394d6073e03e8bbded603530653 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/conf/cfg.ini" @@ -0,0 +1,6 @@ +[kafka] +address=127.0.0.1:9092 +topic=web_log + +[es] +address=127.0.0.1:9200 \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/es/es.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/es/es.go" new file mode 100644 index 0000000000000000000000000000000000000000..e25ee2cc2886eb3cb8448f14e6d3f89d1e973585 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/es/es.go" @@ -0,0 +1,46 @@ +package es + +import ( + "context" + "fmt" + "github.com/olivere/elastic/v7" + "strings" +) + +type LogData struct { + Topic string `json:"topic"` + data string `json:"data"` +} + +var ( + client *elastic.Client + ch = make(chan LogData, 100000) +) +// 初始化ES,准备接受Kafka那边发来的数据 +func Init(address string)(err error) { + if !strings.HasPrefix(address, "http://") { + address = "http://" + address + } + // 使用 elastic库中的NewClient方法 + client, err = elastic.NewClient(elastic.SetURL(address)) + if err != nil { + fmt.Println("connect to es failed, err:", err) + return + } + return +} + +// 发送数据到ES中 +func SendToES(indexStr string, data interface{}) error { + // 构造一条数据 + put1, err := client.Index(). + Index(indexStr). // 拿到索引库 + BodyJson(data). // 将对象转换成json + Do(context.Background()) // 插入,同时可以设置context的超时 + + if err != nil { + return err + } + fmt.Printf("Indexed web_log %s to index %s, type %s, data: %v \n", put1.Id, put1.Index, put1.Type, data) + return err +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/go.mod" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/go.mod" new file mode 100644 index 0000000000000000000000000000000000000000..239d49a55475c0741282d0840067dd8662c7a7b2 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/go.mod" @@ -0,0 +1,15 @@ +module LogTransfer + +go 1.14 + +require ( + github.com/Shopify/sarama v1.19.0 + github.com/eapache/go-resiliency v1.2.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect + github.com/eapache/queue v1.1.0 // indirect + github.com/golang/snappy v0.0.1 // indirect + github.com/olivere/elastic/v7 v7.0.20 + github.com/pierrec/lz4 v2.5.2+incompatible // indirect + github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect + gopkg.in/ini.v1 v1.61.0 +) diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/go.sum" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/go.sum" new file mode 100644 index 0000000000000000000000000000000000000000..cd248039ffa2fcc1aaa85fdf1429127235da5006 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/go.sum" @@ -0,0 +1,129 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/sarama v1.27.0 h1:tqo2zmyzPf1+gwTTwhI6W+EXDw4PVSczynpHKFtVAmo= +github.com/Shopify/sarama v1.27.0/go.mod h1:aCdj6ymI8uyPEux1JJ9gcaDT6cinjGhNCAhs54taSUo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/aws/aws-sdk-go v1.34.13/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/klauspost/compress v1.10.10 h1:a/y8CglcM7gLGYmlbP/stPE5sR3hbhFRUjCBfd/0B3I= +github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/olivere/elastic v1.0.1 h1:UeafjZg+TifCVPhCJNPof0pUHig6vbXuJEbC/A+Ouo0= +github.com/olivere/elastic v6.2.35+incompatible h1:MMklYDy2ySi01s123CB2WLBuDMzFX4qhFcA5tKWJPgM= +github.com/olivere/elastic/v7 v7.0.20 h1:5FFpGPVJlBSlWBOdict406Y3yNTIpVpAiUvdFZeSbAo= +github.com/olivere/elastic/v7 v7.0.20/go.mod h1:Kh7iIsXIBl5qRQOBFoylCsXVTtye3keQU2Y/YbR7HD8= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/pierrec/lz4 v1.0.1 h1:w6GMGWSsCI04fTM8wQRdnW74MuJISakuUU0onU0TYB4= +github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= +github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= +github.com/smartystreets/gunit v1.4.2/go.mod h1:ZjM1ozSIMJlAz/ay4SG8PeKF00ckUp+zMHZXV9/bvak= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200528225125-3c3fba18258b h1:IYiJPiJfzktmDAO1HQiwjMjwjlYKHAL7KzeD544RJPs= +golang.org/x/net v0.0.0-20200528225125-3c3fba18258b/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/ini.v1 v1.61.0 h1:LBCdW4FmFYL4s/vDZD1RQYX7oAR6IjujCYgMdbHBR10= +gopkg.in/ini.v1 v1.61.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= +gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= +gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= +gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200601152816-913338de1bd2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/kafka/kafka.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/kafka/kafka.go" new file mode 100644 index 0000000000000000000000000000000000000000..aa2ec310e520d7460341cbed7c114e4ebd448eea --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/kafka/kafka.go" @@ -0,0 +1,54 @@ +package kafka + +import ( + "LogTransfer/es" + "fmt" + "github.com/Shopify/sarama" +) + +type LogData struct { + data string `json:"data"` +} + +// 初始化Kafka消费者,从Kafka取数据发往ES中 +func Init(address []string, topic string)(error) { + consumer, err := sarama.NewConsumer(address, nil) + if err != nil { + fmt.Printf("fail to start consumer, err:%v\n", err) + return err + } + partitionList, err := consumer.Partitions(topic) // 根据topic取到所有的分区 + if err != nil { + fmt.Printf("fail to get list of partition:err%v\n", err) + return err + } + fmt.Println("分区列表", partitionList) + for partition := range partitionList { // 遍历所有的分区 + // 针对每个分区创建一个对应的分区消费者 + pc, err := consumer.ConsumePartition(topic, int32(partition), sarama.OffsetNewest) + if err != nil { + fmt.Printf("failed to start consumer for partition %d,err:%v\n", partition, err) + return err + } + + // 异步从每个分区消费信息 + go func(sarama.PartitionConsumer) { + for msg := range pc.Messages() { + // 直接发送到ES中 + ld := map[string]interface{} { + "data": string(msg.Value), + } + + if err != nil { + fmt.Printf("unmarshal failed, err: %v \n", err) + return + } + fmt.Println("向ES中发送数据,", ld) + // 发送数据到es 【函数调函数,可以使用异步的方式】 + es.SendToES(topic, ld) + // 优化一下:直接放到一个chan中 + } + }(pc) + } + return err +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..df04f76ddd02d6845b318a0d86d62172ede04168 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/20_LogTransfer/main.go" @@ -0,0 +1,53 @@ +package main + +import ( + "LogTransfer/conf" + "LogTransfer/es" + "LogTransfer/kafka" + "fmt" + "gopkg.in/ini.v1" +) + +// LogTransfer +// 将日志数据从Kafka中取出来,发往ElasticSearch +func main() { + // 加载配置文件 + var cfg conf.LogTransferCfg + // 因为go里面修改是需要传递引用地址,所以需要用 &cfg + // 需要注意:在一个函数修改变量的时候,一定要传递一个指针 + // 与配置文件对应的结构体中,一定要设置tag(特别是嵌套结构体) + err := ini.MapTo(&cfg, "./conf/cfg.ini") + if err != nil { + fmt.Println("init config failed, err:", err) + return + } + fmt.Printf("cfg: %v \n", cfg) + + // 初始化ES + // ES做的事情:初始化一个ES连接的client + // 对外提供一个往ES中写入数据的一个函数 + err = es.Init(cfg.EsCfg.Address) + if err != nil { + fmt.Printf("init ElasticSearch failed, err: %v \n", err) + return + } + fmt.Println("init ElasticSearch Success") + + // 初始化Kafka + //做的事情:连接kafka -> 创建分区的消费者 -> 每个分区的消费者分别取出数据,通过SendToES()将数据发往ES + err = kafka.Init([]string{cfg.KafkaCfg.Address}, cfg.KafkaCfg.Topic) + if err != nil { + fmt.Printf("init kafka consumer failed, err: %v \n", err) + return + } + fmt.Println("init Kafka Success") + + select { + + } + + + // 从Kafka中取日志数据 + + // 发往ElasticSearch +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/3_Goroutine/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/3_Goroutine/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..ccb3d7ea91462659002695dd3fa94552aee7eb8d --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/3_Goroutine/main.go" @@ -0,0 +1,24 @@ +package main + +import ( + "fmt" + "time" +) + +func hello(i int) { + fmt.Println("hello ", i) +} + +// 程序启动之后,会创建一个主goroutine去执行 +func main() { + // 开启一个单独的goroutine去执行hello函数(函数) + for i := 0; i < 10; i++ { + go func(i int) { + // 闭包问题,需要在外面传递一个进去 + fmt.Println(i) + }(i) + } + + fmt.Println("main") + time.Sleep(time.Second) +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/4_socket/client.exe" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/4_socket/client.exe" new file mode 100644 index 0000000000000000000000000000000000000000..1c78f75834837b6ce12975fb44b6a2ee0bfd3050 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/4_socket/client.exe" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/4_socket/client.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/4_socket/client.go" new file mode 100644 index 0000000000000000000000000000000000000000..8d5b4ceaaf7ececdab7ecce0cfa1aaf58c09a958 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/4_socket/client.go" @@ -0,0 +1,36 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" +) +func getInput() string { + //使用os.Stdin开启输入流 + //函数原型 func NewReader(rd io.Reader) *Reader + //NewReader创建一个具有默认大小缓冲、从r读取的*Reader 结构见官方文档 + in := bufio.NewReader(os.Stdin) + //in.ReadLine函数具有三个返回值 []byte bool error + //分别为读取到的信息 是否数据太长导致缓冲区溢出 是否读取失败 + str, _, err := in.ReadLine() + if err != nil { + return err.Error() + } + return string(str) +} + +// tcp client +func main() { + // 与server端建立连接 + conn, err := net.Dial("tcp", "127.0.0.1:20000") + if err != nil { + fmt.Println("dial 127.0.0.1:20000 failed, err:", err) + return + } + // 发送数据 + conn.Write([]byte(getInput())) + + // 关闭流 + defer conn.Close() +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/4_socket/server.exe" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/4_socket/server.exe" new file mode 100644 index 0000000000000000000000000000000000000000..7f246a81b6963bdac538ef22d35ce683623956b5 Binary files /dev/null and "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/4_socket/server.exe" differ diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/4_socket/server.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/4_socket/server.go" new file mode 100644 index 0000000000000000000000000000000000000000..5c585bdab225cb9a2af5ca04189507c7d1f8a6d3 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/4_socket/server.go" @@ -0,0 +1,39 @@ +package main + +import ( + "fmt" + "net" +) + +// 用于接收请求的方法 +func processConn(conn net.Conn) { + // 与客户端通信 + var tmp [128]byte + // 使用for循环监听消息 + for { + n, err := conn.Read(tmp[:]) + if err != nil { + fmt.Println("read from conn failed, err:", err) + return + } + fmt.Println(conn, string(tmp[:n])) + } +} +func main() { + // 本地端口启动服务 + listen, err := net.Listen("tcp", "127.0.0.1:20000") + if err!= nil { + fmt.Println("start server on failed ", err) + } + + // for循环监听 + for { + // 等待别人来建立连接 + conn, err := listen.Accept() + if err != nil { + fmt.Println("accept failed, err: ", err) + return + } + go processConn(conn) + } +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/8_JsonDemo/conf.ini" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/8_JsonDemo/conf.ini" new file mode 100644 index 0000000000000000000000000000000000000000..e4857f31b0c4e47cf4f23efd1a65dfc7ed9c290c --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/8_JsonDemo/conf.ini" @@ -0,0 +1,5 @@ +[mysql] +address=127.0.0.1 +port=3306 +username=root +password=root diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/8_JsonDemo/init.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/8_JsonDemo/init.go" new file mode 100644 index 0000000000000000000000000000000000000000..123c2e9713d2c810d4d440fa2ddc0d1016de0d5e --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/8_JsonDemo/init.go" @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" + "reflect" +) + +// ini配置文件解析器 + +// MysqlConfig MySQL配置结构体 +type MysqlConfig struct { + Address string `ini:"address"` + Port int `ini:"port"` + Username string `ini:"username"` + Password string `ini:"password"` +} + +func loadIni(x interface{}) { + v := reflect.ValueOf(x) + fmt.Println(v) +} + +func main() { + var mc MysqlConfig + loadIni(&mc) + fmt.Println(mc.Address, mc.Port, mc.Username, mc.Password) +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/8_JsonDemo/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/8_JsonDemo/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..ebd54cc71226632f84ba8d8a8ab801e9a61a0a16 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/8_JsonDemo/main.go" @@ -0,0 +1,18 @@ +package main + +import ( + "encoding/json" + "fmt" +) + +type person struct { + Name string `json:"name"` + Age int `json:"age"` +} + +func main() { + str := `{"name":"张三", "age":15}` + var p person + json.Unmarshal([]byte(str), &p) + fmt.Println(p.Name, p.Age) +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/9_httpClient/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/9_httpClient/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..f67a32f786c83c5681691dd98fccadcf49db407e --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/9_httpClient/main.go" @@ -0,0 +1,41 @@ +package main + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/url" +) + +func main() { + res, err := http.Get("http://127.0.0.1:9090/query?name=zansan&age=10") + if err != nil { + fmt.Println(err) + return + } + + // 从res中把服务端返回的数据读取出来 + b, err := ioutil.ReadAll(res.Body) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(string(b)) + + + data := url.Values{} + urlObj, _ := url.Parse("http://127.0.0.1:9090/query") + data.Set("name", "周林") + data.Set("age", "100") + // 对请求进行编码 + queryStr := data.Encode() + urlObj.RawQuery = queryStr + + req, err := http.NewRequest("GET", urlObj.String(), nil) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(req) + +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/9_httpserver/main.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/9_httpserver/main.go" new file mode 100644 index 0000000000000000000000000000000000000000..a6e3d6f6121abc5b3981249fe706253cd7b67470 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/9_httpserver/main.go" @@ -0,0 +1,34 @@ +package main + +import ( + "fmt" + "io/ioutil" + "net/http" +) + +func f1(w http.ResponseWriter, r *http.Request) { + index, err := ioutil.ReadFile("./index.html") + if err != nil { + w.Write([]byte(fmt.Sprintf("%v", err))) + } + w.Write([]byte(index)) +} + +func f2(w http.ResponseWriter, r *http.Request) { + fmt.Println(r.URL) + fmt.Println(r.URL.Query()) // 识别URL中的参数 + queryParams := r.URL.Query() + name := queryParams.Get("name") + age := queryParams.Get("age") + fmt.Println("传递来的name:", name) + fmt.Println("传递来的age:", age) + fmt.Println(r.Method) + fmt.Println(ioutil.ReadAll(r.Body)) +} + +func main() { + http.HandleFunc("/index", f1) + http.HandleFunc("/query", f2) + http.HandleFunc("/about", f1) + http.ListenAndServe("127.0.0.1:9090", nil) +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/LeetCode/1_linkList.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/LeetCode/1_linkList.go" new file mode 100644 index 0000000000000000000000000000000000000000..1fb9ce3b9ef63693c8b9fdef075407e8b5d9903e --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/LeetCode/1_linkList.go" @@ -0,0 +1,15 @@ +package main + +// 判断是否有环 +// 最简单的方法,就是使用快慢指针,一个走一步,一个走两步,如果相遇了,那么说明有环 + +type link struct { + // 值 + val int + // 下一个节点 + next *link +} + +func main() { + +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/MyLogger/FileLogger.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/MyLogger/FileLogger.go" new file mode 100644 index 0000000000000000000000000000000000000000..de99e4906c740ac4ba2c653e3d776315cb313a3a --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/MyLogger/FileLogger.go" @@ -0,0 +1,22 @@ +package main + +// 往文件里面写日志相关的代码 +type FileLogger struct { + Level LogLevel + filePath string // 日志文件保存的路径 + fileName string // 日志文件保存的文件名 + maxFileSize int64 // 最大的文件大小 +} + +func NewFileLogger(levelStr, fp, fn string, maxSize int64)(*FileLogger) { + LogLevel, err := parseLogLevel(levelStr) + if err != nil { + panic(err) + } + return &FileLogger{ + Level: LogLevel, + filePath: fp, + fileName: fn, + maxFileSize: maxSize, + } +} diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/MyLogger/MyLogger.go" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/MyLogger/MyLogger.go" new file mode 100644 index 0000000000000000000000000000000000000000..f4abfde55c7306bb85bad0dd64444006eabb1869 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/MyLogger/MyLogger.go" @@ -0,0 +1,175 @@ +package main + +import ( + "errors" + "fmt" + "os" + "path" + "runtime" + "strings" + "time" +) + +// 往终端写日志相关内容 + +type LogLevel uint16 + +// 定义日志级别 +const( + UNKNOWN LogLevel = iota // 0 + DEBUG + TRACE + INFO + WARNING + ERROR + FATAL +) + +// Logger日志结构体 +type Logger struct { + Level LogLevel +} + +func parseLogLevel(s string) (LogLevel, error) { + s = strings.ToLower(s) + switch s { + case "debug": + return DEBUG, nil + case "trace": + return TRACE, nil + case "info": + return INFO, nil + case "warning": + return WARNING, nil + case "error": + return ERROR, nil + case "fatal": + return FATAL, nil + default: + err := errors.New("无效的日志级别") + return UNKNOWN, err + } + +} + +func getLogLevelStr(logLevel LogLevel) (string) { + switch logLevel { + case DEBUG: + return "debug" + case TRACE: + return "trace" + case INFO: + return "info" + case WARNING: + return "warning" + case ERROR: + return "error" + case FATAL: + return "fatal" + default: + return "unknown" + } +} + +// 获取函数名、文件名、行号 +// skip表示隔了几层 +func getInfo(skip int)(funcName string, fileName string, lineNo int) { + // pc:函数信息 + // file:文件 + // line:行号,也就是当前行号 + pc, file, line, ok := runtime.Caller(skip) + if !ok { + fmt.Printf("runtime.Caller() failed, err:%v \n") + return + } + funName := runtime.FuncForPC(pc).Name() + + return funName, path.Base(file), line +} + +// Logger构造方法 +func NewLog(levelStr string) Logger { + level, err := parseLogLevel(levelStr) + if err != nil { + panic(err) + } + // 构造了一个Logger对象 + return Logger{ + Level: level, + } +} + +// 判断啥级别的日志可以输出是否输出 +func (l Logger) enable(logLevel LogLevel) bool { + return logLevel >= l.Level +} + +func printLog(lv LogLevel, format string, a ...interface{}) { + + msg := fmt.Sprintf(format, a...) + now := time.Now().Format("2006-01-02 15:04:05") + // 拿到第二层的函数名 + funcName, filePath, lineNo := getInfo(3) + + fileObj, err := os.OpenFile("./xx.log", os.O_APPEND | os.O_CREATE | os.O_WRONLY, 0644) + if err != nil { + fmt.Printf("open file failed, err : %v \n", err) + return + } + + fmt.Fprintf(fileObj, "[%s] [%s] [%s:%s:%d] %s \n", now, getLogLevelStr(lv),filePath, funcName, lineNo, msg) + + fmt.Printf("[%s] [%s] [%s:%s:%d] %s \n", now, getLogLevelStr(lv),filePath, funcName, lineNo, msg) + +} + +func (l Logger) Debug(format string, a ...interface{}) { + if l.enable(DEBUG) { + printLog(DEBUG, format, a) + } +} + +func (l Logger) TRACE(msg string) { + if l.enable(TRACE) { + printLog(TRACE, msg) + } +} + +func (l Logger) Info(msg string) { + if l.enable(INFO) { + printLog(INFO, msg) + } +} + +func (l Logger) Warning(msg string) { + + if l.enable(WARNING) { + printLog(WARNING, msg) + } +} + +func (l Logger) Error(msg string) { + if l.enable(ERROR) { + printLog(ERROR, msg) + } +} + +func (l Logger) Fatal(msg string) { + if l.enable(FATAL) { + printLog(FATAL, msg) + } +} + +func main() { + + log := NewLog("DEBUG") + for { + log.Debug("这是一条DEBUG日志: %v", 123) + log.Info("这是一条INFO日志") + log.Warning("这是一条WARNING日志") + log.Error("这是一条ERROR日志") + log.Fatal("这是一条FATAL日志") + fmt.Println("----------------") + time.Sleep(time.Second) + } +} \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/go.mod" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/go.mod" new file mode 100644 index 0000000000000000000000000000000000000000..5de96f25108ecd4dd2a6346c699287703fbf81b0 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/go.mod" @@ -0,0 +1,20 @@ +module GoAdvanceCode + +go 1.14 + +require ( + github.com/coreos/etcd v3.3.25+incompatible // indirect + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect + github.com/go-redis/redis v6.15.9+incompatible // indirect + github.com/go-sql-driver/mysql v1.5.0 // indirect + github.com/gogo/protobuf v1.3.1 // indirect + github.com/google/uuid v1.1.2 // indirect + github.com/hpcloud/tail v1.0.0 + go.etcd.io/etcd v3.3.25+incompatible + go.uber.org/zap v1.16.0 // indirect + google.golang.org/grpc v1.32.0 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect +) + +replace google.golang.org/grpc => google.golang.org/grpc v1.26.0 \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/go.sum" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/go.sum" new file mode 100644 index 0000000000000000000000000000000000000000..f5da186f78c6262167d9187f7da95fc666b97337 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/go.sum" @@ -0,0 +1,116 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/coreos/etcd v0.5.0-alpha.5 h1:0Qi6Jzjk2CDuuGlIeecpu+em2nrjhOgz2wsIwCmQHmc= +github.com/coreos/etcd v3.3.25+incompatible h1:0GQEw6h3YnuOVdtwygkIfJ+Omx0tZ8/QkVyXI4LkbeY= +github.com/coreos/etcd v3.3.25+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= +github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +go.etcd.io/etcd v0.5.0-alpha.5 h1:VOolFSo3XgsmnYDLozjvZ6JL6AAwIDu1Yx1y+4EYLDo= +go.etcd.io/etcd v3.3.25+incompatible h1:V1RzkZJj9LqsJRy+TUBgpWSbZXITLB819lstuTFoZOY= +go.etcd.io/etcd v3.3.25+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/index.html" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/index.html" new file mode 100644 index 0000000000000000000000000000000000000000..7dd67e1f5ca552d26945b25d26da72741a03f0bb --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/index.html" @@ -0,0 +1,7 @@ + + 蘑菇博客 + +
蘑菇博客测试标题
+ 点我去百度 + + \ No newline at end of file diff --git "a/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/xx.log" "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/xx.log" new file mode 100644 index 0000000000000000000000000000000000000000..3aaac6e540c17a1086ddb376b1c6c4918234ee43 --- /dev/null +++ "b/Golang/Golang\350\277\233\351\230\266/GoAdvanceCode/xx.log" @@ -0,0 +1,100 @@ +[2020-08-16 09:45:51] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:45:51] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:45:51] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:45:51] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:45:51] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:45:52] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:45:52] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:45:52] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:45:52] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:45:52] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:45:53] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:45:53] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:45:53] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:45:53] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:45:53] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:45:54] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:45:54] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:45:54] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:45:54] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:45:54] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:45:55] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:45:55] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:45:55] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:45:55] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:45:55] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:45:56] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:45:56] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:45:56] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:45:56] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:45:56] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:21] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:22] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:22] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:22] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:22] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:23] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:23] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:23] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:23] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:23] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:24] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:24] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:24] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:24] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:24] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:25] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:25] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:25] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:25] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:25] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:26] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:26] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:26] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:26] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:26] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:27] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:27] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:27] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:27] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:27] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:28] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:28] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:28] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:28] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:28] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:29] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:29] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:29] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:29] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:29] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:30] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:30] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:30] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:30] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:30] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:31] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:31] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:31] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:31] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:31] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:32] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:32] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:32] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:32] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:32] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:33] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:33] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:33] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:33] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:33] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:34] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:34] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:34] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:34] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:34] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 +[2020-08-16 09:46:35] [debug] [MyLogger.go:main.main:167] 这是一条DEBUG日志: [123] +[2020-08-16 09:46:35] [info] [MyLogger.go:main.main:168] 这是一条INFO日志 +[2020-08-16 09:46:35] [warning] [MyLogger.go:main.main:169] 这是一条WARNING日志 +[2020-08-16 09:46:35] [error] [MyLogger.go:main.main:170] 这是一条ERROR日志 +[2020-08-16 09:46:35] [fatal] [MyLogger.go:main.main:171] 这是一条FATAL日志 diff --git a/Golang/README.md b/Golang/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e4053ebc9d9a43c21085fdd38bcd9b0dd18996b8 --- /dev/null +++ b/Golang/README.md @@ -0,0 +1,23 @@ +## Golang基础 + +> 来源Bilibili IT营 大地老师学习视频:[点我传送](https://www.bilibili.com/video/BV14T4y1g7h9) + +- [Go语言的安装](./Golang基础/0_Go语言的安装) +- [Go语言发展简史](./Golang基础/1_Go语言发展简史) +- [Go的变量](./Golang基础/2_Go的变量) +- [Go的数据类型](./Golang基础/3_Go的数据类型) +- [Go的运算符](./Golang基础/4_Go的运算符) +- [Go的流程控制](./Golang基础/5_Go的流程控制) +- [Go的数组](./Golang基础/6_Go的数组) +- [Go的切片](./Golang基础/7_Go的切片) +- [Go的map](./Golang基础/8_Go的map) +- [Go的函数](./Golang基础/9_Go的函数) +- [Go中的日期函数](./Golang基础/10_Go中的日期函数) +- [Go中的指针](./Golang基础/11_Go中的指针) +- [Go中的结构体](./Golang基础/12_Go中的结构体) +- [Go中的包以及GoMod](./Golang基础/13_Go中的包以及GoMod) +- [Go中的接口](./Golang基础/14_Go中的接口) +- [goroutine实现并行和并发](./Golang基础/15_goroutine实现并行和并发) +- [Golang中的反射](./Golang基础/16_Golang中的反射) +- [源码](./Golang基础/Code) + diff --git "a/Golang/\346\235\202\350\256\260/Gin\346\241\206\346\236\266\344\270\255\350\256\251tmpl\346\250\241\346\235\277\346\226\207\344\273\266\346\234\211\350\257\255\346\263\225\346\217\220\347\244\272/README.md" "b/Golang/\346\235\202\350\256\260/Gin\346\241\206\346\236\266\344\270\255\350\256\251tmpl\346\250\241\346\235\277\346\226\207\344\273\266\346\234\211\350\257\255\346\263\225\346\217\220\347\244\272/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..c1a144d1339cff1766956c62af9582ff658d8cb1 --- /dev/null +++ "b/Golang/\346\235\202\350\256\260/Gin\346\241\206\346\236\266\344\270\255\350\256\251tmpl\346\250\241\346\235\277\346\226\207\344\273\266\346\234\211\350\257\255\346\263\225\346\217\220\347\244\272/README.md" @@ -0,0 +1,22 @@ +# Gin框架中让tmpl模板文件有语法提示 + +## 前言 + +在Gin中,我们要使用 `.tmpl` 结尾的模板文件,但是我们在new的时候,发现没有对应的文件,所以它就会被当成普通的文件来进行解析,因此也没有提示,这对我们使用goland来开发,是非常痛苦的事情 + +## 解决方法 + +其实 `.tmpl` 本质上,还是一个html文件,只是有部分的是有些区别的,比如在渲染数据的时候,我们使用的是这种方法 + +```bash +{{.data}} +``` + +因此,我们就完全可以使用.html模板来解析我们的 `.tmpl`,我们打开我们的goland settting页面 + +![image-20200913213623681](images/image-20200913213623681.png) + +找到 File Types ,然后在找到 HTML,把 *.tmpl 添加进去即可,就能以html的方式来进行解析了 + +![image-20200913213722522](images/image-20200913213722522.png) + diff --git "a/Golang/\346\235\202\350\256\260/Gin\346\241\206\346\236\266\344\270\255\350\256\251tmpl\346\250\241\346\235\277\346\226\207\344\273\266\346\234\211\350\257\255\346\263\225\346\217\220\347\244\272/images/image-20200913213623681.png" "b/Golang/\346\235\202\350\256\260/Gin\346\241\206\346\236\266\344\270\255\350\256\251tmpl\346\250\241\346\235\277\346\226\207\344\273\266\346\234\211\350\257\255\346\263\225\346\217\220\347\244\272/images/image-20200913213623681.png" new file mode 100644 index 0000000000000000000000000000000000000000..921eca1c1bad345197a2cc4ea6be50f31ac79978 Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/Gin\346\241\206\346\236\266\344\270\255\350\256\251tmpl\346\250\241\346\235\277\346\226\207\344\273\266\346\234\211\350\257\255\346\263\225\346\217\220\347\244\272/images/image-20200913213623681.png" differ diff --git "a/Golang/\346\235\202\350\256\260/Gin\346\241\206\346\236\266\344\270\255\350\256\251tmpl\346\250\241\346\235\277\346\226\207\344\273\266\346\234\211\350\257\255\346\263\225\346\217\220\347\244\272/images/image-20200913213722522.png" "b/Golang/\346\235\202\350\256\260/Gin\346\241\206\346\236\266\344\270\255\350\256\251tmpl\346\250\241\346\235\277\346\226\207\344\273\266\346\234\211\350\257\255\346\263\225\346\217\220\347\244\272/images/image-20200913213722522.png" new file mode 100644 index 0000000000000000000000000000000000000000..013271eee074bb31a77f9b9cca54b664a5aa364c Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/Gin\346\241\206\346\236\266\344\270\255\350\256\251tmpl\346\250\241\346\235\277\346\226\207\344\273\266\346\234\211\350\257\255\346\263\225\346\217\220\347\244\272/images/image-20200913213722522.png" differ diff --git "a/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/README.md" "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ef2d0628e805d101de749aee825ebd793dc412c4 --- /dev/null +++ "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/README.md" @@ -0,0 +1,69 @@ +# Goland添加注释模板 + +## 前言 + +对于习惯了使用IDEA进行Java开发的人来说,Go里面的注释方式确实让我有些看不太下去了... + +这是Java里面的场景注释 + +![image-20200914201634434](images/image-20200914201634434.png) + +然后这是Go语言中的注释,都是使用// 来进行注释的,不像Java中的一样有条理和规范 + +![image-20200914201651682](images/image-20200914201651682.png) + +因此,就想着通过定义注释模板,写出比较舒服的注释 + +## 类模板定义 + +Goland中也提供了我们注释模板的定义,到setting中配置即可,首先我们定义创建新文件的时候,生成的类注释 + +![image-20200914203043675](images/image-20200914203043675.png) + +找到Go File即可,然后输入下面的信息保存即可 + +```bash +package ${GO_PACKAGE_NAME} +/** + * @Description + * @Author 陌溪 + * @Date ${DATE} ${TIME} + **/ +func main() { + +} +``` + +下面我们通过 new,创建一个go file文件进行测试 + +![image-20200914204319229](images/image-20200914204319229.png) + +可以看到,刚刚添加的文件,就有了测试信息了~ + +## 方法模板定义 + +下面我们还需要做的就是类似于Java中的方法定义了,我们继续来到settings页面 + +![image-20200914205246807](images/image-20200914205246807.png) + +填写上模板信息 + +```bash +/** + * @Description $end$ + * @Param $param$ + * @return $return$ + **/ +``` + +然后在设置触发条件,我们是回车的时候触发,所以选择Enter + +![image-20200914204809757](images/image-20200914204809757.png) + +然后在选择什么文件下触发,选择go文件 + +![image-20200914205313206](images/image-20200914205313206.png) + +下面我们找到一个方法,输入mc 然后回车即可 + +![image-20200914205343678](images/image-20200914205343678.png) \ No newline at end of file diff --git "a/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914201634434.png" "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914201634434.png" new file mode 100644 index 0000000000000000000000000000000000000000..c69157a07ba234b82d6f1667b5cdfb54eda66da0 Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914201634434.png" differ diff --git "a/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914201651682.png" "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914201651682.png" new file mode 100644 index 0000000000000000000000000000000000000000..b0010d2cf05634fe9eb8865afde7609327564900 Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914201651682.png" differ diff --git "a/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914203043675.png" "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914203043675.png" new file mode 100644 index 0000000000000000000000000000000000000000..8f352e5a76607dde94cfbedf143963fa06954108 Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914203043675.png" differ diff --git "a/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914204319229.png" "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914204319229.png" new file mode 100644 index 0000000000000000000000000000000000000000..89d1fed78eb737ba521c7e20ef6857cd53ad2a14 Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914204319229.png" differ diff --git "a/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914204723832.png" "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914204723832.png" new file mode 100644 index 0000000000000000000000000000000000000000..5d18a6572b6d969f69a513433974b1cef1d4aa31 Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914204723832.png" differ diff --git "a/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914204809757.png" "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914204809757.png" new file mode 100644 index 0000000000000000000000000000000000000000..1f7d86e5c479104819960b068034434e8c0c8bc7 Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914204809757.png" differ diff --git "a/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914204907726.png" "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914204907726.png" new file mode 100644 index 0000000000000000000000000000000000000000..714038ccf49c33cdc79206c061820511e2ff6572 Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914204907726.png" differ diff --git "a/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914205246807.png" "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914205246807.png" new file mode 100644 index 0000000000000000000000000000000000000000..4647849d7238d6659f5dc8c69ec42b1a90bd9c7d Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914205246807.png" differ diff --git "a/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914205313206.png" "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914205313206.png" new file mode 100644 index 0000000000000000000000000000000000000000..42feb9b144e50aa2e9cf0e349343dfdb13b2763b Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914205313206.png" differ diff --git "a/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914205343678.png" "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914205343678.png" new file mode 100644 index 0000000000000000000000000000000000000000..f01f314b98bc72ef7464bfed13429defffdd1269 Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/Goland\346\267\273\345\212\240\346\263\250\351\207\212\346\250\241\346\235\277/images/image-20200914205343678.png" differ diff --git "a/Golang/\346\235\202\350\256\260/\345\233\275\345\206\205\347\216\257\345\242\203\346\211\247\350\241\214GoGet\345\221\275\344\273\244\345\244\261\350\264\245\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/README.md" "b/Golang/\346\235\202\350\256\260/\345\233\275\345\206\205\347\216\257\345\242\203\346\211\247\350\241\214GoGet\345\221\275\344\273\244\345\244\261\350\264\245\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..50af2468d8c3aae3d3d9d2e260eaad19efad1080 --- /dev/null +++ "b/Golang/\346\235\202\350\256\260/\345\233\275\345\206\205\347\216\257\345\242\203\346\211\247\350\241\214GoGet\345\221\275\344\273\244\345\244\261\350\264\245\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/README.md" @@ -0,0 +1,64 @@ +# 执行GoGet命令下载依赖失败的解决方法 + +## 前言 + +最近在学习go连接mysql数据库这块,需要下载mysql的驱动包,使用的是下面的命令 + +```bash +go get -u github.com/go-sql-driver/mysql +``` + +但是在执行的时候,总是出现如下的错误 + +```bash +go get github.com/go-sql-driver/mysql: module github.com/go-sql-driver/mysql: Get "https://proxy.golang.org/github.com/go-sql-driver/mysql/@v/list": dial tcp 172.217.160.81:443: connect +ex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. +``` + +很显然上面的问题就是因为如果连接对应的下载服务器所引起的 + +## 解决方法 + +通过阅读博客,我发现了有专门一个 [Go模块代理网站](https://goproxy.io/zh/) ,提供了一下几种解决方案,使用的是国内的代理 + +![image-20200822085516300](images/image-20200822085516300.png) + +### 如果您使用的 Go 版本是 1.13 及以上 (推荐) + +```bash +go env -w GO111MODULE=on +go env -w GOPROXY=https://goproxy.io,direct + +# 设置不走 proxy 的私有仓库,多个用逗号相隔(可选) +go env -w GOPRIVATE=*.corp.example.com + +# 设置不走 proxy 的私有组织(可选) +go env -w GOPRIVATE=example.com/org_name +``` + +设置完上面几个环境变量后,您的 `go` 命令将从公共代理镜像中快速拉取您所需的依赖代码了。[私有库的支持请看这里](https://goproxy.io/zh/docs/goproxyio-private.html)。 + +### 如果您使用的 Go 版本是 1.12 及以下 + +**Bash (Linux or macOS)** + +```shell +# 启用 Go Modules 功能 +export GO111MODULE=on +# 配置 GOPROXY 环境变量 +export GOPROXY=https://goproxy.io +``` + +或者,根据[文档](https://goproxy.io/zh/docs/getting-started.html)可以把上面的命令写到`.profile`或`.bash_profile`文件中长期生效。 + +**PowerShell (Windows)** + +```shell +# 启用 Go Modules 功能 +$env:GO111MODULE="on" +# 配置 GOPROXY 环境变量 +$env:GOPROXY="https://goproxy.io" +``` + +现在,当你构建或运行你的应用时,Go 将会通过 goproxy.io 获取依赖 + diff --git "a/Golang/\346\235\202\350\256\260/\345\233\275\345\206\205\347\216\257\345\242\203\346\211\247\350\241\214GoGet\345\221\275\344\273\244\345\244\261\350\264\245\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/images/image-20200822085516300.png" "b/Golang/\346\235\202\350\256\260/\345\233\275\345\206\205\347\216\257\345\242\203\346\211\247\350\241\214GoGet\345\221\275\344\273\244\345\244\261\350\264\245\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/images/image-20200822085516300.png" new file mode 100644 index 0000000000000000000000000000000000000000..ab371ea352a5be63d0404dc47e510934d40e806f Binary files /dev/null and "b/Golang/\346\235\202\350\256\260/\345\233\275\345\206\205\347\216\257\345\242\203\346\211\247\350\241\214GoGet\345\221\275\344\273\244\345\244\261\350\264\245\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/images/image-20200822085516300.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..693c62cb6fb4c53053fc222c36073669b9630f54 --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/README.md" @@ -0,0 +1,154 @@ +# 对象实例化内存布局与访问定位 + +## 对象实例化 + +### 面试题 + +- 对象在 JVM 中是怎么存储的? +- 对象头信息里面有哪些东西? +- Java 对象头有什么? + +从对象创建的方式和步骤开始说 + +![image-20200709095356247](https://gitee.com/xlshi/blog_img/raw/master/img/20201009175609.png) + +### 对象创建方式 + +- new:最常见的方式、单例类中调用 getInstance 的静态类方法,XXXFactory 的静态方法 +- Class 的 newInstance 方法:在 JDK 9 里面被标记为过时的方法,**因为只能调用空参构造器**,权限必须是 public +- Constructor 的 newInstance(XXX):反射的方式,可以调用空参的,或者带参的构造器,权限没有要求 +- 使用 clone():不调用任何的构造器,要求当前的类需要实现 Cloneable 接口中的 clone() 方法 +- 使用反序列化:序列化一般用于 Socket 的网络传输,从文件、网络中获取文件二进制流 +- 第三方库 Objenesis + +### 创建对象的步骤 + +#### 判断对象对应的类是否加载、链接、初始化 + +虚拟机遇到一条 new 指令,首先去检查这个指令的参数能否在 Metaspace 的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化(即判断类元信息是否存在)。如果没有,那么在双亲委派模式下,使用当前类加载器以 ClassLoader + 包名 + 类名为 Key 进行查找对应的 .class 文件,如果没有找到文件,则抛出 ClassNotFoundException 异常,如果找到,则进行类加载,并生成对应的 Class 对象。 + +#### 为对象分配内存 + +首先计算对象占用空间的大小,接着在堆中划分一块内存给新对象。如果实例成员变量是引用变量,仅分配引用变量空间即可,即4个字节大小( long 和 double 是8个字节) + +- 如果内存规整:使用指针碰撞 + +>如果内存是规整的,那么虚拟机将采用的是指针碰撞法(Bump The Point)来为对象分配内存。 +> +>意思是所有用过的内存在一边,空闲的内存放另外一边,中间放着一个指针作为分界点的指示器,分配内存就仅仅是把指针指向空闲那边挪动一段与对象大小相等的距离罢了。如果垃圾收集器选择的是 Serial ,ParNew 这种基于压缩算法的,虚拟机采用这种分配方式。一般使用带 Compact(整理)过程的收集器时,使用指针碰撞。 + +- 如果内存不规整:虚拟表需要维护一个列表:空闲列表分配 + +>如果内存不是规整的,已使用的内存和未使用的内存相互交错,那么虚拟机将采用的是空闲列表来为对象分配内存。意思是虚拟机维护了一个列表,记录上那些内存块是可用的,再分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的内容。这种分配方式成为了 “空闲列表(Free List)”。 + +说明:选择哪种分配方式由 Java 堆是否规整所决定,而 Java 堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。 + +#### 处理并发问题 + +在分配内存空间时,另外一个问题是及时保证 new 对象时候的线程安全性:创建对象是非常频繁的操作,虚拟机需要解决并发问题。虚拟机采用了两种方式解决并发问题: + +- CAS(Compare And Swap)失败重试、区域加锁:保证指针更新操作的原子性 +- TLAB 把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在 Java 堆中预先分配一个小块内存,称为本地线程分配缓冲区,(TLAB,Thread Local Allocation Buffer)虚拟机是否使用 TLAB,可以通过 -XX:+/-UseTLAB 参数来设定 + +#### 初始化分配到的内存 + +内存分配结束,虚拟机将分配到的内存空间都初始化为零值(不包括对象头),这一步保证了对象的实例字段在 Java 代码中可以不用赋初始值就可以直接使用,程序能访问到这些字段的数据类型所对应的零值 + +- 属性的默认初始化 +- 显示初始化 +- 代码块中的初始化 +- 构造器初始化 +- 所有属性设置默认值,保证对象实例字段在不赋值可以直接使用 + +#### 设置对象的对象头 + +将对象的所属类(即类的元数据信息)、对象的 HashCode 和对象的 GC 信息、锁信息等数据存储在对象的对象头中。这个过程的具体设置方式取决于 JVM 实现。 + +#### 执行 init 方法进行初始化 + +在 Java 程序的视角看来,初始化才正式开始。初始化成员变量,执行实例化代码块,调用类的构造方法,并把堆内对象的首地址赋值给引用变量 + +因此一般来说(由字节码中跟随 invokespecial 指令所决定),new 指令之后会接着就是执行方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完成创建出来。 + +### 对象实例化的过程 + +1. 加载类元信息 +2. 为对象分配内存 +3. 处理并发问题 +4. 属性的默认初始化(零值初始化) +5. 设置对象头信息 +6. 属性的显示初始化、代码块中初始化、构造器中初始化 + +## 对象内存布局 + +![image-20200709151033237](https://gitee.com/xlshi/blog_img/raw/master/img/20201009181531.png) + +### 对象头(Header) + +对象头包含了两部分,分别是**运行时元数据(Mark Word)**和**类型指针** + +> 如果是数组,还需要记录数组的长度 + +#### 运行时元数据 + +- 哈希值(HashCode) +- GC 分代年龄 +- 锁状态标志 +- 线程持有的锁 +- 偏向线程 ID +- 偏向时间戳 + +#### 类型指针 + +指向类元数据 InstanceKlass ,确定该对象所属的类型。指向的其实是方法区中存放的类元信息 + +### 实例数据(Instance Data) + +#### 说明 + +它是对象真正存储的有效信息,包括程序代码中定义的各种类型的字段(包括从父类继承下来的和本身拥有的字段) + +#### 规划 + +- 相同宽度的字段总是被分配在一起 +- 父类中定义的变量会出现在子类之前 +- 如果 CompactFields 参数为 true(默认为 true),子类的窄变量可能插入到父类变量的空隙 + +### 对齐填充(Padding) + +不是必须的,也没有特别含义,仅仅起到占位符的作用 + +### 小结 + +![image-20200709152801713](https://gitee.com/xlshi/blog_img/raw/master/img/20201009181541.png) + +## 对象的访问定位 + +### 图示 + +JVM 是如何通过栈帧中的对象引用访问到其内部的对象实例呢?——定位,通过栈上 reference 访问 + +![image-20200709164149920](https://gitee.com/xlshi/blog_img/raw/master/img/20201009181548.png) + +创建对象的目的就是为了使用它 + +### 对象访问的两种方式 + +#### 句柄访问 + +![image-20200709164342002](https://gitee.com/xlshi/blog_img/raw/master/img/20201009181602.png) + +句柄访问就是说栈的局部变量表中,记录的对象的引用,然后在堆空间中开辟了一块空间,也就是**句柄池** + +#### 优点 + +reference 中存储稳定句柄地址,对象被移动(垃圾收集时移动对象很普遍)时只会改变句柄中实例数据指针即可,reference 本身不需要被修改 + +#### 直接指针(HotSpot采用) + +![image-20200709164350466](https://gitee.com/xlshi/blog_img/raw/master/img/20201009181633.png) + +直接指针是局部变量表中的引用,直接指向堆中的实例,在对象实例中有类型指针,指向的是方法区中的对象类型数据 + + + diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709095356247.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709095356247.png" new file mode 100644 index 0000000000000000000000000000000000000000..d858f1dca1812691f0d0b2c4e36df455cccab847 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709095356247.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709151033237.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709151033237.png" new file mode 100644 index 0000000000000000000000000000000000000000..29b8201bcb73dd93af297d8fecf27bd4a94a134b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709151033237.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709152801713.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709152801713.png" new file mode 100644 index 0000000000000000000000000000000000000000..fcc37a00d46a6c69cb858cfe7b1556a0b029041b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709152801713.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709164149920.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709164149920.png" new file mode 100644 index 0000000000000000000000000000000000000000..41ee4695952f26744351d72937936897f17ea1d5 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709164149920.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709164342002.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709164342002.png" new file mode 100644 index 0000000000000000000000000000000000000000..85301309fba9a630d7845d52c9eb4aa9298b4b76 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709164342002.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709164350466.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709164350466.png" new file mode 100644 index 0000000000000000000000000000000000000000..5ac91ed8b2d126f37dbfa13468f30aa04261055d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/10_\345\257\271\350\261\241\345\256\236\344\276\213\345\214\226\345\206\205\345\255\230\345\270\203\345\261\200\344\270\216\350\256\277\351\227\256\345\256\232\344\275\215/images/image-20200709164350466.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/11_\347\233\264\346\216\245\345\206\205\345\255\230/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/11_\347\233\264\346\216\245\345\206\205\345\255\230/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..31df1d758671327c6a7fbdaa0caa9481bf40a6b4 --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/11_\347\233\264\346\216\245\345\206\205\345\255\230/README.md" @@ -0,0 +1,46 @@ +# 直接内存 Direct Memory + +不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。 + +**直接内存是在 Java 堆外的、直接向系统申请的内存区间。** + +来源于 NIO ,通过存在堆中的 DirectByteBuffer 操作 Native 内存 + +通常,访问直接内存的速度会优于 Java 堆。即读写性能高。 + +- 因此出于性能考虑,读写频繁的场合可能会考虑使用直接内存。 +- Java 的 NIO 库允许 Java 程序使用直接内存,用于数据缓冲区 + +使用下列代码,直接分配本地内存空间 + +```java +int BUFFER = 1024 * 1024 * 1024; // 1GB +ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER); +``` + +## 非直接缓存区和直接缓存区 + +原来采用 BIO 的架构,我们需要从用户态切换成内核态 + +![image-20200709170907611](https://gitee.com/xlshi/blog_img/raw/master/img/20201012110421.png) + +NIO 的方式使用了直接缓存区的概念 + +![Snipaste_2020-10-08_11-14-47.png](https://gitee.com/xlshi/blog_img/raw/master/img/20201012110433.png) + +## 存在的问题 + +也可能导致 OutOfMemoryError 异常 + +由于直接内存在 Java 堆外,因此它的大小不会直接受限于 -Xmx 指定的最大堆大小,但是系统内存是有限的,Java 堆和直接内存的总和依然受限于操作系统能给出的最大内存。 + +缺点 + +- 分配回收成本较高 +- 不受 JVM 内存回收管理 + +直接内存大小可以通过 MaxDirectMemorySize 设置 + +如果不指定,默认与堆的最大值 -Xmx 参数值一致 + +![image-20200709230647277](https://gitee.com/xlshi/blog_img/raw/master/img/20201012110436.png) \ No newline at end of file diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/11_\347\233\264\346\216\245\345\206\205\345\255\230/images/Snipaste_2020-10-08_11-14-47.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/11_\347\233\264\346\216\245\345\206\205\345\255\230/images/Snipaste_2020-10-08_11-14-47.png" new file mode 100644 index 0000000000000000000000000000000000000000..bc396dc11f35ad81134ddc7c7d886b920c88c7cc Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/11_\347\233\264\346\216\245\345\206\205\345\255\230/images/Snipaste_2020-10-08_11-14-47.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/11_\347\233\264\346\216\245\345\206\205\345\255\230/images/image-20200709170907611.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/11_\347\233\264\346\216\245\345\206\205\345\255\230/images/image-20200709170907611.png" new file mode 100644 index 0000000000000000000000000000000000000000..88535297229b81ecb01c0df98ff3bcdbea0a9795 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/11_\347\233\264\346\216\245\345\206\205\345\255\230/images/image-20200709170907611.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/11_\347\233\264\346\216\245\345\206\205\345\255\230/images/image-20200709230647277.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/11_\347\233\264\346\216\245\345\206\205\345\255\230/images/image-20200709230647277.png" new file mode 100644 index 0000000000000000000000000000000000000000..b8bbde03baef3eb9da265d490bf2bb0015405172 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/11_\347\233\264\346\216\245\345\206\205\345\255\230/images/image-20200709230647277.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ef16d703801c218e1acb5435d2d9b03506df7bed --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/README.md" @@ -0,0 +1,333 @@ +# 执行引擎 + +## 执行引擎概述 + +执行引擎属于 JVM 的下层,里面包括解释器、及时编译器、垃圾回收器 + +![image-20200710080707873](https://gitee.com/xlshi/blog_img/raw/master/img/20201012110934.png) + +**执行引擎是 Java 虚拟机核心的组成部分之一。** + +“虚拟机”是一个相对于“物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的,而**虚拟机的执行引擎则是由软件自行实现的**,因此可以不受物理条件制约地定制指令集与执行引擎的结构体系,**能够执行那些不被硬件直接支持的指令集格式**。 + +JVM 的主要任务是负责**装载字节码到其内部**,但字节码并不能够直接运行在操作系统之上,因为字节码指令并非等价于本地机器指令,它内部包含的仅仅只是一些能够被 JVM 所识别的字节码指令、符号表,以及其他辅助信息。 + +![image-20200710081118053](https://gitee.com/xlshi/blog_img/raw/master/img/20201012110941.png) + +那么,如果想要让一个 Java 程序运行起来,执行引擎(Execution Engine)的任务就是**将字节码指令解释/编译为对应平台上的本地机器指令才可以**。简单来说,**JVM 中的执行引擎充当了将高级语言翻译为机器语言的译者**。 + +![image-20200710081259276](https://gitee.com/xlshi/blog_img/raw/master/img/20201012110943.png) + +### 执行引擎的工作流程 + +1. 执行引擎在执行的过程中究竟需要执行什么样的字节码指令完全依赖于 PC 寄存器。 +2. 每当执行完一项指令操作后,PC 寄存器就会更新下一条需要被执行的指令地址。 +3. 当然方法在执行的过程中,执行引擎有可能会通过存储在局部变量表中的对象引用准确定位到存储在 Java 堆区中的对象实例信息,以及通过对象头中的元数据指针定位到目标对象的类型信息。 + +![image-20200710081627217](https://gitee.com/xlshi/blog_img/raw/master/img/20201012110946.png) + +从外观上来看,所有的 Java 虚拟机的执行引擎输入、输出都是一致的:输入的是字节码二进制流,处理过程是字节码解析执行的等效过程,输出的是执行过程。 + +## Java代码编译和执行过程 + +大部分的程序代码转换成物理机的目标代码或虚拟机能执行的指令集之前,都需要经过上图中的各个步骤 + +- 前面橙色部分是生成字节码文件的过程,和 JVM 无关 +- 后面蓝色和绿色才是 JVM 需要考虑的过程 + +![image-20200710082141643](https://gitee.com/xlshi/blog_img/raw/master/img/20201012110950.png) + +Java 代码编译是由 Java 源码编译器来完成,流程图如下所示: + +![image-20200710082433146](https://gitee.com/xlshi/blog_img/raw/master/img/20201012110953.png) + +Java 字节码的执行是由 JVM 执行引擎来完成,流程图如下所示 + +![image-20200710083036258](https://gitee.com/xlshi/blog_img/raw/master/img/20201012110957.png) + +我们用一个总的图,来说说解释器和编译器 + +![image-20200710083656277](https://gitee.com/xlshi/blog_img/raw/master/img/20201012111000.png) + +### 什么是解释器(Interpreter) + +当 Java 虚拟机启动时会根据预定义的规范**对字节码采用逐行解释的方式执行**,将每条字节码文件中的内容“翻译”为对应平台的本地机器指令执行。 + +### 什么是 JIT 编译器 + +JIT(Just In Time Compiler)编译器:就是虚拟机将源代码直接编译成和本地机器平台相关的机器语言。 + +### 为什么 Java 是半编译半解释型语言 + +JDK 1.0 时代,将 Java 语言定位为“解释执行”还是比较准确的。再后来,Java 也发展出可以直接生成本地代码的编译器。现在 JVM 在执行 Java 代码的时候,通常都会将解释执行与编译执行二者结合起来进行。 + +翻译成本地代码后,就可以做一个缓存操作,存储在方法区中 + +## 机器码、指令、汇编语言 + +### 机器码 + +各种用二进制编码方式表示的指令,叫做机器指令码。开始,人们就用它编写程序,这就是机器语言。 + +机器语言虽然能够被计算机理解和接受,但和人们的语言差别太大,不易被人们理解和记忆,并且用它编程容易出差错。 + +用它编写的程序一经输入计算机,CPU 直接读取运行,因此和其他语言编的程序相比,执行速度最快。 + +机器指令与 CPU 紧密相关,所以不同种类的 CPU 所对应的机器指令也就不同。 + +### 指令 + +由于机器码是有 0 和 1 组成的二进制序列,可读性实在太差,于是人们发明了指令。 + +指令就是把机器码中特定的 0 和 1 序列,简化成对应的指令(一般为英文简写,如 mov,inc 等),可读性稍好 + +由于不同的硬件平台,执行同一个操作,对应的机器码可能不同,所以不同的硬件平台的同一种指令(比如mov),对应的机器码也可能不同。 + +### 指令集 + +不同的硬件平台,各自支持的指令,是有差别的。因此每个平台所支持的指令,称之为对应平台的指令集。 +如常见的 + +- x86 指令集,对应的是 x86 架构的平台 +- ARM 指令集,对应的是 ARM 架构的平台 + +### 汇编语言 + +由于指令的可读性还是太差,于是人们又发明了汇编语言。 + +在汇编语言中,用**助记符(Mnemonics)**代替**机器指令的操作码**,用**地址符号(Symbol)或标号(Label)**代替**指令或操作数的地址**。 + +在不同的硬件平台,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。 + +- 由于计算机只认识指令码,所以用**汇编语言编写的程序还必须翻译成机器指令码**,计算机才能识别和执行。 + +### 高级语言 + +为了使计算机用户编程序更容易些,后来就出现了各种高级计算机语言。高级语言比机器语言、汇编语言**更接近人的语言** + +当计算机执行高级语言编写的程序时,**仍然需要把程序解释和编译成机器的指令码**。完成这个过程的程序就叫做解释程序或编译程序。 + +![image-20200710085323733](https://gitee.com/xlshi/blog_img/raw/master/img/20201012111004.png) + +高级语言也不是直接翻译成机器指令,而是翻译成汇编语言,如下面说的 C 和 C++ + +### C、C++源程序执行过程 + +编译过程又可以分成两个阶段:编译和汇编。 + +编译过程:是读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码 + +汇编过程:实际上指把汇编语言代码翻译成目标机器指令的过程。 + +![image-20200710085553258](https://gitee.com/xlshi/blog_img/raw/master/img/20201012111007.png) + +### 字节码 + +字节码是一种中间状态(中间码)的二进制代码(文件),它比机器码更抽象,需要直译器转译后才能成为机器码 + +字节码主要为了实现特定软件运行和软件环境、**与硬件环境无关**。 + +字节码的实现方式是通过编译器和虚拟机器。编译器将源码编译成字节码,特定平台上的虚拟机器将字节码转译为可以直接执行的指令。 + +- 字节码典型的应用为:Java bytecode + +## 解释器 + +JVM 设计者们的初衷仅仅只是单纯地**为了满足 Java 程序实现跨平台特性**,因此避免采用静态编译的方式直接生成本地机器指令,从而诞生了实现解释器在运行时采用逐行解释字节码执行程序的想法。 + +![image-20200710090203674](https://gitee.com/xlshi/blog_img/raw/master/img/20201012111010.png) + +为什么 Java 源文件不直接翻译成不同平台对应的机器指令 ,而是翻译成字节码文件?可能是因为直接翻译的机器指令代价较大,耗时较长 + +解释器真正意义上所承担的角色就是一个运行时“翻译者”,将字节码文件中的内容“翻译”为对应平台的本地机器指令执行。 + +当一条字节码指令被解释执行完成后,接着再根据 PC 寄存器中记录的下一条需要被执行的字节码指令执行解释操作。 + +### 解释器分类 + +在 Java 的发展历史里,一共有两套解释执行器,即古老的**字节码解释器**、现在普遍使用的**模板解释器**。 + +字节码解释器在执行时通过**纯软件代码**模拟字节码的执行,效率非常低下。 + +而模板解释器将**每一条字节码和一个模板函数相关联**,模板函数中直接产生这条字节码执行时的机器码,从而很大程度上提高了解释器的性能。 + +- 在 HotSpot VM 中,解释器主要由 Interpreter 模块和 Code 模块构成。 + - Interpreter 模块:实现了解释器的核心功能 + - Code 模块:用于管理 HotSpot VM 在运行时生成的本地机器指令 + +### 现状 + +由于解释器在设计和实现上非常简单,因此除了 Java 语言之外,还有许多高级语言同样也是基于解释器执行的,比如 Python、Perl、Ruby 等。但是在今天,**基于解释器执行已经沦落为低效的代名词**,并且时常被一些 C/C++ 程序员所调侃。 + +为了解决这个问题,JVM 平台支持一种叫作**即时编译的技术**。即时编译的目的是避免函数被解释执行,而是**将整个函数体编译成为机器码,每次函数执行时,只执行编译后的机器码即可**,这种方式可以使执行效率大幅度提升。 + +不过无论如何,基于解释器的执行模式仍然为中间语言的发展做出了不可磨灭的贡献。 + +## JIT 编译器 + +### Java 代码的执行分类 + +第一种是将源代码编译成字节码文件,然后在运行时通过解释器将字节码文件转为机器码执行 + +第二种是编译执行(直接编译成机器码)。现代虚拟机为了提高执行效率,会使用即时编译技术(JIT,Just In Time)将方法编译成机器码后再执行 + +HotSpot VM 是目前市面上高性能虚拟机的代表作之一。它**采用解释器与即时编译器并存的架构**。在 Java 虚拟机运行时,解释器和即时编译器能够相互协作,各自取长补短,尽力去选择最合适的方式来权衡编译本地代码的时间和直接解释执行代码的时间。 + +在今天,Java 程序的运行性能早已脱胎换骨,已经达到了可以和 C/C++ 程序一较高下的地步。 + +### 问题来了 + +有些开发人员会感觉到诧异,**既然 HotSpot VM 中已经内置 JIT 编译器了,那么为什么还需要再使用解释器来“拖累”程序的执行性能呢?**比如 JRockit VM 内部就不包含解释器,字节码全部都依靠即时编译器编译后执行。 + +- JRockit 虚拟机是砍掉了解释器,也就是只采及时编译器。那是因为 JRockit 只部署在服务器上,一般已经有时间让他进行指令编译的过程了,对于响应来说要求不高,等及时编译器的编译完成后,就会提供更好的性能 + +首先明确: +当程序启动后,解释器可以马上发挥作用,省去编译的时间,立即执行。 +编译器要想发挥作用,把代码编译成本地代码,需要一定的执行时间。但编译为本地代码后,执行效率高。 + +所以: +尽管 JRockit VM 中程序的执行性能会非常高效,但程序在启动时必然需要花费更长的时间来进行编译。对于服务端应用来说,启动时间并非是关注重点,但对于那些看中启动时间的应用场景而言,或许就需要采用解释器与即时编译器并存的架构来换取一个平衡点。**在此模式下,当 Java 虚拟器启动时,解释器可以首先发挥作用,而不必等待即时编译器全部编译完成后再执行,这样可以省去许多不必要的编译时间。随着时间的推移,编译器发挥作用,把越来越多的代码编译成本地代码,获得更高的执行效率。** + +同时,解释执行在编译器进行激进优化不成立的时候,作为编译器的“逃生门”。 + +### HotSpot JVM执行方式 + +当虚拟机启动的时候,**解释器可以首先发挥作用**,而不必等待即时编译器全部编译完成再执行,这样可以**省去许多不必要的编译时间**。并且随着程序运行时间的推移,即时编译器逐渐发挥作用,根据热点探测功能,**将有价值的字节码编译为本地机器指令**,以换取更高的程序执行效率。 + +### 案例 + +注意解释执行与编译执行在线上环境微妙的辩证关系。**机器在热机状态可以承受的负载要大于冷机状态**。如果以热机状态时的流量进行切流,可能使处于冷机状态的服务器因无法承载流量而假死。 + +在生产环境发布过程中,以分批的方式进行发布,根据机器数量划分成多个批次,每个批次的机器数至多占到整个集群的 1/8 。曾经有这样的故障案例:某程序员在发布平台进行分批发布,在输入发布总批数时,误填写成分为两批发布。如果是热机状态,在正常情况下一半的机器可以勉强承载流量,但由于刚启动的 JVM 均是解释执行,还没有进行热点代码统计和 JIT 动态编译,导致机器启动之后,当前 1/2 发布成功的服务器马上全部宕机,此故障说明了 JIT 的存在。—阿里团队 + +![image-20200710095417462](https://gitee.com/xlshi/blog_img/raw/master/img/20201012111016.png) + +### 概念解释 + +- Java 语言的“编译期”其实是一段“不确定”的操作过程,因为它可能是指一个**前端编译器**(其实叫“编译器的前端”更准确一些)把 .java 文件转变成 .class 文件的过程; +- 也可能是指虚拟机的**后端运行期编译器**(JIT 编译器,Just In Time Compiler)把字节码转变成机器码的过程。 +- 还可能是指使用**静态提前编译器**(AOT 编译器,Ahead of Time Compiler)直接把 .java 文件编译成本地机器代码的过程。 + +前端编译器:Sun 的 Javac、Eclipse JDT 中的增量式编译器(ECJ)。 + +JIT 编译器:HotSpot VM的 C1、C2 编译器。 + +AOT 编译器:GNU Compiler for the Java(GCJ)、Excelsior JET。 + +### 热点探测技术 + +当然是否需要启动 JIT 编译器将字节码直接编译为对应平台的本地机器指令,则需要根据代码被调用**执行的频率**而定。关于那些需要被编译为本地代码的字节码,也被称之为**“热点代码”**,JIT 编译器在运行时会针对那些频繁被调用的“热点代码”做出**深度优化**,将其直接编译为对应平台的本地机器指令,以此提升 Java 程序的执行性能。 + +**一个被多次调用的方法,或者是一个方法体内部循环次数较多的循环体都可以被称之为“热点代码”**,因此都可以通过 JIT 编译器编译为本地机器指令。由于这种编译方式发生在方法的执行过程中,因此被称之为栈上替换,或简称为 **OSR(On Stack Replacement)编译**。 + +一个方法究竟要被调用多少次,或者一个循环体究竟需要执行多少次循环才可以达到这个标准?必然需要一个明确的阈值,JIT 编译器才会将这些“热点代码”编译为本地机器指令执行。这里主要依靠**热点探测功能**。 + +**目前 HotSpot VM 所采用的热点探测方式是基于计数器的热点探测。** + +采用基于计数器的热点探测,HotSpot VM 将会为每一个方法都建立2个不同类型的计数器,分别为方法调用计数器(Invocation Counter)和回边计数器(Back Edge Counter)。 + +- 方法调用计数器用于统计方法的调用次数 +- 回边计数器则用于统计循环体执行的循环次数 + +### 方法调用计数器 + +这个计数器就用于统计方法被调用的次数,它的默认阀值在 Client 模式下是1500次,在 Server 模式下是10000次。超过这个阈值,就会触发 JIT 编译。 + +这个阀值可以通过虚拟机参数 -XX:CompileThreshold 来人为设定。 + +当一个方法被调用时,会先检查该方法是否存在被 JIT 编译过的版本,如果存在,则优先使用编译后的本地代码来执行。如果不存在已被编译过的版本,则将此方法的调用计数器值加1,然后判断**方法调用计数器与回边计数器值之和**是否超过方法调用计数器的阀值。如果已超过阈值,那么将会向即时编译器提交一个该方法的代码编译请求。 + +![image-20200710101829934](https://gitee.com/xlshi/blog_img/raw/master/img/20201012111021.png) + + + +### 热点衰减 + +如果不做任何设置,方法调用计数器统计的并不是方法被调用的绝对次数,而是一个相对的执行频率,即**一段时间之内方法被调用的次数**。当超过**一定的时间限度**,如果方法的调用次数仍然不足以让它提交给即时编译器编译,那这个方法的调用计数器就会被**减少一半**,这个过程称为方法调用计数器**热度的衰减**(Counter Decay),而这段时间就称为此方法统计的**半衰周期**(Counter Half Life Time) + +- 半衰周期是化学中的概念,比如出土的文物通过查看 C60 来获得文物的年龄 + +进行热度衰减的动作是在虚拟机进行垃圾收集时顺便进行的,可以使用虚拟机参数 +-XX:-UseCounterDecay 来关闭热度衰减,让方法计数器统计方法调用的绝对次数,这样,只要系统运行时间足够长,绝大部分方法都会被编译成本地代码。 + +另外,可以使用 -XX:CounterHalfLifeTime 参数设置半衰周期的时间,单位是秒。 + +### 回边计数器 + +它的作用是统计一个方法中**循环体代码执行的次数**,在字节码中遇到控制流向后跳转的指令称为“回边”(Back Edge)。显然,建立回边计数器统计的目的就是为了触发 OSR 编译。 + +![image-20200710103103869](https://gitee.com/xlshi/blog_img/raw/master/img/20201012111024.png) + +### HotSpot VM 可以设置程序执行方法 + +缺省情况下 HotSpot VM 是采用解释器与即时编译器并存的架构,当然开发人员可以根据具体的应用场景,通过命令显式地为 Java 虚拟机指定在运行时到底是**完全采用解释器**执行,还是**完全采用即时编译器**执行。如下所示: + +- -Xint:完全采用解释器模式执行程序 +- -Xcomp:完全采用即时编译器模式执行程序。如果即时编译出现问题,解释器会介入执行 +- -Xmixed:采用解释器+即时编译器的混合模式共同执行程序。 + +![image-20200710103340273](https://gitee.com/xlshi/blog_img/raw/master/img/20201012111026.png) + + + +### HotSpot VM 中 JIT 分类 + +在 HotSpot VM 中内嵌有两个 JIT 编译器,分别为 Client Compiler和Server Compiler,但大多数情况下我们简称为 C1 编译器和 C2 编译器。开发人员可以通过如下命令显式指定 Java 虚拟机在运行时到底使用哪一种即时编译器,如下所示: + +- -client:指定 Java 虚拟机运行在 Client 模式下,并使用 C1 编译器; + - C1 编译器会对字节码进行**简单和可靠的优化,耗时短**。以达到更快的编译速度。 + +- -server:指定 Java 虚拟机运行在 Server 模式下,并使用 C2 编译器。 + - C2 进行**耗时较长的优化,以及激进优化**。但优化的代码执行效率更高。(使用 C++ 实现) + +### C1 和 C2 编译器不同的优化策略 + +在不同的编译器上有不同的优化策略,C1 编译器上主要有方法内联,去虚拟化、元余消除。 + +- 方法内联:将引用的函数代码编译到引用点处,这样可以减少栈帧的生成,减少参数传递以及跳转过程 +- 去虚拟化:对唯一的实现类进行内联 +- 冗余消除:在运行期间把一些不会执行的代码折叠掉 + +C2 的优化主要是在全局层面,逃逸分析是优化的基础。基于逃逸分析在 C2 上有如下几种优化: + +- 标量替换:用标量值代替聚合对象的属性值 +- 栈上分配:对于未逃逸的对象分配对象在栈而不是堆 +- 同步消除:清除同步操作,通常指 synchronized + +### 分层编译策略 + +分层编译(Tiered Compilation)策略:程序解释执行(不开启性能监控)可以触发 C1 编译,将字节码编译成机器码,可以进行简单优化,也可以加上性能监控,C2 编译会根据性能监控信息进行激进优化。 + +不过在 Java 7 版本之后,一旦开发人员在程序中显式指定命令“-server"时,默认将会开启分层编译策略,由 C1 编译器和 C2 编译器相互协作共同来执行编译任务。 + +### 总结 + +- 一般来讲,JIT 编译出来的机器码性能比解释器高 +- C2 编译器启动时长比 C1 慢,系统稳定执行以后,C2 编译器执行速度远快于 C1 编译器 + +### AOT编译器 + +JDK 9 引入了 AOT 编译器(静态提前编译器,Ahead of Time Compiler) + +Java 9 引入了实验性 AOT 编译工具 jaotc。它借助了 Graal 编译器,将所输入的 Java 类文件转换为机器码,并存放至生成的动态共享库之中。 + +所谓 AOT 编译,是与即时编译相对立的一个概念。我们知道,即时编译指的是在**程序的运行过程中**,将字节码转换为可在硬件上直接运行的机器码,并部署至托管环境中的过程。而 AOT 编译指的则是,在**程序运行之前**,便将字节码转换为机器码的过程。 + +``` +.java -> .class -> (使用jaotc) -> .so +``` + +最大的好处:Java 虚拟机加载已经预编译成二进制库,可以直接执行。不必等待及时编译器的预热,减少 Java 应用给人带来“第一次运行慢” 的不良体验 + +缺点: + +- 破坏了 Java “ 一次编译,到处运行”,必须为每个不同的硬件,OS 编译对应的发行包 +- 降低了 Java 链接过程的动态性,加载的代码在编译器就必须全部已知。 +- 还需要继续优化中,最初只支持 Linux X64 java base + +### 写到最后 + +- 自 JDK 10 起,HotSpot 又加入了一个全新的及时编译器:Graal 编译器 +- 编译效果短短几年时间就追平了 C2 编译器,未来可期 +- 目前,带着实验状态标签,需要使用开关参数 -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler 去激活才能使用 + diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710080707873.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710080707873.png" new file mode 100644 index 0000000000000000000000000000000000000000..930374d7ede15aefed3027fb90420378f665252e Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710080707873.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710081118053.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710081118053.png" new file mode 100644 index 0000000000000000000000000000000000000000..e0f5aedfc4c19f6adec47a6bb3cab7014b963a8a Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710081118053.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710081259276.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710081259276.png" new file mode 100644 index 0000000000000000000000000000000000000000..8a3eec5ffc76022de2ca63fc6be71191fae3faad Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710081259276.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710081627217.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710081627217.png" new file mode 100644 index 0000000000000000000000000000000000000000..8c0ead82fbb8011bc42c82bc6dd2423995ab5e6f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710081627217.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710082050139.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710082050139.png" new file mode 100644 index 0000000000000000000000000000000000000000..b5cbda704d7986940a90b23172e926850927677a Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710082050139.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710082141643.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710082141643.png" new file mode 100644 index 0000000000000000000000000000000000000000..b05cbb290044380c06fad44d53d2db8069698e14 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710082141643.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710082433146.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710082433146.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a9e5bf046ce92279c76b314a7faaaeaeeac456b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710082433146.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710083036258.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710083036258.png" new file mode 100644 index 0000000000000000000000000000000000000000..88dd1fef28db6646364a2a9fc0a8935c104cec83 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710083036258.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710083656277.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710083656277.png" new file mode 100644 index 0000000000000000000000000000000000000000..79a3756392faf36f1e62f10c577755ef6fb95b3e Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710083656277.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710085323733.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710085323733.png" new file mode 100644 index 0000000000000000000000000000000000000000..470276eae79dea56048ecd81796f1b7d0cc979bd Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710085323733.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710085553258.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710085553258.png" new file mode 100644 index 0000000000000000000000000000000000000000..b37c308685cb927afa66eaf817fd6243214bde81 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710085553258.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710090203674.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710090203674.png" new file mode 100644 index 0000000000000000000000000000000000000000..98afdea407b074f21a19d4e82b0efe6b0b8fee47 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710090203674.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710095417462.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710095417462.png" new file mode 100644 index 0000000000000000000000000000000000000000..7d75aa24ede19118cb653a31d3dc68bcb10ff30b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710095417462.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710101829934.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710101829934.png" new file mode 100644 index 0000000000000000000000000000000000000000..9b6de415171068e6995248982928683dd705c115 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710101829934.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710103103869.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710103103869.png" new file mode 100644 index 0000000000000000000000000000000000000000..e75b7614ccc20f914b2714317141290c973fa4c4 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710103103869.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710103340273.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710103340273.png" new file mode 100644 index 0000000000000000000000000000000000000000..094b1e24e6c8586d8e02cf42a087f9339820dafb Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/12_\346\211\247\350\241\214\345\274\225\346\223\216/images/image-20200710103340273.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a17fc60f23a1cb6ac2a203c4828f5fb856ebf0aa --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/README.md" @@ -0,0 +1,641 @@ +# StringTable + +## String的基本特性 + +- String:字符串,使用一对 "" 引起来表示 + - String s1 = "mogublog" ; // 字面量的定义方式 + - String s2 = new String("moxi"); +- String 声明为 final 的,不可被继承 +- String 实现了 Serializable 接口:表示字符串是支持序列化的。实现了 Comparable 接口:表示 String 可以比较大小 +- String 在 JDK 8 及以前内部定义了 final char[] value 用于存储字符串数据。JDK 9 时改为 byte[] + +### 为什么 JDK 9 改变了结构 + +String 类的当前实现将字符存储在 char 数组中,每个字符使用两个字节(16位)。从许多不同的应用程序收集的数据表明,字符串是堆使用的主要组成部分,而且,大多数字符串对象只包含拉丁字符。这些字符只需要一个字节的存储空间,因此这些字符串对象的内部 char 数组中有一半的空间将不会使用。 + +> Motivation +> +> The current implementation of the String class stores characters in a char array, using two bytes (sixteen bits) for each character. Data gathered from many different applications indicates that strings are a major component of heap usage and, moreover, t**hat most String objects contain only Lation-1 character. Such characters require only one byte of storage, hence half of the space in the internal char arrays of such String objects is going unused.** +> +> Description +> +> We propose to change the internal representation of the String class from a UTF-16 char array to a byte array plus an encoding-flag field. The new String class will store characters encoded either as ISO-8859-1/Latin-1 (one byte per character), or as UTF-16(two bytes per character), based upon the contents of the string. The encoding flag will indicate which encoding is used. + +我们建议改变字符串的内部表示 Class 从 UTF-16 字符数组到字节数组+一个 encoding-flag 字段。新的 String 类将根据字符串的内容存储编码为 ISO-8859-1/Latin-1(每个字符一个字节)或 UTF-16 (每个字符两个字节)的字符。编码标志将指示使用哪种编码。 + +结论:String 再也不用 char[] 来存储了,改成了 byte [] 加上编码标记,节约了一些空间 + +```java +// 之前 +private final char value[]; +// 之后 +private final byte[] value +``` + +同时基于 String 的数据结构,例如 StringBuffer 和 StringBuilder 也同样做了修改 + +### String的不可变性 + +String:代表不可变的字符序列。简称:不可变性。 + +- 当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的 value 进行赋值。 +- 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的 value 进行赋值。 +- 当调用 String 的 replace() 方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的 value 进行赋值。 + +通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。 + +代码 + +```java +public class StringTest1 { + + public static void test1() { + // 字面量定义的方式,“abc”存储在字符串常量池中 + String s1 = "abc"; + String s2 = "abc"; + System.out.println(s1 == s2); + s1 = "hello"; + System.out.println(s1 == s2); + System.out.println(s1); + System.out.println(s2); + System.out.println("----------------"); + } + + public static void test2() { + String s1 = "abc"; + String s2 = "abc"; + // 只要进行了修改,就会重新创建一个对象,这就是不可变性 + s2 += "def"; + System.out.println(s1); + System.out.println(s2); + System.out.println("----------------"); + } + + public static void test3() { + String s1 = "abc"; + String s2 = s1.replace('a', 'm'); + System.out.println(s1); + System.out.println(s2); + } + + public static void main(String[] args) { + test1(); + test2(); + test3(); + } +} +``` + +运行结果 + +``` +true +false +hello +abc +---------------- +abc +abcdef +---------------- +abc +mbc +``` + +### 面试题 + +```java +public class StringExer { + String str = new String("good"); + char [] ch = {'t','e','s','t'}; + + public void change(String str, char ch []) { + str = "test ok"; + ch[0] = 'b'; + } + + public static void main(String[] args) { + StringExer ex = new StringExer(); + ex.change(ex.str, ex.ch); + System.out.println(ex.str); + System.out.println(ex.ch); + } +} +``` + +输出结果 + +``` +good +best +``` + +### 注意 + +**字符串常量池是不会存储相同内容的字符串的** + +String 的 String Pool 是一个固定大小的 Hashtable ,默认值大小长度是1009。如果放进 String Pool 的 String 非常多,就会造成 Hash 冲突严重,从而导致链表会很长,而链表长了后直接会造成的影响就是当调用 String.intern 时性能会大幅下降。 + +使用 -XX:StringTablesize 可设置 StringTable 的长度 + +在 JDK 6 中 StringTable 是固定的,就是 1009 的长度,所以如果常量池中的字符串过多就会导致效率下降很快。StringTablesize 设置没有要求 + +在 JDK 7 中,StringTable 的长度默认值是 60013 ,StringTablesize 设置没有要求 + +在 JDK 8 中,StringTable 可以设置的最小值为 1009 + +## String的内存分配 + +在 Java 语言中有8种基本数据类型和一种比较特殊的类型 String 。这些类型为了使它们在运行过程中速度更快、更节省内存,都提供了一种常量池的概念。 + +常量池就类似一个 Java 系统级别提供的缓存。8种基本数据类型的常量池都是系统协调的,**String 类型的常量池比较特殊。它的主要使用方法有两种。** + +- 直接使用双引号声明出来的 String 对象会直接存储在常量池中。 + - 比如:String info = "atguigu.com"; + +- 如果不是用双引号声明的 String 对象,**可以使用 String 提供的 intern() 方法**。 + +Java 6 及以前,字符串常量池存放在永久代 + +Java 7 中 Oracle 的工程师对字符串池的逻辑做了很大的改变,即将**字符串常量池的位置调整到 Java 堆内** + +- 所有的字符串都保存在堆(Heap)中,和其他普通对象一样,这样可以让你在进行调优应用时仅需要调整堆大小就可以了。 +- 字符串常量池概念原本使用得比较多,但是这个改动使得我们有足够的理由让我们重新考虑在 Java 7 中使用 String.intern()。 + +Java 8 元空间,字符串常量在堆 + +![image-20200711093546398](https://gitee.com/xlshi/blog_img/raw/master/img/20201012122412.png) + +![image-20200711093558709](https://gitee.com/xlshi/blog_img/raw/master/img/20201012122413.png) + +### 为什么 StringTable 从永久代调整到堆中 + +在 JDK 7 中,interned 字符串不再在 Java 堆的永久代中分配,而是在 Java 堆的主要部分(称为年轻代和年老代)中分配,与应用程序创建的其他对象一起分配。此更改将导致驻留在主 Java 堆中的数据更多,驻留在永久生成中的数据更少,因此可能需要调整堆大小。由于这一变化,大多数应用程序在堆使用方面只会看到相对较小的差异,但加载许多类或大量使用字符串的较大应用程序会出现这种差异。intern() 方法会看到更显著的差异。 + +- 永久代的默认比较小 +- 永久代垃圾回收频率低 + +## String 的基本操作 + +Java 语言规范里要求完全相同的字符串字面量,应该包含同样的 Unicode 字符序列(包含同一份码点序列的常量),并且必须是指向同一个 String 类实例。 + +```java +class Memory { + public static void main(String[] args) { + int i = 1; + Object obj = new Object(); + Memory mem = new Memory(); + mem.foo(obj); + } + + private void foo(Object param) { + String str = param.toString(); + System.out.println(str); + } +} +``` + +![image-20201012122145995](https://gitee.com/xlshi/blog_img/raw/master/img/20201012122148.png) + +## 字符串拼接操作 + +- 常量与常量的拼接结果在常量池,原理是编译期优化 +- 常量池中不会存在相同内容的变量 +- 只要其中有一个是变量,结果就在堆中。变量拼接的原理是 StringBuilder +- 如果拼接的结果调用 intern() 方法,则**主动将常量池中还没有的字符串对象放入池中,并返回此对象地址** + +```java +public static void test1() { + String s1 = "a" + "b" + "c"; // 得到 abc的常量池 + String s2 = "abc"; // abc存放在常量池,直接将常量池的地址返回 + /** + * 最终java编译成.class,再执行.class + */ + System.out.println(s1 == s2); // true,因为存放在字符串常量池 + System.out.println(s1.equals(s2)); // true +} + +public static void test2() { + String s1 = "javaEE"; + String s2 = "hadoop"; + String s3 = "javaEEhadoop"; + String s4 = "javaEE" + "hadoop"; + String s5 = s1 + "hadoop"; + String s6 = "javaEE" + s2; + String s7 = s1 + s2; + + System.out.println(s3 == s4); // true + System.out.println(s3 == s5); // false + System.out.println(s3 == s6); // false + System.out.println(s3 == s7); // false + System.out.println(s5 == s6); // false + System.out.println(s5 == s7); // false + System.out.println(s6 == s7); // false + + String s8 = s6.intern(); + System.out.println(s3 == s8); // true +} +``` + +从上述的结果我们可以知道: + +如果拼接符号的前后出现了变量,则相当于在堆空间中 new String() ,具体的内容为拼接的结果 + +而调用 intern() 方法,则会判断字符串常量池中是否存在 "javaEEhadoop" 值,如果存在则返回常量池中的值,否者就在常量池中创建 + +### 底层原理 + +拼接操作的底层其实使用了 StringBuilder + +![image-20200711102231129](https://gitee.com/xlshi/blog_img/raw/master/img/20201012122408.png) + +s1 + s2 的执行细节 + +- StringBuilder s = new StringBuilder(); +- s.append(s1); +- s.append(s2); +- s.toString(); -> 类似于new String("ab"); + +在 JDK 5 之后,使用的是 StringBuilder,在 JDK 5 之前使用的是 StringBuffer + +| String | StringBuffer | StringBuilder | +| ------------------------------------------------------------ | ------------------------------------------------------------ | ---------------- | +| String 的值是不可变的,这就导致每次对 String 的操作都会生成新的 String 对象,不仅效率低下,而且浪费大量优先的内存空间 | StringBuffer 是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。每个 StringBuffer 对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量 | 可变类,速度更快 | +| 不可变 | 可变 | 可变 | +| | 线程安全 | 线程不安全 | +| | 多线程操作字符串 | 单线程操作字符串 | + +注意,我们左右两边如果是变量的话,就是需要 new StringBuilder 进行拼接,但是如果使用的是 final 修饰,则是从常量池中获取。所以说拼接符号左右两边都是字符串常量或常量引用 则仍然使用编译器优化。也就是说被 final 修饰的变量,将会变成常量,类和方法将不能被继承 + +- 在开发中,能够使用 final 的时候,建议使用上 + +```java +public static void test4() { + final String s1 = "a"; + final String s2 = "b"; + String s3 = "ab"; + String s4 = s1 + s2; + System.out.println(s3 == s4); +} +``` + +运行结果 + +``` +true +``` + +### 拼接操作和 append 性能对比 + +```java +public static void method1(int highLevel) { + String src = ""; + for (int i = 0; i < highLevel; i++) { + src += "a"; // 每次循环都会创建一个StringBuilder对象 + } +} + +public static void method2(int highLevel) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < highLevel; i++) { + sb.append("a"); + } +} +``` + +方法1耗费的时间:4005ms,方法2消耗时间:7ms + +结论: + +- 通过 StringBuilder 的 append() 方式添加字符串的效率,要远远高于 String 的字符串拼接方法 + +好处 + +- StringBuilder 的 append 的方式,自始至终只创建一个 StringBuilder 的对象 +- 对于字符串拼接的方式,还需要创建很多 StringBuilder 对象和调用 toString 时候创建的String 对象 +- 内存中由于创建了较多的 StringBuilder 和 String 对象,内存占用过大,如果进行 GC 那么将会耗费更多的时间 + +改进的空间 + +- 我们使用的是 StringBuilder 的空参构造器,默认的字符串容量是16,然后将原来的字符串拷贝到新的字符串中, 我们也可以默认初始化更大的长度,减少扩容的次数 +- 因此在实际开发中,我们能够确定,前前后后需要添加的字符串不高于某个限定值,那么建议使用构造器创建一个阈值的长度 + +## intern() 的使用 + +intern() 是一个 native 方法,调用的是底层 C 的方法 + +字符串池最初是空的,由 String 类私有地维护。在调用 intern() 方法时,如果池中已经包含了由 equals(object) 方法确定的与该字符串对象相等的字符串,则返回池中的字符串。否则,该字符串对象将被添加到池中,并返回对该字符串对象的引用。 + +如果不是用双引号声明的 String 对象,可以使用 String 提供的 intern() 方法:intern() 方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中。 + +比如: + +``` +String myInfo = new string("I love atguigu").intern(); +``` + +也就是说,如果在任意字符串上调用 String.intern() 方法,那么其返回结果所指向的那个类实例,必须和直接以常量形式出现的字符串实例完全相同。因此,下列表达式的值必定是 true + +```java +("a"+"b"+"c").intern()=="abc" +``` + +通俗点讲,Interned String 就是确保字符串在内存里只有一份拷贝,这样可以节约内存空间,加快字符串操作任务的执行速度。注意,这个值会被存放在字符串内部池(String Intern Pool) + +```java +/** + * 如何保证变量s指向的是字符串常量池中的数据呢? + * 有两种方式: + * 方式一: String s = "shkstart";//字面量定义的方式 + * 方式二: 调用intern() + * String s = new String("shkstart").intern(); + * String s = new StringBuilder("shkstart").toString().intern(); + * + */ +public class StringIntern { + public static void main(String[] args) { + + String s = new String("1"); + s.intern();//调用此方法之前,字符串常量池中已经存在了"1" + String s2 = "1"; + System.out.println(s == s2);//jdk6:false jdk7/8:false + + + String s3 = new String("1") + new String("1");//s3变量记录的地址为:new String("11") + //执行完上一行代码以后,字符串常量池中,是否存在"11"呢?答案:不存在!! + s3.intern();//在字符串常量池中生成"11"。如何理解:jdk6:创建了一个新的对象"11",也就有新的地址。 + // jdk7:此时常量中并没有创建"11",而是创建一个指向堆空间中new String("11")的地址 + String s4 = "11";//s4变量记录的地址:使用的是上一行代码代码执行时,在常量池中生成的"11"的地址 + System.out.println(s3 == s4);//jdk6:false jdk7/8:true + } +} + +``` + +### intern() 的空间效率测试 + +我们通过测试一下,使用了 intern 和不使用的时候,其实相差还挺多的 + +```java +public class StringIntern2 { + static final int MAX_COUNT = 1000 * 10000; + static final String[] arr = new String[MAX_COUNT]; + + public static void main(String[] args) { + Integer [] data = new Integer[]{1,2,3,4,5,6,7,8,9,10}; + long start = System.currentTimeMillis(); + for (int i = 0; i < MAX_COUNT; i++) { + arr[i] = new String(String.valueOf(data[i%data.length])).intern(); + } + long end = System.currentTimeMillis(); + System.out.println("花费的时间为:" + (end - start)); + + try { + Thread.sleep(1000000); + } catch (Exception e) { + e.getStackTrace(); + } + } +} +``` + +**结论**:对于程序中大量使用存在的字符串时,尤其存在很多已经重复的字符串时,使用 intern() 方法能够节省内存空间。 + +大的网站平台,需要内存中存储大量的字符串。比如社交网站,很多人都存储:北京市、海淀区等信息。这时候如果字符串都调用 intern() 方法,就会很明显降低内存的大小。 + +## 面试题 + +### new String("ab")会创建几个对象 + +```java +/** + * new String("ab") 会创建几个对象? 看字节码就知道是2个对象 + * + */ +public class StringNewTest { + public static void main(String[] args) { + String str = new String("ab"); + } +} +``` + +我们转换成字节码来查看 + +``` + 0 new #2 + 3 dup + 4 ldc #3 + 6 invokespecial #4 > + 9 astore_1 +10 return +``` + +这里面就是两个对象 + +- 一个对象是:new 关键字在堆空间中创建 +- 另一个对象:字符串常量池中的对象 + +### new String("a") + new String("b") 会创建几个对象 + +```java +/** + * new String("ab") 会创建几个对象? + * + */ +public class StringNewTest { + public static void main(String[] args) { + String str = new String("a") + new String("b"); + } +} +``` + +字节码文件为 + +``` + 0 new #2 + 3 dup + 4 invokespecial #3 > + 7 new #4 +10 dup +11 ldc #5 +13 invokespecial #6 > +16 invokevirtual #7 +19 new #4 +22 dup +23 ldc #8 +25 invokespecial #6 > +28 invokevirtual #7 +31 invokevirtual #9 +34 astore_1 +35 return +``` + +我们创建了6个对象 + +- 对象1:new StringBuilder() +- 对象2:new String("a") +- 对象3:常量池的 a +- 对象4:new String("b") +- 对象5:常量池的 b +- 对象6:toString 中会创建一个 new String("ab") + - 调用 toString 方法,不会在常量池中生成 ab + +### intern() 的使用:JDK 6 和 JDK 7 + +#### JDK 6 中 + +```java +String s = new String("1"); // 在常量池中已经有了 +s.intern(); // 将该对象放入到常量池。但是调用此方法没有太多的区别,因为已经存在了1 +String s2 = "1"; +System.out.println(s == s2); // false + +String s3 = new String("1") + new String("1"); +s3.intern(); +String s4 = "11"; +System.out.println(s3 == s4); // true +``` + +![image-20201012140923452](https://gitee.com/xlshi/blog_img/raw/master/img/20201012140931.png) + +输出结果 + +``` +false +true +``` + +为什么对象会不一样呢? + +- 一个是 new 创建的对象,一个是常量池中的对象,显然不是同一个 + +如果是下面这样的,那么就是 true + +```java +String s = new String("1"); +s = s.intern(); +String s2 = "1"; +System.out.println(s == s2); // true +``` + +而对于下面的来说,因为 s3 变量记录的地址是 new String("11"),然后这段代码执行完以后,常量池中不存在 "11",这是 JDK 6 的关系,然后执行 s3.intern() 后,就会在常量池中生成 "11",最后 s4 用的就是 s3 的地址 + +> 为什么最后输出的 s3 == s4 会为 false 呢? +> +> 这是因为在 JDK 6 中创建了一个新的对象 "11",也就是有了新的地址, s2 = 新地址 +> +> 而在 JDK 7 中,在 JDK 7 中,并没有创新一个新对象,而是指向常量池中的新对象 + +#### JDK 7 中 + +```java +String s = new String("1"); +s.intern(); +String s2 = "1"; +System.out.println(s == s2); // true + +String s3 = new String("1") + new String("1"); +s3.intern(); +String s4 = "11"; +System.out.println(s3 == s4); // true +``` + +![image-20200711145925091](images/image-20200711145925091.png) + +### 扩展 + +```java +String s3 = new String("1") + new String("1"); +String s4 = "11"; // 在常量池中生成的字符串 +s3.intern(); // 然后s3就会从常量池中找,发现有了,就什么事情都不做 +System.out.println(s3 == s4); +``` + +我们将 s4 的位置向上移动一行,发现变化就会很大,最后得到的是 false + +### 总结 + +总结 String 的 intern() 的使用: + +JDK 1.6 中,将这个字符串对象尝试放入串池。 + +- 如果串池中有,则并不会放入。返回已有的串池中的对象的地址 +- 如果没有,会把**此对象复制一份**,放入串池,并返回串池中的对象地址 + +JDK 1.7 起,将这个字符串对象尝试放入串池。 + +- 如果串池中有,则并不会放入。返回已有的串池中的对象的地址 +- 如果没有,则会把**对象的引用地址**复制一份,放入串池,并返回串池中的引用地址 + +练习: + +![image-20201012142202918](https://gitee.com/xlshi/blog_img/raw/master/img/20201012142204.png) + +![image-20201012142211803](https://gitee.com/xlshi/blog_img/raw/master/img/20201012142213.png) + +- 在 JDK 6 中,在字符串常量池中创建一个字符串 “ab” +- 在 JDK 8 中,在字符串常量池中没有创建 “ab”,而是将堆中的地址复制到串池中。 + +所以上述结果,在 JDK 6 中是: + +``` +true +false +``` + +在 JDK 8 中是 + +``` +true +true +``` + +针对下面这题,在 JDK 6 和 JDK 8 中表现的是一样的 + +![image-20200711151433277](https://gitee.com/xlshi/blog_img/raw/master/img/20201012142321.png) + +## StringTable的垃圾回收 + +```java +/** + * String的垃圾回收 + * -Xms15m -Xmx15m -XX:+PrintStringTableStatistics -XX:+PrintGCDetails + */ +public class StringGCTest { + public static void main(String[] args) { + for (int i = 0; i < 100000; i++) { + String.valueOf(i).intern(); + } + } +} +``` + +![image-20201012142345830](https://gitee.com/xlshi/blog_img/raw/master/img/20201012142346.png) + +## G1 中的 String 去重操作 + +注意这里说的重复,指的是在堆中的数据,而不是常量池中的,因为常量池中的本身就不会重复 + +### 描述 + +背景:对许多 Java 应用(有大的也有小的)做的测试得出以下结果: +- 堆存活数据集合里面 String 对象占了25% +- 堆存活数据集合里面重复的 String 对象有13.5% + +- String 对象的平均长度是45 + +许多大规模的 Java 应用的瓶颈在于内存,测试表明,在这些类型的应用里面,**Java 堆中存活的数据集合差不多25%是 String 对象**。更进一步,这里面差不多一半 String 对象是重复的,重复的意思是说: +string1.equals(string2) = true。堆上存在重复的 String 对象必然是一种内存的浪费。这个项目将在 G1 垃圾收集器中实现自动持续对重复的 String 对象进行去重,这样就能避免浪费内存。 + +### 实现 + +- 当垃圾收集器工作的时候,会访问堆上存活的对象。**对每一个访问的对象都会检查是否是候选的要去重的 String 对象。** +- 如果是,把这个对象的一个引用插入到队列中等待后续的处理。一个去重的线程在后台运行,处理这个队列。处理队列的一个元素意味着从队列删除这个元素,然后尝试去重它引用的 String 对象。 +- 使用一个 Hashtable 来记录所有的被 String 对象使用的不重复的 char 数组。当去重的时候,会查这个 Hashtable ,来看堆上是否已经存在一个一模一样的 char 数组。 +- 如果存在,String 对象会被调整引用那个数组,释放对原来的数组的引用,最终会被垃圾收集器回收掉。 +- 如果查找失败,char 数组会被插入到 Hashtable,这样以后的时候就可以共享这个数组了。 + +### 命令行选项 + +- UsestringDeduplication(bool):开启 String 去重,**默认是不开启的,需要手动开启** +- PrintStringDeduplicationStatistics(bool):打印详细的去重统计信息 +- StringDeduplicationAgeThreshold(uintx):达到这个年龄的 String 对象被认为是去重的候选对象 \ No newline at end of file diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711093546398.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711093546398.png" new file mode 100644 index 0000000000000000000000000000000000000000..cdfab0878129c104609abad3aeadd68d756f0f04 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711093546398.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711093558709.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711093558709.png" new file mode 100644 index 0000000000000000000000000000000000000000..e7daf0b1c805ed9cfc1f7d7ba039ad0dac839fb2 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711093558709.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711102231129.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711102231129.png" new file mode 100644 index 0000000000000000000000000000000000000000..b5f11238623a2dfba20b0efaddaa5960b7154356 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711102231129.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711145925091.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711145925091.png" new file mode 100644 index 0000000000000000000000000000000000000000..03debddbe72f01d3de34f97b38c9100c82af6ef1 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711145925091.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711150859709.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711150859709.png" new file mode 100644 index 0000000000000000000000000000000000000000..10c7aef14eefbd37128a4c27b0f471589a3f5ff7 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711150859709.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711151326909.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711151326909.png" new file mode 100644 index 0000000000000000000000000000000000000000..e84e5609e15a1d252b025586ccc1861ef3a10e7f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711151326909.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711151433277.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711151433277.png" new file mode 100644 index 0000000000000000000000000000000000000000..ebcc747fb800564c72fe004ca4a2d5cf80d82d5b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/13_StringTable/images/image-20200711151433277.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b1b30184d3289e6453bb3030881838f7d455207e --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/README.md" @@ -0,0 +1,148 @@ +# 垃圾回收概述 + +## 概念 + +这次我们主要关注的是黄色部分,内存的分配与回收 + +![image-20200712084539884](https://gitee.com/xlshi/blog_img/raw/master/img/20201013083804.png) + +## 什么是垃圾 + +在提到什么是垃圾之前,我们先看下面一张图 + +![image-20200712085456113](https://gitee.com/xlshi/blog_img/raw/master/img/20201013083818.png) + +从上图我们可以很明确的知道,Java 和 C++ 语言的区别,就在于垃圾收集技术和内存动态分配上,C 语言没有垃圾收集技术,需要我们手动的收集。 + +垃圾收集,不是 Java 语言的伴生产物。早在1960年,第一门开始使用内存动态分配和垃圾收集技术的 Lisp 语言诞生。 +关于垃圾收集有三个经典问题: + +- 哪些内存需要回收? +- 什么时候回收? +- 如何回收? + +垃圾收集机制是 Java 的招牌能力,极大地提高了开发效率。如今,垃圾收集几乎成为现代语言的标配,即使经过如此长时间的发展,Java 的垃圾收集机制仍然在不断的演进中,不同大小的设备、不同特征的应用场景,对垃圾收集提出了新的挑战,这当然也是面试的热点。 + +### 什么是垃圾? + +垃圾是指在**运行程序中没有任何指针指向的对象**,这个对象就是需要被回收的垃圾。 + +如果不及时对内存中的垃圾进行清理,那么,这些垃圾对象所占的内存空间会一直保留到应用程序的结束,被保留的空间无法被其它对象使用,甚至可能导致内存溢出。 + +### 磁盘碎片整理 + +机械硬盘需要进行磁盘整理,同时还有坏道 + +![image-20200712090848669](https://gitee.com/xlshi/blog_img/raw/master/img/20201013084033.png) + +### 大厂面试题 + +#### 蚂蚁金服 + +- 你知道哪几种垃圾回收器,各自的优缺点,重点讲一下 CMS 和 G1? +- JVM GC 算法有哪些,目前的 JDK 版本采用什么回收算法? +- G1 回收器讲下回收过程 GC 是什么?为什么要有 GC? +- GC 的两种判定方法?CMS 收集器与 G1 收集器的特点 + +#### 百度 + +- 说一下 GC 算法,分代回收说下 +- 垃圾收集策略和算法 + +#### 天猫 + +- JVM GC 原理,JVM 怎么回收内存 +- CMS 特点,垃圾回收算法有哪些?各自的优缺点,他们共同的缺点是什么? + +#### 滴滴 + +Java 的垃圾回收器都有哪些,说下 G1 的应用场景,平时你是如何搭配使用垃圾回收器的 + +#### 京东 + +- 你知道哪几种垃圾收集器,各自的优缺点,重点讲下 CMS 和 G1, +- 包括原理,流程,优缺点。垃圾回收算法的实现原理 + +#### 阿里 + +- 讲一讲垃圾回收算法。 +- 什么情况下触发垃圾回收? +- 如何选择合适的垃圾收集算法? +- JVM 有哪三种垃圾回收器? + +#### 字节跳动 + +- 常见的垃圾回收器算法有哪些,各有什么优劣? +- System.gc()和 Runtime.gc()会做什么事情? +- Java GC 机制?GC Roots 有哪些? +- Java 对象的回收方式,回收算法。 +- CMS 和 G1 了解么,CMS 解决什么问题,说一下回收的过程。 +- CMS 回收停顿了几次,为什么要停顿两次? + +## 为什么需要 GC + +对于高级语言来说,一个基本认知是如果不进行垃圾回收,**内存迟早都会被消耗完**,因为不断地分配内存空间而不进行回收,就好像不停地生产生活垃圾而从来不打扫一样。 + +除了释放没用的对象,垃圾回收也可以清除内存里的记录碎片。碎片整理将所占用的堆内存移到堆的一端,**以便JVM 将整理出的内存分配给新的对象**。 + +随着应用程序所应付的业务越来越庞大、复杂,用户越来越多,**没有 GC 就不能保证应用程序的正常进行**。而经常造成 STW 的 GC 又跟不上实际的需求,所以才会不断地尝试对 GC 进行优化。 + +## 早期垃圾回收 + +在早期的 C/C++ 时代,垃圾回收基本上是手工进行的。开发人员可以使用 new 关键字进行内存申请,并使用delete 关键字进行内存释放。比如以下代码: + +```c++ +MibBridge * pBridge = new cmBaseGroupBridge(); +//如果注册失败,使用Delete释放该对象所占内存区域 +if(pBridge -> Register(kDestroy)!= NO ERROR) + delete pBridge; +``` + +这种方式可以灵活控制内存释放的时间,但是会给开发人员带来**频繁申请和释放内存的管理负担**。倘若有一处内存区间由于程序员编码的问题忘记被回收,那么就会产生**内存泄漏**,垃圾对象永远无法被清除,随着系统运行时间的不断增长,垃圾对象所耗内存可能持续上升,直到出现内存溢出并造成**应用程序崩溃**。 + +有了垃圾回收机制后,上述代码极有可能变成这样 + +```c++ +MibBridge * pBridge = new cmBaseGroupBridge(); +pBridge -> Register(kDestroy); +``` + +现在,除了 Java 以外,C#、Python、Ruby 等语言都使用了自动垃圾回收的思想,也是未来发展趋势,可以说这种自动化的内存分配和来及回收方式已经成为了线代开发语言必备的标准。 + +## Java 垃圾回收机制 + +### 优点 + +自动内存管理,无需开发人员手动参与内存的分配与回收,这样**降低内存泄漏和内存溢出的风险** + +- 没有垃圾回收器,Java 也会和 C++ 一样,各种悬垂指针,野指针,泄露问题让你头疼不已。 + +自动内存管理机制,将程序员从繁重的内存管理中释放出来,可以**更专心地专注于业务开发** + +Oracle 官网关于垃圾回收的介绍 +https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/toc.html + +### 担忧 + +对于 Java 开发人员而言,自动内存管理就像是一个黑匣子,如果过度依赖于“自动”,那么这将会是一场灾难,最严重的就会**弱化 Java 开发人员在程序出现内存溢出时定位问题和解决问题的能力。** + +此时,了解 JVM 的自动内存分配和内存回收原理就显得非常重要,只有在真正了解 JVM 是如何管理内存后,我们才能够在遇见 OutOfMemoryError 时,快速地根据错误异常日志定位问题和解决问题。 + +当需要排查各种内存溢出、内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就必须对这些“自动化”的技术**实施必要的监控和调节。** + +### GC 主要关注的区域 + +GC 主要关注于**方法区**和**堆**中的垃圾收集 + +![image-20200712092427246](https://gitee.com/xlshi/blog_img/raw/master/img/20201013090830.png) + +垃圾收集器可以对年轻代回收,也可以对老年代回收,甚至是全栈和方法区的回收 + +- 其中,**Java 堆是垃圾收集器的工作重点** + +从次数上讲: + +- **频繁收集 Young 区** +- **较少收集 Old 区** +- **基本不收集 Perm 区(元空间)** + diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/images/image-20200712084539884.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/images/image-20200712084539884.png" new file mode 100644 index 0000000000000000000000000000000000000000..e086f6b66d89627e2b62b0d8c90f1f5355f8c282 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/images/image-20200712084539884.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/images/image-20200712085456113.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/images/image-20200712085456113.png" new file mode 100644 index 0000000000000000000000000000000000000000..8eef3e316628cb44ce08189b4e0b8368dfa1affc Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/images/image-20200712085456113.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/images/image-20200712090848669.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/images/image-20200712090848669.png" new file mode 100644 index 0000000000000000000000000000000000000000..7f8a47e9dd37029b322969dbe811e79a61109136 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/images/image-20200712090848669.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/images/image-20200712092427246.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/images/image-20200712092427246.png" new file mode 100644 index 0000000000000000000000000000000000000000..dd2167b2065e6ec927dd8c0e9a7ec694018b1fd3 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/14_\345\236\203\345\234\276\345\233\236\346\224\266\346\246\202\350\277\260/images/image-20200712092427246.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..3e2e749de7a11c6236c96763621fb2cd439ef2ff --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/README.md" @@ -0,0 +1,526 @@ +# 垃圾回收相关算法 + +## 标记阶段:引用计数算法 + +在堆里存放着几乎所有的 Java 对象实例,在 GC 执行垃圾回收之前,首先**需要区分出内存中哪些是存活对象,哪些是已经死亡的对象**。只有被**标记**为己经死亡的对象,GC 才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们可以称为**垃圾标记阶段**。 + +那么在 JVM 中究竟是如何标记一个死亡对象呢?简单来说,当一个对象已经不再被任何的存活对象继续引用时,就可以宣判为已经死亡。 + +判断对象存活一般有两种方式:**引用计数算法**和**可达性分析算法。** + +引用计数算法(Reference Counting)比较简单,对每个对象保存一个整型的**引用计数器属性。用于记录对象被引用的情况。** + +对于一个对象 A,只要有任何一个对象引用了 A,则 A 的引用计数器就加1;当引用失效时,引用计数器就减1。只要对象 A 的引用计数器的值为0,即表示对象 A 不可能再被使用,可进行回收。 + +优点:**实现简单,垃圾对象便于辨识;判定效率高,回收没有延迟性。** + +缺点: + +- 它需要单独的字段存储计数器,这样的做法增加了**存储空间的开销**。 +- 每次赋值都需要更新计数器,伴随着加法和减法操作,这增加了**时间开销**。 +- 引用计数器有一个严重的问题,即**无法处理循环引用**的情况。这是一条致命缺陷,导致在 Java 的垃圾回收器中没有使用这类算法。 + +### 循环引用 + +当 p 的指针断开的时候,内部的引用形成一个循环,这就是循环引用,从而造成内存泄漏 + +![image-20200712102205795](https://gitee.com/xlshi/blog_img/raw/master/img/20201013091205.png) + +```java +public class RefCountGC { + // 这个成员属性的唯一作用就是占用一点内存 + private byte[] bigSize = new byte[5*1024*1024]; + // 引用 + Object reference = null; + + public static void main(String[] args) { + RefCountGC obj1 = new RefCountGC(); + RefCountGC obj2 = new RefCountGC(); + obj1.reference = obj2; + obj2.reference = obj1; + obj1 = null; + obj2 = null; + // 显式的执行垃圾收集行为 + //这里发生GC,obj1和obj2能否被回收? + System.gc(); + } +} +``` + +运行结果 + +``` +[GC (System.gc()) [PSYoungGen: 15490K->808K(76288K)] 15490K->816K(251392K), 0.0061980 secs] [Times: user=0.00 sys=0.00, real=0.36 secs] +[Full GC (System.gc()) [PSYoungGen: 808K->0K(76288K)] [ParOldGen: 8K->672K(175104K)] 816K->672K(251392K), [Metaspace: 3479K->3479K(1056768K)], 0.0045983 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] +Heap + PSYoungGen total 76288K, used 655K [0x000000076b500000, 0x0000000770a00000, 0x00000007c0000000) + eden space 65536K, 1% used [0x000000076b500000,0x000000076b5a3ee8,0x000000076f500000) + from space 10752K, 0% used [0x000000076f500000,0x000000076f500000,0x000000076ff80000) + to space 10752K, 0% used [0x000000076ff80000,0x000000076ff80000,0x0000000770a00000) + ParOldGen total 175104K, used 672K [0x00000006c1e00000, 0x00000006cc900000, 0x000000076b500000) + object space 175104K, 0% used [0x00000006c1e00000,0x00000006c1ea8070,0x00000006cc900000) + Metaspace used 3486K, capacity 4496K, committed 4864K, reserved 1056768K + class space used 385K, capacity 388K, committed 512K, reserved 1048576K +``` + +我们能够看到,上述进行了 GC 收集的行为,将上述的新生代中的两个对象都进行回收了 + +``` +PSYoungGen: 15490K->808K(76288K)] 15490K->816K(251392K) +``` + +如果使用引用计数算法,那么这两个对象将会无法回收。而现在两个对象被回收了,说明 Java 使用的不是引用计数算法来进行标记的。 + +![image-20200712103230349](https://gitee.com/xlshi/blog_img/raw/master/img/20201013092054.png) + +### 小结 + +引用计数算法,是很多语言的资源回收选择,例如因人工智能而更加火热的 Python,它更是同时支持引用计数和垃圾收集机制。 + +具体哪种最优是要看场景的,业界有大规模实践中仅保留引用计数机制,以提高吞吐量的尝试。 + +Java 并没有选择引用计数,是因为其存在一个基本的难题,也就是很难处理循环引用关系。 + +Python 如何解决循环引用? + +- 手动解除:很好理解,就是在合适的时机,解除引用关系。 +- 使用弱引用 weakref,weakref 是 Python 提供的标准库,旨在解决循环引用。 + +## 标记阶段:可达性分析算法(或根搜索算法、追踪性垃圾收集) + +### 概念 + +相对于引用计数算法而言,可达性分析算法不仅同样具备实现简单和执行高效等特点,更重要的是该算法可以有效地**解决在引用计数算法中循环引用的问题,防止内存泄漏的发生。** + +相较于引用计数算法,这里的可达性分析就是 **Java、C# 选择的**。这种类型的垃圾收集通常也叫作**追踪性垃圾收集**(Tracing Garbage Collection) + +### 思路 + +所谓 "GC Roots" 根集合就是一组必须活跃的引用。 + +基本思路: + +- 可达性分析算法是以根对象集合(GC Roots)为起始点,按照从上至下的方式**搜索被根对象集合所连接的目标对象是否可达。** +- 使用可达性分析算法后,内存中的存活对象都会被根对象集合直接或间接连接着,搜索所走过的路径称为**引用链(Reference Chain)** +- 如果目标对象没有任何引用链相连,则是不可达的,就意味着该对象己经死亡,可以标记为垃圾对象。 +- 在可达性分析算法中,只有能够被根对象集合直接或者间接连接的对象才是存活对象。 + +![image-20200712104149246](https://gitee.com/xlshi/blog_img/raw/master/img/20201013092446.png) + +> **这里需要注意的是,可达性分析算法中,每次标记的是直接或间接与 GC Roots 连接的对象,标记完成后,遍历整个内存空间,将没有被标记的对象删除** + +官场上的裙带关系,可达性分析在人类关系网中 + +![image-20200712104312406](https://gitee.com/xlshi/blog_img/raw/master/img/20201015155816.png) + +### Java 中 GC Roots 可以是哪些? + +- 虚拟机栈中引用的对象 + - 比如:各个线程被调用的方法中使用到的参数、局部变量等。 +- 本地方法栈内 JNI(通常说的本地方法)引用的对象方法区中类静态属性引用的对象 + - 比如:Java 类的引用类型静态变量 +- 方法区中常量引用的对象 + - 比如:字符串常量池(String Table)里的引用 +- 所有被同步锁 synchronized 持有的对象 +- Java 虚拟机内部的引用。 + - 基本数据类型对应的 Class 对象,一些常驻的异常对象(如:NullPointerException、OutOfMemoryError),系统类加载器。 +- 反映 Java 虚拟机内部情况的 JMXBean、JVMTI 中注册的回调、本地代码缓存等。 + +![image-20200712104622677](https://gitee.com/xlshi/blog_img/raw/master/img/20201013093414.png) + +#### 总结 + +总结一句话就是,堆空间外的一些结构,比如**虚拟机栈、本地方法栈、方法区、字符串常量池**等地方对堆空间进行引用的,都可以作为 GC Roots 进行可达性分析 + +除了这些固定的 GC Roots 集合以外,根据用户所选用的垃圾收集器以及当前回收的内存区域不同,还可以有其他对象“临时性”地加入,共同构成完整 GC Roots 集合。比如:分代收集和局部回收(Partial GC)。 + +如果只针对 Java 堆中的某一块区域进行垃圾回收(比如:典型的只针对新生代),必须考虑到内存区域是虚拟机自己的实现细节,而不是孤立封闭的,这个区域的对象完全有可能被其他区域的对象所引用,这时候就需要一并将关联的区域对象也加入 GC Roots 集合中去考虑,才能保证可达性分析的准确性。 + +#### 小技巧 + +由于 Root 采用栈方式存放变量和指针,所以如果一个指针,它保存了堆内存里面的对象,但是自己又不存放在堆内存里面,那它就是一个 Root。 + +### 注意 + +如果要使用可达性分析算法来判断内存是否可回收,那么分析工作必须在一个能保障一致性的快照中进行。这点不满足的话分析结果的准确性就无法保证。 + +这点也是导致 GC 进行时必须“Stop The World”的一个重要原因。 + +即使是号称(几乎)不会发生停顿的 CMS 收集器中,**枚举根节点时也是必须要停顿的**。 + +## 对象的 finalization机制 + +Java 语言提供了对象终止(finalization)机制来允许开发人员提供**对象被销毁之前的自定义处理逻辑。** + +当垃圾回收器发现没有引用指向一个对象,即:垃圾回收此对象之前,总会先调用这个对象的 finalize() 方法。 + +finalize() 方法允许在子类中被重写,**用于在对象被回收时进行资源释放**。通常在这个方法中进行一些资源释放和清理的工作,比如关闭文件、套接字和数据库连接等。 + +### 注意 + +永远不要主动调用某个对象的 finalize() 方法,应该交给垃圾回收机制调用。理由包括下面三点: + +- 在 finalize() 时可能会导致对象复活。 +- finalize() 方法的执行时间是没有保障的,它完全由 GC 线程决定,极端情况下,若不发生 GC,则 finalize() 方法将没有执行机会。 + - 因为优先级比较低,即使主动调用该方法,也不会因此就直接进行回收 +- 一个糟糕的 finalize() 会严重影响 GC 的性能。 + +从功能上来说, finalize() 方法与 C++ 中的析构函数比较相似,但是 Java 采用的是基于垃圾回收器的自动内存管理机制,所以 finalize() 方法在本质上不同于 C++ 中的析构函数。 + +由于 finalize() 方法的存在,**虚拟机中的对象一般处于三种可能的状态**。 + +### 生存还是死亡? + +如果从所有的根节点都无法访问到某个对象,说明对象己经不再使用了。一般来说,此对象需要被回收。但事实上,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段。**一个无法触及的对象有可能在某一个条件下“复活”自己**,如果这样,那么对它的回收就是不合理的,为此,定义虚拟机中的对象可能的三种状态。如下: + +- **可触及的**:从根节点开始,可以到达这个对象。 +- **可复活的**:对象的所有引用都被释放,但是对象有可能在 finalize() 中复活。 +- **不可触及的**:对象的 finalize() 被调用,并且没有复活,那么就会进入不可触及状态。不可触及的对象不可能被复活,因为 **finalize() 只会被调用一次**。 + +以上3种状态中,是由于 finalize() 方法的存在,进行的区分。只有在对象不可触及时才可以被回收。 + +### 具体过程 + +判定一个对象 objA 是否可回收,至少要经历两次标记过程: + +- 如果对象 objA 到 GC Roots 没有引用链,则进行第一次标记。 + +- 进行筛选,判断此对象是否有必要执行 finalize() 方法 + - 如果对象 objA 没有重写 finalize() 方法,或者 finalize() 方法已经被虚拟机调用过,则虚拟机视为“没有必要执行”,objA 被判定为不可触及的。 + - 如果对象 objA 重写了 finalize() 方法,且还未执行过,那么 objA 会被插入到 F-Queue 队列中,由一个虚拟机自动创建的、低优先级的 Finalizer 线程触发其 finalize() 方法执行。 + - finalize() 方法是对象逃脱死亡的最后机会,稍后 GC 会对 F-Queue 队列中的对象进行第二次标记。如果 objA 在 finalize() 方法中与引用链上的任何一个对象建立了联系,那么在第二次标记时,objA 会被移出“即将回收”集合。之后,对象会再次出现没有引用存在的情况。在这个情况下, finalize() 方法不会被再次调用,对象会直接变成不可触及的状态,也就是说,**一个对象的 finalize() 方法只会被调用一次。** + +![image-20200712110411885](https://gitee.com/xlshi/blog_img/raw/master/img/20201015163550.png) + +上图就是我们看到的 Finalizer 线程 + +### 代码演示 + +我们使用重写 finalize() 方法,然后在方法的内部,重写将其存放到 GC Roots 中 + +```java +public class CanReliveObj { + // 类变量,属于GC Roots的一部分 + public static CanReliveObj canReliveObj; + + @Override + protected void finalize() throws Throwable { + super.finalize(); + System.out.println("调用当前类重写的finalize()方法"); + canReliveObj = this; + } + + public static void main(String[] args) throws InterruptedException { + canReliveObj = new CanReliveObj(); + canReliveObj = null; + System.gc(); + System.out.println("-----------------第一次gc操作------------"); + // 因为Finalizer线程的优先级比较低,暂停2秒,以等待它 + Thread.sleep(2000); + if (canReliveObj == null) { + System.out.println("obj is dead"); + } else { + System.out.println("obj is still alive"); + } + + System.out.println("-----------------第二次gc操作------------"); + canReliveObj = null; + System.gc(); + // 下面代码和上面代码是一样的,但是 canReliveObj却自救失败了 + Thread.sleep(2000); + if (canReliveObj == null) { + System.out.println("obj is dead"); + } else { + System.out.println("obj is still alive"); + } + + } +} +``` + +最后运行结果 + +``` +-----------------第一次gc操作------------ +调用当前类重写的finalize()方法 +obj is still alive +-----------------第二次gc操作------------ +obj is dead +``` + +在进行第一次清除的时候,我们会执行 finalize() 方法,然后对象进行了一次自救操作,但是因为 finalize() 方法只会被调用一次,因此第二次该对象将会被垃圾清除。 + +## MAT 与 JProfiler 的 GC Roots 溯源 + +### MAT 是什么? + +MAT 是Memory Analyzer 的简称,它是一款功能强大的 Java 堆内存分析器。用于查找内存泄漏以及查看内存消耗情况。 + +MAT 是基于 Eclipse 开发的,是一款免费的性能分析工具。 + +大家可以在http://www.eclipse.org/mat/下载并使用 MAT + +![image-20201013095155065](https://gitee.com/xlshi/blog_img/raw/master/img/20201013095156.png) + +### 方法一:命令行使用 jmap + +![image-20200712112026317](https://gitee.com/xlshi/blog_img/raw/master/img/20201013095218.png) + +### 方法二:使用 JVisualVM + +捕获的 Heap Dump 文件是一个临时文件,关闭 JVisualVM 后自动删除,若要保留,需要将其另存为文件。可通过以下方法捕获 Heap Dump: + +在左侧“Application"(应用程序)子窗口中右击相应的应用程序,选择 Heap Dump(堆Dump)。 + +在 Monitor(监视)子标签页中点击Heap Dump(堆Dump)按钮。本地应用程序的 Heap Dumps 作为应用程序标签页的一个子标签页打开。同时,Heap Dump 在左侧的 Application(应用程序)栏中对应一个含有时间戳的节点。 + +右击这个节点选择 Save As(另存为)即可将 Heap Dump 保存到本地。 + +### 使用 MAT 打开 Dump 文件 + +打开后,我们就可以看到有哪些可以作为 GC Roots 的对象 + +![image-20200712112512720](https://gitee.com/xlshi/blog_img/raw/master/img/20201013095539.png) + +里面我们能够看到有一些常用的 Java 类,然后 Thread 线程。 + +### JProfiler 的 GC Roots 溯源 + +我们在实际的开发中,一般不会查找全部的 GC Roots,可能只是查找某个对象的整个链路,或者称为 GC Roots溯源,这个时候,我们就可以使用 JProfiler + +![image-20200712113256075](https://gitee.com/xlshi/blog_img/raw/master/img/20201013095536.png) + +### 如何判断什么原因造成 OOM + +当我们程序出现 OOM 的时候,我们就需要进行排查,我们首先使用下面的例子进行说明 + +```java +/** + * 内存溢出排查 + * -Xms8m -Xmx8m -XX:HeapDumpOnOutOfMemoryError + */ +public class HeapOOM { + // 创建1M的文件 + byte [] buffer = new byte[1 * 1024 * 1024]; + + public static void main(String[] args) { + ArrayList list = new ArrayList<>(); + int count = 0; + try { + while (true) { + list.add(new HeapOOM()); + count++; + } + } catch (Exception e) { + e.getStackTrace(); + System.out.println("count:" + count); + } + } +} +``` + +上述代码就是不断的创建一个 1M 小字节数组,然后让内存溢出,我们需要限制一下内存大小,同时使用HeapDumpOnOutOfMemoryError 将出错时候的 dump 文件输出 + +``` +-Xms8m -Xmx8m -XX:HeapDumpOnOutOfMemoryError +``` + +我们将生成的 dump 文件打开,然后点击 Biggest Objects 就能够看到超大对象 + +![image-20200712150229048](https://gitee.com/xlshi/blog_img/raw/master/img/20201013095533.png) + +然后我们通过线程,还能够定位到哪里出现 OOM + +![image-20200712150303710](https://gitee.com/xlshi/blog_img/raw/master/img/20201013095529.png) + +## 清除阶段:标记-清除算法 + +当成功区分出内存中存活对象和死亡对象后,GC 接下来的任务就是执行垃圾回收,释放掉无用对象所占用的内存空间,以便有足够的可用内存空间为新对象分配内存。目前在 JVM 中比较常见的三种垃圾收集算法是 + +- 标记一清除算法(Mark-Sweep) +- 复制算法(Copying) +- 标记-压缩算法(Mark-Compact) + +### 背景 + +标记-清除算法(Mark-Sweep)是一种非常基础和常见的垃圾收集算法,该算法被 J.McCarthy 等人在1960年提出并并应用于 Lisp 语言。 + +### 执行过程 + +当堆中的有效内存空间(Available Memory)被耗尽的时候,就会停止整个程序(也被称为Stop The World),然后进行两项工作,第一项则是标记,第二项则是清除 + +- **标记**:Collector 从引用根节点开始遍历,**标记所有被引用的对象**。一般是在对象的 Header 中记录为可达对象。 + - **标记的是引用的对象,不是垃圾!!** +- **清除**:Collector 对堆内存从头到尾进行线性的遍历,如果发现某个对象在其 Header 中没有标记为可达对象,则将其回收 + +![image-20200712150935078](https://gitee.com/xlshi/blog_img/raw/master/img/20201013095747.png) + +### 什么是清除? + +这里所谓的清除并不是真的置空,而是把需要清除的对象地址保存在空闲的地址列表里。下次有新对象需要加载时,判断垃圾的位置空间是否够,如果够,就存放覆盖原有的地址。 + +关于空闲列表是在为对象分配内存的时候 + +- 如果内存规整 + - 采用指针碰撞的方式进行内存分配 +- 如果内存不规整 + - 虚拟机需要维护一个列表 + - 空闲列表分配 + +### 缺点 + +- 标记清除算法的效率不算高 +- 在进行 GC 的时候,需要停止整个应用程序,导致用户体验较差 +- 这种方式清理出来的空闲内存是不连续的,产生内存碎片,需要维护一个空闲列表 + +## 清除阶段:复制算法 + +### 背景 + +为了解决标记-清除算法在垃圾收集效率方面的缺陷,M.L.Minsky 于1963年发表了著名的论文,“使用双存储区的 Lisp 语言垃圾收集器 CA LISP Garbage Collector Algorithm Using Serial Secondary Storage)”。M.L.Minsky 在该论文中描述的算法被人们称为复制(Copying)算法,它也被 M.L.Minsky 本人成功地引入到了Lisp 语言的一个实现版本中。 + +### 核心思想 + +将活着的内存空间分为两块,每次只使用其中一块,在垃圾回收时将正在使用的内存中的存活对象复制到未被使用的内存块中,之后清除正在使用的内存块中的所有对象,交换两个内存的角色,最后完成垃圾回收 + +![image-20200712151916991](https://gitee.com/xlshi/blog_img/raw/master/img/20201013095941.png) + +把可达的对象,直接复制到另外一个区域中复制完成后,A 区就没有用了,里面的对象可以直接清除掉,其实里面的新生代里面就用到了复制算法 + +![image-20200712152029615](https://gitee.com/xlshi/blog_img/raw/master/img/20201013100024.png) + +### 优点 + +- 没有标记和清除过程,实现简单,运行高效 +- 复制过去以后保证空间的连续性,不会出现“碎片”问题。 + +### 缺点 + +- 此算法的缺点也是很明显的,就是需要**两倍**的内存空间。 +- 对于 G1 这种分拆成为大量 region 的 GC,复制而不是移动,意味着 GC 需要维护 region 之间对象引用关系,不管是内存占用或者时间开销也不小 + +### 注意 + +如果系统中的垃圾对象很多,复制算法需要复制的存活对象数量并不会太大,或者说非常低才行(老年代大量的对象存活,那么复制的对象将会有很多,效率会很低),特别适合垃圾对象很多,存活对象很少的场景;例如:Young 区的 Survivor0 和 Survivor1 区 + +### 应用场景 + +在新生代,对常规应用的垃圾回收,一次通常可以回收 70% - 99% 的内存空间。回收性价比很高。所以现在的商业虚拟机都是用这种收集算法回收新生代。 + +![image-20200712152847218](https://gitee.com/xlshi/blog_img/raw/master/img/20201013100643.png) + +## 清除阶段:标记-压缩(整理)算法 + +### 背景 + +复制算法的高效性是建立在存活对象少、垃圾对象多的前提下的。这种情况在新生代经常发生,但是在老年代,更常见的情况是大部分对象都是存活对象。如果依然使用复制算法,由于存活对象较多,复制的成本也将很高。因此,**基于老年代垃圾回收的特性,需要使用其他的算法。** + +标记一清除算法的确可以应用在老年代中,但是该算法不仅执行效率低下,而且在执行完内存回收后还会产生内存碎片,所以 JVM 的设计者需要在此基础之上进行改进。标记-压缩(Mark-Compact)算法由此诞生。 + +1970年前后,G.L.Steele、C.J.Chene 和 D.s.Wise 等研究者发布标记-压缩算法。在许多现代的垃圾收集器中,人们都使用了标记-压缩算法或其改进版本。 + +### 执行过程 + +第一阶段和标记清除算法一样,从根节点开始标记所有被引用对象 + +第二阶段将所有的存活对象压缩到内存的一端,按顺序排放。之后,清理边界外所有的空间。 + +![image-20200712153236508](https://gitee.com/xlshi/blog_img/raw/master/img/20201013100916.png) + +### 标清和标整的区别 + +标记-压缩算法的最终效果等同于标记-清除算法执行完成后,再进行一次内存碎片整理,因此,也可以把它称为**标记-清除-压缩(Mark-Sweep-Compact)算法。** + +二者的本质差异在于标记-清除算法是一种**非移动式的回收算法**,标记-压缩是**移动式的**。是否移动回收后的存活对象是一项优缺点并存的风险决策。可以看到,标记的存活对象将会被整理,按照内存地址依次排列,而未被标记的内存会被清理掉。如此一来,当我们需要给新对象分配内存时,JVM 只需要持有一个内存的起始地址即可,这比维护一个空闲列表显然少了许多开销。 + +### 指针碰撞(Bump the Pointer) + +如果内存空间以规整和有序的方式分布,即已用和未用的内存都各自一边,彼此之间维系着一个记录下一次分配起始点的标记指针,当为新对象分配内存时,只需要通过修改指针的偏移量将新对象分配在第一个空闲内存位置上,这种分配方式就叫做指针碰撞(Bump the Pointer) + +### 标整的优缺点 + +#### 优点 + +- 消除了标记-清除算法当中,内存区域分散的缺点,我们需要给新对象分配内存时,JVM 只需要持有一个内存的起始地址即可。 +- 消除了复制算法当中,内存减半的高额代价。 + +#### 缺点 + +- 从效率上来说,标记-整理算法要低于复制算法。 +- 移动对象的同时,如果对象被其他对象引用,则还需要调整引用的地址 +- 移动过程中,需要全程暂停用户应用程序。即:STW + +## 小结 + +效率上来说,复制算法是当之无愧的老大,但是却浪费了太多内存。 + +而为了尽量兼顾上面提到的三个指标,标记-整理算法相对来说更平滑一些,但是效率上不尽如人意,它比复制算法多了一个标记的阶段,比标记-清除多了一个整理内存的阶段。 + +| | 标记清除 | 标记整理 | 复制 | +| ------------ | ------------------ | ---------------- | ------------------------------------- | +| **速率** | 中等 | 最慢 | 最快 | +| **空间开销** | 少(但会堆积碎片) | 少(不堆积碎片) | 通常需要活对象的2倍空间(不堆积碎片) | +| **移动对象** | 否 | 是 | 是 | + +综合我们可以找到,没有最好的算法,只有最合适的算法 + +### 分代收集算法 + +前面所有这些算法中,并没有一种算法可以完全替代其他算法,它们都具有自己独特的优势和特点。分代收集算法应运而生。 + +分代收集算法,是基于这样一个事实:不同的对象的生命周期是不一样的。因此,**不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。**一般是把 Java 堆分为新生代和老年代,这样就可以根据各个年代的特点使用不同的回收算法,以提高垃圾回收的效率。 + +在 Java 程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比如 **Http 请求中的 Session对象、线程、Socket 连接**,这类对象跟业务直接挂钩,因此生命周期比较长。但是还有一些对象,主要是程序运行过程中生成的临时变量,这些对象生命周期会比较短,比如:**String对象**,由于其不变类的特性,系统会产生大量的这些对象,有些对象甚至只用一次即可回收。 + +**目前几乎所有的 GC 都采用分代收集算法执行垃圾回收的** + +在 HotSpot 中,基于分代的概念,GC 所使用的内存回收算法必须结合年轻代和老年代各自的特点。 + +- 年轻代(Young Gen) + +年轻代特点:区域相对老年代较小,对象生命周期短、存活率低,回收频繁。 + +这种情况复制算法的回收整理,速度是最快的。复制算法的效率只和当前存活对象大小有关,因此很适用于年轻代的回收。而复制算法内存利用率不高的问题,通过 HotSpot 中的两个 Survivor 的设计得到缓解。 + +- 老年代(Tenured Gen) + +老年代特点:区域较大,对象生命周期长、存活率高,回收不及年轻代频繁。 + +这种情况存在大量存活率高的对象,复制算法明显变得不合适。一般是由标记-清除或者是标记-清除与标记-整理的混合实现。 + +- Mark 阶段的开销与存活对象的数量成正比。 +- Sweep 阶段的开销与所管理区域的大小成正相关。 +- Compact 阶段的开销与存活对象的数据成正比。 + +以 HotSpot 中的 CMS 回收器为例,CMS 是基于 Mark-Sweep 实现的,对于对象的回收效率很高。而对于碎片问题,CMS 采用基于 Mark-Compact 算法的 Serial Old 回收器作为补偿措施:当内存回收不佳(碎片导致的Concurrent Mode Failure 时),将采用 Serial Old 执行 Full GC 以达到对老年代内存的整理。 + +分代的思想被现有的虚拟机广泛使用。几乎所有的垃圾回收器都区分新生代和老年代 + +## 增量收集算法 + +### 概述 + +上述现有的算法,在垃圾回收过程中,应用软件将处于一种 Stop the World 的状态。在 **Stop the World** 状态下,应用程序所有的线程都会挂起,暂停一切正常的工作,等待垃圾回收的完成。如果垃圾回收时间过长,应用程序会被挂起很久,**将严重影响用户体验或者系统的稳定性。**为了解决这个问题,即对实时垃圾收集算法的研究直接导致了增量收集(Incremental Collecting)算法的诞生。 + +### 基本思想 + +如果一次性将所有的垃圾进行处理,需要造成系统长时间的停顿,那么就可以让垃圾收集线程和应用程序线程**交替执行**。每次,**垃圾收集线程只收集一小片区域的内存空间,接着切换到应用程序线程。依次反复,直到垃圾收集完成。** + +总的来说,增量收集算法的基础仍是传统的标记-清除和复制算法。**增量收集算法通过对线程间冲突的妥善处理允许垃圾收集线程以分阶段的方式完成标记、清理或复制工作** + +### 缺点 + +使用这种方式,由于在垃圾回收过程中,间断性地还执行了应用程序代码,所以能减少系统的停顿时间。但是,因为线程切换和上下文转换的消耗,会使得垃圾回收的总体成本上升,**造成系统吞吐量的下降**。 + +## 分区算法 + +一般来说,在相同条件下,堆空间越大,一次 GC 时所需要的时间就越长,有关 GC 产生的停顿也越长。为了更好地控制 GC 产生的停顿时间,将一块大的内存区域分割成多个小块,根据目标的停顿时间,每次合理地回收若干个小区间,而不是整个堆空间,从而减少一次 GC 所产生的停顿。 + +分代算法将按照对象的生命周期长短划分成两个部分,分区算法将整个堆空间划分成连续的不同小区间。 +每一个小区间都独立使用,独立回收。这种算法的好处是可以控制一次回收多少个小区间。 + +![image-20200712165318590](https://gitee.com/xlshi/blog_img/raw/master/img/20201013102357.png) + +## 写到最后 + +注意,这些只是基本的算法思路,实际 GC 实现过程要复杂的多,目前还在发展中的前沿 GC 都是复合算法,并且并行和并发兼备。 \ No newline at end of file diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712102205795.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712102205795.png" new file mode 100644 index 0000000000000000000000000000000000000000..19ab26758f405bbec37589fafce4e9456adfded2 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712102205795.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712103230349.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712103230349.png" new file mode 100644 index 0000000000000000000000000000000000000000..4a900202bd46921cca3e0154883dc5640aaa2ef6 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712103230349.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712104149246.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712104149246.png" new file mode 100644 index 0000000000000000000000000000000000000000..50b9d5a31e72de9b855090d0ff45e36ddbde8624 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712104149246.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712104312406.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712104312406.png" new file mode 100644 index 0000000000000000000000000000000000000000..e998d3dfd4763a8baeb8b4c2ac936794d159566a Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712104312406.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712104622677.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712104622677.png" new file mode 100644 index 0000000000000000000000000000000000000000..d5afa15cf5e99da6ba9fde2c6d659ab931a34d3c Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712104622677.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712110411885.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712110411885.png" new file mode 100644 index 0000000000000000000000000000000000000000..234fce24605dfbc71191bb800e543c5f2e199166 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712110411885.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712112026317.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712112026317.png" new file mode 100644 index 0000000000000000000000000000000000000000..4efde729d4bc51217aac7932749d90e5f17510ec Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712112026317.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712112512720.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712112512720.png" new file mode 100644 index 0000000000000000000000000000000000000000..41d5652c4bba5cc026511148b7fc825ccd0e28d8 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712112512720.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712113256075.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712113256075.png" new file mode 100644 index 0000000000000000000000000000000000000000..f57bf299ac099073a67444f35b5da91a00d578f2 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712113256075.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712150229048.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712150229048.png" new file mode 100644 index 0000000000000000000000000000000000000000..0619ab81480f819eb1567d166631b74c18663f66 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712150229048.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712150303710.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712150303710.png" new file mode 100644 index 0000000000000000000000000000000000000000..5a1ceb8697057292a79d142b60237bfa7a94bf0d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712150303710.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712150935078.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712150935078.png" new file mode 100644 index 0000000000000000000000000000000000000000..aa312847e2be9b768026b8e3bcc7d4f0ab88d30b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712150935078.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712151916991.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712151916991.png" new file mode 100644 index 0000000000000000000000000000000000000000..c48197d9e8a02d88ecc3e57e391bcaf447ed81f2 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712151916991.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712152029615.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712152029615.png" new file mode 100644 index 0000000000000000000000000000000000000000..20d86c5dc8cfe668bf8ecc5e332c9df4f0e4741d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712152029615.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712152847218.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712152847218.png" new file mode 100644 index 0000000000000000000000000000000000000000..4504fb4f8ae8f56d7ef8eebce3a31036c2540d76 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712152847218.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712153236508.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712153236508.png" new file mode 100644 index 0000000000000000000000000000000000000000..cb760afc9177519a896f708fd5fc1808cd47c73d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712153236508.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712165318590.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712165318590.png" new file mode 100644 index 0000000000000000000000000000000000000000..7be8f9dd37c99cd39848006cc4290b9d4272ac01 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/15_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\347\256\227\346\263\225/images/image-20200712165318590.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..994948402e3285bcce482fdde80ea7f8c1db0e2a --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/README.md" @@ -0,0 +1,592 @@ +# 垃圾回收相关概念 + +## System.gc() 的理解 + +在默认情况下,通过 System.gc() 者 Runtime.getRuntime().gc() 的调用,**会显式触发 Full GC** ,同时对老年代和新生代进行回收,尝试释放被丢弃对象占用的内存。 + +![image-20201013152410192](https://gitee.com/xlshi/blog_img/raw/master/img/20201013152418.png) + +![image-20201013152534706](https://gitee.com/xlshi/blog_img/raw/master/img/20201013152536.png) + +![image-20201013152504160](https://gitee.com/xlshi/blog_img/raw/master/img/20201013152505.png) + +然而 System.gc() 调用附带一个免责声明,无法保证对垃圾收集器的调用。(不能确保立即生效) + +JVM 实现者可以通过 System.gc() 调用来决定 JVM 的 GC 行为。而一般情况下,垃圾回收应该是自动进行的,**无须手动触发,否则就太过于麻烦了**。在一些特殊情况下,如我们正在编写一个性能基准,我们可以在运行之间调用 System.gc() + +代码演示是否出发GC操作 + +```java +class SystemGCTest { + public static void main(String[] args) { + new SystemGCTest(); + System.gc();//提醒JVM的垃圾回收器执行GC,但是不确定是否马上执行GC + //与Runtime.getRuntime().gc();的作用一样。 + + System.runFinalization();//强制调用使用引用的对象的finalize()方法 + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + System.out.println("SystemGCTest 重写了finalize()"); + } +} +``` + +运行结果,但是不一定会触发销毁的方法,调用 System.runFinalization() 会强制调用失去引用对象的 finalize() + +![image-20201013153045157](https://gitee.com/xlshi/blog_img/raw/master/img/20201013153046.png) + +### 手动 GC 来理解不可达对象的回收 + +代码如下所示: + +```java +public class LocalVarGC { + + /** + * 触发Minor GC没有回收对象,然后在触发Full GC将该对象存入old区 + */ + public void localvarGC1() { + byte[] buffer = new byte[10*1024*1024]; + System.gc(); + } + + /** + * 触发YoungGC的时候,已经被回收了 + */ + public void localvarGC2() { + byte[] buffer = new byte[10*1024*1024]; + buffer = null; + System.gc(); + } + + /** + * 不会被回收,因为它还存放在局部变量表索引为1的槽中 + */ + public void localvarGC3() { + { + byte[] buffer = new byte[10*1024*1024]; + } + System.gc(); + } + + /** + * 会被回收,因为它还存放在局部变量表索引为1的槽中,但是后面定义的value把这个槽给替换了 + */ + public void localvarGC4() { + { + byte[] buffer = new byte[10*1024*1024]; + } + int value = 10; + System.gc(); + } + + /** + * localvarGC5中的数组已经被回收 + */ + public void localvarGC5() { + localvarGC1(); + System.gc(); + } + + public static void main(String[] args) { + LocalVarGC localVarGC = new LocalVarGC(); + localVarGC.localvarGC3(); + } +} +``` + +## 内存溢出 + +内存溢出相对于内存泄漏来说,尽管更容易被理解,但是同样的,内存溢出也是引发程序崩溃的罪魁祸首之一。 + +由于 GC 一直在发展,所有一般情况下,除非应用程序占用的内存增长速度非常快,造成垃圾回收已经跟不上内存消耗的速度,否则不太容易出现 OOM 的情况。 + +大多数情况下,GC 会进行各种年龄段的垃圾回收,实在不行了就放大招,来一次独占式的 Full GC 操作,这时候会回收大量的内存,供应用程序继续使用。 + +javadoc 中对 OutOfMemoryError 的解释是,**没有空闲内存,并且垃圾收集器也无法提供更多内存。** + +首先说没有空闲内存的情况:说明 Java 虚拟机的堆内存不够。原因有二: + +- Java 虚拟机的堆内存设置不够。 + +比如:可能存在内存泄漏问题;也很有可能就是堆的大小不合理,比如我们要处理比较可观的数据量,但是没有显式指定 JVM 堆大小或者指定数值偏小。我们可以通过参数 -Xms 、-Xmx 来调整。 + +- 代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用) + +对于老版本的 Oracle JDK,因为永久代的大小是有限的,并且 JVM 对永久代垃圾回收(如,常量池回收、卸载不再需要的类型)非常不积极,所以当我们不断添加新类型的时候,永久代出现 OutOfMemoryError 也非常多见,尤其是在运行时存在大量动态类型生成的场合;类似 intern 字符串缓存占用太多空间,也会导致 OOM 问题。对应的异常信息,会标记出来和永久代相关:“java.lang.OutOfMemoryError:PermGen space"。 + +随着元数据区的引入,方法区内存已经不再那么窘迫,所以相应的 OOM 有所改观,出现 OOM,异常信息则变成了:“java.lang.OutofMemoryError:Metaspace"。直接内存不足,也会导致 OOM。 + +这里面隐含着一层意思是,在抛出 OutofMemoryError 之前,通常垃圾收集器会被触发,尽其所能去清理出空间。 + +- 例如:在引用机制分析中,涉及到 JVM 会去尝试回收**软引用指向的对象等**。 +- 在 java.nio.BIts.reserveMemory() 方法中,我们能清楚的看到,System.gc() 会被调用,以清理空间。 + +当然,也不是在任何情况下垃圾收集器都会被触发的 + +比如,我们去分配一个超大对象,类似一个超大数组超过堆的最大值,JVM 可以判断出垃圾收集并不能解决这个问题,所以直接抛出 OutofMemoryError。 + +## 内存泄漏(Memory Leak) + +内存泄漏也称作“存储渗漏”。**严格来说,只有对象不会再被程序用到了,但是 GC 又不能回收他们的情况,才叫内存泄漏。** + +但实际情况很多时候一些不太好的实践(或疏忽)会导致对象的生命周期变得很长甚至导致 OOM,也可以叫做**宽泛意义上的“内存泄漏”。** + +尽管内存泄漏并不会立刻引起程序崩溃,但是一旦发生内存泄漏,程序中的可用内存就会被逐步蚕食,直至耗尽所有内存,最终出现 OutOfMemory 异常,导致程序崩溃。 + +注意,这里的存储空间并不是指物理内存,而是指虚拟内存大小,这个虚拟内存大小取决于磁盘交换区设定的大小。 + +> 买房子:80平的房子,但是有10平是公摊的面积,我们是无法使用这10平的空间,这就是所谓的内存泄漏 + +![image-20200712195158470](https://gitee.com/xlshi/blog_img/raw/master/img/20201013155307.png) + +Java 使用可达性分析算法,最上面的数据不可达,就是需要被回收的。后期有一些对象不用了,按道理应该断开引用,但是存在一些链没有断开,从而导致没有办法被回收。 + +### 举例 + +- 单例模式 + +单例的生命周期和应用程序是一样长的,所以单例程序中,如果持有对外部对象的引用的话,那么这个外部对象是不能被回收的,则会导致内存泄漏的产生。 + +- 一些提供 close 的资源未关闭导致内存泄漏 + +数据库连接(dataSourse.getConnection() ),网络连接(Socket)和 IO 连接必须手动 close,否则是不能被回收的。 + +## Stop The World + + Stop-The-World,简称 STW,指的是 GC 事件发生过程中,会产生应用程序的停顿。**停顿产生时整个应用程序线程都会被暂停,没有任何响应**,有点像卡死的感觉,这个停顿称为 STW。 + +可达性分析算法中枚举根节点(GC Roots)会导致所有 Java 执行线程停顿。 + +- 分析工作必须在一个能确保一致性的快照中进行 +- 一致性指整个分析期间整个执行系统看起来像被冻结在某个时间点上 + +- **如果出现分析过程中对象引用关系还在不断变化,则分析结果的准确性无法保证** + +被 STW 中断的应用程序线程会在完成 GC 之后恢复,频繁中断会让用户感觉像是网速不快造成电影卡带一样,所以我们需要减少 STW 的发生。 + +STW 事件和采用哪款 GC 无关,所有的 GC 都有这个事件。 + +哪怕是 G1 也不能完全避免 Stop-The-World 情况发生,只能说垃圾回收器越来越优秀,回收效率越来越高,尽可能地缩短了暂停时间。 + +STW 是 JVM 在后台**自动发起和自动完成的**。在用户不可见的情况下,把用户正常的工作线程全部停掉。 + +开发中不要用 System.gc(); 会导致 Stop-The-World 的发生。 + +## 垃圾回收的并行与并发 + +### 并发 + +在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理器上运行。 + +并发不是真正意义上的“同时进行”,只是 CPU 把一个时间段划分成几个时间片段(时间区间),然后在这几个时间区间之间来回切换,由于 CPU 处理的速度非常快,只要时间间隔处理得当,即可让用户感觉是多个应用程序同时在进行。 + +![image-20200712202522051](https://gitee.com/xlshi/blog_img/raw/master/img/20201013161130.png) + +> 从一段时间来看,有多个任务在执行,从单一时间片上看,只有一个任务在执行,实际上就是 CPU 在快速切换任务交替执行 + +### 并行(Parallel) + +当系统有一个以上 CPU 时,当一个 CPU 执行一个进程时,另一个 CPU 可以执行另一个进程,两个进程互不抢占 CPU 资源,可以同时进行,我们称之为并行(Parallel)。 + +其实决定并行的因素不是 CPU 的数量,而是 CPU 的核心数量,比如一个 CPU 多个核也可以并行。 + +适合科学计算,后台处理等弱交互场景 + +![image-20200712202822129](https://gitee.com/xlshi/blog_img/raw/master/img/20201013161136.png) + +### 并发和并行对比 + +**并发**,指的是多个事情,在**同一时间段内同时发生了**。 + +**并行**,指的是多个事情,在**同一时间点上同时发生了**。 + +并发的多个任务之间是互相抢占资源的。并行的多个任务之间是不互相抢占资源的。 + +只有在多 CPU 或者一个 CPU 多核的情况中,才会发生并行。 + +否则,看似同时发生的事情,其实都是并发执行的。 + +### 垃圾回收的并行与并发 + +并发和并行,在谈论垃圾收集器的上下文语境中,它们可以解释如下: + +- 并行(Parallel):指多条垃圾收集线程并行工作,但此时用户线程仍处于等待状态。如 ParNew、Parallel Scavenge、Parallel Old; + +- 串行(Serial) + - 相较于并行的概念,单线程执行。 + - 如果内存不够,则程序暂停,启动 JVM 垃圾回收器进行垃圾回收。回收完,再启动程序的线程。 + +![image-20200712203607845](https://gitee.com/xlshi/blog_img/raw/master/img/20201013162409.png) + +并发和并行,在谈论垃圾收集器的上下文语境中,它们可以解释如下: + +并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),垃圾回收线程在执行时不会停顿用户程序的运行。用户程序在继续运行,而垃圾收集程序线程运行于另一个 CPU 上; + +>如:CMS、G1 + +![image-20200712203815517](https://gitee.com/xlshi/blog_img/raw/master/img/20201013162530.png) + +## 安全点与安全区域 + +### 安全点 + +程序执行时并非在所有地方都能停顿下来开始 GC,只有在特定的位置才能停顿下来开始 GC,这些位置称为“安全点(Safe Point)”。 + +Safe Point 的选择很重要,**如果太少可能导致 GC 等待的时间太长,如果太频繁可能导致运行时的性能问题**。大部分指令的执行时间都非常短暂,通常会根据**“是否具有让程序长时间执行的特征”**为标准。比如:选择一些执行时间较长的指令作为 Safe Point,如**方法调用、循环跳转和异常跳转等**。 + +如何在 GC 发生时,检查所有线程都跑到最近的安全点停顿下来呢? + +- **抢先式中断**:(目前没有虚拟机采用了)首先中断所有线程。如果还有线程不在安全点,就恢复线程,让线程跑到安全点。 +- **主动式中断**:设置一个中断标志,各个线程运行到 Safe Point 的时候主动轮询这个标志,如果中断标志为真,则将自己进行中断挂起。(有轮询的机制) + +### 安全区域 + +Safe Point 机制保证了程序执行时,在不太长的时间内就会遇到可进入 GC 的 Safe Point。但是,程序“不执行”的时候呢?例如线程处于 Sleep-状态或 Blocked 状态,这时候线程无法响应 JVM 的中断请求,“走”到安全点去中断挂起,JVM 也不太可能等待线程被唤醒。对于这种情况,就需要安全区域(Safe Region)来解决。 + +**安全区域是指在一段代码片段中,对象的引用关系不会发生变化,在这个区域中的任何位置开始 GC 都是安全的。**我们也可以把 Safe Region 看做是被扩展了的 Safe Point。 + +**执行流程:** + +- 当线程运行到 Safe Region 的代码时,首先标识已经进入了 Safe Relgion,如果这段时间内发生 GC,JVM会忽略标识为 Safe Region 状态的线程 +- 当线程即将离开 Safe Region 时,会检查 JVM 是否已经完成 GC,如果完成了,则继续运行,否则线程必须等待直到收到可以安全离开 Safe Region 的信号为止; + +## 再谈引用 + +我们希望能描述这样一类对象:当内存空间还足够时,则能保留在内存中;如果内存空间在进行垃圾收集后还是很紧张,则可以抛弃这些对象。 + +【既**偏门**又非常**高频**的面试题】强引用、软引用、弱引用、虚引用有什么区别?具体使用场景是什么? +在 JDK 1.2 版之后,Java 对引用的概念进行了扩充,将引用分为: + +- 强引用(Strong Reference) +- 软引用(Soft Reference) +- 弱引用(Weak Reference) +- 虚引用(Phantom Reference) + +**这4种引用强度依次逐渐减弱。** + +除强引用外,其他3种引用均可以在 java.lang.ref 包中找到它们的身影。如下图,显示了这3种引用类型对应的类,开发人员可以在应用程序中直接使用它们。 + +.![image-20200712205813321](https://gitee.com/xlshi/blog_img/raw/master/img/20201013163433.png) + +Reference 子类中只有终结器引用是包内可见的,其他3种引用类型均为 public,可以在应用程序中直接使用 + +- 强引用(StrongReference):最传统的“引用”的定义,是指在程序代码之中普遍存在的引用赋值,即类似“Object obj = new Object()”这种引用关系。无论任何情况下,只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。 +- 软引用(SoftReference):在系统将要发生内存溢出之前,将会把这些对象列入回收范围之中进行第二次回收。如果这次回收后还没有足够的内存,才会抛出内存流出异常。 +- 弱引用(WeakReference):被弱引用关联的对象只能生存到下一次垃圾收集之前。当垃圾收集器工作时,无论内存空间是否足够,都会回收掉被弱引用关联的对象。 +- 虚引用(PhantomReference):一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来获得一个对象的实例。为一个对象设置虚引用关联的唯一**目的就是能在这个对象被收集器回收时收到一个系统通知。** + +## 再谈引用:强引用——不回收 + +在 Java 程序中,最常见的引用类型是强引用(**普通系统99%以上都是强引用**),也就是我们最常见的普通对象引用,**也是默认的引用类型**。 + +当在 Java 语言中使用 new 操作符创建一个新的对象,并将其赋值给一个变量的时候,这个变量就成为指向该对象的一个强引用。 + +强引用的对象是可触及的,垃圾收集器就永远不会回收掉被引用的对象。 + +对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为null,就是可以当做垃圾被收集了,当然具体回收时机还是要看垃圾收集策略。 + +相对的,软引用、弱引用和虚引用的对象是软可触及、弱可触及和虚可触及的,在一定条件下,都是可以被回收的。所以,**强引用是造成 Java 内存泄漏的主要原因之一**。 + +### 举例 + +强引用的案例说明 + +```java +public class StrongReferenceTest { + public static void main(String[] args) { + StringBuffer str = new StringBuffer ("Hello,尚硅谷"); + StringBuffer str1 = str; + + str = null; + System.gc(); + + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + System.out.println(str1); + } +} +``` + +局部变量 str 指向 StringBuffer 实例所在堆空间,通过 str 可以操作该实例,那么 str 就是 StringBuffer 实例的强引用对应内存结构: + +![image-20200712211501377](https://gitee.com/xlshi/blog_img/raw/master/img/20201013165503.png) + +如果此时,再运行一个赋值语句 + +```java +StringBuffer str = new StringBuffer("hello mogublog"); +StringBuffer str1 = str; +``` + +对应的内存结构为: + +![image-20200712211732976](https://gitee.com/xlshi/blog_img/raw/master/img/20201013165506.png) + +那么我们将 str = null; 则原来堆中的对象也不会被回收,因为还有其它对象指向该区域 + +### 总结 + +本例中的两个引用,都是强引用,强引用具备以下特点: + +- 强引用可以直接访问目标对象。 +- 强引用所指向的对象在任何时候都不会被系统回收,虚拟机宁愿抛出 OOM 异常,也不会回收强引用所指向对象。 +- 强引用可能导致内存泄漏。 + +## 再谈引用: 软引用 + +软引用是用来描述一些还有用,但非必需的对象。**只被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收**,如果这次回收还没有足够的内存,才会抛出内存溢出异常。 + +> 注意,这里的第一次回收是不可达的对象 + +软引用通常用来实现内存敏感的缓存。比如:**高速缓存**就有用到软引用。如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理掉,这样就保证了使用缓存的同时,不会耗尽内存。 + +垃圾回收器在某个时刻决定回收软可达的对象的时候,会清理软引用,并可选地把引用存放到一个引用队列(Reference Queue)。 + +类似弱引用,只不过 Java 虚拟机会尽量让软引用的存活时间长一些,迫不得已才清理。 + +> 一句话概括:当内存足够时,不会回收软引用可达的对象。内存不够时,会回收软引用的可达对象 + +在 JDK 1.2 版之后提供了 SoftReference 类来实现软引用 + +```java +public class SoftReferenceTest { + public static class User { + public User(int id, String name) { + this.id = id; + this.name = name; + } + + public int id; + public String name; + + @Override + public String toString() { + return "[id=" + id + ", name=" + name + "] "; + } + } + + public static void main(String[] args) { + //创建对象,建立软引用 +// SoftReference userSoftRef = new SoftReference(new User(1, "songhk")); + //上面的一行代码,等价于如下的三行代码 + User u1 = new User(1,"songhk"); + SoftReference userSoftRef = new SoftReference(u1); + u1 = null;//取消强引用 + + + //从软引用中重新获得强引用对象 + System.out.println(userSoftRef.get()); + + System.gc(); + System.out.println("After GC:"); +// //垃圾回收之后获得软引用中的对象 + System.out.println(userSoftRef.get());//由于堆空间内存足够,所有不会回收软引用的可达对象。 +// + try { + //让系统认为内存资源紧张、不够 +// byte[] b = new byte[1024 * 1024 * 7]; + byte[] b = new byte[1024 * 7168 - 635 * 1024]; + } catch (Throwable e) { + e.printStackTrace(); + } finally { + //再次从软引用中获取数据 + System.out.println(userSoftRef.get());//在报OOM之前,垃圾回收器会回收软引用的可达对象。 + } + } +} +``` + +```java +Object obj = new Object(); +SoftReference sf = new SoftReference(obj); +obj = null; //销毁强引用 +``` + +## 再谈引用:弱引用 + +> 发现即回收 + +弱引用也是用来描述那些非必需对象,**被弱引用关联的对象只能生存到下一次垃圾收集发生为止。**在系统 GC 时,只要发现弱引用,不管系统堆空间使用是否充足,都会回收掉只被弱引用关联的对象。 + +但是,由于垃圾回收器的线程通常优先级很低,因此,并不一定能很快地发现持有弱引用的对象。在这种情况下,**弱引用对象可以存在较长的时间**。 + +弱引用和软引用一样,在构造弱引用时,也可以指定一个引用队列,当弱引用对象被回收时,就会加入指定的引用队列,通过这个队列可以跟踪对象的回收情况。 + +**软引用、弱引用都非常适合来保存那些可有可无的缓存数据。**如果这么做,当系统内存不足时,这些缓存数据会被回收,不会导致内存溢出。而当内存资源充足时,这些缓存数据又可以存在相当长的时间,从而起到加速系统的作用。 + +在 JDK 1.2 版之后提供了 WeakReference 类来实现弱引用 + +```java +public class WeakReferenceTest { + public static class User { + public User(int id, String name) { + this.id = id; + this.name = name; + } + + public int id; + public String name; + + @Override + public String toString() { + return "[id=" + id + ", name=" + name + "] "; + } + } + + public static void main(String[] args) { + //构造了弱引用 + WeakReference userWeakRef = new WeakReference(new User(1, "songhk")); + //从弱引用中重新获取对象 + System.out.println(userWeakRef.get()); + + System.gc(); + // 不管当前内存空间足够与否,都会回收它的内存 + System.out.println("After GC:"); + //重新尝试从弱引用中获取对象 + System.out.println(userWeakRef.get()); + } +} +``` + +```java +// 声明强引用 +Object obj = new Object(); +// 创建一个弱引用 +WeakReference sf = new WeakReference<>(obj); +obj = null; //销毁强引用 +``` + +**弱引用对象与软引用对象的最大不同**就在于,当 GC 在进行回收时,需要通过算法检查是否回收软引用对象,而对于弱引用对象,GC 总是进行回收。**弱引用对象更容易、更快被 GC 回收**。 + +面试题:你开发中使用过 WeakHashMap 吗? + +WeakHashMap 用来存储图片信息,可以在内存不足的时候,及时回收,避免了 OOM + +## 再谈引用:虚引用 + +也称为“幽灵引用”或者“幻影引用”,是所有引用类型中最弱的一个 + +一个对象是否有虚引用的存在,完全不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它和没有引用几乎是一样的,随时都可能被垃圾回收器回收。 + +它不能单独使用,也无法通过虚引用来获取被引用的对象。当试图通过虚引用的 get() 方法取得对象时,总是 null + +**为一个对象设置虚引用关联的唯一目的在于跟踪垃圾回收过程。比如:能在这个对象被收集器回收时收到一个系统通知。** + +虚引用必须和引用队列一起使用。虚引用在创建时必须提供一个引用队列作为参数。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象后,将这个虚引用加入引用队列,以通知应用程序对象的回收情况。 + +**由于虚引用可以跟踪对象的回收时间,因此,也可以将一些资源释放操作放置在虚引用中执行和记录。** + +> 虚引用无法获取到我们的数据 + +在 JDK 1.2 版之后提供了 PhantomReference 类来实现虚引用。 + +```java +// 声明强引用 +Object obj = new Object(); +// 声明引用队列 +ReferenceQueue phantomQueue = new ReferenceQueue(); +// 声明虚引用(还需要传入引用队列) +PhantomReference sf = new PhantomReference<>(obj, phantomQueue); +obj = null; +``` + +```java +public class PhantomReferenceTest { + public static PhantomReferenceTest obj;//当前类对象的声明 + static ReferenceQueue phantomQueue = null;//引用队列 + + public static class CheckRefQueue extends Thread { + @Override + public void run() { + while (true) { + if (phantomQueue != null) { + PhantomReference objt = null; + try { + objt = (PhantomReference) phantomQueue.remove(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (objt != null) { + System.out.println("追踪垃圾回收过程:PhantomReferenceTest实例被GC了"); + } + } + } + } + } + + @Override + protected void finalize() throws Throwable { //finalize()方法只能被调用一次! + super.finalize(); + System.out.println("调用当前类的finalize()方法"); + obj = this; + } + + public static void main(String[] args) { + Thread t = new CheckRefQueue(); + t.setDaemon(true);//设置为守护线程:当程序中没有非守护线程时,守护线程也就执行结束。 + t.start(); + + phantomQueue = new ReferenceQueue(); + obj = new PhantomReferenceTest(); + //构造了 PhantomReferenceTest 对象的虚引用,并指定了引用队列 + PhantomReference phantomRef = new PhantomReference(obj, phantomQueue); + + try { + //不可获取虚引用中的对象 + System.out.println(phantomRef.get()); + + //将强引用去除 + obj = null; + //第一次进行GC,由于对象可复活,GC无法回收该对象 + System.gc(); + Thread.sleep(1000); + if (obj == null) { + System.out.println("obj 是 null"); + } else { + System.out.println("obj 可用"); + } + System.out.println("第 2 次 gc"); + obj = null; + System.gc(); //一旦将obj对象回收,就会将此虚引用存放到引用队列中。 + Thread.sleep(1000); + if (obj == null) { + System.out.println("obj 是 null"); + } else { + System.out.println("obj 可用"); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} +``` + +最后运行结果 + +```java +null +第一次GC操作 +调用当前类的finalize方法 +obj 不是 null +第二次GC操作 +追踪垃圾回收过程:PhantomReferenceTest实例被GC了 +obj 是 null +``` + +从上述运行结果我们知道,第一次尝试获取虚引用的值,发现无法获取的,这是因为虚引用是无法直接获取对象的值,然后进行第一次 GC ,因为会调用 finalize() 方法,将对象复活了,所以对象没有被回收,但是调用第二次 GC 操作的时候,因为 finalize() 方法只能执行一次,所以就触发了 GC 操作,将对象回收了,同时将会触发第二个操作就是将回收的值存入到引用队列中。 + +## 终结器引用 + +它用于实现对象的 finalize() 方法,也可以称为终结器引用 + +无需手动编码,其内部配合引用队列使用 + +在 GC 时,终结器引用入队。由 Finalizer 线程通过终结器引用找到被引用对象调用它的 finalize() 方法,第二次GC 时才回收被引用的对象 \ No newline at end of file diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712195158470.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712195158470.png" new file mode 100644 index 0000000000000000000000000000000000000000..0f7361602beb9b4cc7bfcdc7effa6833c415260f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712195158470.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712202522051.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712202522051.png" new file mode 100644 index 0000000000000000000000000000000000000000..200bb3cdc6c442d538d707b08a3134125d2fa0e5 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712202522051.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712202822129.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712202822129.png" new file mode 100644 index 0000000000000000000000000000000000000000..166daf03c99cff3a4c6e8c885467a3cd37b4d7a2 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712202822129.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712203607845.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712203607845.png" new file mode 100644 index 0000000000000000000000000000000000000000..2a1dad787739bd3265a617e3edddee25c6680eae Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712203607845.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712203815517.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712203815517.png" new file mode 100644 index 0000000000000000000000000000000000000000..346141c685b3c8551ea553c5678594a664ba9d7c Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712203815517.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712205813321.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712205813321.png" new file mode 100644 index 0000000000000000000000000000000000000000..016b9dc55cd03464bf244efe379e5025094ea1c5 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712205813321.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712211501377.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712211501377.png" new file mode 100644 index 0000000000000000000000000000000000000000..7290e3b1c2a9648f0da381925110ba0f83707f7b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712211501377.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712211732976.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712211732976.png" new file mode 100644 index 0000000000000000000000000000000000000000..2c85b8fc527d0db229ebe6feeb1eaf73af342127 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/16_\345\236\203\345\234\276\345\233\236\346\224\266\347\233\270\345\205\263\346\246\202\345\277\265/images/image-20200712211732976.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..c568a8fff7a0a85f0968566e472587250950ce37 --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/README.md" @@ -0,0 +1,874 @@ +# 垃圾回收器 + +## GC分类与性能指标 + +垃圾收集器没有在规范中进行过多的规定,可以由不同的厂商、不同版本的 JVM 来实现。 + +由于 JDK 的版本处于高速迭代过程中,因此 Java 发展至今已经衍生了众多的 GC 版本。 + +从不同角度分析垃圾收集器,可以将 GC 分为不同的类型。 + +> Java 不同版本新特性 +> +> - 语法层面:Lambda 表达式、switch、自动拆箱装箱、enum +> - API 层面:Stream API、新的日期时间、Optional、String、集合框架 +> - 底层优化:JVM 优化、GC 的变化、元空间、静态域、字符串常量池位置变化 + +### 垃圾收集器分类 + +#### **按线程数分** + +按**线程数**分(垃圾回收线程数),可以分为串行垃圾回收器和并行垃圾回收器。 + +![image-20200713083030867](https://gitee.com/xlshi/blog_img/raw/master/img/20201014095818.png) + +串行回收指的是在同一时间段内只允许有一个 CPU 用于执行垃圾回收操作,此时工作线程被暂停,直至垃圾收集工作结束。 + +- 在诸如单 CPU 处理器或者较小的应用内存等硬件平台不是特别优越的场合,串行回收器的性能表现可以超过并行回收器和并发回收器。所以,**串行回收默认被应用在客户端的 Client 模式下的 JVM 中** +- 在并发能力比较强的 CPU 上,并行回收器产生的停顿时间要短于串行回收器。 + +和串行回收相反,并行收集可以运用多个 CPU 同时执行垃圾回收,因此提升了应用的吞吐量,不过并行回收仍然与串行回收一样,采用独占式,使用了“Stop-The-World”机制。 + +#### 按工作模式分 + +按照**工作模式**分,可以分为并发式垃圾回收器和独占式垃圾回收器。 + +- 并发式垃圾回收器与应用程序线程交替工作,以尽可能减少应用程序的停顿时间。 +- 独占式垃圾回收器(Stop The World)一旦运行,就停止应用程序中的所有用户线程,直到垃圾回收过程完全结束。 + +![image-20200713083443486](https://gitee.com/xlshi/blog_img/raw/master/img/20201014095822.png) + +#### 按碎片处理方式分 + +按**碎片处理方式**分,可分为**压缩式垃圾回收器**和**非压缩式垃圾回收器**。 + +- 压缩式垃圾回收器会在回收完成后,对存活对象进行压缩整理,消除回收后的碎片。 +- 非压缩式的垃圾回收器不进行这步操作。 + +#### 按工作的内存区间分 + +按**工作的内存区间**分,又可分为年轻代垃圾回收器和老年代垃圾回收器。 + +### 评估GC的性能指标 + +- **吞吐量**:运行用户代码的时间占总运行时间的比例(总运行时间 = 程序的运行时间 + 内存回收的时间) +- **垃圾收集开销**:吞吐量的补数,垃圾收集所用时间与总运行时间的比例。 +- **暂停时间**:执行垃圾收集时,程序的工作线程被暂停的时间。 +- **收集频率**:相对于应用程序的执行,收集操作发生的频率。 +- **内存占用**:Java 堆区所占的内存大小。 +- **快速**:一个对象从诞生到被回收所经历的时间。 + +吞吐量、暂停时间、内存占用 这三者共同构成一个“不可能三角”。三者总体的表现会随着技术进步而越来越好。一款优秀的收集器通常最多同时满足其中的两项。 +这三项里,暂停时间的重要性日益凸显。因为随着硬件发展,内存占用多些越来越能容忍,硬件性能的提升也有助于降低收集器运行时对应用程序的影响,即提高了吞吐量。而内存的扩大,对延迟反而带来负面效果。 +简单来说,主要抓住两点: + +- 吞吐量 +- 暂停时间 + +### 评估 GC 的性能指标:吞吐量(Throughput) + +吞吐量就是 CPU 用于运行用户代码的时间与 CPU 总消耗时间的比值,即吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间) + +>比如:虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。 + +这种情况下,应用程序能容忍较高的暂停时间,因此,高吞吐量的应用程序有更长的时间基准,快速响应是不必考虑的 + +吞吐量优先,意味着在单位时间内,STW 的时间最短:0.2 + 0.2 = 0.4 + +![image-20200713084726176](https://gitee.com/xlshi/blog_img/raw/master/img/20201014095825.png) + +### 评估 GC 的性能指标:暂停时间 + +“暂停时间”是指一个时间段内应用程序线程暂停,让 GC 线程执行的状态 + +- 例如,GC 期间100毫秒的暂停时间意味着在这100毫秒期间内没有应用程序线程是活动的。 + +暂停时间优先,意味着尽可能让单次 STW 的时间最短:0.1 + 0.1 + 0.1 + 0.1 + 0.1 = 0.5 + +![image-20200713085306400](https://gitee.com/xlshi/blog_img/raw/master/img/20201014095827.png) + +### 吞吐量 vs 暂停时间 + +高吞吐量较好因为这会让应用程序的最终用户感觉只有应用程序线程在做“生产性”工作。直觉上,吞吐量越高程序运行越快。 + +低暂停时间(低延迟)较好因为从最终用户的角度来看不管是 GC 还是其他原因导致一个应用被挂起始终是不好的。这取决于应用程序的类型,**有时候甚至短暂的200毫秒暂停都可能打断终端用户体验**。因此,具有低的较大暂停时间是非常重要的,特别是对于一个**交互式应用程序**。 + +不幸的是”高吞吐量”和”低暂停时间”是一对相互竞争的目标(矛盾)。 + +- 因为如果选择以吞吐量优先,那么**必然需要降低内存回收的执行频率**,但是这样会导致 GC 需要更长的暂停时间来执行内存回收。 + +- 相反的,如果选择以低延迟优先为原则,那么为了降低每次执行内存回收时的暂停时间,也只能频繁地执行内存回收,但这又**引起了年轻代内存的缩减和导致程序吞吐量的下降**。 + +在设计(或使用)GC 算法时,我们必须确定我们的目标:一个 GC 算法只可能针对两个目标之一(即只专注于较大吞吐量或最小暂停时间),或尝试找到一个二者的折衷。 + +现在标准:**在最大吞吐量优先的情况下,降低停顿时间** + +## 不同的垃圾回收器概述 + +垃圾收集机制是 Java 的招牌能力,极大地提高了开发效率。这当然也是面试的热点。 + +那么,Java常见的垃圾收集器有哪些? + +> GC垃圾收集器是和JVM一脉相承的,它是和JVM进行搭配使用,在不同的使用场景对应的收集器也是有区别 + +### 垃圾回收器发展史 + +有了虚拟机,就一定需要收集垃圾的机制,这就是 Garbage Collection,对应的产品我们称为 Garbage Collector。 + +- 1999年随 JDK 1.3.1 一起来的是串行方式的 Serial GC ,它是第一款 GC。ParNew 垃圾收集器是 Serial 收集器的多线程版本 +- 2002年2月26日,Parallel GC 和 Concurrent Mark Sweep GC 跟随 JDK 1.4.2 一起发布· +- Parallel GC 在 JDK 6 之后成为 HotSpot 默认 GC。 +- 2012年,在 JDK 1.7u4 版本中,G1 可用。 +- 2017年,JDK 9 中 G1 变成默认的垃圾收集器,以替代 CMS。 +- 2018年3月,JDK 10 中 G1 垃圾回收器的并行完整垃圾回收,实现并行性来改善最坏情况下的延迟。 +- 2018年9月,JDK 11 发布。引入 Epsilon 垃圾回收器,又被称为 "No-Op(无操作)“ 回收器。同时,引入ZGC:可伸缩的低延迟垃圾回收器(Experimental) +- 2019年3月,JDK 12 发布。增强 G1,自动返回未用堆内存给操作系统。同时,引入 Shenandoah GC:低停顿时间的GC(Experimental)。 +- 2019年9月,JDK 13 发布。增强 ZGC,自动返回未用堆内存给操作系统。 +- 2020年3月,JDK 14 发布。删除 CMS 垃圾回收器。扩展 ZGC 在 macOS 和 Windows 上的应用 + +### 7种经典的垃圾收集器 + +- 串行回收器:Serial、Serial Old +- 并行回收器:ParNew、Parallel Scavenge、Parallel Old +- 并发回收器:CMS、G11 + +![image-20200713093551365](https://gitee.com/xlshi/blog_img/raw/master/img/20201014095832.png) + +### 7款经典收集器与垃圾分代之间的关系 + +![image-20200713093757644](https://gitee.com/xlshi/blog_img/raw/master/img/20201015174011.png) + +新生代收集器:Serial、ParNew、Parallel Scavenge; + +老年代收集器:Serial Old、Parallel Old、CMS; + +整堆收集器:G1; + +### 垃圾收集器的组合关系 + +![image-20200713094745366](https://gitee.com/xlshi/blog_img/raw/master/img/20201014095835.png) + +- 两个收集器间有连线,表明它们可以搭配使用:Serial/Serial Old、Serial/CMS、ParNew/Serial Old、ParNew/CMS、Parallel Scavenge/Serial Old、Parallel Scavenge/Parallel Old、G1; +- 其中 Serial Old 作为 CMS 出现"Concurrent Mode Failure"失败的后备预案。 +- (红色虚线)由于维护和兼容性测试的成本,在 JDK 8 时将 Serial+CMS、ParNew+Serial Old 这两个组合声明为废弃(JEP173),并在 JDK 9 中完全取消了这些组合的支持(JEP214),即:移除。 +- (绿色虚线)JDK 14 中:弃用 Parallel Scavenge 和 Serialold GC 组合(JEP366) +- (青色虚线)JDK 14 中:删除 CMS 垃圾回收器(JEP363) + +> 为什么 CMS GC 不可以和 Parallel Scavenge GC 搭配使用? +> +> 答:Parallel Scavenge GC 底层框架和其他垃圾回收器不同 + +为什么要有很多收集器,一个不够吗?因为 Java 的使用场景很多,移动端,服务器等。所以就需要针对不同的场景,提供不同的垃圾收集器,提高垃圾收集的性能。 + +虽然我们会对各个收集器进行比较,但并非为了挑选一个最好的收集器出来。没有一种放之四海皆准、任何场景下都适用的完美收集器存在,更加没有万能的收集器。所以**我们选择的只是对具体应用最合适的收集器**。 + +### 如何查看默认垃圾收集器 + +-XX:+PrintCommandLineFlags:查看命令行相关参数(包含使用的垃圾收集器) + +使用命令行指令:jinfo -flag 相关垃圾回收器参数 进程 ID + +## Serial 回收器:串行回收 + +Serial 收集器是最基本、历史最悠久的垃圾收集器了。JDK 1.3 之前回收新生代唯一的选择。 + +Serial 收集器作为 HotSpot 中 Client 模式下的默认新生代垃圾收集器。 + +**Serial 收集器采用复制算法、串行回收和"Stop-The-World"机制的方式执行内存回收。** + +除了年轻代之外,Serial 收集器还提供用于执行老年代垃圾收集的 Serial Old 收集器。**Serial Old 收集器同样也采用了串行回收和"Stop The World"机制,只不过内存回收算法使用的是标记-压缩算法。** + +- Serial Old 是运行在 Client 模式下默认的老年代的垃圾回收器 +- Serial Old 在 Server 模式下主要有两个用途: + - 与新生代的 Parallel Scavenge 配合使用 + - 作为老年代 CMS 收集器的后备垃圾收集方案 + +![image-20200713100703799](https://gitee.com/xlshi/blog_img/raw/master/img/20201014095838.png) + +这个收集器是一个单线程的收集器,但它的“单线程”的意义并不仅仅说明它**只会使用一个 CPU 或一条收集线程去完成垃圾收集工作**,更重要的是在它进行垃圾收集时,**必须暂停其他所有的工作线程**,直到它收集结束(Stop The World) + +优势:**简单而高效**(与其他收集器的单线程比),对于限定单个 CPU 的环境来说,Serial 收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。 + +- 运行在 Client 模式下的虚拟机是个不错的选择。 + +在用户的桌面应用场景中,可用内存一般不大(几十 MB 至一两百 MB),可以在较短时间内完成垃圾收集(几十 ms 至一百多 ms),只要不频繁发生,使用串行回收器是可以接受的。 + +在 HotSpot 虚拟机中,使用 -XX:+UseSerialGC 参数可以指定年轻代和老年代都使用串行收集器。 + +等价于新生代用 Serial GC,且老年代用 Serial Old GC + +### 总结 + +这种垃圾收集器大家了解,现在已经不用串行的了。而且在限定单核 CPU 才可以用。现在都不是单核的了。 + +对于交互较强的应用而言,这种垃圾收集器是不能接受的。一般在 Java web 应用程序中是不会采用串行垃圾收集器的。 + +## ParNew 回收器:并行回收 + +如果说 Serial GC 是年轻代中的单线程垃圾收集器,那么 ParNew 收集器则是 Serial 收集器的多线程版本。 + +- Par 是 Parallel 的缩写,New:只能处理的是新生代 + +ParNew 收集器除了采用**并行回收**的方式执行内存回收外,两款垃圾收集器之间几乎没有任何区别。ParNew 收集器在年轻代中同样也是**采用复制算法**、"Stop-The-World"机制。 + +ParNew 是很多 JVM 运行在 Server 模式下新生代的默认垃圾收集器。 + +![image-20200713102030127](https://gitee.com/xlshi/blog_img/raw/master/img/20201014095840.png) + +- 对于新生代,回收次数频繁,使用并行方式高效。 +- 对于老年代,回收次数少,使用串行方式节省资源。(CPU 并行需要切换线程,串行可以省去切换线程的资源) + +由于 ParNew 收集器是基于并行回收,那么是否可以断定 ParNew 收集器的回收效率在任何场景下都会比 Serial收集器更高效? + +- ParNew 收集器运行在多 CPU 的环境下,由于可以充分利用多 CPU、多核心等物理硬件资源优势,可以更快速地完成垃圾收集,提升程序的吞吐量 +- 但是在**单个 CPU 的环境下,ParNew 收集器不比 Serial 收集器更高效**。虽然 Serial 收集器是基于串行回收,但是由于 CPU 不需要频繁得做任务切换,因此可以有效避免多线程交互过程中产生的一些额外开销 + +除 Serial Old GC 外,目前只有 ParNew GC 能与 CMS 收集器配合工作(JDK 8 中 Serial Old GC 移除对 ParNew GC 的支持,JDK 9 版本中已经明确提示 UserParNewGC was deprecated,将在后续版本中被移除,JDK 14中移除 CMS GC) + +在程序中,开发人员可以通过选项"-XX:+UseParNewGC"手动指定使用 ParNew 收集器执行内存回收任务。它表示年轻代使用并行收集器,不影响老年代。 + +-XX:ParallelGCThreads 限制线程数量,默认开启和 CPU 数据相同的线程数。 + +## Parallel 回收器:吞吐量优先 + +HotSpot 的年轻代中除了拥有 ParNew 收集器是基于并行回收的以外,Parallel Scavenge 收集器同样也采用了**复制算法、并行回收和"Stop The World"机制**。 + +那么 Parallel 收集器的出现是否多此一举? + +- 和 ParNew 收集器不同,Parallel Scavenge 收集器的目标则是达到**一个可控制的吞吐量**(Throughput),它也被称为吞吐量优先的垃圾收集器。 +- 自适应调节策略也是 Parallel Scavenge 与 ParNew 一个重要区别。 + +高吞吐量则可以高效率地利用 CPU 时间,尽快完成程序的运算任务,主要**适合在后台运算而不需要太多交互的任务**。因此,常见在服务器环境中使用。**例如,那些执行批量处理、订单处理、工资支付、科学计算的应用程序。** + +Parallel 收集器在 JDK 1.6 时提供了用于执行老年代垃圾收集的 Parallel Old 收集器,用来代替老年代的Serial Old 收集器。 + +Parallel Old 收集器采用了**标记-压缩算法**,但同样也是基于并行回收和"Stop-The-World"机制。 + +![image-20200713110359441](https://gitee.com/xlshi/blog_img/raw/master/img/20201014095843.png) + +在程序吞吐量优先的应用场景中,Parallel 收集器和 Parallel Old 收集器的组合,在 Server 模式下的内存回收性能很不错。在 Java 8 中,默认是此垃圾收集器。 + +### 参数配置 + +-XX:+UseParallelGC 手动指定年轻代使用 Parallel 并行收集器执行内存回收任务。 + +-XX:+UseParalleloldGC 手动指定老年代都是使用并行回收收集器。 + +- 分别适用于新生代和老年代。默认 JDK 8 是开启的。 +- 上面两个参数,默认开启一个,另一个也会被开启。(互相激活) + +-XX:ParallelGcrhreads设置年轻代并行收集器的线程数。一般地,最好与 CPU 数量相等,以避免过多的线程数影响垃圾收集性能。 + +在默认情况下,当 CPU 数量小于8个,ParallelGCThreads的值等于 CPU 数量。 + +当 CPU 数量大于8个,ParallelGCThreads 的值等于3+[5*CPU_Count] / 8] + +-XX:MaxGCPauseMillis 设置垃圾收集器最大停顿时间(即 STW 的时间)。单位是毫秒。 + +- 为了尽可能地把停顿时间控制在 MaxGCPauseMills 以内,收集器在工作时会调整 Java 堆大小或者其他一些参数。 +- 对于用户来讲,停顿时间越短体验越好。但是在服务器端,我们注重高并发,整体的吞吐量。所以服务器端适合 Parallel,进行控制。该参数使用需谨慎。 + +-XX:GCTimeRatio 垃圾收集时间占总时间的比例(= 1 /(N+1))。用于衡量吞吐量的大小。 + +- 取值范围(0,100)。默认值99,也就是垃圾回收时间不超过1%。 + +- 与前一个 -XX:MaxGCPauseMillis 参数有一定矛盾性。暂停时间越长,Radio 参数就容易超过设定的比例。 + +-XX:+UseAdaptiveSizePolicy 设置 Parallel Scavenge 收集器具有**自适应调节策略** + +- 在这种模式下,年轻代的大小、Eden 和 Survivor 的比例、晋升老年代的对象年龄等参数会被自动调整,已达到在堆大小、吞吐量和停顿时间之间的平衡点。 + +- 在手动调优比较困难的场合,可以直接使用这种自适应的方式,仅指定虚拟机的最大堆、目标的吞吐量(GCTimeRatio)和停顿时间(MaxGCPauseMills),让虚拟机自己完成调优工作。 + +## CMS 回收器:低延迟 + +在 JDK 1.5 时期,HotSpot 推出了一款在**强交互应用**中几乎可认为有划时代意义的垃圾收集器:CMS(Concurrent-Mark-Sweep)收集器,**这款收集器是 HotSpot 虚拟机中第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程同时工作**。 + +CMS 收集器的关注点是尽可能缩短垃圾收集时用户线程的停顿时间。停顿时间越短(低延迟)就越适合与用户交互的程序,良好的响应速度能提升用户体验。 + +- **目前很大一部分的 Java 应用集中在互联网站或者 B/S 系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短,**以给用户带来较好的体验。CMS 收集器就非常符合这类应用的需求。 + +CMS 的垃圾收集算法采用**标记-清除**算法,并且也会"Stop-The-World" + +不幸的是,CMS 作为老年代的收集器,却无法与 JDK 1.4.0 中已经存在的新生代收集器 Parallel Scavenge 配合工作,所以在 JDK 1.5 中使用 CMS 来收集老年代的时候,新生代只能选择 ParNew 或者 Serial 收集器中的一个。 + +在 G1 出现之前,CMS 使用还是非常广泛的。一直到今天,仍然有很多系统使用 CMS GC。 + +![image-20200713205154007](https://gitee.com/xlshi/blog_img/raw/master/img/20201014103647.png) + +CMS 整个过程比之前的收集器要复杂,整个过程分为4个主要阶段,即**初始标记阶段、并发标记阶段、重新标记阶段和并发清除阶段**。(涉及STW的阶段主要是:初始标记 和 重新标记) + +- **初始标记**(Initial-Mark)阶段:在这个阶段中,程序中所有的工作线程都将会因为“Stop-The-World”机制而出现短暂的暂停,这个阶段的主要任务仅仅只是**标记出 GC Roots 能直接关联到的对象**。一旦标记完成之后就会恢复之前被暂停的所有应用线程。由于直接关联对象比较小,所以这里的**速度非常快。** +- **并发标记**(Concurrent-Mark)阶段:从 GC Roots 的**直接关联对象开始遍历整个对象图的过程**,这个过程**耗时较长**但是**不需要停顿用户线程**,可以与垃圾收集线程一起并发运行。 +- **重新标记**(Remark)阶段:由于在并发标记阶段中,程序的工作线程会和垃圾收集线程同时运行或者交叉运行,因此为了**修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录**,这个阶段的停顿时间通常会比初始标记阶段稍长一些,但也远比并发标记阶段的时间短。 +- **并发清除**(Concurrent-Sweep)阶段:此阶段**清理删除掉标记阶段判断的已经死亡的对象,释放内存空间**。由于不需要移动存活对象,所以这个阶段也是可以与用户线程同时并发的 + +尽管 CMS 收集器采用的是并发回收(非独占式),但是在其**初始化标记和再次标记这两个阶段中仍然需要执行“Stop-the-World”**机制暂停程序中的工作线程,不过暂停时间并不会太长,因此可以说明目前所有的垃圾收集器都做不到完全不需要“stop-the-World”,只是尽可能地缩短暂停时间。 + +**由于最耗费时间的并发标记与并发清除阶段都不需要暂停工作,所以整体的回收是低停顿的。** + +另外,由于在垃圾收集阶段用户线程没有中断,所以**在 CMS 回收过程中,还应该确保应用程序用户线程有足够的内存可用**。因此,CMS 收集器不能像其他收集器那样等到老年代几乎完全被填满了再进行收集,而是**当堆内存使用率达到某一阈值时,便开始进行回收**,以确保应用程序在 CMS 工作过程中依然有足够的空间支持应用程序运行。要是 CMS 运行期间预留的内存无法满足程序需要,就会出现一次**“Concurrent Mode Failure”**失败,这时虚拟机将启动后备预案:临时启用 Serial Old 收集器来重新进行老年代的垃圾收集,这样停顿时间就很长了。 + +CMS 收集器的垃圾收集算法采用的是**标记-清除算法**,这意味着每次执行完内存回收后,由于被执行内存回收的无用对象所占用的内存空间极有可能是不连续的一些内存块,不可避免地将会**产生一些内存碎片**。那么 CMS 在为新对象分配内存空间时,将无法使用指针碰撞(Bump the Pointer)技术,而只能够选择空闲列表(Free List)执行内存分配。 + +![image-20200713212230352](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104839.png) + +### CMS 为什么不使用标记整理(压缩)算法? + +答案其实很简答,因为当并发清除的时候,用 Compact 整理内存的话,原来的用户线程使用的内存还怎么用呢?要保证用户线程能继续执行,前提的它运行的资源不受影响。Mark Compact 更适合“Stop The World” +这种场景下使用 + +### 优点 + +- 并发收集 +- 低延迟 + +### 缺点 + +- **会产生内存碎片**,导致并发清除后,用户线程可用的空间不足。在无法分配大对象的情况下,不得不提前触发Full GC。 + +- **CMS 收集器对 CPU 资源非常敏感**。在并发阶段,它虽然不会导致用户停顿,但是会因为占用了一部分线程而导致应用程序变慢,总吞吐量会降低。 +- **CMS 收集器无法处理浮动垃圾**。可能出现“Concurrent Mode Failure"失败而导致另一次 Full GC 的产生。在并发标记阶段由于程序的工作线程和垃圾收集线程是同时运行或者交叉运行的,那么在并发标记阶段如果产生新的垃圾对象,CMS 将无法对这些垃圾对象进行标记,最终会导致这些新产生的垃圾对象没有被及时回收,从而只能在下一次执行 GC 时释放这些之前未被回收的内存空间。 + +### CMS 收集器可以设置的参数 + +- -XX:+UseConcMarkSweepGC 手动指定使用 CMS 收集器执行内存回收任务。 + - 开启该参数后会自动将 -XX:+UseParNewGC 打开。即:ParNew(Young区用)+ CMS(Old 区用)+Serial Old的组合。 + +- -XX:CMSInitiatingoccupanyFraction 设置堆内存使用率的阈值,一旦达到该阈值,便开始进行回收。 + - JDK 5 及以前版本的默认值为68,即当老年代的空间使用率达到68%时,会执行一次 CMS 回收。**JDK 6 及以上版本默认值为92%** + - 如果内存增长缓慢,则可以设置一个稍大的值,大的阀值可以有效降低 CMS 的触发频率,减少老年代回收的次数可以较为明显地改善应用程序性能。反之,如果应用程序内存使用率增长很快,则应该降低这个阈值,以避免频繁触发老年代串行收集器。因此**通过该选项便可以有效降低 Full GC 的执行次数。** + +- -XX:+UseCMSCompactAtFullCollection用于指定在执行完 Full GC 后对内存空间进行压缩整理,以此避免内存碎片的产生。不过由于内存压缩整理过程无法并发执行,所带来的问题就是停顿时间变得更长了。 + +- -XX:CMSFullGCsBeforecompaction 设置在执行多少次 Full GC 后对内存空间进行压缩整理。 +- -XX:ParallelcMSThreads 设置 CMS 的线程数量。 + - CMS 默认启动的线程数是(ParallelGCThreads+3)/ 4,ParallelGCThreads 是年轻代并行收集器的线程数。当 CPU 资源比较紧张时,受到 CMS 收集器线程的影响,应用程序的性能在垃圾回收阶段可能会非常糟糕。 + +### 小结 + +HotSpot 有这么多的垃圾回收器,那么如果有人问,Serial GC、Parallel GC、Concurrent Mark Sweep GC 这三个 GC 有什么不同呢? + +请记住以下口令: + +- 如果你想要最小化地使用内存和并行开销,请选 Serial GC; +- 如果你想要最大化应用程序的吞吐量,请选 Parallel GC; +- 如果你想要最小化 GC 的中断或停顿时间,请选 CMS GC。 + +### JDK 后续版本中 CMS 的变化 + +JDK 9 新特性:CMS 被标记为 Deprecate 了(JEP291) + +- 如果对 JDK 9 及以上版本的 HotSpot 虚拟机使用参数-XX:+UseConcMarkSweepGC 来开启 CMS 收集器的话,用户会收到一个警告信息,提示 CMS 未来将会被废弃。 + +JDK 14 新特性:删除 CMS 垃圾回收器(JEP363)移除了 CMS 垃圾收集器,如果在 JDK 14 中使用 +XX:+UseConcMarkSweepGC 的话,JVM 不会报错,只是给出一个 Warning 信息,但是不会 exit。JVM 会自动回退以默认 GC 方式启动 JVM + +> OpenJDK 64-bit Server VM Warning: Ignoring option UseConcMarkSweepGC; support was removed in 14.0 and the VM will continue execution using the default collector. + +## G1 回收器:区域化分代式 + +### 既然我们已经有了前面几个强大的 GC,为什么还要发布 Garbage First(G1)? + +原因就在于应用程序所应对的**业务越来越庞大、复杂,用户越来越多**,没有 GC 就不能保证应用程序正常进行,而经常造成 STW 的 GC 又跟不上实际的需求,所以才会不断地尝试对 GC 进行优化。G1(Garbage-First)垃圾回收器是在 Java7 update 4 之后引入的一个新的垃圾回收器,**是当今收集器技术发展的最前沿成果之一**。 + +与此同时,为了适应现在**不断扩大的内存和不断增加的处理器数量**,进一步降低暂停时间(pause time),同时兼顾良好的吞吐量。 + +**官方给G1设定的目标是在延迟可控的情况下获得尽可能高的吞吐量,所以才担当起“全功能收集器”的重任与期望**。 + +### 为什么名字叫 Garbage First(G1) 呢? + +因为 G1 是一个并行回收器,它把堆内存分割为很多不相关的区域(Region)(物理上不连续的)。使用不同的Region 来表示 Eden、幸存者0区,幸存者1区,老年代等。 + +G1 GC 有计划地避免在整个 Java 堆中进行全区域的垃圾收集。G1 跟踪各个 Region 里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,**每次根据允许的收集时间,优先回收价值最大的 Region。** + +由于这种方式的侧重点在于回收垃圾最大量的区间(Region),所以我们给 G1 一个名字:垃圾优先(Garbage First)。 + +G1(Garbage-First)是一款面向服务端应用的垃圾收集器,**主要针对配备多核 CPU 及大容量内存的机器**,以极高概率满足 GC 停顿时间的同时,还兼具高吞吐量的性能特征。 + +在 JDK 1.7 版本正式启用,移除了 Experimental 的标识,**是 JDK 9 以后的默认垃圾回收器**,取代了 CMS 回收器以及 Parallel + Parallel Old 组合。被 Oracel 官方称为**“全功能的垃圾收集器”**。 + +与此同时,CMS 已经在 JDK 9 中被标记为废弃(deprecated)。在 JDK 8 中还不是默认的垃圾回收器,需要使用 -XX:+UseG1GC 来启用。 + +### G1 垃圾收集器的优点 + +与其他 GC 收集器相比,G1 使用了全新的分区算法,其特点如下所示: + +#### 并行与并发 + +- 并行性:G1 在回收期间,可以有多个 GC 线程同时工作,有效利用多核计算能力。此时用户线程 STW +- 并发性:G1 拥有与应用程序交替执行的能力,部分工作可以和应用程序同时执行,因此,一般来说,不会在整个回收阶段发生完全阻塞应用程序的情况 + +#### 分代收集 + +- 从分代上看,**G1 依然属于分代型垃圾回收器**,它会区分年轻代和老年代,年轻代依然有 Eden 区和 Survivor 区。但从堆的结构上看,它不要求整个 Eden 区、年轻代或者老年代都是连续的,也不再坚持固定大小和固定数量。 +- 将**堆空间分为若干个区域(Region),这些区域中包含了逻辑上的年轻代和老年代。** +- 和之前的各类回收器不同,它**同时兼顾年轻代和老年代**。对比其他回收器,或者工作在年轻代,或者工作在老年代; + +G1 所谓的分代,已经不是下面这样的了 + +![image-20200713215105293](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104902.png) + +而是这样的一个区域 + +![image-20200713215133839](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104904.png) + +#### 空间整合 + +- CMS:“标记-清除”算法、内存碎片、若干次 GC 后进行一次碎片整理 +- G1 将内存划分为一个个的 Region。内存的回收是以 Region 作为基本单位的。**Region 之间是复制算法,**但整体上实际可看作是**标记-压缩(Mark-Compact)算法**,两种算法都可以避免内存碎片。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次 GC。尤其是当 Java 堆非常大的时候,G1 的优势更加明显。 + +#### 可预测的停顿时间模型(即:软实时 Soft Real-Time) +这是 G1 相对于 CMS 的另一大优势,G1 除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集上的时间不得超过 N 毫秒。 + +- 由于分区的原因,G1 可以只选取部分区域进行内存回收,这样缩小了回收的范围,因此对于全局停顿情况的发生也能得到较好的控制。 +- G1 跟踪各个 Region 里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,**每次根据允许的收集时间,优先回收价值最大的 Region** 。保证了 G1 收集器在有限的时间内可以**获取尽可能高的收集效率**。 +- 相比于 CMS GC,G1 未必能做到 CMS 在最好情况下的延时停顿,但是最差情况要好很多。 + +### G1 垃圾收集器的缺点 + +相较于 CMS,G1 还不具备全方位、压倒性优势。比如在用户程序运行过程中,G1 无论是为了垃圾收集产生的内存占用(Footprint)还是程序运行时的额外执行负载(Overload)都要比 CMS 要高。 + +从经验上来说,在小内存应用上 CMS 的表现大概率会优于 G1,而 G1 在大内存应用上则发挥其优势。平衡点在6-8GB 之间。 + +### G1 参数设置 + +- -XX:+UseG1GC:手动指定使用 G1 垃圾收集器执行内存回收任务 +- -XX:G1HeapRegionSize:设置每个 Region 的大小。值是2的幂,范围是 1MB 到 32MB 之间,目标是根据最小的 Java 堆大小划分出约2048个区域。默认是堆内存的1/2000。 +- -XX:MaxGCPauseMillis:设置期望达到的最大 GC 停顿时间指标(JVM 会尽力实现,但不保证达到)。默认值是200ms +- -XX:+ParallelGcThread:设置 STW 工作线程数的值。最多设置为8 +- -XX:ConcGCThreads:设置并发标记的线程数。将n设置为并行垃圾回收线程数(ParallelGCThreads)的1/4左右。 +- -XX:InitiatingHeapOccupancyPercent:设置触发并发 GC 周期的 Java 堆占用率阈值。超过此值,就触发GC。默认值是45。 + +### G1 收集器的常见操作步骤 + +G1 的设计原则就是简化 JVM 性能调优,开发人员只需要简单的三步即可完成调优: + +- 第一步:开启 G1 垃圾收集器 +- 第二步:设置堆的最大内存 +- 第三步:设置最大的停顿时间 + +G1 中提供了三种垃圾回收模式:YoungGC、Mixed GC 和Full GC,在不同的条件下被触发。 + +### G1 收集器的适用场景 + +面向服务端应用,针对具有大内存、多处理器的机器。(在普通大小的堆里表现并不惊喜) + +最主要的应用是需要低 GC 延迟,并具有大堆的应用程序提供解决方案; + +如:在堆大小约 6GB 或更大时,可预测的暂停时间可以低于0.5秒;(G1 通过每次只清理一部分而不是全部的Region 的增量式清理来保证每次 GC 停顿时间不会过长)。 +用来替换掉 JDK 1.5 中的 CMS 收集器;在下面的情况时,使用 G1 可能比 CMS 好: + +- 超过50%的 Java 堆被活动数据占用; +- 对象分配频率或年代提升频率变化很大; +- GC 停顿时间过长(长于0.5至1秒) + +HotSpot 垃圾收集器里,除了 G1 以外,其他的垃圾收集器使用内置的 JVM 线程执行 GC 的多线程操作,而 G1 GC 可以采用应用线程承担后台运行的 GC 工作,即当 JVM 的 GC 线程处理速度慢时,系统会调用应用程序线程帮助加速垃圾回收过程。 + +### 分区 Region:化整为零 + +使用 G1 收集器时,它将整个 Java 堆划分成约2048个大小相同的独立 Region 块,每个 Region 块大小根据堆空间的实际大小而定,整体被控制在 1MB 到 32MB 之间,且为2的N次幂,即1MB,2MB,4MB,8MB,16MB,32MB。可以通过 -XX:G1HeapRegionSize设定。**所有的 Region 大小相同,且在 JVM 生命周期内不会被改变。** + +虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分 Region(不需要连续)的集合。通过 Region 的动态分配方式实现逻辑上的连续。 + +![image-20200713223244886](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104908.png) + +一个 Region 有可能属于 Eden,Survivor 或者 Old/Tenured 内存区域。但是一个 Region 只可能属于一个角色。图中的 E 表示该 Region 属于 Eden 内存区域,S 表示属于 Survivor 内存区域,O 表示属于 Old 内存区域。图中空白的表示未使用的内存空间。 + +G1 垃圾收集器还增加了一种新的内存区域,叫做 Humongous 内存区域,如图中的 H 块。主要用于存储大对象,如果超过 1.5 个 Region,就放到 H。 + +**设置H的原因:**对于堆中的对象,默认直接会被分配到老年代,**但是如果它是一个短期存在的大对象就会对垃圾收集器造成负面影响**。为了解决这个问题,G1 划分了一个 Humongous 区,它用来专门存放大对象。如果一个H 区装不下一个大对象,那么 G1 会寻找连续的 H 区来存储。为了能找到连续的 H 区,有时候不得不启动Full GC。G1 的大多数行为都把 H 区作为老年代的一部分来看待。 + +每个 Region 都是通过指针碰撞来分配空间 + +![image-20200713223509993](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104911.png) + +### G1 垃圾回收器的回收过程 + +G1 GC 的垃圾回收过程主要包括如下三个环节: + +- 年轻代 GC(Young GC) +- 老年代并发标记过程(Concurrent Marking) +- 混合回收(Mixed GC) + +- (如果需要,单线程、独占式、高强度的 Full GC 还是继续存在的。它针对 GC 的评估失败提供了一种失败保护机制,即强力回收。) + +![image-20200713224113996](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104914.png) + +顺时针,Young GC -> Young GC + Concurrent Mark -> Mixed GC 顺序,进行垃圾回收。 + +应用程序分配内存,**当年轻代的 Eden 区用尽时开始年轻代回收过程**;G1 的年轻代收集阶段是一个**并行**的**独占式**收集器。在年轻代回收期,G1 GC 暂停所有应用程序线程,启动多线程执行年轻代回收。然后**从年轻代区间移动存活对象到 Survivor 区间或者老年区间,也有可能是两个区间都会涉及。** + +当堆内存使用达到一定值(默认45%)时,开始老年代并发标记过程。 + +标记完成马上开始混合回收过程。对于一个混合回收期,G1 GC 从老年区间移动存活对象到空闲区间,这些空闲区间也就成为了老年代的一部分。和年轻代不同,老年代的 G1 回收器和其他 GC 不同,**G1 的老年代回收器不需要整个老年代被回收,一次只需要扫描/回收一小部分老年代的 Region 就可以了**。同时,这个老年代 Region 是和年轻代一起被回收的。 + +举个例子:一个 Web 服务器,Java 进程最大堆内存为4G,每分钟响应1500个请求,每45秒钟会新分配大约2G的内存。G1 会每45秒钟进行一次年轻代回收,每31个小时整个堆的使用率会达到45%,会开始老年代并发标记过程,标记完成后开始四到五次的混合回收。 + +### Remembered Set(记忆集) + +一个对象被不同区域引用的问题 + +一个 Region 不可能是孤立的,一个 Region 中的对象可能被其他任意 Region 中对象引用,判断对象存活时,是否需要扫描整个 Java 堆才能保证准确? + +在其他的分代收集器,也存在这样的问题(而 G1 更突出)回收新生代也不得不同时扫描老年代?这样的话会降低 Minor GC 的效率; + +**解决方法:** + +无论 G1 还是其他分代收集器,JVM 都是使用 Remembered Set 来避免全局扫描: + +每个 Region 都有一个对应的 Remembered Set ;每次 Reference 类型数据写操作时,都会产生一个 Write Barrier 暂时中断操作; + +然后检查将要写入的引用指向的对象是否和该 Reference 类型数据在不同的 Region(其他收集器:检查老年代对象是否引用了新生代对象);如果不同,通过 CardTable 把相关引用信息记录到引用指向对象的所在 Region对应的 Remembered Set 中;当进行垃圾收集时,在 GC 根节点的枚举范围加入 Remembered Set;就可以保证不进行全局扫描,也不会有遗漏。 + +![image-20200713224716715](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104917.png) + +### G1 回收过程一:年轻代 GC + +JVM 启动时,G1 先准备好 Eden 区,程序在运行过程中不断创建对象到 Eden 区,当 Eden 空间耗尽时,G1 会启动一次年轻代垃圾回收过程。 + +年轻代垃圾回收只会回收 Eden 区和 Survivor 区 + +首先 G1 停止应用程序的执行(Stop-The-World),G1 创建回收集(Collection Set),回收集是指需要被回收的内存分段的集合,年轻代回收过程的回收集包含年轻代 Eden 区和 Survivor 区所有的内存分段。 + +![image-20200713225100632](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104919.png) + +然后开始如下回收过程: + +#### **第一阶段,扫描根** + +根是指 static 变量指向的对象,正在执行的方法调用链条上的局部变量等。根引用连同 RSet 记录的外部引用作为扫描存活对象的入口。 + +#### **第二阶段,更新 RSet** + +处理 Dirty Card Queue(见备注)中的 Card,更新 RSet。此阶段完成后,**RSet 可以准确的反映老年代对所在的内存分段中对象的引用。** + +> 对于应用程序的引用赋值语句 `object.field = object`,JVM 会在之前和之后执行特殊的操作以在 Dirty Card Queue 中入队一个保存了对象引用信息的 Card。在年轻代回收的时候,G1 会对 Dirty Card Queue中所有的 Card 进行处理,以更新 RSet,保证 RSet 实时准确的反映引用关系。 +> +> 那为什么不在引用赋值语句处直接更新 RSet 呢?这是为了性能的需要,RSet 的处理需要线程同步,开销会很大,使用队列性能会好很多。 + +#### 第三阶段,处理RSet + +识别被老年代对象指向的 Eden 中的对象,这些被指向的 Eden 中的对象被认为是存活的对象。 + +#### 第四阶段,复制对象 + +此阶段,对象树被遍历,Eden 区内存段中存活的对象会被复制到 Survivor 区中空的内存分段,Survivor 区内存段中存活的对象如果年龄未达阈值,年龄会加1,达到阀值会被会被复制到 Old 区中空的内存分段。如果 Survivor 空间不够,Eden 空间的部分数据会直接晋升到老年代空间。 + +#### 第五阶段,处理引用 + +处理 Soft,Weak,Phantom,Final,JNI Weak 等引用。最终 Eden 空间的数据为空,GC 停止工作,而目标内存中的对象都是连续存储的,没有碎片,所以复制过程可以达到内存整理的效果,减少碎片。 + +### G1 回收过程二:并发标记过程(主要针对老年代) + +1. **初始标记阶段**:标记从根节点直接可达的对象。这个阶段是 STW 的,并且会触发一次年轻代 GC。 +2. **根区域扫描(Root Region Scanning)**:G1 GC 扫描 Survivor 区直接可达的老年代区域对象,并标记被引用的对象。这一过程必须在 Young GC 之前完成。 +3. **并发标记(Concurrent Marking)**:在整个堆中进行并发标记(和应用程序并发执行),此过程可能被Young GC 中断。在并发标记阶段,**若发现区域对象中的所有对象都是垃圾,那这个区域会被立即回收**。同时,并发标记过程中,会计算每个区域的对象活性(区域中存活对象的比例)。 +4. **再次标记(Remark)**:由于应用程序持续进行,需要修正上一次的标记结果。是 STW 的。G1 中采用了比CMS 更快的初始快照算法:Snapshot-At-The-Beginning(SATB)。 +5. **独占清理(cleanup,STW)**:计算各个区域的存活对象和 GC 回收比例,并进行排序,识别可以混合回收的区域。为下阶段做铺垫。是 STW 的。这个阶段并不会实际上去做垃圾的收集 +6. **并发清理阶段**:识别并清理完全空闲的区域。 + +### G1 回收过程三:混合回收 + +当越来越多的对象晋升到老年代 Old Region 时,为了避免堆内存被耗尽,虚拟机会触发一个混合的垃圾收集器,即 Mixed GC ,该算法并不是一个 Old GC,除了回收整个 Young Region,还会回收一部分的 Old Region。这里需要注意:**是一部分老年代,而不是全部老年代**。可以选择哪些 Old Region 进行收集,从而可以对垃圾回收的耗时时间进行控制。也要注意的是 Mixed GC 并不是 Full GC。 + +![image-20200713225810871](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104922.png) + +并发标记结束以后,老年代中百分百为垃圾的内存分段被回收了,部分为垃圾的内存分段被计算了出来。默认情况下,这些老年代的内存分段会分8次(可以通过-XX:G1MixedGCCountTarget设置)被回收 + +混合回收的回收集(Collection Set)包括八分之一的老年代内存分段,Eden 区内存分段,Survivor 区内存分段。混合回收的算法和年轻代回收的算法完全一样,只是回收集多了老年代的内存分段。具体过程请参考上面的年轻代回收过程。 + +由于老年代中的内存分段默认分8次回收,G1 会优先回收垃圾多的内存分段。**垃圾占内存分段比例越高的,越会被先回收。并且有一个阈值会决定内存分段是否被回收,** -XX:G1MixedGCLiveThresholdPercent,默认为65%,意思是垃圾占内存分段比例要达到65%才会被回收。如果垃圾占比太低,意味着存活的对象占比高,在复制的时候会花费更多的时间。 + +混合回收并不一定要进行8次。有一个阈值 -XX:G1HeapWastePercent,默认值为10%,意思是允许整个堆内存中有10%的空间被浪费,意味着如果发现可以回收的垃圾占堆内存的比例低于10%,则不再进行混合回收。因为GC 会花费很多的时间但是回收到的内存却很少。 + +### G1 回收可选的过程四:Full GC + +G1 的初衷就是要避免 Full GC 的出现。但是如果上述方式不能正常工作,G1 会**停止应用程序的执行**(Stop-The-World),使用**单线程**的内存回收算法进行垃圾回收,性能会非常差,应用程序停顿时间会很长。 + +要避免 Full GC 的发生,一旦发生需要进行调整。什么时候会发生 Full GC 呢?比如堆内存太小,当 G1 在复制存活对象的时候没有空的内存分段可用,则会回退到 Full GC ,这种情况可以通过增大内存解决。 +导致G1 Full GC 的原因可能有两个: + +- Evacuation 的时候没有足够的 To-Space 来存放晋升的对象; +- 并发处理过程完成之前空间耗尽。 + +### G1 回收的优化建议 + + 从 Oracle 官方透露出来的信息可获知,回收阶段(Evacuation)其实本也有想过设计成与用户程序一起并发执行,但这件事情做起来比较复杂,考虑到 G1 只是回收一部分 Region,停顿时间是用户可控制的,所以并不迫切去实现,而**选择把这个特性放到了 G1 之后出现的低延迟垃圾收集器(即ZGC)中**。另外,还考虑到 G1 不是仅仅面向低延迟,停顿用户线程能够最大幅度提高垃圾收集效率,为了保证吞吐量所以才选择了完全暂停用户线程的实现方案。 + +年轻代大小 + +- 避免使用 -Xmn 或 -XX:NewRatio 等相关选项显式设置年轻代大小 +- 固定年轻代的大小会覆盖暂停时间目标 + +暂停时间目标暂停时间目标不要太过严苛 + +- G1 GC 的吞吐量目标是90%的应用程序时间和10%的垃圾回收时间 +- 评估 G1 GC 的吞吐量时,暂停时间目标不要太严苛。目标太过严苛表示你愿意承受更多的垃圾回收开销,而这些会直接影响到吞吐量。 + +## 垃圾回收器总结 + +截止 JDK 1.8,一共有7款不同的垃圾收集器。每一款的垃圾收集器都有不同的特点,在具体使用的时候,需要根据具体的情况选用不同的垃圾收集器。 + +![image-20200714075738203](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104925.png) + +GC 发展阶段:Serial => Parallel(并行)=> CMS(并发)=> G1 => ZGC + +不同厂商、不同版本的虚拟机实现差距比较大。HotSpot 虚拟机在 JDK7/8 后所有收集器及组合如下图 + +![image-20200714080151020](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104927.png) + +- 两个收集器间有连线,表明它们可以搭配使用:Serial/Serial Old、Serial/CMS、ParNew/Serial Old、ParNew/CMS、Parallel Scavenge/Serial Old、Parallel Scavenge/Parallel Old、G1; +- 其中 Serial Old 作为 CMS 出现"Concurrent Mode Failure"失败的后备预案。 +- (红色虚线)由于维护和兼容性测试的成本,在 JDK 8 时将 Serial+CMS、ParNew+Serial Old 这两个组合声明为废弃(JEP173),并在 JDK 9 中完全取消了这些组合的支持(JEP214),即:移除。 +- (绿色虚线)JDK 14 中:弃用 Parallel Scavenge 和 Serialold GC 组合(JEP366) +- (青色虚线)JDK 14 中:删除 CMS 垃圾回收器(JEP363) + +### 怎么选择垃圾回收器 + +Java 垃圾收集器的配置对于 JVM 优化来说是一个很重要的选择,选择合适的垃圾收集器可以让 JVM 的性能有一个很大的提升。怎么选择垃圾收集器? + +- 优先调整堆的大小让 JVM 自适应完成。 +- 如果内存小于100M,使用串行收集器 +- 如果是单核、单机程序,并且没有停顿时间的要求,串行收集器 +- 如果是多 CPU、需要高吞吐量、允许停顿时间超过1秒,选择并行或者 JVM 自己选择 +- 如果是多 CPU、追求低停顿时间,需快速响应(比如延迟不能超过1秒,如互联网应用),使用并发收集器 +- 官方推荐 G1,性能高。**现在互联网的项目,基本都是使用 G1。** + +最后需要明确一个观点: + +- 没有最好的收集器,更没有万能的收集 +- 调优永远是针对特定场景、特定需求,不存在一劳永逸的收集器 + +### 面试 + +对于垃圾收集,面试官可以循序渐进从理论、实践各种角度深入,也未必是要求面试者什么都懂。但如果你懂得原理,一定会成为面试中的加分项。 +这里较通用、基础性的部分如下: + +- 垃圾收集的算法有哪些?如何判断一个对象是否可以回收? + +- 垃圾收集器工作的基本流程。 + +另外,大家需要多关注垃圾回收器这一章的各种常用的参数 + +## GC 日志分析 + +通过阅读 GC 日志,我们可以了解 Java 虚拟机内存分配与回收策略。 +内存分配与垃圾回收的参数列表 + +- -XX:+PrintGC 输出 GC 日志。类似:-verbose:gc +- -XX:+PrintGCDetails 输出 GC 的详细日志 +- -XX:+PrintGCTimestamps 输出 GC 的时间戳(以基准时间的形式) +- -XX:+PrintGCDatestamps 输出 GC 的时间戳(以日期的形式,如2013-05-04T21:53:59.234+0800) +- -XX:+PrintHeapAtGC在进行 GC 的前后打印出堆的信息 +- -Xloggc:../logs/gc.log日志文件的输出路径 + +### verbose:gc + +打开GC日志 + +```bash +-verbose:gc +``` + +这个只会显示总的 GC 堆的变化,如下: + +![image-20200714081610474](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104930.png) + +参数解析 + +![image-20200714081622526](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104933.png) + +### PrintGCDetails + +打开 GC 日志 + +```bash +-verbose:gc -XX:+PrintGCDetails +``` + +输入信息如下 + +![image-20200714081909309](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104935.png) + +参数解析 + +![image-20200714081925767](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104937.png) + +### 时间戳 + +打开 GC 日志: + +``` +-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps +``` + +输入信息如下: + +![image-20201015212300750](https://gitee.com/xlshi/blog_img/raw/master/img/20201015212302.png) + +说明:带上了日期和时间 + +### GC 日志 + +把 GC 日志保存到文件 + +``` +-Xloggc:/path/to/gc.log +``` + +### 补充 + +- "[GC"和"[Full GC"说明了这次垃圾收集的停顿类型,如果有"Full"则说明 GC 发生了"Stop The World" +- 使用 Serial 收集器在新生代的名字是Default New Generation,因此显示的是"[DefNew" +- 使用 ParNew 收集器在新生代的名字会变成"[ParNew",意思是"Parallel New Generation" +- 使用 Parallel Scavenge 收集器在新生代的名字是”[PSYoungGen" +- 老年代的收集和新生代道理一样,名字也是收集器决定的 +- 使用 G1 收集器的话,会显示为"Garbage-First Heap" + +**Allocation Failure** + +- 表明本次引起 GC 的原因是因为在年轻代中没有足够的空间能够存储新的数据了。 + +**[PSYoungGen:5986K->696K(8704K)]5986K->704K(9216K)中括号内:** + +- GC 回收前年轻代大小,回收后大小,(年轻代总大小) +- 括号外:GC回收前年轻代和老年代大小,回收后大小,(年轻代和老年代总大小) + +**user 代表用户态回收耗时,sys 内核态回收耗时,rea 实际耗时。由于多核的原因,时间总和可能会超过 real 时间** + +![image-20201015212651783](https://gitee.com/xlshi/blog_img/raw/master/img/20201015212653.png) + +### Young GC(Minor GC) + +![image-20201015212734528](https://gitee.com/xlshi/blog_img/raw/master/img/20201015212735.png) + +### Full GC + +![image-20201015212742320](https://gitee.com/xlshi/blog_img/raw/master/img/20201015212743.png) + +### GC 回收举例 + +我们编写一个程序,用来说明 GC 收集的过程 + +```java +/** + * GC垃圾收集过程 + */ +public class GCUseTest { + static final Integer _1MB = 1024 * 1024; + public static void main(String[] args) { + byte [] allocation1, allocation2, allocation3, allocation4; + allocation1 = new byte[2 *_1MB]; + allocation2 = new byte[2 *_1MB]; + allocation3 = new byte[2 *_1MB]; + allocation4 = new byte[4 *_1MB]; + } +} +``` + +我们设置 JVM 启动参数 + +```bash +-Xms10m -Xmx10m -XX:+PrintGCDetails +``` + +首先我们会将3个 2M 的数组存放到 Eden 区,然后后面 4M 的数组来了后,将无法存储,因为 Eden 区只剩下2M 的剩余空间了,那么将会进行一次 Young GC 操作,将原来 Eden 区的内容,存放到 Survivor 区,但是Survivor 区也存放不下,那么就会直接晋级存入 Old 区 + +![image-20200714083332238](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104945.png) + +然后我们将 4M 对象存入到 Eden 区中 + +![image-20200714083526790](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104947.png) + +可以用一些工具去分析这些 GC 日志 + +常用的日志分析工具有:GCViewer、GCEasy、GCHisto、GCLogViewer、Hpjmeter、garbagecat 等 + +**GCViewer** + +![image-20200714084921184](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104952.png) + +**GC easy** + +![image-20200714084726824](https://gitee.com/xlshi/blog_img/raw/master/img/20201014104955.png) + + + +## 垃圾回收器的新发展 + +GC 仍然处于飞速发展之中,目前的默认选项 **G1 GC 在不断的进行改进**,很多我们原来认为的缺点,例如串行的Full GC、Card Table 扫描的低效等,都已经被大幅改进,例如,JDK 10 以后,Full GC 已经是并行运行,在很多场景下,其表现还略优于 Parallel GC 的并行 Full GC 实现。 + +即使是 Serial GC,虽然比较古老,但是简单的设计和实现未必就是过时的,它本身的开销,不管是 GC 相关数据结构的开销,还是线程的开销,都是非常小的,所以随着云计算的兴起,**在 Serverless 等新的应用场景下,Serial GC 找到了新的舞台。** + +比较不幸的是 CMS GC,因为其算法的理论缺陷等原因,虽然现在还有非常大的用户群体,但在 JDK 9 中已经被标记为废弃,并在 JDK 14 版本中移除 + +Epsilon:A No-Op GarbageCollector(Epsilon 垃圾回收器,"No-Op(无操作)"回收器)http://openidk.iava.net/iep s/318 + +ZGC:A Scalable Low-Latency Garbage Collector(Experimental)(ZGC:可伸缩的低延迟垃圾回收器,处于实验性阶段) + +现在 G 1回收器已成为默认回收器好几年了。我们还看到了引入了两个新的收集器:ZGC(JDK 11 出现)和Shenandoah(Open JDK 12) + +- 主打特点:低停顿时间 + +### Open JDK 12 的 Shenandoash GC + +Open JDK 12 的 Shenandoash GC:低停顿时间的 GC(实验性) + +**Shenandoah,无疑是众多 GC 中最孤独的一个**。是第一款不由 Oracle 公司团队领导开发的 HotSpot 垃圾收集器。不可避免的受到官方的排挤。比如号称 OpenJDK 和 OracleJDK 没有区别的 Oracle 公司仍拒绝在OracleJDK12中支持 Shenandoah。 + +Shenandoah 垃圾回收器最初由 RedHat 进行的一项垃圾收集器研究项目 Pauseless GC 的实现,旨在针对 JVM上的内存回收实现低停顿的需求。在2014年贡献给 OpenJDK。 + +Red Hat 研发 Shenandoah 团队对外宣称,**Shenandoah 垃圾回收器的暂停时间与堆大小无关,这意味着无论将堆设置为 200MB 还是 200GB,99.9%的目标都可以把垃圾收集的停顿时间限制在十毫秒以内**。不过实际使用性能将取决于实际工作堆的大小和工作负载。 + +![image-20200714090608807](https://gitee.com/xlshi/blog_img/raw/master/img/20201015213141.png) + +这是 RedHat 在2016年发表的论文数据,测试内容是使用 ES 对200GB的维基百科数据进行索引。从结果看: +- 停顿时间比其他几款收集器确实有了质的飞跃,但也未实现最大停顿时间控制在十毫秒以内的目标。 +- 而吞吐量方面出现了明显的下降,总运行时间是所有测试收集器里最长的。 + +#### 总结 + +- Shenandoah GC 的弱项:高运行负担下的吞吐量下降。 +- shenandoah GC 的强项:低延迟时间。 + +### 革命性的 ZGC + +ZGC 与 Shenandoah 目标高度相似,**在尽可能对吞吐量影响不大的前提下,实现在任意堆内存大小下都可以把垃圾收集的停颇时间限制在十毫秒以内的低延迟。** + +《深入理解Java虚拟机》一书中这样定义 ZGC:ZGC 收集器是一款基于 Region 内存布局的,(暂时)不设分代的,使用了读屏障、染色指针和内存多重映射等技术来实现**可并发的标记-压缩算法**的,以低延迟为首要目标的一款垃圾收集器。 + +ZGC 的工作过程可以分为4个阶段:**并发标记 - 并发预备重分配 - 并发重分配 - 并发重映射** 等。 + +ZGC 几乎在所有地方并发执行的,除了初始标记的是 STW 的。所以停顿时间几乎就耗费在初始标记上,这部分的实际时间是非常少的。 + +![image-20200714091201073](https://gitee.com/xlshi/blog_img/raw/master/img/20201014105000.png) + +停顿时间对比 + +![image-20200714091401511](https://gitee.com/xlshi/blog_img/raw/master/img/20201014105009.png) + +在 ZGC 的强项停顿时间测试上,塔毫不留情的将 Parallel、G1 拉开了两个数量级的差距。无论平均挺对、95%停顿、99%停顿、99.9%停顿,还是最大停顿时间,ZGC 都能毫不费劲控制在10毫秒以内。 + +虽然 ZGC 还在试验状态,没有完成所有特性,但此时性能已经相当亮眼,用“令人震惊、革命性”来形容,不为过。 +**未来将在服务端、大内存、低延迟应用的首选垃圾收集器。** + +![image-20200714093243028](https://gitee.com/xlshi/blog_img/raw/master/img/20201014105012.png) + +JDK 14 之前,ZGC 仅 Linux 才支持。 + +尽管许多使用 ZGC 的用户都使用类 Linux 的环境,但在 Windows 和 macOS 上,人们也需要 ZGC 进行开发部署和测试。许多桌面应用也可以从 ZGC 中受益。因此,ZGC 特性被移植到了 Windows 和 macOS 上。 + +现在 mac 或 Windows 上也能使用 ZGC 了,示例如下: + +```bash +-XX:+UnlockExperimentalVMOptions-XX:+UseZGC +``` + +### AliGC + +AliGC 是阿里巴巴 JVM 团队基于 G1 算法,面向大堆(LargeHeap)应用场景。指定场景下的对比: + +![image-20200714093604012](https://gitee.com/xlshi/blog_img/raw/master/img/20201015213651.png) + +当然,其它厂商也提供了各种别具一格的 GC 实现,例如比较有名的低延迟 GC——Zing \ No newline at end of file diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713083030867.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713083030867.png" new file mode 100644 index 0000000000000000000000000000000000000000..6d34442f4e50c8cc29fb150eba26b594419dbc39 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713083030867.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713083443486.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713083443486.png" new file mode 100644 index 0000000000000000000000000000000000000000..309d3a2fa0fbb5a14702fbfe4a688ab1278b5123 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713083443486.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713084726176.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713084726176.png" new file mode 100644 index 0000000000000000000000000000000000000000..db25cf1ad82ac2fc8a5b7f231667f38c47e45a25 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713084726176.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713085306400.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713085306400.png" new file mode 100644 index 0000000000000000000000000000000000000000..565c1ff22ac66761224af9b635038d3ae8c09f8b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713085306400.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713093551365.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713093551365.png" new file mode 100644 index 0000000000000000000000000000000000000000..082e528420e9943f3094fa1334630439bf7efc77 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713093551365.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713093757644.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713093757644.png" new file mode 100644 index 0000000000000000000000000000000000000000..87e5ced7e9ee1bbe08b13d4875c06debea5005b9 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713093757644.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713094745366.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713094745366.png" new file mode 100644 index 0000000000000000000000000000000000000000..df07f7c0542605667c507bd53dff079ad96be591 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713094745366.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713100703799.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713100703799.png" new file mode 100644 index 0000000000000000000000000000000000000000..edad53c26d329cc0ee410dfaaee597f64cc73e2e Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713100703799.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713102030127.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713102030127.png" new file mode 100644 index 0000000000000000000000000000000000000000..22c4966304f77a41ac5cd98b8092cfa25d7a6a44 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713102030127.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713110359441.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713110359441.png" new file mode 100644 index 0000000000000000000000000000000000000000..62362cec4a9ea86b2fe9e8ca6b8d8f8dda20cc57 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713110359441.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713205154007.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713205154007.png" new file mode 100644 index 0000000000000000000000000000000000000000..d2d8f4701eca922780620c0c80d0154213976d62 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713205154007.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713212230352.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713212230352.png" new file mode 100644 index 0000000000000000000000000000000000000000..4c267b8dd8531d22b9b8feacc4ae3629868e6394 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713212230352.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713215105293.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713215105293.png" new file mode 100644 index 0000000000000000000000000000000000000000..5da33ab2cbe722fd532b87b18ba6c8c8a44e72de Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713215105293.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713215133839.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713215133839.png" new file mode 100644 index 0000000000000000000000000000000000000000..d657c4e1296361a6ce3c8450ea50890f3548083d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713215133839.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713223244886.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713223244886.png" new file mode 100644 index 0000000000000000000000000000000000000000..42cecec9ee1356c021078626a459c47717d43671 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713223244886.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713223509993.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713223509993.png" new file mode 100644 index 0000000000000000000000000000000000000000..7d9cac0c6664f0fced8a57ee9cef1718f2c000de Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713223509993.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713224113996.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713224113996.png" new file mode 100644 index 0000000000000000000000000000000000000000..017f31b10d8a869ef19502655500876146db572e Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713224113996.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713224716715.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713224716715.png" new file mode 100644 index 0000000000000000000000000000000000000000..af732bb54a27fc0a6313e541ca8e71d0c85fecd3 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713224716715.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713225100632.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713225100632.png" new file mode 100644 index 0000000000000000000000000000000000000000..268f75dcfcb9c004bb3fb1e9b1485663789ba441 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713225100632.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713225810871.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713225810871.png" new file mode 100644 index 0000000000000000000000000000000000000000..e8db0e5fd56a3d6a490c4836ce3909e73a03bcb9 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200713225810871.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714075738203.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714075738203.png" new file mode 100644 index 0000000000000000000000000000000000000000..6730496b8bdd102d7b5c51c3b624512ee2525426 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714075738203.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714080151020.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714080151020.png" new file mode 100644 index 0000000000000000000000000000000000000000..1766d8a965ac6391b3ecfa906b0d9b5996028b72 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714080151020.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714081610474.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714081610474.png" new file mode 100644 index 0000000000000000000000000000000000000000..8d38e43709d8728399e778f98ca12eaac84b99a2 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714081610474.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714081622526.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714081622526.png" new file mode 100644 index 0000000000000000000000000000000000000000..535087ca92684e6c227e6641e7aeb49e3225c129 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714081622526.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714081909309.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714081909309.png" new file mode 100644 index 0000000000000000000000000000000000000000..ce7870d5c9b3ed1dd3bdc48be74104d63a80d447 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714081909309.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714081925767.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714081925767.png" new file mode 100644 index 0000000000000000000000000000000000000000..6b3716660194cb165f201ba34cd07d6dbf16b4ee Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714081925767.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714082555688.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714082555688.png" new file mode 100644 index 0000000000000000000000000000000000000000..e006d618fb09aebd90008a46e7a385269b0011b9 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714082555688.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714082714690.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714082714690.png" new file mode 100644 index 0000000000000000000000000000000000000000..3cdc6fb8c66516fb4164aca0410e58c557ef0abf Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714082714690.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714083332238.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714083332238.png" new file mode 100644 index 0000000000000000000000000000000000000000..6cdcd1e342a5cf0562614167cdd2de0da929d1c9 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714083332238.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714083526790.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714083526790.png" new file mode 100644 index 0000000000000000000000000000000000000000..1d0317dbea5c57e359cea94c9ec9d1c929b36c96 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714083526790.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714084726824.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714084726824.png" new file mode 100644 index 0000000000000000000000000000000000000000..ed3f7b3bc7eee5c963e69db10e9294cd1e937175 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714084726824.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714084921184.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714084921184.png" new file mode 100644 index 0000000000000000000000000000000000000000..30ec0e7cecadcf5d99daa55e5396d7ccf326279f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714084921184.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714090608807.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714090608807.png" new file mode 100644 index 0000000000000000000000000000000000000000..fcf2936853101ec8aa0fe71d7b70fb266842ae8e Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714090608807.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714091201073.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714091201073.png" new file mode 100644 index 0000000000000000000000000000000000000000..447e6872aa68d9d0fa473fb1afffc64373ec2b44 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714091201073.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714091401511.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714091401511.png" new file mode 100644 index 0000000000000000000000000000000000000000..ff87e5efa14b03d32e3e30caa7043844bd42df45 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714091401511.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714093243028.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714093243028.png" new file mode 100644 index 0000000000000000000000000000000000000000..0ec1cd64972f498dffdf7dcce76a085fc253963b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714093243028.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714093604012.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714093604012.png" new file mode 100644 index 0000000000000000000000000000000000000000..15a251d2daace6c3ee1ba487c6b77ab3022cb035 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/17_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/images/image-20200714093604012.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..c0321fbf29b94cf4e5538518dd798548abf9a913 --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/README.md" @@ -0,0 +1,491 @@ +# JVM 与 Java 体系结构 + +## 前言 + +作为 Java 工程师的你曾被伤害过吗?你是否也遇到过这些问题? + +运行着的线上系统突然卡死,系统无法访问,甚至直接 OOM ! + +- 想解决线上 JVM GC 问题,但却无从下手。 +- 新项目上线,对各种 JVM 参数设置一脸茫然,直接默认吧然后就 GG 了 +- 每次面试之前都要重新背一遍 JVM 的一些原理概念性的东西,然而面试官却经常问你在实际项目中如何调优VM 参数,如何解决 GC、OOM 等问题,一脸懵逼。 + +![image-20200704111417472](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111704.png) + +大部分 Java 开发人员,除会在项目中使用到与 Java 平台相关的各种高精尖技术,对于 Java 技术的核心 Java 虚拟机了解甚少。 + +一些有一定工作经验的开发人员,打心眼儿里觉得 SSM 、微服务等上层技术才是重点,基础技术并不重要,这其实是一种本末倒置的“病态”。如果我们把核心类库的 API 比做数学公式的话,那么 Java 虚拟机的知识就好比公式的推导过程。 + +计算机系统体系对我们来说越来越远,在不了解底层实现方式的前提下,通过高级语言很容易编写程序代码。但事实上计算机并不认识高级语言 + +![image-20200704112119729](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111707.png) + +### 架构师每天都在思考什么? + +- 应该如何让我的系统更快? +- 如何避免系统出现瓶颈? + +知乎上有条帖子:应该如何看招聘信息,直通年薪50万+? + +- 参与现有系统的性能优化,重构,保证平台性能和稳定性 +- 根据业务场景和需求,决定技术方向,做技术选型 +- 能够独立架构和设计海量数据下高并发分布式解决方案,满足功能和非功能需求 +- 解决各类潜在系统风险,核心功能的架构与代码编写 +- 分析系统瓶颈,解决各种疑难杂症,性能调优等 + +### 为什么要学习 JVM + +- 面试的需要(BATJ、TMD,PKQ等面试都爱问) +- 中高级程序员必备技能 + - 项目管理、调优的需求 + +- 追求极客的精神 + - 比如:垃圾回收算法、JIT(及时编译器)、底层原理 + +### Java vs C++ + +垃圾收集机制为我们打理了很多繁琐的工作,大大提高了开发的效率,但是,垃圾收集也不是万能的,懂得 JVM内部的内存结构、工作机制,是设计高扩展性应用和诊断运行时问题的基础,也是 Java 工程师进阶的必备能力。 + +![image-20200704112700211](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111710.png) + +C 语言需要自己来分配内存和回收内存,Java 全部交给 JVM 进行分配和回收。 + +### 参考书目 + +![image-20200704145340513](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111712.png) + +![image-20201009091117997](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111713.png) + +![image-20201009091158558](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111716.png) + +## Java 及 JVM 简介 + +### Java:跨平台的语言 + +Java 是目前应用最为广泛的软件开发平台之一。随着 Java 以及 Java 社区的不断壮大 Java 也早已不再是简简单单的一门计算机语言了,它更是一个平台、一种文化、一个社区。 + +- 作为一个平台,Java 虚拟机扮演着举足轻重的作用 + - Groovy、Scala、JRuby、Kotlin等都是Java平台的一部分 + +- 作为一种文化,Java 几乎成为了“开源”的代名词。 + - 第三方开源软件和框架。如Tomcat、Struts,MyBatis,Spring等。 + - 就连 JDK 和 JVM 自身也有不少开源的实现,如OpenJDK、Harmony。 +- 作为一个社区,Java 拥有全世界最多的技术拥护者和开源社区支持,有数不清的论坛和资料。从桌面应用软件、嵌入式开发到企业级应用、后台服务器、中间件,都可以看到 Java 的身影。其应用形式之复杂、参与人数之众多也令人咂舌。 + +![image-20200704151731216](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111719.png) + +每个语言都需要转换成字节码文件,最后转换的字节码文件都能通过 Java 虚拟机进行运行和处理 + +### JVM:跨平台的语言 + +![image-20200704152052489](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111721.png) + +随着 Java 7 的正式发布,Java 虚拟机的设计者们通过 JSR-292 规范基本实现在 **Java 虚拟机平台上运行非 Java语言编写的程序。** + +Java 虚拟机根本不关心运行在其内部的程序到底是使用何种编程语言编写的,**它只关心“字节码”文件**。也就是说 Java 虚拟机拥有语言无关性,并不会单纯地与 Java 语言“终身绑定”,只要其他编程语言的编译结果满足并包含 Java 虚拟机的内部指令集、符号表以及其他的辅助信息,它就是一个有效的字节码文件,就能够被虚拟机所识别并装载运行。 + +### 字节码 + +我们平时说的 Java 字节码,指的是用 Java 语言编译成的字节码。准确的说任何能在 JVM 平台上执行的字节码格式都是一样的。所以应该统称为:**JVM 字节码。** + +不同的编译器,可以编译出相同的字节码文件,字节码文件也可以在不同的 JVM 上运行。 + +Java 虚拟机与 Java 语言并没有必然的联系,它只与特定的二进制文件格式— Class 文件格式所关联,Class 文件中包含了 Java 虚拟机指令集(或者称为字节码、Bytecodes)和符号表,还有一些其他辅助信息。 + +### 多语言混合编程 + +**Java 平台上的多语言混合编程正成为主流,通过特定领域的语言去解决特定领域的问题是当前软件开发应对日趋复杂的项目需求的一个方向。** + +试想一下,在一个项目之中,并行处理用 Clojure 语言编写,展示层使用 JRuby/Rails ,中间层则是 Java ,每个应用层都将使用不同的编程语言来完成,而且,接口对每一层的开发者都是透明的,**各种语言之间的交互不存在任何困难,就像使用自己语言的原生 API 一样方便,因为它们最终都运行在一个虚拟机之上。** + +对这些运行于 Java 虚拟机之上、Java 之外的语言,来自系统级的、底层的支持正在迅速增强,以 JSR-292 为核心的一系列项目和功能改进(如 Da Vinci Machine 项目、Nashorn 引擎、InvokeDynamic 指令、java.lang.invoke 包等),推动 Java 虚拟机从“Java 语言的虚拟机”向 “多语言虚拟机”的方向发展。 + +## Java发展的重大事件 + +- 1990年,在 Sun 计算机公司中,由 Patrick Naughton、MikeSheridan 及 James Gosling 领导的小组Green Team,开发出的新的程序语言,命名为 oak ,后期命名为 Java +- 1995年,Sun 正式发布 Java 和 HotJava 产品,Java 首次公开亮相。 +- 1996年1月23日 Sun Microsystems 发布了 JDK 1.0。 +- 1998年,JDK 1.2 版本发布。同时,Sun 发布了 JSP/Servlet、EJB 规范,以及将 Java 分成了 J2EE、J2SE 和 J2ME。这表明了 Java 开始向企业、桌面应用和移动设备应用3大领域挺进。 +- 2000年,JDK 1.3 发布,**Java HotSpot Virtual Machine 正式发布,成为 Java 的默认虚拟机。** +- 2002年,JDK 1.4 发布,古老的 Classic 虚拟机退出历史舞台。 +- 2003年年底,**Java 平台的 Scala 正式发布,同年 Groovy 也加入了 Java 阵营。** +- 2004年,JDK 1.5 发布。同时 JDK 1.5 改名为 JavaSE 5.0。 +- 2006年,JDK 6 发布。同年,**Java 开源并建立了 OpenJDK**。顺理成章,**HotSpot 虚拟机也成为了OpenJDK 中的默认虚拟机。** + +- 2007年,**Java 平台迎来了新伙伴 Clojure。** +- 2008年,Oracle 收购了 BEA,**得到了 JRockit 虚拟机。** +- 2009年,Twitter 宣布把后台大部分程序从 Ruby 迁移到 Scala ,这是 Java 平台的又一次大规模应用。 +- 2010年,Oracle 收购了 Sun,获得 Java 商标和最真价值的 HotSpot 虚拟机。此时,Oracle 拥有市场占用率最高的两款虚拟机 HotSpot 和 JRockit,并计划在未来对它们进行整合:HotRockit +- 2011年,JDK 7 发布。在 JDK 1.7u4 中,**正式启用了新的垃圾回收器 G1。** +- 2017年,JDK 9 发布。**将 G1 设置为默认 GC,替代 CMS** +- 同年,**IBM 的 J9 开源**,形成了现在的 Open J9 社区 +- 2018年,Android 的 Java 侵权案判决,Google 赔偿 Oracle 计88亿美元 +- 同年,Oracle 宣告 JavaEE 成为历史名词 JDBC、JMS、Servlet 赠予 Eclipse 基金会 +- 同年,JDK 11 发布,LTS 版本的 JDK,**发布革命性的 ZGC,调整 JDK 授权许可** +- 2019年,JDK 12 发布,加入 RedHat 领导开发的 **Shenandoah GC** + +![image-20200704182035810](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111725.png) + +在 JDK 11 之前,OracleJDK 中还会存在一些 OpenJDK 中没有的、闭源的功能。但在 JDK 11 中,我们可以认为 OpenJDK 和 OracleJDK 代码实质上已经完全一致的程度。 + +## 虚拟机与 Java 虚拟机 + +### 虚拟机 + +所谓虚拟机(Virtual Machine),就是一台虚拟的计算机。它是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为**系统虚拟机和程序虚拟机。** + +- 大名鼎鼎的 Visual Box,VMware 就属于系统虚拟机,它们**完全是对物理计算机的仿真**,提供了一个可运行完整操作系统的软件平台。 +- 程序虚拟机的典型代表就是 Java 虚拟机,它**专门为执行单个计算机程序而设计**,在 Java 虚拟机中执行的指令我们称为 Java 字节码指令。 + +无论是系统虚拟机还是程序虚拟机,在上面运行的软件都被限制于虚拟机提供的资源中。 + +### Java虚拟机 + +Java 虚拟机是一台执行 Java 字节码的虚拟计算机,它拥有独立的运行机制,其运行的 Java 字节码也未必由 Java 语言编译而成。 + +JVM 平台的各种语言可以共享 Java 虚拟机带来的跨平台性、优秀的垃圾回器,以及可靠的即时编译器。 + +**Java 技术的核心就是 Java 虚拟机**(JVM,Java Virtual Machine),因为所有的 Java 程序都运行在 Java 虚拟机内部。 + +作用: + +**Java 虚拟机就是二进制字节码的运行环境**,负责装载字节码到其内部,解释/编译为对应平台上的机器指令执行。每一条 Java 指令,Java 虚拟机规范中都有详细定义,如怎么取操作数,怎么处理操作数,处理结果放在哪里。 + +特点: + +- 一次编译,到处运行 +- 自动内存管理 +- 自动垃圾回收功能 + +### JVM 的位置 + +JVM 是运行在操作系统之上的,它与硬件没有直接的交互 + +![image-20200704183048061](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111728.png) + +Java 的体系结构 + +![image-20200704183236169](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111730.png) + +## JVM 的整体结构 + +- HotSpot VM 是目前市面上高性能虚拟机的代表作之一。 +- **它采用解释器与即时编译器并存的架构**。 +- 在今天,Java 程序的运行性能早已脱胎换骨,已经达到了可以和 C/C++ 程序一较高下的地步。 + +![image-20200704183436495](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111732.png) + +执行引擎包含三部分:解释器,及时编译器,垃圾回收器 + +## Java 代码执行流程 + +![image-20200704210429535](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111735.png) + +只是能生成被 Java 虚拟机所能解释的字节码文件,那么理论上就可以自己设计一套代码了 + +## JVM 的架构模型 + +Java 编译器输入的指令流基本上是一种基于**栈的指令集架构**,另外一种指令集架构则是基于**寄存器的指令集架构**。具体来说:这两种架构之间的区别: + +基于栈式架构的特点: + +- 设计和实现更简单,适用于资源受限的系统; +- 避开了寄存器的分配难题:使用零地址指令方式分配。 +- 指令流中的指令大部分是零地址指令,其执行过程依赖于操作栈。指令集更小,编译器容易实现。 +- 不需要硬件支持,可移植性更好,更好实现跨平台 + +基于寄存器架构的特点 + +- 典型的应用是 x86 的二进制指令集:比如传统的 PC 以及 Android 的 Davlik 虚拟机。 +- 指令集架构则完全依赖硬件,可移植性差 +- 性能优秀和执行更高效 +- 花费更少的指令去完成一项操作。 +- 在大部分情况下,基于寄存器架构的指令集往往都以一地址指令、二地址指令和三地址指令为主,而基于栈式架构的指令集却是以零地址指令为主 + +### 举例 + +同样执行2+3这种逻辑操作,其指令分别如下: + +基于栈的计算流程(以Java虚拟机为例): + +```bash +iconst_2 // 常量2入栈 +istore_1 +iconst_3 // 常量3入栈 +istore_2 +iload_1 +iload_2 +iadd //常量2/3出栈,执行相加 +istore_0 // 结果5入栈 +``` + +而基于寄存器的计算流程 + +```bash +mov eax,2 //将eax寄存器的值设为1 +add eax,3 //使eax寄存器的值加3 +``` + +### 字节码反编译 + +我们编写一个简单的代码,然后查看一下字节码的反编译后的结果 + +```java +public class StackStruTest { + public static void main(String[] args) { + int i = 2 + 3; + } +} +``` + +然后我们找到编译后的 class 文件,使用下列命令进行反编译 + +```bash +javap -v(verbose) StackStruTest.class +``` + +得到的文件为: + +```java + public static void main(java.lang.String[]); + descriptor: ([Ljava/lang/String;)V + flags: ACC_PUBLIC, ACC_STATIC + Code: + stack=2, locals=4, args_size=1 + 0: iconst_2 + 1: istore_1 + 2: iconst_3 + 3: istore_2 + 4: iload_1 + 5: iload_2 + 6: iadd + 7: istore_3 + 8: return + LineNumberTable: + line 9: 0 + line 10: 2 + line 11: 4 + line 12: 8 + LocalVariableTable: + Start Length Slot Name Signature + 0 9 0 args [Ljava/lang/String; + 2 7 1 i I + 4 5 2 j I + 8 1 3 k I +``` + +### 总结 + +**由于跨平台性的设计,Java 的指令都是根据栈来设计的**。不同平台 CPU 架构不同,所以不能设计为基于寄存器的。优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要更多的指令。 + +时至今日,尽管嵌入式平台已经不是 Java 程序的主流运行平台了(准确来说应该是 HotSpotVM 的宿主环境已经不局限于嵌入式平台了),那么为什么不将架构更换为基于寄存器的架构呢? + +### 栈 + +- 跨平台性 +- 指令集小 +- 指令多 +- 执行性能比寄存器差 + +## JVM 的生命周期 + +### 虚拟机的启动 + +Java 虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实现指定的。 + +### 虚拟机的执行 + +- 一个运行中的 Java 虚拟机有着一个清晰的任务:执行 Java 程序。 +- 程序开始执行时他才运行,程序结束时他就停止。 +- **执行一个所谓的 Java 程序的时候,真真正正在执行的是一个叫做 Java 虚拟机的进程。** + +### 虚拟机的退出 + +有如下的几种情况: + +- 程序正常执行结束 + +- 程序在执行过程中遇到了异常或错误而异常终止 +- 由于操作系统用现错误而导致 Java 虚拟机进程终止 +- 某线程调用 Runtime 类或 System 类的 exit 方法,或 Runtime 类的 halt 方法,并且 Java 安全管理器也允许这次 exit 或 halt 操作。 +- 除此之外,JNI(Java Native Interface)规范描述了用 JNI Invocation API 来加载或卸载 Java 虚拟机时,Java 虚拟机的退出情况。 + +## JVM 发展历程 + +### Sun Classic VM + +- 早在1996年 Java1.0 版本的时候,Sun 公司发布了一款名为 Sun Classic VM 的 Java 虚拟机,它同时也是**世界上第一款商用 Java 虚拟机**,JDK 1.4 时完全被淘汰。 +- 这款虚拟机内部只提供解释器。现在还有及时编译器,因此效率比较低,而及时编译器会把热点代码缓存起来,那么以后使用热点代码的时候,效率就比较高。 +- 如果使用 JIT 编译器,就需要进行外挂。但是一旦使用了 JIT 编译器,JIT 就会接管虚拟机的执行系统。解释器就不再工作。解释器和编译器不能配合工作。 +- 现在 HotSpot 内置了此虚拟机。 + +### Exact VM + +为了解决上一个虚拟机问题,JDK 1.2 时,Sun 提供了此虚拟机。 +Exact Memory Management:准确式内存管理 + +- 也可以叫 Non-Conservative/Accurate Memory Management +- 虚拟机可以知道内存中某个位置的数据具体是什么类型。 + +具备现代高性能虚拟机的维形 + +- 热点探测(寻找出热点代码进行缓存) +- 编译器与解释器混合工作模式 + +只在 Solaris 平台短暂使用,其他平台上还是 Classic VM, + +- 英雄气短,终被 HotSpot 虚拟机替换 + +### HotSpot VM + +HotSpot 历史 +- 最初由一家名为“Longview Technologies”的小公司设计 +- 1997年,此公司被 Sun 收购;2009年,Sun 公司被甲骨文收购。 +- JDK 1.3 时,HotSpot VM 成为默认虚拟机 + +目前 **HotSpot 占有绝对的市场地位,称霸武林**。 + +- 不管是现在仍在广泛使用的 JDK 6 ,还是使用比例较多的 JDK 8 中,默认的虚拟机都是 HotSpot +- Sun/Oracle JDK 和 OpenJDK 的默认虚拟机 +- 因此本课程中默认介绍的虚拟机都是 HotSpot,相关机制也主要是指 HotSpot 的 GC 机制。**(比如其他两个商用虚机都没有方法区的概念)** + +从服务器、桌面到移动端、嵌入式都有应用。 + +名称中的 HotSpot 指的就是它的热点代码探测技术。 + +- 通过计数器找到最具编译价值代码,触发即时编译或栈上替换 +- 通过编译器与解释器协同工作,在最优化的程序响应时间与最佳执行性能中取得平衡 + +### JRockit + +**专注于服务器端应用** + +- 它可以不太关注程序启动速度,因此 **JRockit 内部不包含解析器实现**,全部代码都靠即时编译器编译后执行。 + +大量的行业基准测试显示,JRockit JVM 是世界上最快的 JVM。 + +- 使用 JRockit 产品,客户已经体验到了显著的性能提高(一些超过了70%)和硬件成本的减少(达50%)。 + +优势:全面的 Java 运行时解决方案组合 + +- JRockit 面向延迟敏感型应用的解决方案 JRockit Real Time 提供以毫秒或微秒级的 JVM 响应时间,适合财务、军事指挥、电信网络的需要 +- MissionControl 服务套件,它是一组以极低的开销来监控、管理和分析生产环境中的应用程序的工具。 + +2008年,JRockit 被 Oracle 收购。 + +Oracle 表达了整合两大优秀虚拟机的工作,大致在 JDK 8 中完成。整合的方式是在 HotSpot 的基础上,移植JRockit 的优秀特性。 + +高斯林:目前就职于谷歌,研究人工智能和水下机器人 + +### IBM 的 J9 + +全称:IBM Technology for Java Virtual Machine,简称 IT4J,内部代号:J9 + +市场定位与 HotSpot 接近,服务器端、桌面应用、嵌入式等多用途 VM + +广泛用于 IBM 的各种 Java 产品。 + +目前,有影响力的三大商用虚拟机之一,也号称是世界上最快的 Java 虚拟机。 + +2017年左右,IBM 发布了开源 J9 VM,命名为 OpenJ9,交给 EClipse 基金会管理,也称为 Eclipse OpenJ9 + +OpenJDK -> 是 JDK 开源了,包括了虚拟机 + +### KVM 和 CDC / CLDC HotSpot + +Oracle 在 Java ME 产品线上的两款虚拟机为:CDC/CLDC HotSpot Implementation VM KVM(Kilobyte)是 CLDC-HI 早期产品目前移动领域地位尴尬,智能机被 Angroid 和 IOS 二分天下。 + +KVM 简单、轻量、高度可移植,面向更低端的设备上还维持自己的一片市场 + +- 智能控制器、传感器 +- 老人手机、经济欠发达地区的功能手机 + +所有的虚拟机的原则:一次编译,到处运行。 + +### Azul VM + +前面三大“高性能 Java 虚拟机”使用在通用硬件平台上这里 Azul VW 和 BEALiquid VM 是与**特定硬件平台绑定、软硬件配合的专有虚拟机** +- 高性能 Java 虚拟机中的战斗机。 + +Azul VM 是 Azul Systems 公司在 HotSpot 基础上进行大量改进,运行于 Azul Systems 公司的专有硬件 Vega系统上的 Java 虚拟机。 + +**每个 Azul VM 实例都可以管理至少数十个 CPU 和数百GB内存的硬件资源,并提供在巨大内存范围内实现可控的 GC 时间的垃圾收集器、专有硬件优化的线程调度等优秀特性。** + +2010年,Azul Systems 公司开始从硬件转向软件,发布了自己的 Zing JVM,可以在通用 x86 平台上提供接近于 Vega 系统的特性。 + +### Liquid VM + +高性能 Java 虚拟机中的战斗机。 + +BEA 公司开发的,直接运行在自家 Hypervisor 系统上 + +Liquid VM 即是现在的 JRockit VE(Virtual Edition),**Liquid VM 不需要操作系统的支持,或者说它自己本身实现了一个专用操作系统的必要功能,如线程调度、文件系统、网络支持等。** + +随着 JRockit 虚拟机终止开发,Liquid VM 项目也停止了。 + +### Apache Marmony + +Apache 也曾经推出过与 JDK 1.5 和 JDK 1.6 兼容的 Java 运行平台 Apache Harmony。 + +它是 IBM 和 Intel 联合开发的开源 JVM,受到同样开源的 OpenJDK 的压制,Sun 坚决不让 Harmony 获得 JCP 认证,最终于2011年退役,IBM 转而参与 OpenJDK + +虽然目前并没有 Apache Harmony 被大规模商用的案例,但是它的 Java 类库代码吸纳进了 Android SDK。 + +### Micorsoft JVM + +微软为了在 IE3 浏览器中支持 Java Applets,开发了 Microsoft JVM。 + +只能在 Windows 平台下运行。但确是当时 Windows 下性能最好的 Java VM。 + +1997年,Sun 以侵犯商标、不正当竞争罪名指控微软成功,赔了 Sun 很多钱。微软 Windows XP SP3 中抹掉了其 VM。现在 Windows 上安装的 JDK 都是 HotSpot。 + +### Taobao JVM + +由 AliJVM 团队发布。阿里,国内使用 Java 最强大的公司,覆盖云计算、金融、物流、电商等众多领域,需要解决高并发、高可用、分布式的复合问题。有大量的开源产品。 + +**基于 OpenJDK 开发了自己的定制版本 AlibabaJDK,简称 AJDK。**是整个阿里 Java 体系的基石。 + +基于 OpenJDK HotSpot VM 发布的国内第一个优化、**深度定制且开源的高性能服务器版 Java 虚拟机**。 + +- 创新的 GCIH(GC Invisible Heap)技术实现了 Off-Heap,**即将生命周期较长的 Java 对象从 Heap 中移到Heap 之外,并且 GC 不能管理 GCIH 内部的 Java 对象,以此达到降低 GC 的回收频率和提升 GC 的回收效率的目的。** +- GCIH 中的**对象还能够在多个 Java 虚拟机进程中实现共享** +- 使用 crc32 指令实现 JVM Intrinsic 降低 JNI 的调用开销 +- PMU Hardware 的 Java Profiling Tool 和诊断协助功能 +- 针对大数据场景的 ZenGC + +TaoBao VM 应用在阿里产品上性能高,硬件严重依赖 Intel 的 CPU,损失了兼容性,但提高了性能 + +目前已经在淘宝、天猫上线,把 Oracle 官方 JVM 版本全部替换了。 + +### Dalvik VM + +谷歌开发的,应用于 Android 系统,并在 Android 2.2 中提供了 JIT,发展迅猛。 + +Dalvik 只能称作虚拟机,而不能称作“Java 虚拟机”,它没有遵循 Java 虚拟机规范 + +不能直接执行 Java 的 Class 文件 + +基于寄存器架构,不是 JVM 的栈架构。 + +执行的是编译以后的 dex(Dalvik Executable)文件。执行效率比较高。 + +- 它执行的 dex(Dalvik Executable)文件可以通过 class 文件转化而来,使用 Java 语法编写应用程序,可以直接使用大部分的 Java API 等。 + +Android 5.0 使用支持提前编译(Ahead of Time Compilation,AoT)的 ART VM 替换 Dalvik VM。 + +### Graal VM + +2018年4月,Oracle Labs 公开了 Graal VM,号称 "Run Programs Faster Anywhere",勃勃野心。与1995年Java 的”write once,run anywhere"遥相呼应。 + +Graal VM 在 HotSpot VM 基础上增强而成的跨语言全栈虚拟机,可以作为“任何语言” +的运行平台使用。语言包括:Java、Scala、Groovy、Kotlin;C、C++、Javascript、Ruby、Python、R 等 + +支持不同语言中混用对方的接口和对象,支持这些语言使用已经编写好的本地库文件 + +工作原理是将这些语言的源代码或源代码编译后的中间格式,通过解释器转换为能被 Graal VM 接受的中间表示。Graal VM 提供 Truffle 工具集快速构建面向一种新语言的解释器。在运行时还能进行即时编译优化,获得比原生编译器更优秀的执行效率。 + +如果说 HotSpot 有一天真的被取代,Graal VM 希望最大。但是 Java 的软件生态没有丝毫变化。 + +### 总结 + +具体 JVM 的内存结构,其实取决于其实现,不同厂商的 JVM,或者同一厂商发布的不同版本,都有可能存在一定差异。主要以 Oracle HotSpot VM 为默认虚拟机。 \ No newline at end of file diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704111417472.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704111417472.png" new file mode 100644 index 0000000000000000000000000000000000000000..766851de9b76fdf87ebb6d1ae970258514fba9fb Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704111417472.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704112119729.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704112119729.png" new file mode 100644 index 0000000000000000000000000000000000000000..b57cc93ae00b839ab3df0eb02ec08b0ad121d626 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704112119729.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704112700211.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704112700211.png" new file mode 100644 index 0000000000000000000000000000000000000000..785cbfe0f23c7f709c83a1c220571eb65198ff85 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704112700211.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704145340513.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704145340513.png" new file mode 100644 index 0000000000000000000000000000000000000000..4dd2cfbd6d49d72b40a7925050b7f95c11356e99 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704145340513.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704151731216.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704151731216.png" new file mode 100644 index 0000000000000000000000000000000000000000..c62bba5481c03be646c0e42bc9b865083a9bffbe Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704151731216.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704152052489.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704152052489.png" new file mode 100644 index 0000000000000000000000000000000000000000..69885d21f11447551eb50c22b99987ae49ac6b70 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704152052489.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704182035810.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704182035810.png" new file mode 100644 index 0000000000000000000000000000000000000000..b85a4d4f43bd92bddcce5504b611c6db909f8868 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704182035810.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704183048061.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704183048061.png" new file mode 100644 index 0000000000000000000000000000000000000000..7bbcf3da2fc200400b296714dc40f0703dad4a9d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704183048061.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704183236169.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704183236169.png" new file mode 100644 index 0000000000000000000000000000000000000000..52b2da02f591090c8a618d41a789ce6a6bf81b20 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704183236169.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704183436495.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704183436495.png" new file mode 100644 index 0000000000000000000000000000000000000000..144561c7ce99f6cdbd7ba359a49cc691d339b671 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704183436495.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704210429535.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704210429535.png" new file mode 100644 index 0000000000000000000000000000000000000000..87e80c279a046114e0f6bbf98c7b9b3f8cfaa46f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/1_JVM\344\270\216Java\344\275\223\347\263\273\347\273\223\346\236\204/images/image-20200704210429535.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..18a48ab109f8addd34d4fc87f3572329e420518d --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/README.md" @@ -0,0 +1,420 @@ +# 类加载子系统 + +## 内存结构概述 + +![image-20200705080719531](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111546.png) + +完整图如下 + +![image-20200705080911284](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111552.png) + +如果自己想手写一个 Java 虚拟机的话,主要考虑哪些结构呢? + +- 类加载器 +- 执行引擎 + +## 类加载器子系统的加载过程 + +类加载器子系统负责从文件系统或者网络中加载 class 文件,class 文件在文件开头有特定的文件标识。 + +ClassLoader 只负责 class 文件的加载,至于它是否可以运行,则由 Execution Engine 决定。 + +加载的类信息存放于一块称为**方法区**的内存空间。除了类的信息外,方法区中还会存放**运行时常量池信息**,可能还包括**字符串字面量**和**数字常量**(这部分常量信息是 class 文件中常量池部分的内存映射) + +![image-20200705081813409](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111556.png) + +1. class file 存在于本地硬盘上,可以理解为设计师画在纸上的模板,而最终这个模板在执行的时候是要加载到JVM 当中来根据这个文件实例化出 n 个一模一样的实例。 +2. class file 加载到 JVM 中,被称为 DNA 元数据模板,放在方法区。 +3. 在 class 文件 -> JVM -> 最终成为元数据模板,此过程就要一个运输工具(类装载器Class Loader),扮演一个快递员的角色。 + +![image-20200705081913538](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111558.png) + +### 类的加载过程 + +例如下面的一段简单的代码 + +```java +public class HelloLoader { + public static void main(String[] args) { + System.out.println("我已经被加载啦"); + } +} +``` + +它的加载过程是怎么样的呢? + +![image-20200705082255746](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111601.png) + +完整的流程图如下所示 + +![image-20200705082601441](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111603.png) + +### 加载 + +1. 通过一个类的全限定名获取定义此类的二进制字节流 + +2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构 + +3. **在内存中生成一个代表这个类的 java.lang.Class 对象**,作为方法区这个类的各种数据的访问入口 + +### 补充:加载 .class 文件的方式 + +- 从本地系统中直接加载 +- 通过网络获取,典型场景:Web Applet +- 从 zip 压缩包中读取,成为日后 jar、war 格式的基础 +- 运行时计算生成,使用最多的是:动态代理技术 +- 由其他文件生成,典型场景:JSP 应用从专有数据库中提取 .class 文件,比较少见 +- 从加密文件中获取,典型的防 class 文件被反编译的保护措施 + +### 链接 + +#### 验证 Verify + +- 目的在于确保 class 文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全。 + +- 主要包括四种验证:文件格式验证,元数据验证,字节码验证,符号引用验证。 + +> 工具:Binary Viewer 查看 + +![image-20200705084038680](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111605.png) + +如果出现不合法的字节码文件,那么将会验证不通过 + +同时我们可以通过安装 IDEA 的插件,来查看我们的 class 文件 + +![image-20200705090237078](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111608.png) + +安装完成后,我们编译完一个 class 文件后,点击 view 即可显示我们安装的插件来查看字节码方法了 + +![image-20200705090328171](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111613.png) + +### 准备 Prepare + +为类变量分配内存并且设置该类变量的默认初始值,即零值。 + +```java +public class HelloApp { + private static int a = 1; // 准备阶段为0,在下个阶段,也就是初始化的时候才是1 + public static void main(String[] args) { + System.out.println(a); + } +} +``` + +上面的变量 a 在准备阶段会赋初始值,但不是1,而是0。 + +- 为类变量分配内存并且设置该类变量的默认初始值,即零值; + +- **这里不包含用 final 修饰的 static,因为 final 在编译的时候就会分配了,准备阶段会显式初始化;** + +- **这里不会为实例变量分配初始化**,类变量会分配在方法区中,而实例变量是会随着对象一起分配到 Java 堆中。 + +### 解析 Resolve + +- 将常量池内的符号引用转换为直接引用的过程。 + +- 事实上,解析操作往往会伴随着 JVM 在执行完初始化之后再执行。 + +- 符号引用就是一组符号来描述所引用的目标。符号引用的字面量形式明确定义在《Java虚拟机规范》的 class文件格式中。直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。 + +- 解析动作主要针对类或接口、字段、类方法、接口方法、方法类型等。对应常量池中的 CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info 等 + +### 初始化 + +- 初始化阶段就是执行类构造器法 ()的过程。 + +- 此方法不需定义,是 javac 编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来。 + - 也就是说,当我们代码中包含 static 变量的时候,就会有 clinit 方法 + +- 构造器方法中指令按语句在源文件中出现的顺序执行。 + +- ()不同于类的构造器。(关联:构造器是虚拟机视角下的 ()) +- 若该类具有父类,JVM 会保证子类的 ()执行前,父类的 ()已经执行完毕。 +- 虚拟机必须保证一个类的 ()方法在多线程下被同步加锁。 + +任何一个类在声明后,都有生成一个构造器,默认是空参构造器 + +```java +public class ClassInitTest { + private static int num = 1; + static { + num = 2; + number = 20; + System.out.println(num); + System.out.println(number); //报错,非法的前向引用 + } + + private static int number = 10; + + public static void main(String[] args) { + System.out.println(ClassInitTest.num); // 2 + System.out.println(ClassInitTest.number); // 10 + } +} +``` + +关于涉及到父类时候的变量赋值过程 + +```java +public class ClinitTest1 { + static class Father { + public static int A = 1; + static { + A = 2; + } + } + + static class Son extends Father { + public static int b = A; + } + + public static void main(String[] args) { + System.out.println(Son.b); + } +} +``` + +我们输出结果为 2,也就是说首先加载 ClinitTest1 的时候,会找到 main 方法,然后执行 Son 的初始化,但是Son 继承了 Father,因此还需要执行 Father 的初始化,同时将 A 赋值为2。我们通过反编译得到 Father 的加载过程,首先我们看到原来的值被赋值成1,然后又被复制成2,最后返回 + +```bash +iconst_1 +putstatic #2 +iconst_2 +putstatic #2 +return +``` + +虚拟机必须保证一个类的()方法在多线程下被同步加锁。 + +```java +public class DeadThreadTest { + public static void main(String[] args) { + new Thread(() -> { + System.out.println(Thread.currentThread().getName() + "\t 线程t1开始"); + new DeadThread(); + }, "t1").start(); + + new Thread(() -> { + System.out.println(Thread.currentThread().getName() + "\t 线程t2开始"); + new DeadThread(); + }, "t2").start(); + } +} +class DeadThread { + static { + if (true) { + System.out.println(Thread.currentThread().getName() + "\t 初始化当前类"); + while(true) { + + } + } + } +} +``` + +上面的代码,输出结果为 + +``` +线程t1开始 +线程t2开始 +线程t2 初始化当前类 +``` + +从上面可以看出初始化后,只能够执行一次初始化,这也就是同步加锁的过程 + +## 类加载器的分类 + +JVM 支持两种类型的类加载器 。分别为**引导类加载器(Bootstrap ClassLoader)**和**自定义类加载器(User-Defined ClassLoader)**。 + +从概念上来讲,自定义类加载器一般指的是程序中由开发人员自定义的一类类加载器,但是 Java 虚拟机规范却没有这么定义,而是**将所有派生于抽象类 ClassLoader 的类加载器都划分为自定义类加载器**。 + +无论类加载器的类型如何划分,在程序中我们最常见的类加载器始终只有3个,如下所示: + +![image-20200705094149223](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111619.png) + +这里的四者之间是包含关系,不是上层和下层,也不是子系统的继承关系。 + +我们通过一个类,获取它不同的加载器 + +```java +public class ClassLoaderTest { + public static void main(String[] args) { + // 获取系统类加载器 + ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); + System.out.println(systemClassLoader); + + // 获取其上层的:扩展类加载器 + ClassLoader extClassLoader = systemClassLoader.getParent(); + System.out.println(extClassLoader); + + // 试图获取 根加载器 + ClassLoader bootstrapClassLoader = extClassLoader.getParent(); + System.out.println(bootstrapClassLoader); + + // 获取自定义加载器 + ClassLoader classLoader = ClassLoaderTest.class.getClassLoader(); + System.out.println(classLoader); + + // 获取String类型的加载器 + ClassLoader classLoader1 = String.class.getClassLoader(); + System.out.println(classLoader1); + } +} +``` + +![image-20201009104747510](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111622.png) + +得到的结果,从结果可以看出,根加载器无法直接通过代码获取,同时目前用户代码所使用的加载器为系统类加载器。同时我们通过获取 String 类型的加载器,发现是 null ,那么说明 String 类型是通过根加载器进行加载的,也就是说 Java 的核心类库都是使用根加载器进行加载的。 + +### 虚拟机自带的加载器 + +#### 启动类加载器(引导类加载器,Bootstrap ClassLoader) + +- 这个类加载使用 C/C++ 语言实现的,嵌套在 JVM 内部。 +- 它用来加载 Java 的核心库(JAVAHOME/jre/lib/rt.jar、resources.jar 或 sun.boot.class.path 路径下的内容),用于提供 JVM 自身需要的类 +- 并不继承自 java.lang.ClassLoader,没有父加载器。 +- 加载扩展类和应用程序类加载器,并指定为他们的父类加载器。 +- 出于安全考虑,Bootstrap 启动类加载器只加载包名为 java、javax、sun 等开头的类 + +### 扩展类加载器(Extension ClassLoader) + +- Java 语言编写,由 sun.misc.Launcher$ExtClassLoader 实现。 +- 派生于 ClassLoader 类 +- 父类加载器为启动类加载器 +- 从 java.ext.dirs 系统属性所指定的目录中加载类库,或从 JDK 的安装目录的 jre/lib/ext 子目录(扩展目录)下加载类库。如果用户创建的 JAR 放在此目录下,也会自动由扩展类加载器加载。 + +### 应用程序类加载器(系统类加载器,AppClassLoader) + +- Java 语言编写,由 sun.misc.LaunchersAppClassLoader 实现 +- 派生于 ClassLoader 类 +- 父类加载器为扩展类加载器 +- 它负责加载环境变量 classpath 或系统属性 java.class.path 指定路径下的类库 +- 该类加载是程序中默认的类加载器,一般来说,Java 应用的类都是由它来完成加载 +- 通过 ClassLoader#getSystemClassLoader() 方法可以获取到该类加载器 + +### 用户自定义类加载器 + +在 Java 的日常应用程序开发中,类的加载几乎是由上述3种类加载器相互配合执行的,在必要时,我们还可以自定义类加载器,来定制类的加载方式。 +为什么要自定义类加载器? + +- 隔离加载类 +- 修改类加载的方式 +- 扩展加载源 +- 防止源码泄漏 + +用户自定义类加载器实现步骤: + +- 开发人员可以通过继承抽象类 java.lang.ClassLoader 类的方式,实现自己的类加载器,以满足一些特殊的需求 +- 在 JDK 1.2 之前,在自定义类加载器时,总会去继承 ClassLoader 类并重写 loadClass() 方法,从而实现自定义的类加载类,但是在 JDK 1.2 之后已不再建议用户去覆盖 loadClass() 方法,而是建议把自定义的类加载逻辑写在 findClass() 方法中 +- 在编写自定义类加载器时,如果没有太过于复杂的需求,可以直接继承 URIClassLoader 类,这样就可以避免自己去编写 findClass() 方法及其获取字节码流的方式,使自定义类加载器编写更加简洁。 + +### 查看根加载器所能加载的目录 + +刚刚我们通过概念了解到了,根加载器只能够加载 java/lib目录下的class,我们通过下面代码验证一下 + +```java +public class ClassLoaderTest1 { + public static void main(String[] args) { + System.out.println("*********启动类加载器************"); + // 获取BootstrapClassLoader 能够加载的API的路径 + URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs(); + for (URL url : urls) { + System.out.println(url.toExternalForm()); + } + + // 从上面路径中,随意选择一个类,来看看他的类加载器是什么:得到的是null,说明是 根加载器 + ClassLoader classLoader = Provider.class.getClassLoader(); + } +} +``` + +得到的结果 + +``` +*********启动类加载器************ +file:/E:/Software/JDK1.8/Java/jre/lib/resources.jar +file:/E:/Software/JDK1.8/Java/jre/lib/rt.jar +file:/E:/Software/JDK1.8/Java/jre/lib/sunrsasign.jar +file:/E:/Software/JDK1.8/Java/jre/lib/jsse.jar +file:/E:/Software/JDK1.8/Java/jre/lib/jce.jar +file:/E:/Software/JDK1.8/Java/jre/lib/charsets.jar +file:/E:/Software/JDK1.8/Java/jre/lib/jfr.jar +file:/E:/Software/JDK1.8/Java/jre/classes +null +``` + +### 关于ClassLoader + +ClassLoader 类,它是一个抽象类,其后所有的类加载器都继承自 ClassLoader(不包括启动类加载器) + +![image-20200705103516138](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111627.png) + +sun.misc.Launcher 它是一个 Java 虚拟机的入口应用 + +![image-20200705103636003](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111631.png) + +获取 ClassLoader 的途径 + +- 获取当前 ClassLoader:clazz.getClassLoader() +- 获取当前线程上下文的 ClassLoader:Thread.currentThread().getContextClassLoader() +- 获取系统的 ClassLoader:ClassLoader.getSystemClassLoader() +- 获取调用者的 ClassLoader:DriverManager.getCallerClassLoader() + +## 双亲委派机制 + +Java 虚拟机对 class 文件采用的是**按需加载**的方式,也就是说当需要使用该类时才会将它的 class 文件加载到内存生成 class 对象。而且加载某个类的 class 文件时,Java 虚拟机采用的是**双亲委派模式**,即把请求交由父类处理,它是一种任务委派模式。 + +### 工作原理 + +- 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行; +- 如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器; +- 如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。 + +![image-20200705105151258](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111634.png) + +### 双亲委派机制举例 + +当我们加载 jdbc.jar 用于实现数据库连接的时候,首先我们需要知道的是 jdbc.jar 是基于 SPI 接口进行实现的,所以在加载的时候,会进行双亲委派,最终从根加载器中加载 SPI 核心类,然后在加载 SPI 接口类,接着在进行反向委派,通过线程上下文类加载器进行实现类 jdbc.jar 的加载。 + +![image-20200705105810107](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111636.png) + +### 沙箱安全机制 + +自定义 String 类,但是在加载自定义 String 类的时候会率先使用引导类加载器加载,而引导类加载器在加载的过程中会先加载 JDK 自带的文件(rt.jar包中java\lang\String.class),报错信息说没有 main 方法,就是因为加载的是 rt.jar 包中的 String 类。这样可以保证对 Java 核心源代码的保护,这就是沙箱安全机制。 + +### 双亲委派机制的优势 + +通过上面的例子,我们可以知道,双亲机制可以 + +- 避免类的重复加载 +- 保护程序安全,防止核心 API 被随意篡改 + - 自定义类:java.lang.String + - 自定义类:java.lang.ShkStart(报错:阻止创建 java.lang 开头的类) + +## 其它 + +### 如何判断两个 class 对象是否相同 + +在 JVM 中表示两个 class 对象是否为同一个类存在两个必要条件: +- 类的完整类名必须一致,包括包名。 +- 加载这个类的 ClassLoader(指 ClassLoader 实例对象)必须相同。 + +换句话说,在 JVM 中,即使这两个类对象(class对象)来源同一个 Class 文件,被同一个虚拟机所加载,但只要加载它们的 ClassLoader 实例对象不同,那么这两个类对象也是不相等的。 + +JVM 必须知道一个类型是由启动加载器加载的还是由用户类加载器加载的。如果一个类型是由用户类加载器加载的,那么 JVM 会将**这个类加载器的一个引用作为类型信息的一部分保存在方法区中**。当解析一个类型到另一个类型的引用的时候,JVM 需要保证这两个类型的类加载器是相同的。 + +### 类的主动使用和被动使用 + +Java 程序对类的使用方式分为:主动使用和被动使用。 +主动使用,又分为七种情况: + +- 创建类的实例 +- 访问某个类或接口的静态变量,或者对该静态变量赋值 +- 调用类的静态方法 +- 反射(比如:Class.forName("com.atguigu.Test")) +- 初始化一个类的子类 +- Java 虚拟机启动时被标明为启动类的类 +- JDK 7 开始提供的动态语言支持: +- java.lang.invoke.MethodHandle 实例的解析结果 REF getStatic、REF putStatic、REF invokeStatic 句柄对应的类没有初始化,则初始化 + +除了以上七种情况,其他使用 Java 类的方式都被看作是对类的**被动使用**,都**不会导致类的初始化**。 \ No newline at end of file diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705080719531.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705080719531.png" new file mode 100644 index 0000000000000000000000000000000000000000..cec89aad455d5e7d7bb6cf77956a41f5f42788b8 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705080719531.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705080911284.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705080911284.png" new file mode 100644 index 0000000000000000000000000000000000000000..752f60de3f63dc57b5f0a22a6559ea9a066a3042 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705080911284.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705081813409.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705081813409.png" new file mode 100644 index 0000000000000000000000000000000000000000..59404bf6564c03e96992d334de66aa3baed187af Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705081813409.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705081913538.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705081913538.png" new file mode 100644 index 0000000000000000000000000000000000000000..cf6531ef766d8ccad3730dde1d973ad403ba8d86 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705081913538.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705082255746.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705082255746.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ccf44c99d52c2056212833b10747089b2ca02ba Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705082255746.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705082601441.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705082601441.png" new file mode 100644 index 0000000000000000000000000000000000000000..3739a2830e97be1192213d250144051d81500c96 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705082601441.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705084038680.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705084038680.png" new file mode 100644 index 0000000000000000000000000000000000000000..631944240a95c3fe173ca392dd968a1a9c5eed21 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705084038680.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705090237078.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705090237078.png" new file mode 100644 index 0000000000000000000000000000000000000000..c54e47b9b5d0ec0b8878e3d472708b0428d004a9 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705090237078.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705090328171.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705090328171.png" new file mode 100644 index 0000000000000000000000000000000000000000..d40c5dc863f8537f5057091434846888c22c1923 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705090328171.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705094149223.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705094149223.png" new file mode 100644 index 0000000000000000000000000000000000000000..2da633cba70d906a9ec94363b79c4b3945ffa13d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705094149223.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705103516138.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705103516138.png" new file mode 100644 index 0000000000000000000000000000000000000000..2c698c55bb769eb18d285a69d988a52e49497aa8 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705103516138.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705103636003.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705103636003.png" new file mode 100644 index 0000000000000000000000000000000000000000..e0c13e69d93ad15cb6cdb24f2ceca480fe30b85c Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705103636003.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705105151258.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705105151258.png" new file mode 100644 index 0000000000000000000000000000000000000000..32ee5e71683939eea73743a1bf7ee2863e06aadf Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705105151258.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705105810107.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705105810107.png" new file mode 100644 index 0000000000000000000000000000000000000000..7c63f5f7049e1cebb3e7228df0bf810f821109bc Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/2_\347\261\273\345\212\240\350\275\275\345\255\220\347\263\273\347\273\237/images/image-20200705105810107.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b4e03c9a2570b6e110e1c5580bad303ee663d346 --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/README.md" @@ -0,0 +1,53 @@ +# 运行时数据区概述及线程 + +## 概述 + +本节主要讲的是运行时数据区,也就是下图这部分,它是在类加载完成后的阶段 + +![image-20200705111640511](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111502.png) + +当我们通过前面的:类的加载-> 验证 -> 准备 -> 解析 -> 初始化 这几个阶段完成后,就会用到执行引擎对我们的类进行使用,同时执行引擎将会使用到我们运行时数据区 + +![image-20200705111843003](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111507.png) + +也就是大厨做饭,我们把大厨后面的东西(切好的菜,刀,调料),比作是运行时数据区。而厨师可以类比于执行引擎,将通过准备的东西进行制作成精美的菜品 + +![image-20200705112036630](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111512.png) + +内存是非常重要的系统资源,是硬盘和 CPU 的中间仓库及桥梁,承载着操作系统和应用程序的实时运行 JVM 内存布局规定了 Java 在运行过程中内存申请、分配、管理的策略,保证了 JVM 的高效稳定运行。**不同的 JVM 对于内存的划分方式和管理机制存在着部分差异**。结合 JVM 虚拟机规范,来探讨一下经典的 JVM 内存布局。 + +> 我们通过磁盘或者网络 IO 得到的数据,都需要先加载到内存中,然后 CPU 从内存中获取数据进行读取,也就是说内存充当了 CPU 和磁盘之间的桥梁 + +运行时数据区的完整图 + +![image-20200705112416101](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111515.png) + +Java 虚拟机定义了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁。另外一些则是与线程一一对应的,这些与线程对应的数据区域会随着线程开始和结束而创建和销毁。 + +灰色的为单独线程私有的,红色的为多个线程共享的。即: + +- 每个线程:独立包括程序计数器、栈、本地栈。 +- 线程间共享:堆、堆外内存(永久代或元空间、代码缓存) + +![image-20200705112601211](https://gitee.com/xlshi/blog_img/raw/master/img/20201009111518.png) + +每个 JVM 只有一个 Runtime 实例。即为运行时环境。 + +## 线程 + +- 线程是一个程序里的运行单元。JVM 允许一个应用有多个线程并行的执行。 +- 在 HotSpot JVM 里,每个线程都与操作系统的本地线程直接映射。 + - 当一个 Java 线程准备好执行以后,此时一个操作系统的本地线程也同时创建。Java 线程执行终止后,本地线程也会回收。 + +- 操作系统负责所有线程的安排调度到任何一个可用的 CPU 上。一旦本地线程初始化成功,它就会调用 Java 线程中的 run() 方法。 + +### JVM 系统线程 + +如果你使用 jconsole 或者是任何一个调试工具,都能看到在后台有许多线程在运行。这些后台线程不包括调用public static void main(String[]) 的 main 线程以及所有这个 main 线程自己创建的线程。 +这些主要的后台系统线程在 HotSpot JVM 里主要是以下几个: + +- 虚拟机线程:这种线程的操作是需要 JVM 达到安全点才会出现。这些操作必须在不同的线程中发生的原因是他们都需要 JVM 达到安全点,这样堆才不会变化。这种线程的执行类型包括 "Stop-The-World" 的垃圾收集,线程栈收集,线程挂起以及偏向锁撤销。 +- 周期任务线程:这种线程是时间周期事件的体现(比如中断),他们一般用于周期性操作的调度执行。 +- GC 线程:这种线程对在 JVM 里不同种类的垃圾收集行为提供了支持。 +- 编译线程:这种线程在运行时会将字节码编译成到本地代码。 +- 信号调度线程:这种线程接收信号并发送给 JVM,在它内部通过调用适当的方法进行处理。 diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705111640511.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705111640511.png" new file mode 100644 index 0000000000000000000000000000000000000000..8e39de92edb13aacb13602b86af83090ac631a9d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705111640511.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705111843003.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705111843003.png" new file mode 100644 index 0000000000000000000000000000000000000000..213df2372b9bdba7260716aa3943a81e132e9411 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705111843003.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705112036630.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705112036630.png" new file mode 100644 index 0000000000000000000000000000000000000000..91c8c34dc4df586e3934345d88a1eeb42d9972a4 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705112036630.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705112416101.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705112416101.png" new file mode 100644 index 0000000000000000000000000000000000000000..f7919f405131d43eac35bd7e23e83cb43f177cf6 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705112416101.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705112601211.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705112601211.png" new file mode 100644 index 0000000000000000000000000000000000000000..56757f49ae41bdf3273272338de5d0b014c30838 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/3_\350\277\220\350\241\214\346\227\266\346\225\260\346\215\256\345\214\272\346\246\202\350\277\260\345\217\212\347\272\277\347\250\213/images/image-20200705112601211.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ab9779001dcf97708135f878149e36b85f077f6f --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/README.md" @@ -0,0 +1,84 @@ +# 程序计数器 + +## PC Register 介绍 + +JVM 中的程序计数寄存器(Program Counter Register)中,Register 的命名源于 CPU 的寄存器,寄存器存储指令相关的现场信息。CPU 只有把数据装载到寄存器才能够运行。这里,并非是广义上所指的物理寄存器,或许将其翻译为 PC 计数器(或指令计数器)会更加贴切(也称为程序钩子),并且也不容易引起一些不必要的误会。**JVM 中的 PC 寄存器是对物理 PC 寄存器的一种抽象模拟。** + +![image-20200705155551919](https://gitee.com/xlshi/blog_img/raw/master/img/20201009112000.png) + +- 它是一块很小的内存空间,几乎可以忽略不记。也是运行速度最快的存储区域。 + +- 在 JVM 规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致。 + +- 任何时间一个线程都只有一个方法在执行,也就是所谓的**当前方法**。程序计数器会存储当前线程正在执行的 Java 方法的 JVM 指令地址;或者,如果是在执行 native 方法,则是未指定值(undefined)。 + +- 它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。 +- 字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。 + +- **它是唯一一个在 Java 虚拟机规范中没有规定任何 OutOfMemoryError 情况的区域。** + +**作用:** + +PC 寄存器用来存储指向下一条指令的地址,也即将要执行的指令代码。由执行引擎读取下一条指令。 + +![image-20200705155728557](https://gitee.com/xlshi/blog_img/raw/master/img/20201009112200.png) + +### 举例说明 + +我们首先写一个简单的代码 + +```java +public class PCRegisterTest { + public static void main(String[] args) { + int i = 10; + int j = 20; + int k = i + j; + } +} +``` + +然后将代码进行编译成字节码文件,我们再次查看 ,发现在字节码的左边有一个行号标识,它其实就是指令地址,用于指向当前执行到哪里。 + +```bash +0: bipush 10 +2: istore_1 +3: bipush 20 +5: istore_2 +6: iload_1 +7: iload_2 +8: iadd +9: istore_3 +10: return +``` + +通过 PC 寄存器,我们就可以知道当前程序执行到哪一步了 ![image-20200705161007423](https://gitee.com/xlshi/blog_img/raw/master/img/20201009112204.png) + +## 两个常见问题 + +### 使用 PC 寄存器存储字节码指令地址有什么用呢? + +因为 CPU 需要不停的切换各个线程,这时候切换回来以后,就得知道接着从哪开始继续执行。 + +JVM 的字节码解释器就需要通过改变 PC 寄存器的值来明确下一条应该执行什么样的字节码指令。 + +![image-20200705161409533](https://gitee.com/xlshi/blog_img/raw/master/img/20201009112206.png) + +### PC 寄存器为什么被设定为私有的? + +我们都知道所谓的多线程在一个特定的时间段内只会执行其中某一个线程的方法,CPU 会不停地做任务切换,这样必然导致经常中断或恢复,如何保证分毫无差呢?为了能够准确地记录各个线程正在执行的当前字节码指令地址,最好的办法自然是为每一个线程都分配一个 PC 寄存器,这样一来各个线程之间便可以进行独立计算,从而不会出现相互干扰的情况。 + +由于 CPU 时间片轮限制,众多线程在并发执行过程中,任何一个确定的时刻,一个处理器或者多核处理器中的一个内核,只会执行某个线程中的一条指令。 + +这样必然导致经常中断或恢复,如何保证分毫无差呢?每个线程在创建后,都会产生自己的程序计数器和栈帧,程序计数器在各个线程之间互不影响。 + +![image-20200705161812542](https://gitee.com/xlshi/blog_img/raw/master/img/20201009112208.png) + +### CPU 时间片 + +CPU 时间片即 CPU 分配给各个程序的时间,每个线程被分配一个时间段,称作它的时间片。 + +在宏观上:我们可以同时打开多个应用程序,每个程序并行不悖,同时运行。 + +但在微观上:由于只有一个 CPU ,一次只能处理程序要求的一部分,如何处理公平,一种方法就是引入时间片,每个程序轮流执行。 + +![image-20200705161849557](https://gitee.com/xlshi/blog_img/raw/master/img/20201009112210.png) \ No newline at end of file diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705155551919.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705155551919.png" new file mode 100644 index 0000000000000000000000000000000000000000..4cecde6a7911b8a9567055c828afd6b2cc39d556 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705155551919.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705155728557.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705155728557.png" new file mode 100644 index 0000000000000000000000000000000000000000..c700ba041a090e3859f9416fe9c8ed8b6b1d42fd Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705155728557.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705161007423.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705161007423.png" new file mode 100644 index 0000000000000000000000000000000000000000..359dcb9caa56b961a3047935d067e5f13ccea497 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705161007423.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705161409533.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705161409533.png" new file mode 100644 index 0000000000000000000000000000000000000000..174b57e09e9ae38d79ba516ced471c54c1244399 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705161409533.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705161812542.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705161812542.png" new file mode 100644 index 0000000000000000000000000000000000000000..e885bd425e7edc577b13b81d0b12da8363c002a0 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705161812542.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705161849557.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705161849557.png" new file mode 100644 index 0000000000000000000000000000000000000000..5029c76a4c97e14949b3954d04ca8ce30a424267 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/4_\347\250\213\345\272\217\350\256\241\346\225\260\345\231\250/images/image-20200705161849557.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..7a04b04d94b4ea8240ee071f5d586df8af319b47 --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/README.md" @@ -0,0 +1,567 @@ +# 虚拟机栈 + +## 虚拟机栈概述 + +由于跨平台性的设计,Java 的指令都是根据栈来设计的。不同平台 CPU 架构不同,所以不能设计为基于寄存器的。 +**优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要更多的指令。** + +有不少 Java 开发人员一提到 Java 内存结构,就会非常粗粒度地将 JVM 中的内存区理解为仅有 Java 堆(heap)和 Java 栈(stack)?为什么? + +首先**栈是运行时的单位,而堆是存储的单位** + +- 栈解决程序的运行问题,即程序如何执行,或者说如何处理数据。 +- 堆解决的是数据存储的问题,即数据怎么放,放哪里 + +![image-20200705163928652](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115324.png) + +### Java虚拟机栈是什么 + +Java 虚拟机栈(Java Virtual Machine Stack),早期也叫 Java 栈。每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个的栈帧(Stack Frame),对应着一次次的 Java 方法调用。 + +- 是线程私有的 + +![image-20200705164722033](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115322.png) + +### 生命周期 + +生命周期和线程一致,也就是线程结束了,该虚拟机栈也销毁了 + +### 作用 + +主管 Java 程序的运行,它保存方法的局部变量、部分结果,并参与方法的调用和返回。 + +> 局部变量,它是相比于成员变量来说的(或属性) +> +> 基本数据类型变量 VS 引用类型变量(类、数组、接口) + +### 栈的特点(优点) + +栈是一种快速有效的分配存储方式,访问速度仅次于程序计数器。JVM 直接对 Java 栈的操作只有两个: + +- 每个方法执行,伴随着进栈(入栈、压栈) +- 执行结束后的出栈工作 + +对于栈来说不存在垃圾回收问题(栈存在溢出的情况) + +![image-20200705165025382](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115319.png) + +### 开发中遇到哪些异常? + +栈中可能出现的异常 + +Java 虚拟机规范允许 **Java 栈的大小是动态的或者是固定不变的。** + +如果采用固定大小的 Java 虚拟机栈,那每一个线程的 Java 虚拟机栈容量可以在线程创建的时候独立选定。如果线程请求分配的栈容量超过 Java 虚拟机栈允许的最大容量,Java 虚拟机将会抛出一个 StackoverflowError 异常。 + +如果 Java 虚拟机栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者在创建新的线程时没有足够的内存去创建对应的虚拟机栈,那 Java 虚拟机将会抛出一个 OutOfMemoryError 异常。 + +```java +public static void main(String[] args) { + test(); +} + +public static void test() { + test(); +} +//抛出异常:Exception in thread "main" java.lang.StackOverflowError +//程序不断地进行递归调用,而且没有退出条件,就会导致不断地进行压栈 +``` + +```java +public static int show(int a) { + a++; + if (a > 8) + return a; + show(a); + return a; +} +//Exception in thread "main" java.lang.StackOverflowError +``` + +```java +public class StackErrorTest { + private static int count = 1; + public static void main(String[] args) { + System.out.println(count++); + main(args); + } +} +``` + +![image-20201009114235089](https://gitee.com/xlshi/blog_img/raw/master/img/20201009114236.png) + +### 设置栈内存大小 + +我们可以使用参数 -Xss 选项来设置线程的最大栈空间,栈的大小直接决定了函数调用的最大可达深度 + +```java +-Xss1m +-Xss1k +``` + +```java +public class StackDeepTest { + private static int count = 0; + + public static void recursion() { + count++; + recursion(); + } + + public static void main(String[] args) { + try { + recursion(); + } catch (Throwable throwable) { + System.out.println("deep of calling = " + count); + throwable.printStackTrace(); + } + } +} +``` + +## 栈的存储单位 + +### 栈中存储什么? + +- 每个线程都有自己的栈,栈中的数据都是以栈帧(Stack Frame)的格式存在。 +- 在这个线程上正在执行的每个方法都各自对应一个栈帧(Stack Frame)。 +- 栈帧是一个内存区块,是一个数据集,维系着方法执行过程中的各种数据信息。 + +> OOP 的基本概念:类和对象 +> +> 类中基本结构:field(属性、字段、域)、method + +### 栈运行原理 + +- JVM 直接对 Java 栈的操作只有两个,就是对栈帧的**压栈**和**出栈**,**遵循“先进后出”/“后进先出”原则**。 + +- 在一条活动线程中,一个时间点上,只会有一个活动的栈帧。即只有当前正在执行的方法的栈帧(栈顶栈帧)是有效的,这个栈帧被称为**当前栈帧(Current Frame)**,与当前栈帧相对应的方法就是**当前方法(Current Method)**,定义这个方法的类就是**当前类(Current Class)**。 + +- 执行引擎运行的所有字节码指令只针对当前栈帧进行操作。 + +- 如果在该方法中调用了其他方法,对应的新的栈帧会被创建出来,放在栈的顶端,成为新的当前帧。 + +![image-20200705203142545](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115032.png) + +下面写一个简单的代码 + +```java +public class StackFrameTest { + public static void main(String[] args) { + method01(); + } + + private static int method01() { + System.out.println("方法1的开始"); + int i = method02(); + System.out.println("方法1的结束"); + return i; + } + + private static int method02() { + System.out.println("方法2的开始"); + int i = method03(); + System.out.println("方法2的结束"); + return i; + } + + private static int method03() { + System.out.println("方法3的开始"); + int i = 30; + System.out.println("方法3的结束"); + return i; + } +} +``` + +输出结果为 + +```bash +方法1的开始 +方法2的开始 +方法3的开始 +方法3的结束 +方法2的结束 +方法1的结束 +``` + +满足栈先进后出的概念,通过 Idea 的 DEBUG ,能够看到栈信息 + +![image-20200705203916023](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115309.png) + +不同线程中所包含的栈帧是不允许存在相互引用的,即不可能在一个栈帧之中引用另外一个线程的栈帧。 + +如果当前方法调用了其他方法,方法返回之际,当前栈帧会传回此方法的执行结果给前一个栈帧,接着,虚拟机会丢弃当前栈帧,使得前一个栈帧重新成为当前栈帧。 + +Java 方法有两种返回函数的方式,**一种是正常的函数返回,使用 return 指令;另外一种是抛出异常。不管使用哪种方式,都会导致栈帧被弹出。** + +### 栈帧的内部结构 + +每个栈帧中存储着: + +- **局部变量表(Local Variables)** +- **操作数栈(Operand Stack)(或表达式栈)** +- 动态链接(Dynamic Linking)(或指向运行时常量池的方法引用) +- 方法返回地址(Return Address)(或方法正常退出或者异常退出的定义) +- 一些附加信息 + +![image-20200705204836977](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115338.png) + +并行每个线程下的栈都是私有的,因此每个线程都有自己各自的栈,并且每个栈里面都有很多栈帧,**栈帧的大小主要由局部变量表和操作数栈决定的** + +![image-20200705205443993](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115341.png) + +## 局部变量表 + +局部变量表:Local Variables,被称之为局部变量数组或本地变量表 + +定义为一个数字数组,**主要用于存储方法参数和定义在方法体内的局部变量**,这些数据类型包括各类基本数据类型、对象引用(reference),以及 returnAddress 类型。 + +由于局部变量表是建立在线程的栈上,是线程的私有数据,因此**不存在数据安全问题** + +**局部变量表所需的容量大小是在编译期确定下来的**,并保存在方法的 Code 属性的 Maximum Local Variables 数据项中。在方法运行期间是不会改变局部变量表的大小的。 + +**方法嵌套调用的次数由栈的大小决定**。一般来说,**栈越大,方法嵌套调用次数越多**。对一个函数而言,它的参数和局部变量越多,使得局部变量表膨胀,它的栈帧就越大,以满足方法调用所需传递的信息增大的需求。进而函数调用就会占用更多的栈空间,导致其嵌套调用次数就会减少。 + +**局部变量表中的变量只在当前方法调用中有效。**在方法执行时,虚拟机通过使用局部变量表完成参数值到参数变量列表的传递过程。**当方法调用结束后,随着方法栈帧的销毁,局部变量表也会随之销毁**。 + +### 关于 Slot 的理解 + +参数值的存放总是在局部变量数组的 index0 开始,到数组长度-1的索引结束。 + +局部变量表,最基本的存储单元是 Slot(变量槽)局部变量表中存放编译期可知的各种基本数据类型(8种),引用类型(reference)、returnAddress 类型的变量。 + +在局部变量表里,32位以内的类型只占用一个 slot(包括 returnAddress 类型),64位的类型(long 和double)占用两个 Slot。 + +- byte、short、char 在存储前被转换为 int,boolean 也被转换为 int,0表示 false,非0表示 true。 +- long 和 double 则占据两个 Slot。 + +JVM 会为局部变量表中的每一个 Slot 都分配一个访问索引,通过这个索引即可成功访问到局部变量表中指定的局部变量值 + +当一个实例方法被调用的时候,它的方法参数和方法体内部定义的局部变量将会**按照顺序**被复制到局部变量表中的每一个 Slot 上 + +如果需要访问局部变量表中一个64bit的局部变量值时,只需要使用前一个索引即可。(比如:访问 long 或double 类型变量) + +如果当前帧是由构造方法或者实例方法创建的,那么该对象引用 this 将会存放在 index 为0的 Slot 处,其余的参数按照参数表顺序继续排列。 + +![image-20200705212454445](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115344.png) + +### Slot 的重复利用 + +**栈帧中的局部变量表中的槽位是可以重用的**,如果一个局部变量过了其作用域,那么在其作用域之后申明的新的局部变就很有可能会复用过期局部变量的槽位,从而**达到节省资源的目的**。 + +![image-20200705213106749](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115346.png) + +### 举例:静态变量与局部变量的对比 + +变量的分类: + +- 按数据类型分:基本数据类型、引用数据类型 +- 按类中声明的位置分:成员变量(类变量,实例变量)、局部变量 + - 类变量:linking 的 prepare 阶段,给类变量默认赋值,init 阶段给类变量显示赋值即静态代码块 + - 实例变量:随着对象创建,会在堆空间中分配实例变量空间,并进行默认赋值 + - 局部变量:在使用前必须进行显式赋值,不然编译不通过。 + +参数表分配完毕之后,再根据方法体内定义的变量的顺序和作用域分配。 + +我们知道类变量表有两次初始化的机会,第一次是在“**准备阶段**”,执行系统初始化,对类变量设置零值,另一次则是在“**初始化**”阶段,赋予程序员在代码中定义的初始值。 + +**和类变量初始化不同的是,局部变量表不存在系统初始化的过程,这意味着一旦定义了局部变量则必须人为的初始化,否则无法使用。** + +在栈帧中,与性能调优关系最为密切的部分就是前面提到的局部变量表。在方法执行时,虚拟机使用局部变量表完成方法的传递。 + +**局部变量表中的变量也是重要的垃圾回收根节点,只要被局部变量表中直接或间接引用的对象都不会被回收。** + +## 操作数栈 + +### 概念 + +操作数栈:Operand Stack + +每一个独立的栈帧中除了包含局部变量表以外,还包含一个**后进先出(Last - In - First -Out)**的操作数栈,也可以称之为**表达式栈**(Expression Stack) + +**操作数栈,在方法执行过程中,根据字节码指令,往栈中写入数据或提取数据,即入栈(push)和 出栈(pop)** + +- 某些字节码指令将值压入操作数栈,其余的字节码指令将操作数取出栈。使用它们后再把结果压入栈 +- 比如:执行复制、交换、求和等操作 + +![image-20200706090618332](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115350.png) + +![image-20200706090833697](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115352.png) + +操作数栈,**主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。** + +操作数栈就是 JVM 执行引擎的一个工作区,当一个方法刚开始执行的时候,一个新的栈帧也会随之被创建出来,**这个方法的操作数栈是空的**。. + +> 这个时候数组是有长度的,因为数组一旦创建,那么就是不可变的 + +每一个操作数栈都会拥有一个明确的栈深度用于存储数值,其所需的最大深度在编译期就定义好了,保存在方法的Code 属性中,为 max_stack 的值。 + +栈中的任何一个元素都是可以任意的 Java 数据类型 + +- 32bit的类型占用一个栈单位深度 +- 64bit的类型占用两个栈单位深度 + +操作数栈**并非采用访问索引的方式来进行数据访问的**,而是只能通过标准的入栈和出栈操作来完成一次数据访问 + +**如果被调用的方法带有返回值的话,其返回值将会被压入当前栈帧的操作数栈中,**并更新PC寄存器中下一条需要执行的字节码指令。 + +操作数栈中元素的数据类型必须与字节码指令的序列严格匹配,这由编译器在编译期间进行验证,同时在类加载过程中的类检验阶段的数据流分析阶段要再次验证。| + +另外,我们说 Java 虚拟机的**解释引擎是基于栈的执行引擎,其中的栈指的就是操作数栈**。 + +### 代码追踪 + +我们给定代码 + +```java +public void testAddOperation() { + byte i = 15; + int j = 8; + int k = i + j; +} +``` + +使用 javap 命令反编译 class 文件: **javap -v 类名.class** + +![image-20200706092610730](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115354.png) + +> byte、short、char、boolean 内部都是使用 int 型来进行保存的 +> +> 从上面的代码我们可以知道,我们都是通过 bipush 对操作数 15 和 8 进行入栈操作 +> +> 同时使用的是 iadd 方法进行相加操作,i -> 代表的就是 int,也就是 int 类型的加法操作 + +执行流程如下所示: + +首先执行第一条语句,PC 寄存器指向的是0,也就是指令地址为0,然后使用 bipush 让操作数15入栈。 + +![image-20200706093131621](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115357.png) + +执行完后,让 PC + 1,指向下一行代码,下一行代码就是将操作数栈的元素存储到局部变量表1的位置,我们可以看到局部变量表的已经增加了一个元素 + +![image-20200706093251302](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115359.png) + +> 为什么局部变量表不是从0开始的呢? +> +> 其实局部变量表也是从0开始的,但是因为0号位置存储的是this指针,所以说就直接省略了 + +然后 PC + 1,指向的是下一行。让操作数8也入栈,同时执行 istore 操作,存入局部变量表中 + +![image-20200706093646406](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115401.png) + +![image-20200706093751711](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115403.png) + +然后从局部变量表中,依次将数据放在操作数栈中 + +![image-20200706093859191](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115405.png) + +![image-20200706093921573](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115408.png) + +然后将操作数栈中的两个元素执行相加操作,并存储在局部变量表3的位置 + +![image-20200706094046782](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115410.png) + +![image-20200706094109629](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115412.png) + +最后 PC 寄存器的位置指向10,也就是 return 方法,则直接退出方法 + +i++ 和++i 的区别? + +> 从字节码角度来讲,i++ 和 ++i 没有区别 +> +> ![image-20201009121556092](https://gitee.com/xlshi/blog_img/raw/master/img/20201009121557.png) + +## 栈顶缓存技术 + +栈顶缓存技术:Top Of Stack Cashing + +前面提过,**基于栈式架构的虚拟机所使用的零地址指令更加紧凑**,但完成一项操作的时候必然需要使用更多的入栈和出栈指令,这同时也就意味着将需要更多的指令分派(Instruction Dispatch)次数和内存读/写次数。 + +由于操作数是存储在内存中的,因此频繁地执行内存读/写操作必然会影响执行速度。为了解决这个问题,HotSpot JVM 的设计者们提出了栈顶缓存(ToS,Top-of-Stack Cashing)技术,**将栈顶元素全部缓存在物理CPU 的寄存器中,以此降低对内存的读/写次数,提升执行引擎的执行效率。** + +> 寄存器:指令更少,执行速度快 + +## 动态链接 + +动态链接:Dynamic Linking + +![image-20200706100311886](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115416.png) + +> 动态链接、方法返回地址、附加信息 : 有些地方被称为帧数据区 + +每一个栈帧内部都包含一个指向**运行时常量池**中**该栈帧所属方法的引用**,包含这个引用的目的就是为了支持当前方法的代码能够实现**动态链接(Dynamic Linking)**。比如:invokedynamic 指令 + +在 Java 源文件被编译到字节码文件中时,所有的变量和方法引用都作为符号引用(Symbolic Reference)保存在 class 文件的常量池里。 + +比如:描述一个方法调用了另外的其他方法时,就是通过常量池中指向方法的符号引用来表示的,那么**动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用。** + +![image-20200706101251847](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115418.png) + +> 为什么需要运行时常量池? +> +> 因为在不同的方法,都可能调用常量或者方法,所以只需要存储一份即可,节省了空间 +> +> 常量池的作用,就是为了提供一些符号和常量,便于指令的识别 + +## 方法调用:解析与分配 + +在 JVM 中,将符号引用转换为调用方法的直接引用与方法的绑定机制相关 + +### 链接 + +#### 静态链接 + +当一个字节码文件被装载进 JVM 内部时,如果被调用的**目标方法在编译期可知**,且运行期保持不变时,这种情况下将调用方法的符号引用转换为直接引用的过程称之为静态链接 + +#### 动态链接 + +如果**被调用的方法在编译期无法被确定下来**,也就是说,只能够在程序运行期将调用的方法的符号转换为直接引用,由于这种引用转换过程具备动态性,因此也被称之为动态链接。 + +### 绑定机制 + +对应的方法的绑定机制为:早期绑定(Early Binding)和晚期绑定(Late Binding)。**绑定是一个字段、方法或者类在符号引用被替换为直接引用的过程,这仅仅发生一次。** + +#### 早期绑定 + +早期绑定就是指被调用的**目标方法如果在编译期可知,且运行期保持不变时**,即可将这个方法与所属的类型进行绑定,这样一来,由于明确了被调用的目标方法究竟是哪一个,因此也就可以使用静态链接的方式将符号引用转换为直接引用。 + +#### 晚期绑定 + +如果**被调用的方法在编译期无法被确定下来,只能够在程序运行期根据实际的类型绑定相关的方法**,这种绑定方式也就被称之为晚期绑定。 + +### 早晚期绑定的发展历史 + +随着高级语言的横空出世,类似于 Java 一样的基于面向对象的编程语言如今越来越多,尽管这类编程语言在语法风格上存在一定的差别,但是它们彼此之间始终保持着一个共性,那就是都支持封装、继承和多态等面向对象特性,既然**这一类的编程语言具备多态特性,那么自然也就具备早期绑定和晚期绑定两种绑定方式**。 + +Java 中任何一个普通的方法其实都具备虚函数的特征,它们相当于 C++ 语言中的虚函数(C++ 中则需要使用关键字 virtual 来显式定义)。如果在 Java 程序中不希望某个方法拥有虚函数的特征时,则可以使用关键字 final 来标记这个方法。 + +### 虚方法和非虚方法 + +- 如果方法在编译期就确定了具体的调用版本,这个版本在运行时是不可变的。这样的方法称为非虚方法。 +- 静态方法、私有方法、final 方法、实例构造器、父类方法都是非虚方法。 +- 其他方法称为虚方法。 + +> 子类对象的多态的使用前提 +> +> - 类的继承关系 +> - 方法的重写 + +虚拟机中提供了以下几条方法调用指令: + +#### 普通调用指令: + +- **invokestatic:调用静态方法,解析阶段确定唯一方法版本** +- **invokespecial:调用 方法、私有及父类方法,解析阶段确定唯一方法版本** +- invokevirtual:调用所有虚方法 +- invokeinterface:调用接口方法 + +#### 动态调用指令: + +- invokedynamic:动态解析出需要调用的方法,然后执行 + +前四条指令固化在虚拟机内部,方法的调用执行不可人为干预,而 invokedynamic 指令则支持由用户确定方法版本。其中 **invokestatic 指令和 invokespecial 指令调用的方法称为非虚方法,其余的(final 修饰的除外)称为虚方法。** + +### invokednamic 指令 + +JVM 字节码指令集一直比较稳定,一直到 Java 7 中才增加了一个 invokedynamic 指令,这是 **Java 为了实现动态类型语言支持而做的一种改进。** + +但是在 Java 7 中并没有提供直接生成 invokedynamic 指令的方法,需要借助 ASM 这种底层字节码工具来产生invokedynamic 指令。**直到 Java 8 的 Lambda 表达式的出现,invokedynamic 指令的生成,在 Java 中才有了直接的生成方式。** + +Java 7 中增加的动态语言类型支持的本质是对 Java 虚拟机规范的修改,而不是对 Java 语言规则的修改,这一块相对来讲比较复杂,增加了虚拟机中的方法调用,最直接的受益者就是运行在 Java 平台的动态语言的编译器。 + +### 动态类型语言和静态类型语言 + +动态类型语言和静态类型语言两者的区别就在于对类型的检查是在编译期还是在运行期,满足前者就是静态类型语言,反之是动态类型语言。 + +说的再直白一点就是,**静态类型语言是判断变量自身的类型信息;动态类型语言是判断变量值的类型信息,变量没有类型信息,变量值才有类型信息**,这是动态语言的一个重要特征。 + +> Java:String info = "atiguigu"; (Java 是静态类型语言的,会先编译就进行类型检查) +> +> JS:var name = "shkstart"; var name = 10; (运行时才进行检查) + +### 方法重写的本质 + +#### Java 语言中方法重写的本质: + +- 找到操作数栈顶的第一个元素所执行的对象的实际类型,记作 C。 +- 如果在类型 C 中找到与常量中的描述符合简单名称都相符的方法,则进行访问权限校验,如果通过则返回这个方法的直接引用,查找过程结束;如果不通过,则返回 java.lang.illegalAccessError 异常。 +- 否则,按照继承关系从下往上依次对 C 的各个父类进行第2步的搜索和验证过程。 +- 如果始终没有找到合适的方法,则抛出 java.lang.AbstractMethodserror 异常。 + +#### IllegalAccessError介绍 + +程序试图访问或修改一个属性或调用一个方法,这个属性或方法,你没有权限访问。一般的,这个会引起编译器异常。这个错误如果发生在运行时,就说明一个类发生了不兼容的改变。 + +### 方法的调用:虚方法表 + +在面向对象的编程中,会很频繁的使用到动态分派,如果在每次动态分派的过程中都要重新在类的方法元数据中搜索合适的目标的话就可能影响到执行效率。因此,**为了提高性能**,JVM 采用在类的方法区建立一个虚方法表 +**(Virtual Method Table)(非虚方法不会出现在表中)来实现。使用索引表来代替查找。** + +每个类中都有一个虚方法表,表中存放着各个方法的实际入口。 + +虚方法表是什么时候被创建的呢? + +**虚方法表会在类加载的链接阶段被创建并开始初始化,类的变量初始值准备完成之后,JVM 会把该类的方法表也初始化完毕。** + +![image-20200706144954070](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115423.png) + +如上图所示:如果类中重写了方法,那么调用的时候,就会直接在虚方法表中查找,否则将会直接连接到 Object的方法中。 + +## 方法返回地址 + +存放调用该方法的 PC 寄存器的值。一个方法的结束,有两种方式: + +- 正常执行完成 + +- 出现未处理的异常,非正常退出 + +无论通过哪种方式退出,在方法退出后都返回到该方法被调用的位置。方法正常退出时,**调用者的 PC 计数器的值作为返回地址,即调用该方法的指令的下一条指令的地址**。而通过异常退出的,返回地址是要通过异常表来确定,栈帧中一般不会保存这部分信息。 + +本质上,方法的退出就是当前栈帧出栈的过程。此时,需要恢复上层方法的局部变量表、操作数栈、将返回值压入调用者栈帧的操作数栈、设置 PC 寄存器值等,让调用者方法继续执行下去。 + +**正常完成出口和异常完成出口的区别在于:通过异常完成出口退出的不会给他的上层调用者产生任何的返回值。** + +当一个方法开始执行后,只有两种方式可以退出这个方法: + +1. 执行引擎遇到任意一个方法返回的字节码指令(return),会将返回值传递给上层的方法调用者,简称**正常完成出口;** + - 一个方法在正常调用完成之后,究竟需要使用哪一个返回指令,还需要根据方法返回值的实际数据类型而定。 + - 在字节码指令中,返回指令包含 ireturn(当返回值是 boolean,byte,char,short 和 int 类型时使用),lreturn(Long类型),freturn(Float类型),dreturn(Double类型),areturn(引用类型)。另外还有一个 return 指令声明为 void 的方法,实例初始化方法,类和接口的初始化方法使用。 + +2. 在方法执行过程中遇到异常(Exception),并且这个异常没有在方法内进行处理,也就是只要在本方法的异常表中没有搜索到匹配的异常处理器,就会导致方法退出,简称**异常完成出口。** + +方法执行过程中抛出异常时的异常处理,存储在一个异常处理表,方便在发生异常的时候找到处理异常的代码 + +![image-20200706154554604](https://gitee.com/xlshi/blog_img/raw/master/img/20201009115427.png) + +## 一些附加信息 + +![image-20201009144516753](https://gitee.com/xlshi/blog_img/raw/master/img/20201009144525.png) + +栈帧中还允许携带与 Java 虚拟机实现相关的一些附加信息。例如:对程序调试提供支持的信息。 + +## 栈的相关面试题 + +- 举例栈溢出的情况?(StackOverflowError) + - 通过 -Xss 设置栈的大小 +- 调整栈大小,就能保证不出现溢出么? + - 不能保证不溢出 +- 分配的栈内存越大越好么? + - 不是,一定时间内降低了 OOM 概率,但是会挤占其它的线程空间,因为整个空间是有限的。 +- 垃圾回收是否涉及到虚拟机栈? + - 不会 +- 方法中定义的局部变量是否线程安全? + - 具体问题具体分析 + +总结一句话就是:如果对象是在内部产生,并在内部消亡,没有返回到外部,那么它就是线程安全的,反之则是线程不安全的。 + +运行时数据区,是否存在 Error 和 GC ? + +| 运行时数据区 | 是否存在Error | 是否存在GC | +| ------------ | ------------- | ---------- | +| 程序计数器 | 否 | 否 | +| 虚拟机栈 | 是 | 否 | +| 本地方法栈 | 是 | 否 | +| 方法区 | 是(OOM) | 是 | +| 堆 | 是 | 是 | + diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705163928652.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705163928652.png" new file mode 100644 index 0000000000000000000000000000000000000000..33c46d5cc50df1b00d5eefe89b5852bc4e1e3c2c Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705163928652.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705164722033.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705164722033.png" new file mode 100644 index 0000000000000000000000000000000000000000..d91e03155e637418d53d39be514d53d475ee5474 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705164722033.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705165025382.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705165025382.png" new file mode 100644 index 0000000000000000000000000000000000000000..3d9911ff0a635df67e1acba65c9facb08bde25ec Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705165025382.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705203142545.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705203142545.png" new file mode 100644 index 0000000000000000000000000000000000000000..3db698f44cc73f82215c0845418314ad2f73af50 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705203142545.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705203916023.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705203916023.png" new file mode 100644 index 0000000000000000000000000000000000000000..aed6c14c55f0010ed33fc96ff01437cd1b277a27 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705203916023.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705204836977.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705204836977.png" new file mode 100644 index 0000000000000000000000000000000000000000..1c82a812e1aad7ad614de4b877af13b1554bb40d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705204836977.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705205443993.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705205443993.png" new file mode 100644 index 0000000000000000000000000000000000000000..e11cd24bfa322f5d6d61c93462443da6bcd67ed1 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705205443993.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705212454445.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705212454445.png" new file mode 100644 index 0000000000000000000000000000000000000000..1f8104362242d8ddfa788719c2256cba9e305b53 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705212454445.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705213106749.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705213106749.png" new file mode 100644 index 0000000000000000000000000000000000000000..98c9cd5a3492ca07588cac4d6147ed7ccec3deec Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200705213106749.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706090618332.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706090618332.png" new file mode 100644 index 0000000000000000000000000000000000000000..5859fd59c79cb28c07742565e0fe72bce9d6563e Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706090618332.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706090833697.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706090833697.png" new file mode 100644 index 0000000000000000000000000000000000000000..37b5fc0e33d9329be3b0052b9e3c8bfcfc18b0d7 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706090833697.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706092610730.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706092610730.png" new file mode 100644 index 0000000000000000000000000000000000000000..aebf2106eee491e2e8cdd3065672547bd5886d2f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706092610730.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093131621.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093131621.png" new file mode 100644 index 0000000000000000000000000000000000000000..319568b868545059606e9ad96a31cc586a29d115 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093131621.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093251302.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093251302.png" new file mode 100644 index 0000000000000000000000000000000000000000..430dbc6e01f4cb363ac62fba0fb935f40111154a Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093251302.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093646406.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093646406.png" new file mode 100644 index 0000000000000000000000000000000000000000..36f0cbe04056c7b37813e21d274a537707e18c0c Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093646406.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093751711.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093751711.png" new file mode 100644 index 0000000000000000000000000000000000000000..81340dc690bf7fea96c9ad9a906e393f1f257a23 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093751711.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093859191.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093859191.png" new file mode 100644 index 0000000000000000000000000000000000000000..02538ce3ce694158d3245047a3c90219e861ff76 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093859191.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093921573.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093921573.png" new file mode 100644 index 0000000000000000000000000000000000000000..afc8ddfc0642c7dc1498db52bd195ea2619144de Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706093921573.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706094046782.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706094046782.png" new file mode 100644 index 0000000000000000000000000000000000000000..c656b8687d48280402a05d323ceb749b73b2f986 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706094046782.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706094109629.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706094109629.png" new file mode 100644 index 0000000000000000000000000000000000000000..b45e920adba2f65714f4f31ecd878456835b3eed Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706094109629.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706100311886.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706100311886.png" new file mode 100644 index 0000000000000000000000000000000000000000..9563eb5ff0c3be9d6f00e61eb91d47b171b33c2d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706100311886.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706101251847.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706101251847.png" new file mode 100644 index 0000000000000000000000000000000000000000..0ff79b4e5032f5b45bf2633c72dd3c98ba0c5b80 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706101251847.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706144954070.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706144954070.png" new file mode 100644 index 0000000000000000000000000000000000000000..cbb894197d06220ab76027bf3a59df0c7ba96070 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706144954070.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706154554604.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706154554604.png" new file mode 100644 index 0000000000000000000000000000000000000000..b12f41d375259e4e50dc585d6bd2b44cf4d234a0 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/5_\350\231\232\346\213\237\346\234\272\346\240\210/images/image-20200706154554604.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/6_\346\234\254\345\234\260\346\226\271\346\263\225\346\216\245\345\217\243/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/6_\346\234\254\345\234\260\346\226\271\346\263\225\346\216\245\345\217\243/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..8feab868975dcf69131406fae8112f7985d48589 --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/6_\346\234\254\345\234\260\346\226\271\346\263\225\346\216\245\345\217\243/README.md" @@ -0,0 +1,46 @@ +# 本地方法接口 + +## 什么是本地方法 + +简单地讲,**一个 Native Method 是一个 Java 调用非 Java 代码的接囗**。一个 Native Method 是这样一个 Java 方法:该方法的实现由非 Java 语言实现,比如 C。这个特征并非 Java 所特有,很多其它的编程语言都有这一机制,比如在 C++ 中,你可以用 extern "c" 告知 C++ 编译器去调用一个 C 的函数。 + +"A native method is a Java method whose implementation is provided by non-java code."(本地方法是一个非 Java 的方法,它的具体实现是非 Java 代码的实现) + +在定义一个 Native Method 时,并不提供实现体(有些像定义一个 Java interface),因为其实现体是由非 Java 语言在外面实现的。 + +本地接口的作用是融合不同的编程语言为 Java 所用,它的初衷是融合 C/C++ 程序。 + +![image-20200706164139252](https://gitee.com/xlshi/blog_img/raw/master/img/20201009145225.png) + +代码举例说明 Native 方法是如何编写的 + +```java +public class IhaveNatives { + public native void Native1(int x); + native static public long Native2(); + native synchronized private float Native3(Object o); + native void Natives(int[] ary) throws Exception; +} +``` + +> 需要注意的是:标识符 native 可以与其它 Java 标识符连用,但是 abstract 除外 + +## 为什么使用 Native Method ? + +Java 使用起来非常方便,然而有些层次的任务用 Java 实现起来不容易,或者我们对程序的效率很在意时,问题就来了。 + +### 与 Java 环境的交互 + +**有时 Java 应用需要与 Java 外面的环境交互,这是本地方法存在的主要原因。**你可以想想 Java 需要与一些底层系统,如操作系统或某些硬件交换信息时的情况。**本地方法正是这样一种交流机制:它为我们提供了一个非常简洁的接口,而且我们无需去了解 Java 应用之外的繁琐的细节。** + +### 与操作系统的交互 + +JVM 支持着 Java 语言本身和运行时库,它是 Java 程序赖以生存的平台,它由一个解释器(解释字节码)和一些连接到本地代码的库组成。然而不管怎样,它毕竟不是一个完整的系统,它经常依赖于一底层系统的支持。这些底层系统常常是强大的操作系统。**通过使用本地方法,我们得以用 Java 实现了 jre 的与底层系统的交互,甚至 JVM 的一些部分就是用 C 写的。**还有,如果我们要使用一些 Java 语言本身没有提供封装的操作系统的特性时,我们也需要使用本地方法。 + +### Sun's Java + +**Sun 的解释器是用 C 实现的,这使得它能像一些普通的 C 一样与外部交互。**jre 大部分是用 Java 实现的,它也通过一些本地方法与外界交互。例如:类 java.lang.Thread 的 setPriority()方法是用 Java 实现的,但是它实现调用的是该类里的本地方法 setPriority0()。这个本地方法是用 C 实现的,并被植入 JVM 内部,在Windows 95 的平台上,这个本地方法最终将调用 Win32 setPriority()API。这是一个本地方法的具体实现由JVM 直接提供,更多的情况是本地方法由外部的动态链接库(external dynamic link library)提供,然后被JVM 调用。 + +## 现状 + +**目前该方法使用的越来越少了,除非是与硬件有关的应用**,比如通过 Java 程序驱动打印机或者 Java 系统管理生产设备,在企业级应用中已经比较少见。因为现在的异构领域间的通信很发达,比如可以使用 Socket 通信,也可以使用 Web Service 等等,不多做介绍。 \ No newline at end of file diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/6_\346\234\254\345\234\260\346\226\271\346\263\225\346\216\245\345\217\243/images/image-20200706164139252.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/6_\346\234\254\345\234\260\346\226\271\346\263\225\346\216\245\345\217\243/images/image-20200706164139252.png" new file mode 100644 index 0000000000000000000000000000000000000000..1f6045e045af06b689846f6a9cbbb293392ec1f0 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/6_\346\234\254\345\234\260\346\226\271\346\263\225\346\216\245\345\217\243/images/image-20200706164139252.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/7_\346\234\254\345\234\260\346\226\271\346\263\225\346\240\210/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/7_\346\234\254\345\234\260\346\226\271\346\263\225\346\240\210/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..dbb00abe4d13bc4cf08429b301048c57f94618d9 --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/7_\346\234\254\345\234\260\346\226\271\346\263\225\346\240\210/README.md" @@ -0,0 +1,27 @@ +# 本地方法栈(Native Method Stack) + +Java 虚拟机栈用于管理 Java 方法的调用,而**本地方法栈用于管理本地方法的调用**。 + +本地方法栈,也是线程私有的。 + +允许被实现成固定或者是可动态扩展的内存大小。(在内存溢出方面是相同的) + +- 如果线程请求分配的栈容量超过本地方法栈允许的最大容量,Java 虚拟机将会抛出一个 StackOverFlowError 异常。 +- 如果本地方法栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者在创建新的线程时没有足够的内存去创建对应的本地方法栈,那么 Java 虚拟机将会抛出一个 OutOfMemoryError 异常。 + +本地方法是使用 C 语言实现的。 + +它的具体做法是 Native Method Stack 中登记 native 方法,在 Execution Engine 执行时加载本地方法库。 + +![image-20200706174708418](https://gitee.com/xlshi/blog_img/raw/master/img/20201009150415.png) + +**当某个线程调用一个本地方法时,它就进入了一个全新的并且不再受虚拟机限制的世界。它和虚拟机拥有同样的权限。** + +- 本地方法可以通过本地方法接口来**访问虚拟机内部的运行时数据区。** +- 它甚至可以直接使用本地处理器中的寄存器 +- 直接从本地内存的堆中分配任意数量的内存。 + +并不是所有的 JVM 都支持本地方法。因为 Java 虚拟机规范并没有明确要求本地方法栈的使用语言、具体实现方式、数据结构等。如果 JVM 产品不打算支持 native 方法,也可以无需实现本地方法栈。 + +**在 HotSpot JVM 中,直接将本地方法栈和虚拟机栈合二为一。** + diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/7_\346\234\254\345\234\260\346\226\271\346\263\225\346\240\210/images/image-20200706174708418.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/7_\346\234\254\345\234\260\346\226\271\346\263\225\346\240\210/images/image-20200706174708418.png" new file mode 100644 index 0000000000000000000000000000000000000000..6be72349acd1168591a2ad46c530135de3acec10 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/7_\346\234\254\345\234\260\346\226\271\346\263\225\346\240\210/images/image-20200706174708418.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/1.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/1.png" new file mode 100644 index 0000000000000000000000000000000000000000..3aa9a6c7f3576f2b1d498a93a1a5eebc897095a5 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/1.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/10.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/10.png" new file mode 100644 index 0000000000000000000000000000000000000000..1a8ee02c965b3c108b73b7df975a13c49c12fd23 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/10.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/11.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/11.png" new file mode 100644 index 0000000000000000000000000000000000000000..eeea1174cd82701f53e1fa5c40d17b5200869445 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/11.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/13.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/13.png" new file mode 100644 index 0000000000000000000000000000000000000000..fc69e975023e1d68bc99b4664f7130c2449e767f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/13.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/14.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/14.png" new file mode 100644 index 0000000000000000000000000000000000000000..2272ccccc88d14fa5830a774c98fda6fbeaafc11 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/14.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/15.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/15.png" new file mode 100644 index 0000000000000000000000000000000000000000..dfe4606d70bf4c9fe247acc8570f12e9a3587fb5 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/15.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/18.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/18.png" new file mode 100644 index 0000000000000000000000000000000000000000..6adcf580188601d004b95f2e8e182b77f432a5fc Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/18.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/2.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/2.png" new file mode 100644 index 0000000000000000000000000000000000000000..adb4edb2abd5bf03268472457000b997a2669a76 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/2.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/20.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/20.png" new file mode 100644 index 0000000000000000000000000000000000000000..8a33ef5836b69396e469adbf143a308267356e4f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/20.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/21.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/21.png" new file mode 100644 index 0000000000000000000000000000000000000000..62007e5c9a2307fc3c561e4ec8ea15dce089657f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/21.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/22.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/22.png" new file mode 100644 index 0000000000000000000000000000000000000000..48efdcd02fb8486ecb9209c9b2bd5c4a1b2537cd Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/22.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/23.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/23.png" new file mode 100644 index 0000000000000000000000000000000000000000..d0d341f362253c8be73ee7e4b7c6f2b396c4a0de Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/23.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/24.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/24.png" new file mode 100644 index 0000000000000000000000000000000000000000..062d5f5a5ebd073f8101311ba19d34c759399b05 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/24.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/25.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/25.png" new file mode 100644 index 0000000000000000000000000000000000000000..c50b2dc9da35f1748071e39baed4cd4051bd5c08 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/25.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/26.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/26.png" new file mode 100644 index 0000000000000000000000000000000000000000..a4a2624db2172c2bc47ae016eaca8c376fe15a16 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/26.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/27.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/27.png" new file mode 100644 index 0000000000000000000000000000000000000000..2d15300a1d87d9109a6e4e596e81ae1c6c0f6ed9 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/27.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/28.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/28.png" new file mode 100644 index 0000000000000000000000000000000000000000..4282bc861ca12d28e80a0b8ce3cfc394a218cfd7 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/28.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/29.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/29.png" new file mode 100644 index 0000000000000000000000000000000000000000..0109656726622de8470267c7fa9ffa746bf4a8d1 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/29.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/3.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/3.png" new file mode 100644 index 0000000000000000000000000000000000000000..16628f743c5f83643525a19c7281158ad7d1a587 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/3.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/30.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/30.png" new file mode 100644 index 0000000000000000000000000000000000000000..b0a38f9d61ade05a90a223585517c6ae49d3d379 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/30.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/31.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/31.png" new file mode 100644 index 0000000000000000000000000000000000000000..cd0fb7632ab0dcf7f68bcb85f4e8ad08a8248faf Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/31.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/32.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/32.png" new file mode 100644 index 0000000000000000000000000000000000000000..bf8682714073c7b2b8c36e77ff5d854c8ae47613 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/32.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/33.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/33.png" new file mode 100644 index 0000000000000000000000000000000000000000..3319bf2509134ed94fa0b827513e3adb023f976a Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/33.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/34.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/34.png" new file mode 100644 index 0000000000000000000000000000000000000000..d5eb235ef7fe03acd558256e7fb6a2cc4ebdbdb8 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/34.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/35.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/35.png" new file mode 100644 index 0000000000000000000000000000000000000000..8ae37b99a5329f7f51e86d48121423c476531738 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/35.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/36.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/36.png" new file mode 100644 index 0000000000000000000000000000000000000000..41c7506a571f328139d8f89218f8fed66fd221f4 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/36.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/37.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/37.png" new file mode 100644 index 0000000000000000000000000000000000000000..9b1190ed6115e834b69a5577ab2c2d53bbcfeccb Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/37.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/38.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/38.png" new file mode 100644 index 0000000000000000000000000000000000000000..1e8d1599e906c9bedbaeacd41b30841c92c61400 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/38.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/4.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/4.png" new file mode 100644 index 0000000000000000000000000000000000000000..ba13aee5b7ece7c4649df9551f8ed3e7b3f799fb Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/4.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/41.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/41.png" new file mode 100644 index 0000000000000000000000000000000000000000..f7bd899186df9a74570629f7a39c8e8fccd4d5bd Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/41.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/42.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/42.png" new file mode 100644 index 0000000000000000000000000000000000000000..154d99e9269af2f4ca0882eb39190569f2e1336f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/42.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/43.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/43.png" new file mode 100644 index 0000000000000000000000000000000000000000..576d5c28f71935c0f43984865e386b9149724882 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/43.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/44.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/44.png" new file mode 100644 index 0000000000000000000000000000000000000000..92affceb955574c5628003d63ab13eb34c530558 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/44.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/45.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/45.png" new file mode 100644 index 0000000000000000000000000000000000000000..587be89e4921e39ceeaa4887142a37ebebe99376 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/45.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/46.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/46.png" new file mode 100644 index 0000000000000000000000000000000000000000..03a581a36b3eed96bb02167cf92f90d29da06a98 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/46.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/48.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/48.png" new file mode 100644 index 0000000000000000000000000000000000000000..576eff75249cf9465740edceb85ded1e042f303e Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/48.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/49.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/49.png" new file mode 100644 index 0000000000000000000000000000000000000000..280c8c834b37a1505f426fdabd3c0017a575ccbf Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/49.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/5.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/5.png" new file mode 100644 index 0000000000000000000000000000000000000000..a13e49cd94bd1593a1450ca7884913a94cb8accc Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/5.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/50.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/50.png" new file mode 100644 index 0000000000000000000000000000000000000000..800be4fb84a908dd756ab63a43a1062485e10733 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/50.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/51.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/51.png" new file mode 100644 index 0000000000000000000000000000000000000000..6f7ecc2e25d40d805e657cb14d0325990169c2ce Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/51.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/52.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/52.png" new file mode 100644 index 0000000000000000000000000000000000000000..380de5496f64db9260c2002eae6e2ada6d9bfeff Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/52.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/53.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/53.png" new file mode 100644 index 0000000000000000000000000000000000000000..5371d1259df69b71b47c1672c7cde5679057823e Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/53.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/54.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/54.png" new file mode 100644 index 0000000000000000000000000000000000000000..a4543b10e0e3253865feebb0973a25fff99e3ffc Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/54.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/55.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/55.png" new file mode 100644 index 0000000000000000000000000000000000000000..f9b5d2ff776ee4032b03da9e8e57b58a8be00da6 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/55.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/57.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/57.png" new file mode 100644 index 0000000000000000000000000000000000000000..27f9b016af2ac2708401277c43c6169505a00a05 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/57.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/58.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/58.png" new file mode 100644 index 0000000000000000000000000000000000000000..2f9d7d0706d805953eeb55b8972ab676d25adc15 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/58.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/59.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/59.png" new file mode 100644 index 0000000000000000000000000000000000000000..cd53481d834dae0a63f6a03250152fbcc489113d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/59.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/6.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/6.png" new file mode 100644 index 0000000000000000000000000000000000000000..3c91cc04c7d05b3c2dfa544dd9357b204d561a86 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/6.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/60.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/60.png" new file mode 100644 index 0000000000000000000000000000000000000000..6c5448c3b5d8c9956f09b3bdbbe112d553df18e4 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/60.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/61.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/61.png" new file mode 100644 index 0000000000000000000000000000000000000000..5b5750eefbc79687ad457432376eaab0a95cf43d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/61.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/62.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/62.png" new file mode 100644 index 0000000000000000000000000000000000000000..7183d02bfbfdef0c04f58c145dd8066ec9325f1d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/62.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/63.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/63.png" new file mode 100644 index 0000000000000000000000000000000000000000..447b81d1742600305e593588b213b1aeaa8a191b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/63.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/64.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/64.png" new file mode 100644 index 0000000000000000000000000000000000000000..da6543ca6dc60f392ba1eef32a2a682d8afa3509 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/64.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/65.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/65.png" new file mode 100644 index 0000000000000000000000000000000000000000..c841e0368508bc3bb80356cb765b029552db823b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/65.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/66.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/66.png" new file mode 100644 index 0000000000000000000000000000000000000000..ac1675f45aa685867cd3351079c35c66f268f770 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/66.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/67.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/67.png" new file mode 100644 index 0000000000000000000000000000000000000000..208d81abd5f40f1b26560fdd35a4a32b3c1c6174 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/67.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/69.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/69.png" new file mode 100644 index 0000000000000000000000000000000000000000..6aa49a361d487c332b72ef4efa0ee07222f12668 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/69.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/7.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/7.png" new file mode 100644 index 0000000000000000000000000000000000000000..e69fdc5a31027e10658e4b6c6ae662229b568058 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/7.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/70.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/70.png" new file mode 100644 index 0000000000000000000000000000000000000000..6cbf372cdbcd06ed949668bdfa369aa89b72fd42 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/70.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/71.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/71.png" new file mode 100644 index 0000000000000000000000000000000000000000..049332e65fccf9dbd51bac684f24a261faf19d02 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/71.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/72.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/72.png" new file mode 100644 index 0000000000000000000000000000000000000000..499b3924984be96ba680c9fd563a848956f4d470 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/72.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/73.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/73.png" new file mode 100644 index 0000000000000000000000000000000000000000..f9652043e0081aa20d70ec52a5ba9928e2faf2b9 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/73.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/75.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/75.png" new file mode 100644 index 0000000000000000000000000000000000000000..3e787f197a437f6a5855c4be4cde2575e1c5b410 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/75.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/76.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/76.png" new file mode 100644 index 0000000000000000000000000000000000000000..e7ad64349f4282a2e03f243ceab4a4d8da2e007d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/76.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/77.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/77.png" new file mode 100644 index 0000000000000000000000000000000000000000..afad08bf596ec43a6cc4290611e182e623668ab1 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/77.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/9.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/9.png" new file mode 100644 index 0000000000000000000000000000000000000000..7326c6e0d3f4f986dc468afa2afe131bf0f887a2 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/PPT/9.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..17f9e57364c40c086ebafc986bac0d94e115df96 --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/README.md" @@ -0,0 +1,844 @@ +# 堆 + +## 堆的核心概念 + +堆和方法区针对一个 JVM 进程来说是唯一的,也就是一个进程只有一个 JVM ,但是进程包含多个线程,他们是共享同一堆和方法区空间的,每个线程各自包含一套程序计数器、本地方法栈和虚拟机栈。 + +![image-20200706195127740](https://gitee.com/xlshi/blog_img/raw/master/img/20201009150619.png) + +一个 JVM 实例只存在一个堆内存,堆也是 Java 内存管理的核心区域。 + +Java 堆区在 JVM 启动的时候即被创建,其空间大小也就确定了。是 JVM 管理的最大一块内存空间。 + +- 堆内存的大小是可以调节的。 + +《Java虚拟机规范》规定,**堆可以处于物理上不连续的内存空间中,但在逻辑上它应该被视为连续的。** + +所有的线程共享 Java 堆,在这里还可以划分线程私有的缓冲区(Thread Local Allocation Buffer,TLAB)。 + +> -Xms10m:最小堆内存 +> +> -Xmx10m:最大堆内存 + +下图就是使用:Java VisualVM 查看堆空间的内容,通过 jdk/bin提供的插件 + +![image-20200706200739392](https://gitee.com/xlshi/blog_img/raw/master/img/20201009150850.png) + +《Java虚拟机规范》中对 Java 堆的描述是:所有的对象实例以及数组都应当在运行时分配在堆上。(The heap is the run-time data area from which memory for all class instances and arrays is allocated) + +我要说的是:**“几乎”**所有的对象实例都在这里分配内存。——从实际使用角度看的。 + +- 因为还有一些对象是在**栈上分配**的 + +数组和对象可能永远不会存储在栈上,因为栈帧中保存引用,这个引用指向对象或者数组在堆中的位置。 + +在方法结束后,堆中的对象不会马上被移除,仅仅在垃圾收集的时候才会被移除。 + +- 也就是触发了 GC 的时候,才会进行回收 +- 如果堆中对象马上被回收,那么用户线程就会收到影响,因为有 Stop The Word + +**堆,是 GC(Garbage Collection,垃圾收集器)执行垃圾回收的重点区域。** + +![image-20200706201904057](https://gitee.com/xlshi/blog_img/raw/master/img/20201009150843.png) + +### 堆内存细分 + +Java 7 及之前堆内存逻辑上分为三部分:新生区+养老区+**永久区** + +- Young Generation Space 新生区 Young/New 又被划分为 Eden 区和 Survivor 区 +- Tenure Generation Space 养老区 Old/Tenure +- Permanent Space 永久区 Perm + +Java 8 及之后堆内存逻辑上分为三部分:新生区+养老区+**元空间** +- Young Generation Space 新生区 Young/New 又被划分为 Eden 区和 Survivor 区 +- Tenure Generation Space 养老区 Old/Tenure +- Meta Space 元空间 Meta + +约定:新生区 <-> 新生代 <-> 年轻代 、 养老区 <-> 老年区 <-> 老年代、 永久区 <-> 永久代 + +![image-20200706203419496](https://gitee.com/xlshi/blog_img/raw/master/img/20201009150951.png) + +堆空间内部结构,JDK 1.8 时从**永久代**替换成**元空间** + +![image-20200706203835403](https://gitee.com/xlshi/blog_img/raw/master/img/20201009151016.png) + +## 设置堆内存大小与 OOM + +Java 堆区用于存储 Java 对象实例,那么堆的大小在 JVM 启动时就已经设定好了,大家可以通过选项"-Xmx"和"-Xms"来进行设置。 + +- “-Xms" 用于表示堆区的起始内存,等价于 -XX:InitialHeapSize +- “-Xmx" 则用于表示堆区的最大内存,等价于 -XX:MaxHeapSize + +一旦堆区中的内存大小超过 "-Xmx" 所指定的最大内存时,将会抛出 OutOfMemoryError 异常。 + +通常会将 -Xms 和 -Xmx 两个参数配置相同的值,其**目的是为了能够在 Java 垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小,从而提高性能**。 + +默认情况下: + +- 初始内存大小:物理电脑内存大小/64 + +- 最大内存大小:物理电脑内存大小/4 + +```java +public class HeapSpaceInitial { + public static void main(String[] args) { + // 返回Java虚拟机中的堆内存总量 + long initialMemory = Runtime.getRuntime().totalMemory() / 1024 / 1024; + // 返回Java虚拟机试图使用的最大堆内存 + long maxMemory = Runtime.getRuntime().maxMemory() / 1024 / 1024; + System.out.println("-Xms:" + initialMemory + "M"); + System.out.println("-Xmx:" + maxMemory + "M"); + } +} +``` + +输出结果 + +``` +-Xms:245M +-Xmx:3623M +``` + +> 开发中建议将初始堆内存和最大堆内存设置成相同的值 + +如何查看堆内存的内存分配情况 + +``` +jps -> jstat -gc 进程id +``` + +![image-20200706205756045](images/image-20200706205756045.png) + +``` +-XX:+PrintGCDetails +``` + +![image-20200706205821919](images/image-20200706205821919.png) + +> 为什么设置初始堆内存为600M,实际只有575M? +> +> 答:因为在新生代中,数据存放在 Eden 区和 Survivor 区,其中 Survivor0 和 Survivor1 区只能二选一存放,少了一个25600 / 1024 = 25M。 + +### OutOfMemory 举例 + +```java +public class OOMTest { + public static void main(String[] args) { + ArrayList list = new ArrayList<>(); + + while (true) { + list.add(new Picture(new Random().nextInt(1024 * 1024))); + } + } +} +``` + +![image-20200706210000461](https://gitee.com/xlshi/blog_img/raw/master/img/20201009151420.png) + +我们简单的写一个 OOM 例子 + +```java +public class OOMTest { + public static void main(String[] args) { + List list = new ArrayList<>(); + while(true) { + list.add(999999999); + } + } +} +``` + +然后设置启动参数 + +``` +-Xms10m -Xmx:10m +``` + +运行后,就出现 OOM 了,那么我们可以通过 VisualVM 这个工具查看具体是什么参数造成的 OOM + +![image-20200706211652779](images/image-20200706211652779.png) + +## 年轻代与老年代 + +存储在 JVM 中的 Java 对象可以被划分为两类: +- 一类是生命周期较短的瞬时对象,这类对象的创建和消亡都非常迅速 + - 生命周期短的,及时回收即可 +- 另外一类对象的生命周期却非常长,在某些极端的情况下还能够与 JVM 的生命周期保持一致 + +Java 堆区进一步细分的话,可以划分为年轻代(YoungGen)和老年代(OldGen) + +其中年轻代又可以划分为 Eden 空间、Survivor0 空间和 Survivor1 空间(有时也叫做 From 区、To 区) + +![image-20200707075847954](https://gitee.com/xlshi/blog_img/raw/master/img/20201009151544.png) + +下面这参数开发中一般不会调: + +![image-20200707080154039](https://gitee.com/xlshi/blog_img/raw/master/img/20201009151604.png) + +- Eden : From : To -> 8 : 1 : 1 +- 新生代 : 老年代 - > 1 : 2 + +配置新生代与老年代在堆结构的占比。 + +- 默认-XX:NewRatio=2,表示新生代占1,老年代占2,新生代占整个堆的1/3 + +- 可以修改-XX:NewRatio=4,表示新生代占1,老年代占4,新生代占整个堆的1/5 + +> 当发现在整个项目中,生命周期长的对象偏多,那么就可以通过调整老年代的大小,来进行调优 + +在 HotSpot 中,Eden 空间和另外两个 Survivor 空间缺省所占的比例是8 : 1 : 1,当然开发人员可以通过选项“-XX:SurvivorRatio”调整这个空间比例。比如-XX:SurvivorRatio=8 + +> 为什么默认是8:1:1,而实际当中是6:1:1? +> +> 答:因为存在自适应机制,即-XX:-UseAdaptiveSizePolicy(+启用,-禁用),但这种方法一般不能生效,所以一般采用-XX:SurvivorRatio=8 + +**几乎所有的** Java 对象都是在 Eden 区被 new 出来的。绝大部分的 Java 对象的销毁都在新生代进行了。(有些大的对象在 Eden 区无法存储时候,将直接进入老年代) + +>IBM 公司的专门研究表明,新生代中80%的对象都是“朝生夕死”的。 + +可以使用选项"-Xmn"设置新生代最大内存大小(优先级高于-XX:NewRatio) + +>这个参数一般使用默认值就可以了。 + +![image-20200707084208115](https://gitee.com/xlshi/blog_img/raw/master/img/20201009151752.png) + +## 图解对象分配过程 + +### 概述 + +为新对象分配内存是一件非常严谨和复杂的任务,JVM 的设计者们不仅需要考虑内存如何分配、在哪里分配等问题,并且由于内存分配算法与内存回收算法密切相关,所以还需要考虑 GC 执行完内存回收后是否会在内存空间中产生内存碎片。 + +- new 的对象先放伊甸园区。此区有大小限制。 +- 当伊甸园的空间填满时,程序又需要创建对象,JVM 的垃圾回收器将对伊甸园区进行垃圾回收(MinorGC),将伊甸园区中的不再被其他对象所引用的对象进行销毁。再加载新的对象放到伊甸园区 +- 然后将伊甸园中的剩余对象移动到幸存者0区。 +- 如果再次触发垃圾回收,此时上次幸存下来的放到幸存者0区的,如果没有回收,就会放到幸存者1区。 +- 如果再次经历垃圾回收,此时会重新放回 Survivor0 区,接着再去 Survivor1 区。 +- 啥时候能去养老区呢?可以设置次数。默认是15次。 + - **可以设置参数:-Xx:MaxTenuringThreshold=N进行设置** +- 在养老区,相对悠闲。当养老区内存不足时,再次触发 GC : Major GC,进行养老区的内存清理 +- 若养老区执行了 Major GC 之后,发现依然无法进行对象的保存,就会产生 OOM 异常。 + - `java.lang.OutOfMemoryError: Java heap space` + +### 图解过程 + +我们创建的对象,一般都是存放在 Eden 区的,当我们 Eden 区满了后,就会触发 GC 操作,一般被称为 YGC / Minor GC 操作 + +![image-20200707084714886](https://gitee.com/xlshi/blog_img/raw/master/img/20201009152825.png) + +当我们进行一次垃圾收集后,红色的将会被回收,而绿色的还会被占用着,存放在 S0(Survivor From) 区。同时我们给每个对象设置了一个年龄计数器,一次回收后就是1。 + +同时 Eden 区继续存放对象,当 Eden 区再次存满的时候,又会触发一个 MinorGC 操作,此时 GC 将会把 Eden 和 Survivor From 中的对象进行一次收集,把存活的对象放到 Survivor To区,同时让年龄 + 1 + +![image-20200707085232646](https://gitee.com/xlshi/blog_img/raw/master/img/20201009152829.png) + +我们继续不断的进行对象生成和垃圾回收,当 Survivor 中的对象的年龄达到15的时候,将会触发一次 Promotion 晋升的操作,也就是将年轻代中的对象晋升到老年代中 + +![image-20200707085737207](https://gitee.com/xlshi/blog_img/raw/master/img/20201009152831.png) + +### 思考:幸存区区满了后? + +**特别注意,在 Eden 区满了的时候,才会触发 Minor GC,而 Survivor 区满了后,不会触发 Minor GC 操作** + +如果 Survivor 区满了后,将会触发一些特殊的规则,也就是可能直接晋升老年代 + +> 举例:以当兵为例,正常人的晋升可能是 : 新兵 -> 班长 -> 排长 -> 连长 +> +> 但是也有可能有些人因为做了非常大的贡献,直接从 新兵 -> 排长 + +### 对象分配的特殊情况 + +![image-20200707091058346](https://gitee.com/xlshi/blog_img/raw/master/img/20201009152835.png) + +### 代码演示对象分配过程 + +我们不断的创建大对象 + +```java +public class Test { + byte[] buffer = new byte[new Random().nextInt(1024 * 1024)]; + + public static void main(String[] args) { + ArrayList list = new ArrayList<>(); + while (true) { + list.add(new Test()); + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} +``` + +然后设置 JVM 参数 + +```bash +-Xms600m -Xmx600m +``` + +然后 cmd 输入下面命令,打开 VisualVM 图形化界面 + +``` +jvisualvm +``` + +然后通过执行上面代码,通过 VisualGC 进行动态化查看 + +![垃圾回收](https://gitee.com/xlshi/blog_img/raw/master/img/20201009153110.gif) + +最终,在老年代和新生代都满了,就出现 OOM + +``` +Exception in thread "main" java.lang.OutOfMemoryError: Java heap space + at com.atguigu.java.chapter08.HeapInstanceTest.(HeapInstanceTest.java:13) + at com.atguigu.java.chapter08.HeapInstanceTest.main(HeapInstanceTest.java:17) +``` + +### 常用的调优工具 + +- JDK命令行 +- Eclipse:Memory Analyzer Tool +- Jconsole +- Visual VM(实时监控 推荐~) +- Jprofiler(推荐~) +- Java Flight Recorder(实时监控) +- GCViewer +- GCEasy + +### 总结 + +- 针对幸存者 S0,S1 区的总结:复制之后有交换,谁空谁是 To +- 关于垃圾回收:频繁在新生区收集,很少在老年代收集,几乎不再永久代和元空间进行收集 +- 新生代采用复制算法的目的:是为了减少内碎片 + +## Minor GC,MajorGC、Full GC + +- Minor GC:新生代的 GC +- Major GC:老年代的 GC +- Full GC:整堆收集,收集整个 Java 堆和方法区的垃圾收集 + +>我们都知道,JVM 的调优的一个环节,也就是垃圾收集,我们需要尽量的避免垃圾回收,因为在垃圾回收的过程中,容易出现 STW 的问题 +> +>而 Major GC 和 Full GC 出现 STW 的时间,是 Minor GC 的10倍以上 + +JVM 在进行 GC 时,并非每次都对上面三个内存(新生代、老年代;方法区)区域一起回收的,大部分时候回收的都是指新生代。 + +针对 HotSpot VM 的实现,它里面的 GC 按照回收区域又分为两大种类型:一种是部分收集(Partial GC),一种是整堆收集(Full GC) + +部分收集:不是完整收集整个 Java 堆的垃圾收集。其中又分为: + +- 新生代收集(Minor GC/Young GC):只是新生代的垃圾收集 +- 老年代收集(Major GC/Old GC):只是老年代的圾收集。 + - 目前,只有 CMS GC 会有单独收集老年代的行为。 + - **注意,很多时候 Major GC会和 Full GC 混淆使用,需要具体分辨是老年代回收还是整堆回收。** +- 混合收集(Mixed GC):收集整个新生代以及部分老年代的垃圾收集。 + - 目前,只有 G1 GC 会有这种行为 + +整堆收集(Full GC):收集整个 Java 堆和方法区的垃圾收集。 + +### Minor GC + +**年轻代GC(Minor GC)触发机制:** + +- 当年轻代空间不足时,就会触发 Minor GC ,这里的年轻代满指的是 Eden 代满,Survivor 满不会引发 GC 。(每次 Minor GC 会清理年轻代的内存。) + +- 因为 Java 对象**大多都具备朝生夕灭**的特性,所以 Minor GC 非常频繁,一般回收速度也比较快。这一定义既清晰又易于理解。 + +- Minor GC 会引发 STW ,暂停其它用户的线程,等垃圾回收结束,用户线程才恢复运行 + +> STW:Stop The Word + +![image-20200707095606813](https://gitee.com/xlshi/blog_img/raw/master/img/20201009153353.png) + +### Major GC + +**老年代GC(Major GC/Full GC)触发机制:** + +- 指发生在老年代的 GC ,对象从老年代消失时,我们说 “Major GC” 或 “Full GC” 发生了 + +- 出现了 Major GC ,经常会伴随至少一次的 Minor GC (但非绝对的,在 Parallel Scavenge 收集器的收集策略里就有直接进行 Major GC 的策略选择过程) + - 也就是在老年代空间不足时,会先尝试触发 Minor GC 。如果之后空间还不足,则触发 Major GC + +- Major GC 的速度一般会比 Minor GC 慢10倍以上, STW 的时间更长 +- 如果 Major GC 后,内存还不足,就报 OOM 了 + +### Full GC + +触发 Full GC 执行的情况有如下五种: + +- 调用 System.gc() 时,系统建议执行 Full GC ,但是不必然执行 +- 老年代空间不足 +- 方法区空间不足 +- 通过 Minor GC 后进入老年代的平均大小大于老年代的可用内存 +- 由 Eden 区、Survivor space0(From Space)区向 Survivor space1(To Space)区复制时,对象大小大于 To Space 可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小 + +说明:**Full GC 是开发或调优中尽量要避免的。这样暂时时间会短一些** + +### GC 举例 + +我们编写一个 OOM 的异常,因为我们在不断的创建字符串,是存放在元空间的 + +```java +public class GCTest { + public static void main(String[] args) { + int i = 0; + try { + List list = new ArrayList<>(); + String a = "mogu blog"; + while(true) { + list.add(a); + a = a + a; + i++; + } + }catch (Exception e) { + e.getStackTrace(); + } + } +} +``` + +设置 JVM 启动参数 + +```bash +-Xms10m -Xmx10m -XX:+PrintGCDetails +``` + +打印出的日志 + +``` +[GC (Allocation Failure) [PSYoungGen: 2038K->500K(2560K)] 2038K->797K(9728K), 0.3532002 secs] [Times: user=0.01 sys=0.00, real=0.36 secs] +[GC (Allocation Failure) [PSYoungGen: 2108K->480K(2560K)] 2405K->1565K(9728K), 0.0014069 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] +[Full GC (Ergonomics) [PSYoungGen: 2288K->0K(2560K)] [ParOldGen: 6845K->5281K(7168K)] 9133K->5281K(9728K), [Metaspace: 3482K->3482K(1056768K)], 0.0058675 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] +[GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] 5281K->5281K(9728K), 0.0002857 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] +[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] [ParOldGen: 5281K->5263K(7168K)] 5281K->5263K(9728K), [Metaspace: 3482K->3482K(1056768K)], 0.0058564 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] +Heap + PSYoungGen total 2560K, used 60K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000) + eden space 2048K, 2% used [0x00000000ffd00000,0x00000000ffd0f138,0x00000000fff00000) + from space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000) + to space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000) + ParOldGen total 7168K, used 5263K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000) + object space 7168K, 73% used [0x00000000ff600000,0x00000000ffb23cf0,0x00000000ffd00000) + Metaspace used 3514K, capacity 4498K, committed 4864K, reserved 1056768K + class space used 388K, capacity 390K, committed 512K, reserved 1048576K + + Exception in thread "main" java.lang.OutOfMemoryError: Java heap space + at java.util.Arrays.copyOfRange(Arrays.java:3664) + at java.lang.String.(String.java:207) + at java.lang.StringBuilder.toString(StringBuilder.java:407) + at com.atguigu.java.chapter08.GCTest.main(GCTest.java:20) +``` + +**触发 OOM 的时候,一定是进行了一次 Full GC ,因为只有在老年代空间不足时候,才会爆出 OOM 异常** + +## 堆空间分代思想 + +为什么要把 Java 堆分代?不分代就不能正常工作了吗?经研究,不同对象的生命周期不同。70%-99%的对象是临时对象。 + +- 新生代:有 Eden 、两块大小相同的 Survivor(又称为 From/To,S0/S1)构成,To 总为空。 +- 老年代:存放新生代中经历多次 GC 仍然存活的对象。 + +![image-20200707101511025](https://gitee.com/xlshi/blog_img/raw/master/img/20201009153648.png) + +其实不分代完全可以,分代的唯一理由就是**优化 GC 性能**。如果没有分代,那所有的对象都在一块,就如同把一个学校的人都关在一个教室。 GC 的时候要找到哪些对象没用,这样就会对堆的所有区域进行扫描。而很多对象都是朝生夕死的,如果分代的话,把新创建的对象放到某一地方,当 GC 的时候先把这块存储“朝生夕死”对象的区域进行回收,这样就会腾出很大的空间出来。 + +![image-20200707101543871](https://gitee.com/xlshi/blog_img/raw/master/img/20201009153714.png) + +## 内存分配策略 + +如果对象在 Eden 出生并经过第一次 Minor GC 后仍然存活,并且能被 Survivor 容纳的话,将被移动到 Survivor 空间中,并将对象年龄设为1。对象在 Survivor 区中每熬过一次 Minor GC ,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁,其实每个 JVM 、每个 GC 都有所不同)时,就会被晋升到老年代 + +对象晋升老年代的年龄阀值,可以通过选项 **-XX:MaxTenuringThreshold** 来设置 + +针对不同年龄段的对象分配原则如下所示: + +- 优先分配到 Eden + - 开发中比较长的字符串或者数组,会直接存在老年代,但是因为新创建的对象都是朝生夕死的,所以这个大对象可能也很快被回收,但是因为老年代触发 Major GC 的次数比 Minor GC 要更少,因此可能回收起来就会比较慢 +- 大对象直接分配到老年代 + - 尽量避免程序中出现过多的大对象 +- 长期存活的对象分配到老年代 +- 动态对象年龄判断 + - 如果 Survivor 区中相同年龄的所有对象大小的总和大于 Survivor 空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代,无须等到 MaxTenuringThreshold 中要求的年龄。 + +- 空间分配担保: **-XX:HandlePromotionFailure** + - 也就是经过 Minor GC 后,所有的对象都存活,因为 Survivor 比较小,所以就需要将 Survivor 无法容纳的对象,存放到老年代中。 + +## 为对象分配内存:TLAB + +### 问题:堆空间都是共享的么? + +不一定,因为还有 TLAB 这个概念,在堆中划分出一块区域,为每个**线程**所独占 + +### 为什么有 TLAB? + +TLAB:Thread Local Allocation Buffer,也就是为每个线程单独分配了一个缓冲区 + +- 堆区是线程共享区域,任何线程都可以访问到堆区中的共享数据 + +- 由于对象实例的创建在 JVM 中非常频繁,因此在并发环境下从堆区中划分内存空间是线程不安全的 + +- 为避免多个线程操作同一地址,需要使用加锁等机制,进而影响分配速度。 + +### 什么是 TLAB + +- 从内存模型而不是垃圾收集的角度,对 Eden 区域继续进行划分, JVM 为**每个线程分配了一个私有缓存区域**,它包含在 Eden 空间内。 + +- 多线程同时分配内存时,使用 TLAB 可以避免一系列的非线程安全问题,同时还能够提升内存分配的吞吐量,因此我们可以将这种内存分配方式称之为**快速分配策略**。 + +- 据我所知所有 OpenJDK 衍生出来的 JVM 都提供了 TLAB 的设计。 + +![image-20200707103547712](https://gitee.com/xlshi/blog_img/raw/master/img/20201009154426.png) + +**说明:** + +- 尽管不是所有的对象实例都能够在 TLAB 中成功分配内存,但 **JVM 确实是将 TLAB 作为内存分配的首选**。 + +- 在程序中,开发人员可以通过选项“-XX:UseTLAB”设置是否开启 TLAB 空间。 + +- 默认情况下,TLAB 空间的内存非常小,**仅占有整个 Eden 空间的1%**,当然我们可以通过选项“-XX:TLABWasteTargetPercent”设置 TLAB 空间所占用 Eden 空间的百分比大小。 + +- 一旦对象在 TLAB 空间分配内存失败时,JVM 就会尝试着通过**使用加锁机制**确保数据操作的原子性,从而直接在 Eden 空间中分配内存。 + +### TLAB分配过程 + +对象首先是通过 TLAB 开辟空间,如果不能放入,那么需要通过 Eden 来进行分配 + +![image-20200707104253530](https://gitee.com/xlshi/blog_img/raw/master/img/20201009154501.png) + +## 小结堆空间的参数设置 + +- -XX:+PrintFlagsInitial:查看所有的参数的默认初始值 +- -XX:+PrintFlagsFinal:查看所有的参数的最终值(可能会存在修改,不再是初始值) +- -Xms:初始堆空间内存(默认为物理内存的1/64) +- -Xmx:最大堆空间内存(默认为物理内存的1/4) +- -Xmn:设置新生代的大小。(初始值及最大值) +- -XX:NewRatio:配置新生代与老年代在堆结构的占比 + +- -XX:SurvivorRatio:设置新生代中Eden和S0/S1空间的比例 +- -XX:MaxTenuringThreshold:设置新生代垃圾的最大年龄 +- -XX:+PrintGCDetails:输出详细的GC处理日志 + - 打印gc简要信息:①-Xx:+PrintGC ② - verbose:gc +- -XX:HandlePromotionFalilure:是否设置空间分配担保 + +在发生 Minor GC 之前,虚拟机会**检查老年代最大可用的连续空间是否大于新生代所有对象的总空间**。 + +- 如果大于,则此次 Minor GC 是安全的 +- 如果小于,则虚拟机会查看 -XX:HandlePromotionFailure 设置值是否允担保失败。 + - 如果 HandlePromotionFailure=true ,那么会**继续检查老年代最大可用连续空间是否大于历次晋升到老年代的对象的平均大小**。 + - 如果大于,则尝试进行一次 Minor GC ,但这次 Minor GC 依然是有风险的; + - 如果小于,则改为进行一次 Full GC 。 + - 如果 HandlePromotionFailure=false,则改为进行一次 Full GC 。 + +在 JDK 6 Update24 之后,HandlePromotionFailure 参数不会再影响到虚拟机的空间分配担保策略,观察 OpenJDK 中的源码变化,虽然源码中还定义了 HandlePromotionFailure 参数,但是在代码中已经不会再使用它。 JDK6 Update24 之后的规则变为**只要老年代的连续空间大于新生代对象总大小**或者**历次晋升的平均大小就会进行 Minor GC** ,否则将进行 Full GC 。 + +## 堆是分配对象的唯一选择么? + +### 逃逸分析 + +在《深入理解Java虚拟机》中关于 Java 堆内存有这样一段描述: + +随着 JIT 编译期的发展与**逃逸分析技术**逐渐成熟,**栈上分配、标量替换优化技术**将会导致一些微妙的变化,所有的对象都分配到堆上也渐渐变得不那么“绝对”了。 + +在 Java 虚拟机中,对象是在 Java 堆中分配内存的,这是一个普遍的常识。但是,有一种特殊情况,那就是**如果经过逃逸分析(Escape Analysis)后发现,一个对象并没有逃逸出方法的话,那么就可能被优化成栈上分配。**这样就无需在堆上分配内存,也无须进行垃圾回收了。这也是最常见的堆外存储技术。 + +此外,前面提到的基于 OpenJDK 深度定制的 TaoBao VM ,其中创新的 GCIH(GC Invisible Heap)技术实现Off-Heap,将生命周期较长的 Java 对象从 Heap 中移至 Heap 外,并且 GC 不能管理 GCIH 内部的 Java 对象,以此达到降低 GC 的回收频率和提升 GC 的回收效率的目的。 + +- 如何将堆上的对象分配到栈,需要使用逃逸分析手段。 + +- 这是一种可以有效减少 Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。 +- 通过逃逸分析, Java HotSpot 编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。 +- 逃逸分析的基本行为就是分析对象动态作用域: + - 当一个对象在方法中被定义后,对象只在方法内部使用,则认为没有发生逃逸。 + - 当一个对象在方法中被定义后,它被外部方法所引用,则认为发生逃逸。例如作为调用参数传递到其他地方中。 + +如何快速的判断是否发生了逃逸分析,就看 new 的对象是否在方法外被调用。 + +#### 逃逸分析举例 + +没有发生逃逸的对象,则可以分配到栈上,随着方法执行的结束,栈空间就被移除,每个栈里面包含了很多栈帧,也就是发生逃逸分析 + +针对下面的代码 + +```java +public static StringBuffer createStringBuffer(String s1, String s2) { + StringBuffer sb = new StringBuffer(); + sb.append(s1); + sb.append(s2); + return sb; +} +``` + +如果想要 StringBuffer sb 不发生逃逸,可以这样写 + +```java +public static String createStringBuffer(String s1, String s2) { + StringBuffer sb = new StringBuffer(); + sb.append(s1); + sb.append(s2); + return sb.toString(); +} +``` + +完整的逃逸分析代码举例 + +```java +public class EscapeAnalysis { + + public EscapeAnalysis obj; + + /** + * 方法返回EscapeAnalysis对象,发生逃逸 + * @return + */ + public EscapeAnalysis getInstance() { + return obj == null ? new EscapeAnalysis():obj; + } + + /** + * 为成员属性赋值,发生逃逸 + */ + public void setObj() { + this.obj = new EscapeAnalysis(); + } + + /** + * 对象的作用于仅在当前方法中有效,没有发生逃逸 + */ + public void useEscapeAnalysis() { + EscapeAnalysis e = new EscapeAnalysis(); + } + + /** + * 引用成员变量的值,发生逃逸 + */ + public void useEscapeAnalysis2() { + EscapeAnalysis e = getInstance(); + // getInstance().XXX 发生逃逸 + } +} +``` + +#### 参数设置 + +在 JDK 6u23 版本之后, HotSpot 中默认就已经开启了逃逸分析 + +如果使用的是较早的版本,开发人员则可以通过: + +- 选项 "-XX:+DoEscapeAnalysis" 显式开启逃逸分析 +- 通过选项 "-XX:+PrintEscapeAnalysis" 查看逃逸分析的筛选结果 + +#### 结论 + +**开发中能使用局部变量的,就不要使用在方法外定义。** + +使用逃逸分析,编译器可以对代码做如下优化: + +- **栈上分配:**将堆分配转化为栈分配。如果一个对象在子程序中被分配,要使指向该对象的指针永远不会发生逃逸,对象可能是栈上分配的候选,而不是堆上分配 +- **同步省略:**如果一个对象被发现只有一个线程被访问到,那么对于这个对象的操作可以不考虑同步。 +- **分离对象或标量替换:**有的对象可能不需要作为一个连续的内存结构存在也可以被访问到,那么对象的部分(或全部)可以不存储在内存,而是存储在 CPU 寄存器中。 + +### 栈上分配 + + JIT 编译器在编译期间根据逃逸分析的结果,发现如果一个对象并没有逃逸出方法的话,就可能被优化成栈上分配。分配完成后,继续在调用栈内执行,最后线程结束,栈空间被回收,局部变量对象也被回收。这样就无须进行垃圾回收了。 + +常见的栈上分配的场景: + +> 在逃逸分析中,已经说明了。分别是给成员变量赋值、方法返回值、实例引用传递。 + +#### 举例 + +我们通过举例来说明 开启逃逸分析和未开启逃逸分析时候的情况 + +```java +class User { + private String name; + private String age; + private String gender; + private String phone; +} + +public class StackAllocation { + public static void main(String[] args) throws InterruptedException { + long start = System.currentTimeMillis(); + for (int i = 0; i < 100000000; i++) { + alloc(); + } + long end = System.currentTimeMillis(); + System.out.println("花费的时间为:" + (end - start) + " ms"); + + // 为了方便查看堆内存中对象个数,线程sleep + Thread.sleep(10000000); + } + + private static void alloc() { + User user = new User(); + } +} +``` + +设置 JVM 参数,表示未开启逃逸分析 + +``` +-Xmx1G -Xms1G -XX:-DoEscapeAnalysis -XX:+PrintGCDetails +``` + +运行结果,同时还触发了 GC 操作 + +``` +花费的时间为:664 ms +``` + +然后查看内存的情况,发现有大量的 User 存储在堆中 + +![image-20200707203038615](images/image-20200707203038615.png) + + + +我们再开启逃逸分析 + +``` +-Xmx1G -Xms1G -XX:+DoEscapeAnalysis -XX:+PrintGCDetails +``` + +然后查看运行时间,我们能够发现花费的时间快速减少,同时不会发生 GC 操作 + +``` +花费的时间为:5 ms +``` + +然后再看内存情况,我们发现只有很少的 User 对象,说明 User 发生了逃逸,因为他们存储在栈中,随着栈的销毁而消失 + +![image-20200707203441718](images/image-20200707203441718.png) + +### 同步省略 + +线程同步的代价是相当高的,同步的后果是降低并发性和性能。 + +在动态编译同步块的时候, JIT 编译器可以借助逃逸分析来**判断同步块所使用的锁对象是否只能够被一个线程访问而没有被发布到其他线程**。如果没有,那么 JIT 编译器在编译这个同步块的时候就会取消对这部分代码的同步。这样就能大大提高并发性和性能。这个取消同步的过程就叫同步省略,也叫**锁消除**。 + +例如下面的代码 + +```java +public void f() { + Object hellis = new Object(); + synchronized(hellis) { + System.out.println(hellis); + } +} +``` + +代码中对 hellis 这个对象加锁,但是 hellis 对象的生命周期只在 f() 方法中,并不会被其他线程所访问到,所以在JIT编译阶段就会被优化掉,优化成: + +```java +public void f() { + Object hellis = new Object(); + System.out.println(hellis); +} +``` + +我们将其转换成字节码 + +![image-20200707205634266](https://gitee.com/xlshi/blog_img/raw/master/img/20201009160845.png) + +### 分离对象和标量替换 + +**标量(Scalar)**是指一个无法再分解成更小的数据的数据。 Java 中的原始数据类型就是标量。 + +相对的,那些还可以分解的数据叫做**聚合量(Aggregate)**, Java 中的对象就是聚合量,因为他可以分解成其他聚合量和标量。 + +在 JIT 阶段,如果经过逃逸分析,发现一个对象不会被外界访问的话,那么经过 JIT 优化,就会把这个对象拆解成若干个其中包含的若干个成员变量来代替。这个过程就是**标量替换**。 + +```java +public static void main(String args[]) { + alloc(); +} + +class Point { + private int x; + private int y; +} + +private static void alloc() { + Point point = new Point(1,2); + System.out.println("point.x" + point.x + ";point.y" + point.y); +} +``` + +以上代码,经过标量替换后,就会变成 + +```java +private static void alloc() { + int x = 1; + int y = 2; + System.out.println("point.x = " + x + "; point.y=" + y); +} +``` + +可以看到,Point 这个聚合量经过逃逸分析后,发现他并没有逃逸,就被替换成两个聚合量了。那么标量替换有什么好处呢?就是可以大大减少堆内存的占用。因为一旦不需要创建对象了,那么就不再需要分配堆内存了。 +标量替换为栈上分配提供了很好的基础。 + +### 标量替换 + +```java +public class StackAllocation { + public static void main(String[] args) { + long start = System.currentTimeMillis(); + + for (int i = 0; i < 100000000; i++) { + alloc(); + } + // 查看执行时间 + long end = System.currentTimeMillis(); + System.out.println("花费的时间为: " + (end - start) + " ms"); + // 为了方便查看堆内存中对象个数,线程sleep + try { + Thread.sleep(1000000); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + + private static void alloc() { + User user = new User();//未发生逃逸 + } + + static class User { + + } +} +``` + +上述代码在主函数中进行了1亿次 alloc 。调用进行对象创建,由于 User 对象实例需要占据约16字节的空间,因此累计分配空间达到将近1.5GB。如果堆空间小于这个值,就必然会发生 GC 。使用如下参数运行上述代码: + +```bash +-server -Xmx100m -Xms100m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:+EliminateAllocations +``` + +这里设置参数如下: + +- 参数 -server:启动 Server 模式,因为在 Server 模式下,才可以启用逃逸分析。 +- 参数 -XX:+DoEscapeAnalysis:启用逃逸分析 +- 参数 -Xmx10m:指定了堆空间最大为10MB +- 参数 -XX:+PrintGC:将打印 GC 日志。 +- 参数 -XX:+EliminateAllocations:开启了标量替换(默认打开),允许将对象打散分配在栈上,比如对象拥有 id 和 name 两个字段,那么这两个字段将会被视为两个独立的局部变量进行分配 + +### 逃逸分析的不足 + +关于逃逸分析的论文在1999年就已经发表了,但直到 JDK 1.6 才有实现,而且这项技术到如今也并不是十分成熟的。 + +其根本原因就是**无法保证逃逸分析的性能消耗一定能高于他的消耗。虽然经过逃逸分析可以做标量替换、栈上分配、和锁消除。但是逃逸分析自身也是需要进行一系列复杂的分析的,这其实也是一个相对耗时的过程。** + +一个极端的例子,就是经过逃逸分析之后,发现没有一个对象是不逃逸的。那这个逃逸分析的过程就白白浪费掉了。 + +虽然这项技术并不十分成熟,但是它也是**即时编译器优化技术中一个十分重要的手段**。 + +注意到有一些观点,认为通过逃逸分析, JVM 会在栈上分配那些不会逃逸的对象,这在理论上是可行的,但是取决于 JVM 设计者的选择。据我所知, Oracle HotSpot JVM 中并未这么做,这一点在逃逸分析相关的文档里已经说明,所以可以明确所有的对象实例都是创建在堆上。 + +目前很多书籍还是基于 JDK 7 以前的版本, JDK 已经发生了很大变化,intern 字符串的缓存和静态变量曾经都被分配在永久代上,而永久代已经被元数据区取代。但是,intern 字符串缓存和静态变量并不是被转移到元数据区,而是直接在堆上分配,所以这一点同样符合前面一点的结论:**对象实例都是分配在堆上**。 + +## 小结 + +- 年轻代是对象的诞生、成长、消亡的区域,一个对象在这里产生、应用,最后被垃圾回收器收集、结束生命。 + +- 老年代放置长生命周期的对象,通常都是从 Survivor 区域筛选拷贝过来的 Java 对象。当然,也有特殊情况,我们知道普通的对象会被分配在 TLAB 上;如果对象较大,JVM 会试图直接分配在 Eden 其他位置上;如果对象太大,完全无法在新生代找到足够长的连续空闲空间,JVM 就会直接分配到老年代。 +- 当 GC 只发生在年轻代中,回收年轻代对象的行为被称为 Minor GC 。当 GC 发生在老年代时则被称为 Major GC 或者 Full GC 。一般的,Minor GC 的发生频率要比 Major GC 高很多,即老年代中垃圾回收发生的频率将大大低于年轻代。 \ No newline at end of file diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706195127740.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706195127740.png" new file mode 100644 index 0000000000000000000000000000000000000000..eb948c7f8f79bfa9acb2a8ab1c0acee6848d0e09 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706195127740.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706200739392.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706200739392.png" new file mode 100644 index 0000000000000000000000000000000000000000..ae1070ed8e8f0bc97010cde56e50f242f0f438f5 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706200739392.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706201904057.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706201904057.png" new file mode 100644 index 0000000000000000000000000000000000000000..6a09ca7114005fe3751fe658de1f8d84ffb7cb33 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706201904057.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706203419496.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706203419496.png" new file mode 100644 index 0000000000000000000000000000000000000000..e0b70eb6733cf757cc72405948da1509c18f891a Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706203419496.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706203835403.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706203835403.png" new file mode 100644 index 0000000000000000000000000000000000000000..41e9f0b8bc261ffde3867f6ee596570f3e709cf2 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706203835403.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706205756045.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706205756045.png" new file mode 100644 index 0000000000000000000000000000000000000000..ff56cc3f9183223145cd86e7b523048389d4bd6f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706205756045.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706205821919.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706205821919.png" new file mode 100644 index 0000000000000000000000000000000000000000..7ad070cd89ca3a32b8a3fc6ae5d48bc3e81a9775 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706205821919.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706205947535.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706205947535.png" new file mode 100644 index 0000000000000000000000000000000000000000..13f2b50ada8554db30d53e35038eadab4bb6ff9d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706205947535.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706210000461.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706210000461.png" new file mode 100644 index 0000000000000000000000000000000000000000..1ffc7b4adc2ca5be99067633df65d99c40bd7ecd Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706210000461.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706211652779.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706211652779.png" new file mode 100644 index 0000000000000000000000000000000000000000..51c0a12aa2545b9c4662802a89cf59dde1968b46 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200706211652779.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707075847954.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707075847954.png" new file mode 100644 index 0000000000000000000000000000000000000000..0f2e24fca45e2b29f98daff528828aacd3e0979e Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707075847954.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707080154039.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707080154039.png" new file mode 100644 index 0000000000000000000000000000000000000000..c94dc8ca2af632fe655950a7cecd1c23175170eb Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707080154039.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707084208115.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707084208115.png" new file mode 100644 index 0000000000000000000000000000000000000000..5b748a534de147c7818ccb2f4e4696c4fdc7f45a Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707084208115.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707084714886.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707084714886.png" new file mode 100644 index 0000000000000000000000000000000000000000..4a4f49ff8c3b95828cceaddb00eb1779b0344630 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707084714886.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707085232646.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707085232646.png" new file mode 100644 index 0000000000000000000000000000000000000000..0bd98fb3ad522048b464b5ef7c82e7e4178c16b6 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707085232646.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707085737207.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707085737207.png" new file mode 100644 index 0000000000000000000000000000000000000000..5acad410c24de8893cee8b9b933ddd47b7aee2b9 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707085737207.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707091058346.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707091058346.png" new file mode 100644 index 0000000000000000000000000000000000000000..ce81bab9b1a612885975bed9cd62dfc1df1b17e6 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707091058346.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707095606813.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707095606813.png" new file mode 100644 index 0000000000000000000000000000000000000000..758562e86b332f6c6706d8e7e34996c9f7174f4a Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707095606813.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707101511025.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707101511025.png" new file mode 100644 index 0000000000000000000000000000000000000000..1c7171de26da3bf6fdc272bfbc88f96e9a127c3b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707101511025.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707101543871.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707101543871.png" new file mode 100644 index 0000000000000000000000000000000000000000..d89c3be11adae7f3de1c225e22d4f53922eafcb7 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707101543871.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707103547712.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707103547712.png" new file mode 100644 index 0000000000000000000000000000000000000000..ef9e3f25274bcbf2e635ee5ba03c00ecde721f85 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707103547712.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707104253530.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707104253530.png" new file mode 100644 index 0000000000000000000000000000000000000000..579fa52ed382fff71f24e9ee6bcd17a16a0a3f7d Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707104253530.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707203038615.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707203038615.png" new file mode 100644 index 0000000000000000000000000000000000000000..7a4a78a6268d5b90ef272a12ef09481948125a9f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707203038615.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707203441718.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707203441718.png" new file mode 100644 index 0000000000000000000000000000000000000000..92be692a45c65b2e96add06a182b6ad8907b68df Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707203441718.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707205634266.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707205634266.png" new file mode 100644 index 0000000000000000000000000000000000000000..1976a09c7fb2a970a8a6757aa82b2e82ecc2b2e1 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/image-20200707205634266.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/\345\236\203\345\234\276\345\233\236\346\224\266.gif" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/\345\236\203\345\234\276\345\233\236\346\224\266.gif" new file mode 100644 index 0000000000000000000000000000000000000000..6727100e34232690f48a16733d305015c6a1d199 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/8_\345\240\206/images/\345\236\203\345\234\276\345\233\236\346\224\266.gif" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/README.md" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a027b499ba6df489d377519ce4a7e2a070c9ded2 --- /dev/null +++ "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/README.md" @@ -0,0 +1,494 @@ +# 方法区 + +## 栈、堆、方法区的交互关系 + +这次所讲述的是运行时数据区的最后一个部分——方法区 + +![image-20200708093918121](https://gitee.com/xlshi/blog_img/raw/master/img/20201009161540.png) + +从线程共享与否的角度来看 + +![image-20200708094507624](https://gitee.com/xlshi/blog_img/raw/master/img/20201009161543.png) + +ThreadLocal:如何保证多个线程在并发环境下的安全性?典型应用就是数据库连接管理,以及会话管理 + +## 栈、堆、方法区的交互关系 + +下面就涉及了对象的访问定位 + +![image-20200708094747667](https://gitee.com/xlshi/blog_img/raw/master/img/20201009161601.png) + +- Person:存放在元空间,也可以说方法区 +- person:存放在 Java 栈的局部变量表中 +- new Person():存放在 Java 堆中 + +## 方法区的理解 + +《Java虚拟机规范》中明确说明:“尽管所有的方法区在逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。”但对于 HotSpot JVM 而言,方法区还有一个别名叫做 Non-Heap(非堆),目的就是要和堆分开。 + +所以,**方法区看作是一块独立于 Java 堆的内存空间。** + +![image-20200708095853544](https://gitee.com/xlshi/blog_img/raw/master/img/20201009161711.png) + +方法区主要存放的是 Class ,而堆中主要存放的是实例化的对象 + +- 方法区(Method Area)与 Java 堆一样,是各个线程共享的内存区域。 +- 方法区在 JVM 启动的时候被创建,并且它的实际的物理内存空间中和 Java 堆区一样都可以是不连续的(逻辑上连续,物理上可以不连续)。 +- 方法区的大小,跟堆空间一样,可以选择固定大小或者可扩展。 +- 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出错误:java.lang.OutOfMemoryError:**PermGen space** 或者 java.lang.OutOfMemoryError:**Metaspace** + - 加载大量的第三方的 jar 包 + - Tomcat 部署的工程过多(30~50个) + - 大量动态的生成反射类 +- 关闭 JVM 就会释放这个区域的内存。 + +### HotSpot 中方法区的演进 + +在 JDK 7 及以前,习惯上把方法区,称为永久代。 JDK 8 开始,使用元空间取代了永久代。 + +- JDK 1.8 后,元空间存放在堆外内存中(In JDK 8, classes metadata is now stored in the **native heap** and this space is called **Metaspace**.) + +本质上,方法区和永久代并不等价,仅是对 HotSpot 而言的。《Java虚拟机规范》对如何实现方法区,不做统一要求。例如:BEAJRockit / IBM J9 中不存在永久代的概念。 +>现在来看,当年使用永久代,不是好的idea。导致 Java 程序更容易 OOM (超过-XX:MaxPermsize上限) + +![image-20200708102919149](https://gitee.com/xlshi/blog_img/raw/master/img/20201009161858.png) + +而到了 JDK 8 ,终于完全废弃了永久代的概念,改用与 JRockit、J9 一样在**本地内存**中实现的元空间(Metaspace)来代替 + +![image-20200708103055914](https://gitee.com/xlshi/blog_img/raw/master/img/20201009161906.png) + +元空间的本质和永久代类似,都是对 JVM 规范中方法区的实现。不过元空间与永久代最大的区别在于:**元空间不在虚拟机设置的内存中,而是使用本地内存** + +永久代、元空间二者并不只是名字变了,内部结构也调整了 + +根据《Java虚拟机规范》的规定,如果方法区无法满足新的内存分配需求时,将抛出 OOM 异常 + +## 设置方法区大小与 OOM + +方法区的大小不必是固定的, JVM 可以根据应用的需要动态调整。 + +### JDK 7 及以前 + +- **通过 -XX:PermSize 来设置永久代初始分配空间。默认值是20.75M** +- **-XX:MaxPermSize 来设定永久代最大可分配空间。32位机器默认是64M,64位机器模式是82M** +- 当 JVM 加载的类信息容量超过了这个值,会报异常 OutOfMemoryError:PermGen space。 + +![image-20200708111756800](https://gitee.com/xlshi/blog_img/raw/master/img/20201009162349.png) + +### JDK 8 以后 + +元数据区大小可以使用参数 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 指定 + +默认值依赖于平台。**windows下,-XX:MetaspaceSize 是21M,-XX:MaxMetaspaceSize 的值是-1,即没有限制。** + +与永久代不同,如果不指定大小,默认情况下,虚拟机会耗尽所有的可用系统内存。如果元数据区发生溢出,虚拟机一样会抛出异常 OutOfMemoryError:Metaspace + +-XX:MetaspaceSize:设置初始的元空间大小。对于一个64位的服务器端 JVM 来说,其默认的 -XX:MetaspaceSize 值为21MB。这就是初始的高水位线,一旦触及这个水位线,Full GC 将会被触发并卸载没用的类(即这些类对应的类加载器不再存活)然后这个高水位线将会重置。新的高水位线的值取决于 GC 后释放了多少元空间。如果释放的空间不足,那么在不超过 MaxMetaspaceSize 时,适当提高该值。如果释放空间过多,则适当降低该值。 + +如果初始化的高水位线设置过低,上述高水位线调整情况会发生很多次。通过垃圾回收器的日志可以观察到 Full GC 多次调用。为了避免频繁地 GC ,建议将 -XX:MetaspaceSize 设置为一个相对较高的值。 + +```java +public class OOMTest extends ClassLoader { + public static void main(String[] args) { + int j = 0; + try { + OOMTest test = new OOMTest(); + for (int i = 0; i < 10000; i++) { + //创建ClassWriter对象,用于生成类的二进制字节码 + ClassWriter classWriter = new ClassWriter(0); + //指明版本号,public,类名,包名,父类,接口 + classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Class" + i, null, "java/lang/Object", null); + byte[] code = classWriter.toByteArray(); + //类的加载 + test.defineClass("Class" + i, code, 0, code.length); + j++; + } + } finally { + System.out.println(j); + } + } +} +``` + +运行结果: + +![image-20201009163450844](https://gitee.com/xlshi/blog_img/raw/master/img/20201009163452.png) + +### 如何解决这些 OOM + +- 要解决 OOM 异常或 Heap Space 的异常,一般的手段是首先通过内存映像分析工具(如 Eclipse Memory Analyzer)对 dump 出来的堆转储快照进行分析,重点是确认内存中的对象是否是必要的,也就是要先分清楚到底是出现了内存泄漏(Memory Leak)还是内存溢出(Memory Overflow) + - 内存泄漏就是有大量的引用指向某些对象,但是这些对象以后不会使用了,但是因为它们还和 GC ROOT 有关联,所以导致以后这些对象也不会被回收,这就是内存泄漏的问题 + - 内存泄漏得不到解决,从而占据满整个内存空间就会造成内存溢出 + +- 如果是内存泄漏,可进一步通过工具查看泄漏对象到 GC Roots 的引用链。于是就能找到泄漏对象是通过怎样的路径与 GC Roots 相关联并导致垃圾收集器无法自动回收它们的。掌握了泄漏对象的类型信息,以及 GC Roots 引用链的信息,就可以比较准确地定位出泄漏代码的位置。 + +- 如果不存在内存泄漏,换句话说就是内存中的对象确实都还必须存活着,那就应当检查虚拟机的堆参数(-Xmx 与 -Xms ),与机器物理内存对比看是否还可以调大,从代码上检查是否存在某些对象生命周期过长、持有状态时间过长的情况,尝试减少程序运行期的内存消耗。 + +## 方法区的内部结构 + +![image-20200708161728320](https://gitee.com/xlshi/blog_img/raw/master/img/20201009163702.png) + +《深入理解Java虚拟机》书中对方法区(Method Area)存储内容描述如下:它用于存储已被虚拟机加载的**类型信息、常量、静态变量、即时编译器编译后的代码缓存等。** + +![image-20200708161856504](https://gitee.com/xlshi/blog_img/raw/master/img/20201009163705.png) + +### 类型信息 + +对每个加载的类型(类class、接口interface、枚举enum、注解annotation),JVM 必须在方法区中存储以下类型信息: + +- 这个类型的完整有效名称(全名=包名.类名) +- 这个类型直接父类的完整有效名(对于interface或是java.lang.object,都没有父类) +- 这个类型的修饰符(public,abstract,final的某个子集) +- 这个类型直接接口的一个有序列表 + +### 域(Field)信息 + +JVM 必须在方法区中保存类型的所有域的相关信息以及域的声明顺序。 + +域的相关信息包括:域名称、域类型、域修饰符(public,private,protected,static,final,volatile,transient 的某个子集) + +### 方法(Method)信息 + +JVM 必须保存所有方法的以下信息,同域信息一样包括声明顺序: + +- 方法名称 +- 方法的返回类型(或 void ) +- 方法参数的数量和类型(按顺序) +- 方法的修饰符(public,private,protected,static,final,synchronized,native,abstract的一个子集) +- 方法的字节码(bytecodes)、操作数栈、局部变量表及大小(abstract和native方法除外) +- 异常表(abstract和native方法除外) + - 每个异常处理的开始位置、结束位置、代码处理在程序计数器中的偏移地址、被捕获的异常类的常量池索引 + +### Non-Final 的类变量 + +静态变量和类关联在一起,随着类的加载而加载,他们成为类数据在逻辑上的一部分 + +类变量被类的所有实例共享,即使没有类实例时,你也可以访问它 + +```java +public class MethodAreaTest { + public static void main(String[] args) { + Order order = null; + order.hello(); + System.out.println(order.count); + } +} + +class Order { + public static int count = 1; + + public static void hello() { + System.out.println("Hello!"); + } +} +``` + +运行结果: + +``` +Hello! +1 +``` + +如上代码所示,即使我们把 order 设置为 null ,也不会出现空指针异常 + +### 全局常量 + +全局常量就是使用 static final 进行修饰 + +被声明为 final 的类变量的处理方法则不同,每个全局常量在编译的时候就会被分配了。 + +### 运行时常量池 VS 常量池 + +运行时常量池,就是运行时常量池 + +![image-20200708171151384](https://gitee.com/xlshi/blog_img/raw/master/img/20201009164843.png) + +- 方法区,内部包含了运行时常量池 +- 字节码文件,内部包含了常量池 +- 要弄清楚方法区,需要理解清楚 ClassFile ,因为加载类的信息都在方法区。 +- 要弄清楚方法区的运行时常量池,需要理解清楚 ClassFile 中的常量池。 + +### 常量池 + +![image-20200708172357052](https://gitee.com/xlshi/blog_img/raw/master/img/20201009170851.png) + +一个有效的字节码文件中除了包含类的版本信息、字段、方法以及接口等描述符信息外,还包含一项信息就是常量池表(Constant Pool Table),包括各种字面量和对类型、域和方法的符号引用 + +#### 为什么需要常量池 + +一个 Java 源文件中的类、接口,编译后产生一个字节码文件。而 Java 中的字节码需要数据支持,通常这种数据会很大以至于不能直接存到字节码里,换另一种方式,可以存到常量池,这个字节码包含了指向常量池的引用。r在动态链接的时候会用到运行时常量池,之前有介绍。 + +比如:如下的代码: + +```java +public class SimpleClass { + public void sayHello() { + System.out.println("hello"); + } +} +``` + +虽然上述代码只有194字节,但是里面却使用了 String、System、PrintStream 及 Object 等结构。这里的代码量其实很少了,如果代码多的话,引用的结构将会更多,这里就需要用到常量池了。 + +#### 常量池中有什么 + +**几种在常量池内存存储的数据类型包括:** + +- 数量值 +- 字符串值 +- 类引用 +- 字段引用 +- 方法引用 + +例如下面这段代码 + +```java +public class MethodAreaTest2 { + public static void main(String args[]) { + Object obj = new Object(); + } +} +``` + +`Object obj = new Object();`将会被翻译成如下字节码 + +```bash +new #2 //Class java/lang/Object +dup +invokespecial //Method java/lang/Object ""()V +``` + +#### 小结 + +常量池、可以看做是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等类型 + +### 运行时常量池 + +- 运行时常量池(Runtime Constant Pool)是方法区的一部分。 + +- 常量池表(Constant Pool Table)是 Class 文件的一部分,**用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。** + +- 运行时常量池,在加载类和接口到虚拟机后,就会创建对应的运行时常量池。 + +- JVM 为每个已加载的类型(类或接口)都维护一个常量池。池中的数据项像数组项一样,是通过**索引访问**的。 + +- 运行时常量池中包含多种不同的常量,包括编译期就已经明确的数值字面量,也包括到运行期解析后才能够获得的方法或者字段引用。此时不再是常量池中的符号地址了,这里换为真实地址。 + - 运行时常量池,相对于 Class 文件常量池的另一重要特征是:**具备动态性**。 + - String.intern() + +- 运行时常量池类似于传统编程语言中的符号表(Symbol Table),但是它所包含的数据却比符号表要更加丰富一些。 + +- 当创建类或接口的运行时常量池时,如果构造运行时常量池所需的内存空间超过了方法区所能提供的最大值,则 JVM 会抛 OutOfMemoryError 异常。 + +## 方法区使用举例 + +如下代码 + +```java +public class MethodAreaDemo { + public static void main(String args[]) { + int x = 500; + int y = 100; + int a = x / y; + int b = 50; + System.out.println(a+b); + } +} +``` + +字节码执行过程展示 + +![image-20200708204750374](https://gitee.com/xlshi/blog_img/raw/master/img/20201009173956.png) + +首先现将操作数500放入到操作数栈中 + +![image-20200708204953552](https://gitee.com/xlshi/blog_img/raw/master/img/20201009173954.png) + +然后存储到局部变量表中 + +![image-20200708205029376](https://gitee.com/xlshi/blog_img/raw/master/img/20201009173950.png) + +然后重复一次,把100放入局部变量表中,最后再将变量表中的500和100取出,进行操作 + +![image-20200708205221737](https://gitee.com/xlshi/blog_img/raw/master/img/20201009173950.png) + +将500和100进行一个除法运算,在把结果入栈 + +![image-20200708205413721](https://gitee.com/xlshi/blog_img/raw/master/img/20201009173949.png) + +在最后就是输出流,需要调用运行时常量池的常量 + +![image-20200708205708057](https://gitee.com/xlshi/blog_img/raw/master/img/20201009173947.png) + +最后调用 invokevirtual(虚方法调用),然后返回 + +![image-20200708205909176](https://gitee.com/xlshi/blog_img/raw/master/img/20201009173946.png) + +返回时 + +![image-20200708210540696](https://gitee.com/xlshi/blog_img/raw/master/img/20201009173944.png) + +程序计数器始终计算的都是当前代码运行的位置,目的是为了方便记录方法调用后能够正常返回,或者是进行了CPU 切换后,也能回来到原来的代码进行执行。 + +## 方法区的演进细节 + +首先明确:只有 HotSpot 才有永久代。BEA JRockit、IBMJ9 等来说,是不存在永久代的概念的。原则上如何实现方法区属于虚拟机实现细节,不受《Java虚拟机规范》管束,并不要求统一 + +HotSpot 中方法区的变化: + +| JDK1.6及以前 | 有永久代,静态变量存储在永久代上 | +| :----------: | ------------------------------------------------------------ | +| **JDK1.7** | **有永久代,但已经逐步 “去永久代”,字符串常量池,静态变量移除,保存在堆中** | +| **JDK1.8** | **无永久代,类型信息,字段,方法,常量保存在本地内存的元空间,但字符串常量池、静态变量仍然在堆中。** | + +JDK 6 的时候 + +![image-20200708211541300](https://gitee.com/xlshi/blog_img/raw/master/img/20201009174318.png) + +JDK 7 的时候 + +![image-20200708211609911](https://gitee.com/xlshi/blog_img/raw/master/img/20201009174316.png) + +JDK 8 的时候,元空间大小只受物理内存影响 + +![image-20200708211637952](https://gitee.com/xlshi/blog_img/raw/master/img/20201009174314.png) + +### 为什么永久代要被元空间替代? + +JRockit 是和 HotSpot 融合后的结果,因为 JRockit 没有永久代,所以他们不需要配置永久代 + +随着 Java 8 的到来,HotSpot VM 中再也见不到永久代了。但是这并不意味着类的元数据信息也消失了。这些数据被移到了一个与**堆不相连的本地内存区域,这个区域叫做元空间(Metaspace)。** + +由于类的元数据分配在本地内存中,元空间的最大可分配空间就是系统可用内存空间,这项改动是很有必要的,原因有: + +- 为永久代设置空间大小是很难确定的。 + +在某些场景下,如果动态加载类过多,容易产生 Perm 区的 OOM 。比如某个实际 Web 工 +程中,因为功能点比较多,在运行过程中,要不断动态加载很多类,经常出现致命错误。 + +“Exception in thread‘dubbo client x.x connector'java.lang.OutOfMemoryError:PermGen space” + +而元空间和永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。 +因此,默认情况下,元空间的大小仅受本地内存限制。 + +- 对永久代进行调优是很困难的。 + - 主要是为了降低 Full GC + +有些人认为方法区(如 HotSpot 虚拟机中的元空间或者永久代)是没有垃圾收集行为的,其实不然。《Java虚拟机规范》对方法区的约束是非常宽松的,提到过可以不要求虚拟机在方法区中实现垃圾收集。事实上也确实有未实现或未能完整实现方法区类型卸载的收集器存在(如 JDK 11 时期的 ZGC 收集器就不支持类卸载)。 +一般来说**这个区域的回收效果比较难令人满意,尤其是类型的卸载,条件相当苛刻**。但是这部分区域的回收有时又确实是必要的。以前 Sun 公司的 Bug 列表中,曾出现过的若干个严重的 Bug 就是由于低版本的 HotSpot 虚拟机对此区域未完全回收而导致内存泄漏 + +方法区的垃圾收集主要回收两部分内容:**常量池中废弃的常量和不在使用的类型** + +### StringTable为什么要调整位置 + +JDK 7 中将 StringTable 放到了堆空间中。因为永久代的回收效率很低,在 Full GC 的时候才会触发。而 Full GC 是老年代的空间不足、永久代不足时才会触发。 + +这就导致 StringTable 回收效率不高。而我们开发中会有大量的字符串被创建,回收效率低,导致永久代内存不足。放到堆里,能及时回收内存。 + +### 静态变量存放在那里? + +静态引用对应的对象实体始终都存在堆空间 + +可以使用 jhsdb.ext,需要在 JDK 9 的时候才引入的 + +```java +public class StaticObject { + static class Test { + static ObjectHolder staticObj = new ObjectHolder(); + ObjectHolder instanceObj = new ObjectHolder(); + + void foo() { + ObjectHolder localObj = new ObjectHolder(); + System.out.println("done"); + } + } + + private static class ObjectHolder { + + } + + public static void main(String[] args) { + Test test = new StaticObjTest.Test(); + test.foo(); + } +} +``` + +staticObj 随着 Test 的类型信息存放在方法区,instanceObj 随着 Test 的对象实例存放在 Java 堆,localObject则是存放在 foo()方法栈帧的局部变量表中。 + +![image-20200708215025527](images/image-20200708215025527.png) + +测试发现:三个对象的数据在内存中的地址都落在 Eden 区范围内,所以结论:只要是对象实例必然会在 Java 堆中分配。 + +接着,找到了一个引用该 staticObj 对象的地方,是在一个 java.lang.Class 的实例里,并且给出了这个实例的地址,通过Inspector查看该对象实例,可以清楚看到这确实是一个 java.lang.Class 类型的对象实例,里面有一个名为 staticObj 的实例字段: + +![image-20200708215218078](https://gitee.com/xlshi/blog_img/raw/master/img/20201009175431.png) + +从《Java虚拟机规范》所定义的概念模型来看,所有 Class 相关的信息都应该存放在方法区之中,但方法区该如何实现,《Java虚拟机规范》并未做出规定,这就成了一件允许不同虚拟机自己灵活把握的事情。JDK 7 及其以后版本的 HotSpot 虚拟机选择把静态变量与类型在 Java 语言一端的映射 Class 对象存放在一起,存储于 Java 堆之中,从我们的实验中也明确验证了这一点 + +## 方法区的垃圾回收 + +有些人认为方法区(如 HotSpot 虚拟机中的元空间或者永久代)是没有垃圾收集行为的,其实不然。《Java虚拟机规范》对方法区的约束是非常宽松的,提到过可以不要求虚拟机在方法区中实现垃圾收集。事实上也确实有未实现或未能完整实现方法区类型卸载的收集器存在(如 JDK 11 时期的 ZGC 收集器就不支持类卸载)。 + +一般来说**这个区域的回收效果比较难令人满意,尤其是类型的卸载,条件相当苛刻。**但是这部分区域的回收**有时又确实是必要**的。以前 Sun 公司的 Bug 列表中,曾出现过的若干个严重的 Bug 就是由于低版本的 HotSpot 虚拟机对此区域未完全回收而导致内存泄漏。 + +**方法区的垃圾收集主要回收两部分内容:常量池中废弃的常量和不再使用的类型。** + +先来说说方法区内常量池之中主要存放的两大类常量:**字面量和符号引用**。字面量比较接近 Java 语言层次的常量概念,如文本字符串、被声明为 final 的常量值等。而符号引用则属于编译原理方面的概念,包括下面三类常量: + +- 类和接口的全限定名 +- 字段的名称和描述符 +- 方法的名称和描述符 + +HotSpot 虚拟机对常量池的回收策略是很明确的,**只要常量池中的常量没有被任何地方引用,就可以被回收**。 + +回收废弃常量与回收 Java 堆中的对象非常类似。(关于常量的回收比较简单,重点是类的回收) + +判定一个常量是否“废弃”还是相对简单,而要判定一个类型是否属于“不再被使用的类”的条件就比较苛刻了。需要同时满足下面三个条件: + +- 该类所有的实例都已经被回收,也就是 Java 堆中不存在该类及其任何派生子类的实例。 +- 加载该类的类加载器已经被回收,这个条件除非是经过精心设计的可替换类加载器的场景,如 OSGi、JSP 的重加载等,否则通常是很难达成的。 +- 该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。 + +Java 虚拟机被允许对满足上述三个条件的无用类进行回收,这里说的仅仅是“被允许”,而并不是和对象一样,没有引用了就必然会回收。关于是否要对类型进行回收,HotSpot 虚拟机提供了 -Xnoclassgc 参数进行控制,还可以使用 -verbose:class 以及 -XX:+TraceClass-Loading、-XX:+TraceClassUnLoading 查看类加载和卸载信息 + +在大量使用反射、动态代理、CGLib 等字节码框架,动态生成 JSP 以及 OSGi 这类频繁自定义类加载器的场景中,通常都需要 Java 虚拟机具备类型卸载的能力,以保证不会对方法区造成过大的内存压力。 + +## 总结 + +![image-20200708220303243](https://gitee.com/xlshi/blog_img/raw/master/img/20201009175509.png) + +### 常见面试题 + +百度 +三面:说一下 JVM 内存模型吧,有哪些区?分别干什么的? + +蚂蚁金服: +Java 8 的内存分代改进 +JVM 内存分哪几个区,每个区的作用是什么? +一面:JVM 内存分布/内存结构?栈和堆的区别?堆的结构?为什么两个 Survivor 区? +二面:Eden 和 Survior 的比例分配 + +小米: +JVM 内存分区,为什么要有新生代和老年代 + +字节跳动: +二面:Java 的内存分区 +二面:讲讲 JVM 运行时数据库区 +什么时候对象会进入老年代? + +京东: +JVM 的内存结构,Eden 和 Survivor 比例。 +JVM 内存为什么要分成新生代,老年代,持久代。新生代中为什么要分为 Eden 和 Survivor 。 + +天猫: +一面:JVM 内存模型以及分区,需要详细到每个区放什么。 +一面:JVM 的内存模型,Java 8 做了什么改 + +拼多多: +JVM 内存分哪几个区,每个区的作用是什么? + +美团: +Java 内存分配 +JVM 的永久代中会发生垃圾回收吗? +一面:JVM 内存分区,为什么要有新生代和老年代? \ No newline at end of file diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708093918121.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708093918121.png" new file mode 100644 index 0000000000000000000000000000000000000000..dd1ff26004feac65d0772532e6904bcb84de671f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708093918121.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708094507624.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708094507624.png" new file mode 100644 index 0000000000000000000000000000000000000000..7712f722077dfe8ade24d1226611c6de6ec0b8e2 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708094507624.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708094747667.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708094747667.png" new file mode 100644 index 0000000000000000000000000000000000000000..1324419b4b7b710acc7411ca577b43adabb8e042 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708094747667.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708095853544.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708095853544.png" new file mode 100644 index 0000000000000000000000000000000000000000..b2cd7ea09ddde88f9bb2a0e0788e6400c2f39cdb Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708095853544.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708102919149.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708102919149.png" new file mode 100644 index 0000000000000000000000000000000000000000..eff863b70b95c51b6bb687b14300173dc6edbcc7 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708102919149.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708103055914.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708103055914.png" new file mode 100644 index 0000000000000000000000000000000000000000..939d84a0a4a203b3cec9156b56a2b1dae625f4ce Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708103055914.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708111756800.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708111756800.png" new file mode 100644 index 0000000000000000000000000000000000000000..cf0e2f356c66909c2eab053fb9f1b187c853be71 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708111756800.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708161728320.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708161728320.png" new file mode 100644 index 0000000000000000000000000000000000000000..5c9935279fa7cbb611eaaa947ed2f4129c4d9bc8 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708161728320.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708161856504.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708161856504.png" new file mode 100644 index 0000000000000000000000000000000000000000..3401d639bba66942474dbb61a89439b751e4ad1a Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708161856504.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708171151384.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708171151384.png" new file mode 100644 index 0000000000000000000000000000000000000000..57a1d9d01ef4c3886a713f963ddb5f6315303107 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708171151384.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708172357052.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708172357052.png" new file mode 100644 index 0000000000000000000000000000000000000000..e67d22230c73907545e926dd2a9c18a1069454ee Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708172357052.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708204750374.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708204750374.png" new file mode 100644 index 0000000000000000000000000000000000000000..f95f9cebf570f0559bde670d816a06dd160fcea8 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708204750374.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708204953552.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708204953552.png" new file mode 100644 index 0000000000000000000000000000000000000000..f3c8ae0437625c78fac96a67596a324d28475f86 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708204953552.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205029376.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205029376.png" new file mode 100644 index 0000000000000000000000000000000000000000..15246ad6f174201ee41db3f73aa7f23f68b4d7a4 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205029376.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205221737.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205221737.png" new file mode 100644 index 0000000000000000000000000000000000000000..e1c174fadd8302f9b45c959f9684cd9d0f70bda7 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205221737.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205413721.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205413721.png" new file mode 100644 index 0000000000000000000000000000000000000000..d6c54aeb2c7c08bd738fbba13065401421b2bd1b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205413721.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205708057.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205708057.png" new file mode 100644 index 0000000000000000000000000000000000000000..cdd8e9f6370831f8b0532f392940a75e8bc8be7a Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205708057.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205909176.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205909176.png" new file mode 100644 index 0000000000000000000000000000000000000000..bbbc1812786a3d5d02bef22412227fd12ea64e7a Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708205909176.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708210536259.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708210536259.png" new file mode 100644 index 0000000000000000000000000000000000000000..50511d6b8ab3fa124b40d765227aee103f05c35f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708210536259.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708210540696.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708210540696.png" new file mode 100644 index 0000000000000000000000000000000000000000..50511d6b8ab3fa124b40d765227aee103f05c35f Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708210540696.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708211541300.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708211541300.png" new file mode 100644 index 0000000000000000000000000000000000000000..fe0e6ead33ae3a9f2ad42ecc6df13d563964f246 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708211541300.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708211609911.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708211609911.png" new file mode 100644 index 0000000000000000000000000000000000000000..7cdadee78470225c0dd2ff26fe3913c362f5993b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708211609911.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708211637952.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708211637952.png" new file mode 100644 index 0000000000000000000000000000000000000000..3cf2a87abc39a442f5ad7d17397ec39c67dafde0 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708211637952.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708215025527.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708215025527.png" new file mode 100644 index 0000000000000000000000000000000000000000..cc3f821e5ba544557277a4166c998a661d3bface Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708215025527.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708215218078.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708215218078.png" new file mode 100644 index 0000000000000000000000000000000000000000..1b5bfe047b204b1666dbdbfc91d4c9421a9ec682 Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708215218078.png" differ diff --git "a/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708220303243.png" "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708220303243.png" new file mode 100644 index 0000000000000000000000000000000000000000..c88aed407352495113a371eba8b8628d2e68890b Binary files /dev/null and "b/JVM/1_\345\206\205\345\255\230\344\270\216\345\236\203\345\234\276\345\233\236\346\224\266\347\257\207/9_\346\226\271\346\263\225\345\214\272/images/image-20200708220303243.png" differ diff --git a/JVM/Code/.idea/.gitignore b/JVM/Code/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..73f69e0958611ac6e00bde95641f6699030ad235 --- /dev/null +++ b/JVM/Code/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/JVM/Code/.idea/.name b/JVM/Code/.idea/.name new file mode 100644 index 0000000000000000000000000000000000000000..7d8f9ab49eebbc54621862f7a9a6da3bb152346a --- /dev/null +++ b/JVM/Code/.idea/.name @@ -0,0 +1 @@ +JVMDemo \ No newline at end of file diff --git a/JVM/Code/.idea/codeStyles/codeStyleConfig.xml b/JVM/Code/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000000000000000000000000000000000000..a55e7a179bde3e4e772c29c0c85e53354aa54618 --- /dev/null +++ b/JVM/Code/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/JVM/Code/.idea/compiler.xml b/JVM/Code/.idea/compiler.xml new file mode 100644 index 0000000000000000000000000000000000000000..4bd9c81857bd5ce5bc9fa507f9021b43d1a69132 --- /dev/null +++ b/JVM/Code/.idea/compiler.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/JVM/Code/.idea/inspectionProfiles/Project_Default.xml b/JVM/Code/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000000000000000000000000000000000000..fa99c1bf483d02cd385290f953e907e2316ab73c --- /dev/null +++ b/JVM/Code/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,97 @@ + + + + \ No newline at end of file diff --git a/JVM/Code/.idea/jarRepositories.xml b/JVM/Code/.idea/jarRepositories.xml new file mode 100644 index 0000000000000000000000000000000000000000..712ab9d985c20018a0c97b93d2148ac1ffe588a5 --- /dev/null +++ b/JVM/Code/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/JVM/Code/.idea/misc.xml b/JVM/Code/.idea/misc.xml new file mode 100644 index 0000000000000000000000000000000000000000..4b661a5ffc3c46924b456f0eac25ea4c6e9b4047 --- /dev/null +++ b/JVM/Code/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/JVM/Code/.idea/smartfox_info.xml b/JVM/Code/.idea/smartfox_info.xml new file mode 100644 index 0000000000000000000000000000000000000000..1c2584f990e305e762d6d822c77dbd94ea31c7e4 --- /dev/null +++ b/JVM/Code/.idea/smartfox_info.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/JVM/Code/.idea/vcs.xml b/JVM/Code/.idea/vcs.xml new file mode 100644 index 0000000000000000000000000000000000000000..b2bdec2d71b6a5ce4ae49efc37516809c50e4d5e --- /dev/null +++ b/JVM/Code/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/JVM/Code/JVMDemo.iml b/JVM/Code/JVMDemo.iml new file mode 100644 index 0000000000000000000000000000000000000000..cf17af26acb00343a859ad08b968dbdf1e50b160 --- /dev/null +++ b/JVM/Code/JVMDemo.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/JVM/Code/pom.xml b/JVM/Code/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..53a2515559c17bc97b0c9d70f99dd6f3ed6c1786 --- /dev/null +++ b/JVM/Code/pom.xml @@ -0,0 +1,12 @@ + + + 4.0.0 + + org.example + JVMDemo + 1.0-SNAPSHOT + + + \ No newline at end of file diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter01/StackStruTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter01/StackStruTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d903aa5533c4b66e6f6a1045105f5ad28b396f56 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter01/StackStruTest.java @@ -0,0 +1,14 @@ +//package com.atguigu.java.chapter01; +// +///** +// * @author: 陌溪 +// * @create: 2020-07-04-21:17 +// */ +//public class StackStruTest { +// public static void main(String[] args) { +// int i = 2; +// int j = 3; +// int k = i + j; +// } +//} +// diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClassInitTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClassInitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3cd5b0476ea7e29eb6dabf18bc9ff16af9b306e8 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClassInitTest.java @@ -0,0 +1,22 @@ +package com.atguigu.java.chapter02; + +/** + * @author: 陌溪 + * @create: 2020-07-05-8:47 + */ +public class ClassInitTest { + private static int num = 1; + static { + num = 2; + number = 20; + System.out.println(num); +// System.out.println(number); //报错,非法的前向引用(static只能赋值,不能调用) + } + + private static int number = 10; + + public static void main(String[] args) { + System.out.println(ClassInitTest.num); // 2 + System.out.println(ClassInitTest.number); // 10 + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClassLoaderTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClassLoaderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..88a2afd839513d32ff3b8261230c3a7459282c34 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClassLoaderTest.java @@ -0,0 +1,29 @@ +package com.atguigu.java.chapter02; + +/** + * @author: 陌溪 + * @create: 2020-07-05-9:47 + */ +public class ClassLoaderTest { + public static void main(String[] args) { + // 获取系统类加载器 + ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); + System.out.println(systemClassLoader); + + // 获取其上层的:扩展类加载器 + ClassLoader extClassLoader = systemClassLoader.getParent(); + System.out.println(extClassLoader); + + // 试图获取 根加载器 + ClassLoader bootstrapClassLoader = extClassLoader.getParent(); + System.out.println(bootstrapClassLoader); + + // 获取自定义加载器 + ClassLoader classLoader = ClassLoaderTest.class.getClassLoader(); + System.out.println(classLoader); + + // 获取String类型的加载器 + ClassLoader classLoader1 = String.class.getClassLoader(); + System.out.println(classLoader1); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClassLoaderTest1.java b/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClassLoaderTest1.java new file mode 100644 index 0000000000000000000000000000000000000000..0fb06931de6d83e042820101df21346eb32aad65 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClassLoaderTest1.java @@ -0,0 +1,22 @@ +package com.atguigu.java.chapter02; + +import java.net.URL; +import java.security.Provider; + +/** + * @author: 陌溪 + * @create: 2020-07-05-10:17 + */ +public class ClassLoaderTest1 { + public static void main(String[] args) { + System.out.println("*********启动类加载器************"); + // 获取BootstrapClassLoader 能够加载的API的路径 + URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs(); + for (URL url : urls) { + System.out.println(url.toExternalForm()); + } + + // 从上面路径中,随意选择一个类,来看看他的类加载器是什么:得到的是null,说明是 根加载器 + ClassLoader classLoader = Provider.class.getClassLoader(); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClinitTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClinitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1f954ecf14a6bde841fa0e37a3feea58fe4cac0e --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClinitTest.java @@ -0,0 +1,13 @@ +package com.atguigu.java.chapter02; + +/** + * @author: 陌溪 + * @create: 2020-07-05-8:56 + */ +public class ClinitTest { + // 任何一个类申明后,都会存在一个构造器 + private int a = 1; + public static void main(String[] args) { + int b = 2; + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClinitTest1.java b/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClinitTest1.java new file mode 100644 index 0000000000000000000000000000000000000000..83de882705a8994549b9f00560253a84d6436736 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter02/ClinitTest1.java @@ -0,0 +1,22 @@ +package com.atguigu.java.chapter02; + +/** + * @author: 陌溪 + * @create: 2020-07-05-9:06 + */ +public class ClinitTest1 { + static class Father { + public static int A = 1; + static { + A = 2; + } + } + + static class Son extends Father { + public static int b = A; + } + + public static void main(String[] args) { + System.out.println(Son.b); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter02/CustomClassLoader.java b/JVM/Code/src/main/java/com/atguigu/java/chapter02/CustomClassLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..6b543df4b262466e4dc1749cec37603aafd4e54c --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter02/CustomClassLoader.java @@ -0,0 +1,12 @@ +package com.atguigu.java.chapter02; + +/** + * @author: 陌溪 + * @create: 2020-07-05-10:32 + */ +public class CustomClassLoader extends ClassLoader{ + @Override + protected Class findClass(String name) throws ClassNotFoundException { + return super.findClass(name); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter02/DeadThreadTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter02/DeadThreadTest.java new file mode 100644 index 0000000000000000000000000000000000000000..dcee4da21dfe18d366e046276c62bedd3f710734 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter02/DeadThreadTest.java @@ -0,0 +1,29 @@ +package com.atguigu.java.chapter02; + +/** + * @author: 陌溪 + * @create: 2020-07-05-9:14 + */ +public class DeadThreadTest { + public static void main(String[] args) { + new Thread(() -> { + System.out.println(Thread.currentThread().getName() + "\t 线程t1开始"); + new DeadThread(); + }, "t1").start(); + + new Thread(() -> { + System.out.println(Thread.currentThread().getName() + "\t 线程t2开始"); + new DeadThread(); + }, "t2").start(); + } +} +class DeadThread { + static { + if (true) { + System.out.println(Thread.currentThread().getName() + "\t 初始化当前类"); + while(true) { + + } + } + } +} \ No newline at end of file diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter02/HelloApp.java b/JVM/Code/src/main/java/com/atguigu/java/chapter02/HelloApp.java new file mode 100644 index 0000000000000000000000000000000000000000..9c2f1be8562602f1a7183c3ad1b42d7a2a2d2f92 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter02/HelloApp.java @@ -0,0 +1,12 @@ +package com.atguigu.java.chapter02; + +/** + * @author: 陌溪 + * @create: 2020-07-05-8:42 + */ +public class HelloApp { + private static int a = 1; + public static void main(String[] args) { + System.out.println(a); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter02/HelloLoader.java b/JVM/Code/src/main/java/com/atguigu/java/chapter02/HelloLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..8a97c1962194669750e3da4f9718d70cab4d8cf9 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter02/HelloLoader.java @@ -0,0 +1,12 @@ +package com.atguigu.java.chapter02; + +/** + * 类加载子系统 + * @author: 陌溪 + * @create: 2020-07-05-8:24 + */ +public class HelloLoader { + public static void main(String[] args) { + System.out.println("我已经被加载啦"); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter04/PCRegisterTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter04/PCRegisterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..31c9436a339c2614942e64d7ea947aef4de4c810 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter04/PCRegisterTest.java @@ -0,0 +1,13 @@ +package com.atguigu.java.chapter04; + +/**程序计数器 + * @author: 陌溪 + * @create: 2020-07-05-16:01 + */ +public class PCRegisterTest { + public static void main(String[] args) { + int i = 10; + int j = 20; + int k = i + j; + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter05/DynamicLinkingTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter05/DynamicLinkingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..36b530bdd8ee191fa8cbcafd50b176b4d452688d --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter05/DynamicLinkingTest.java @@ -0,0 +1,22 @@ +package com.atguigu.java.chapter05; + +/** + * 动态链接 + * + * @author: 陌溪 + * @create: 2020-07-06-10:06 + */ +public class DynamicLinkingTest { + + int num = 10; + + public void methodA() { + System.out.println("methodA()...."); + } + + public void methodB() { + System.out.println("methodA()...."); + methodA(); + num ++; + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter05/StackErrorTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter05/StackErrorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ee70454a1a0d8dfef894fa3a435d675fb9c53a43 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter05/StackErrorTest.java @@ -0,0 +1,14 @@ +package com.atguigu.java.chapter05; + +/** + * 演示栈中的异常:StackOverflowError + * @author: 陌溪 + * @create: 2020-07-05-17:11 + */ +public class StackErrorTest { + private static int count = 1; + public static void main(String[] args) { + System.out.println(count++); + main(args); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter05/StackFrameTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter05/StackFrameTest.java new file mode 100644 index 0000000000000000000000000000000000000000..763cf348d9688f2e7c31085e583f1ea8594a4f32 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter05/StackFrameTest.java @@ -0,0 +1,33 @@ +package com.atguigu.java.chapter05; + +/** + * 栈帧 + * + * @author: 陌溪 + * @create: 2020-07-05-20:33 + */ +public class StackFrameTest { + public static void main(String[] args) { + method01(); + } + + private static int method01() { + System.out.println("方法1的开始"); + int i = method02(); + System.out.println("方法1的结束"); + return i; + } + + private static int method02() { + System.out.println("方法2的开始"); + int i = method03();; + System.out.println("方法2的结束"); + return i; + } + private static int method03() { + System.out.println("方法3的开始"); + int i = 30; + System.out.println("方法3的结束"); + return i; + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter05/StringBuilderTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter05/StringBuilderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..93486c05eddc0766b2fb3026c3d9c666f103d1ed --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter05/StringBuilderTest.java @@ -0,0 +1,57 @@ +package com.atguigu.java.chapter05; + +/** + * 面试题 + * 方法中定义局部变量是否线程安全?具体情况具体分析 + * 何为线程安全? + * 如果只有一个线程才可以操作此数据,则必是线程安全的 + * 如果有多个线程操作,则此数据是共享数据,如果不考虑共享机制,则为线程不安全 + * @author: 陌溪 + * @create: 2020-07-06-16:08 + */ +public class StringBuilderTest { + + // s1的声明方式是线程安全的 + public static void method01() { + // 线程内部创建的,属于局部变量 + StringBuilder s1 = new StringBuilder(); + s1.append("a"); + s1.append("b"); + } + + // 这个也是线程不安全的,因为有返回值,有可能被其它的程序所调用 + public static StringBuilder method04() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("a"); + stringBuilder.append("b"); + return stringBuilder; + } + + // stringBuilder 是线程不安全的,操作的是共享数据 + public static void method02(StringBuilder stringBuilder) { + stringBuilder.append("a"); + stringBuilder.append("b"); + } + + + /** + * 同时并发的执行,会出现线程不安全的问题 + */ + public static void method03() { + StringBuilder stringBuilder = new StringBuilder(); + new Thread(() -> { + stringBuilder.append("a"); + stringBuilder.append("b"); + }, "t1").start(); + + method02(stringBuilder); + } + + // StringBuilder是线程安全的,但是String也可能线程不安全的 + public static String method05() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("a"); + stringBuilder.append("b"); + return stringBuilder.toString(); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter06/IhaveNatives.java b/JVM/Code/src/main/java/com/atguigu/java/chapter06/IhaveNatives.java new file mode 100644 index 0000000000000000000000000000000000000000..8a9cf9023fe4c4e2b90d07e5e0325a91c1b0dfbb --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter06/IhaveNatives.java @@ -0,0 +1,14 @@ +package com.atguigu.java.chapter06; + +/** + * 本地方法 + * + * @author: 陌溪 + * @create: 2020-07-06-16:45 + */ +public class IhaveNatives { + public native void Native1(int x); + native static public long Native2(); + native synchronized private float Native3(Object o); + native void Natives(int[] ary) throws Exception; +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter08/EscapeAnalysis.java b/JVM/Code/src/main/java/com/atguigu/java/chapter08/EscapeAnalysis.java new file mode 100644 index 0000000000000000000000000000000000000000..1652a2af96b74d9936cca83b835754ce0a9b250e --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter08/EscapeAnalysis.java @@ -0,0 +1,42 @@ +package com.atguigu.java.chapter08; + +/** + * 逃逸分析 + * 如何快速的判断是否发生了逃逸分析,大家就看new的对象是否在方法外被调用。 + * @author: 陌溪 + * @create: 2020-07-07-20:05 + */ +public class EscapeAnalysis { + + public EscapeAnalysis obj; + + /** + * 方法返回EscapeAnalysis对象,发生逃逸 + * @return + */ + public EscapeAnalysis getInstance() { + return obj == null ? new EscapeAnalysis():obj; + } + + /** + * 为成员属性赋值,发生逃逸 + */ + public void setObj() { + this.obj = new EscapeAnalysis(); + } + + /** + * 对象的作用于仅在当前方法中有效,没有发生逃逸 + */ + public void useEscapeAnalysis() { + EscapeAnalysis e = new EscapeAnalysis(); + } + + /** + * 引用成员变量的值,发生逃逸 + */ + public void useEscapeAnalysis2() { + EscapeAnalysis e = getInstance(); + // getInstance().XXX 发生逃逸 + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter08/GCTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter08/GCTest.java new file mode 100644 index 0000000000000000000000000000000000000000..81f67bc860d1c2bf6dfa6ee70e9bc2cbf9cc3dc9 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter08/GCTest.java @@ -0,0 +1,27 @@ +package com.atguigu.java.chapter08; + +import java.util.ArrayList; +import java.util.List; + +/** + * GC测试 + * + * @author: 陌溪 + * @create: 2020-07-07-10:01 + */ +public class GCTest { + public static void main(String[] args) { + int i = 0; + try { + List list = new ArrayList<>(); + String a = "mogu blog"; + while(true) { + list.add(a); + a = a + a; + i++; + } + }catch (Exception e) { + e.getStackTrace(); + } + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter08/HeapDemo.java b/JVM/Code/src/main/java/com/atguigu/java/chapter08/HeapDemo.java new file mode 100644 index 0000000000000000000000000000000000000000..660fced25969b8e392488f8ac170ae089e4d67b0 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter08/HeapDemo.java @@ -0,0 +1,20 @@ +package com.atguigu.java.chapter08; + +/** + * -Xms10m -Xmx10m + * @author: 陌溪 + * @create: 2020-07-06-19:58 + */ +public class HeapDemo { + public static void main(String[] args) { + System.out.println("start........."); + try { + Thread.sleep(100000000); + } catch (Exception e) { + e.printStackTrace(); + } finally { + System.out.println("end......."); + } + + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter08/HeapDemo2.java b/JVM/Code/src/main/java/com/atguigu/java/chapter08/HeapDemo2.java new file mode 100644 index 0000000000000000000000000000000000000000..62a8c71c2a197a28b8d6bffb78fa28652cc92f13 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter08/HeapDemo2.java @@ -0,0 +1,20 @@ +package com.atguigu.java.chapter08; + +/** + * -Xms20m -Xmx20m + * @author: 陌溪 + * @create: 2020-07-06-19:59 + */ +public class HeapDemo2 { + public static void main(String[] args) { + System.out.println("start........."); + try { + Thread.sleep(100000000); + } catch (Exception e) { + e.printStackTrace(); + } finally { + System.out.println("end......."); + } + + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter08/HeapInstanceTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter08/HeapInstanceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..af09e7f7697f4ec3ff32db74d2071e599d2f7888 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter08/HeapInstanceTest.java @@ -0,0 +1,21 @@ +package com.atguigu.java.chapter08; + +import java.util.ArrayList; +import java.util.Random; + +/** + * 代码演示对象创建过程 + * + * @author: 陌溪 + * @create: 2020-07-07-9:16 + */ +public class HeapInstanceTest { + byte [] buffer = new byte[new Random().nextInt(1024 * 200)]; + public static void main(String[] args) throws InterruptedException { + ArrayList list = new ArrayList<>(); + while (true) { + list.add(new HeapInstanceTest()); + Thread.sleep(10); + } + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter08/HeapSpaceInitial.java b/JVM/Code/src/main/java/com/atguigu/java/chapter08/HeapSpaceInitial.java new file mode 100644 index 0000000000000000000000000000000000000000..11e5f0905cf592580508ac8c76eac397e8f95cc2 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter08/HeapSpaceInitial.java @@ -0,0 +1,21 @@ +package com.atguigu.java.chapter08; + +/** + * -Xms 用来设置堆空间(年轻代+老年代)的初始内存大小 + * -X:是jvm运行参数 + * ms:memory start + * -Xmx:用来设置堆空间(年轻代+老年代)的最大内存大小 + * + * @author: 陌溪 + * @create: 2020-07-06-20:44 + */ +public class HeapSpaceInitial { + public static void main(String[] args) { + // 返回Java虚拟机中的堆内存总量 + long initialMemory = Runtime.getRuntime().totalMemory() / 1024 / 1024; + // 返回Java虚拟机试图使用的最大堆内存 + long maxMemory = Runtime.getRuntime().maxMemory() / 1024 / 1024; + System.out.println("-Xms:" + initialMemory + "M"); + System.out.println("-Xmx:" + maxMemory + "M"); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter08/OOMTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter08/OOMTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7410df6a173055447055f950a032eb4d3577102b --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter08/OOMTest.java @@ -0,0 +1,20 @@ +package com.atguigu.java.chapter08; + +import java.util.ArrayList; +import java.util.List; + +/** + * OOM测试 + * + * @author: 陌溪 + * @create: 2020-07-06-21:11 + */ +public class OOMTest { + public static void main(String[] args) throws InterruptedException { + List list = new ArrayList<>(); + while(true) { + Thread.sleep(1); + list.add(999999999); + } + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter08/StackAllocation.java b/JVM/Code/src/main/java/com/atguigu/java/chapter08/StackAllocation.java new file mode 100644 index 0000000000000000000000000000000000000000..4713ad01395eed9e2319557b90aee4de0e44fbe3 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter08/StackAllocation.java @@ -0,0 +1,31 @@ +package com.atguigu.java.chapter08; + +/** + * 栈上分配 + * -Xmx1G -Xms1G -XX:-DoEscapeAnalysis -XX:+PrintGCDetails + * @author: 陌溪 + * @create: 2020-07-07-20:23 + */ +class User { + private String name; + private String age; + private String gender; + private String phone; +} +public class StackAllocation { + public static void main(String[] args) throws InterruptedException { + long start = System.currentTimeMillis(); + for (int i = 0; i < 100000000; i++) { + alloc(); + } + long end = System.currentTimeMillis(); + System.out.println("花费的时间为:" + (end - start) + " ms"); + + // 为了方便查看堆内存中对象个数,线程sleep + Thread.sleep(10000000); + } + + private static void alloc() { + User user = new User(); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter09/MethodAreaTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter09/MethodAreaTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a8999ec26ff6587893206a9f4c9e81e3a931ed54 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter09/MethodAreaTest.java @@ -0,0 +1,22 @@ +package com.atguigu.java.chapter09; + +/** + * non-final的类变量 + * + * @author: 陌溪 + * @create: 2020-07-08-16:54 + */ +public class MethodAreaTest { + public static void main(String[] args) { + Order order = new Order(); + order.hello(); + System.out.println(order.count); + } +} +class Order { + public static int count = 1; + public static final int number = 2; + public static void hello() { + System.out.println("hello!"); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter09/OOMTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter09/OOMTest.java new file mode 100644 index 0000000000000000000000000000000000000000..863a8a4c46e9774cb7eb101d03e77921c7e47b28 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter09/OOMTest.java @@ -0,0 +1,30 @@ +package com.atguigu.java.chapter09; + +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.Opcodes; + +/** + * 元空间溢出 + * + * @author: 陌溪 + * @create: 2020-07-08-15:46 + */ +public class OOMTest { + public static void main(String[] args) { + int j = 0; + try { + OOMTest test = new OOMTest(); + for (int i = 0; i < 10000; i++) { + // 创建classWriter对象,用于生成类的二进制字节码 + ClassWriter classWriter = new ClassWriter(0); + // 创建对应的基本信息(版本号 1.8,修饰符,类名,) + classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Class"+i, null, "java/lang/Object", null); + // 返回byte[] + byte [] code = classWriter.toByteArray(); + // 类的加载 + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringExer.java b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringExer.java new file mode 100644 index 0000000000000000000000000000000000000000..d836d6d7d16a22c3e77250bbc693bd1b595c900d --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringExer.java @@ -0,0 +1,24 @@ +package com.atguigu.java.chapter13; + +/** + * 面试题 + * + * @author: 陌溪 + * @create: 2020-07-11-9:05 + */ +public class StringExer { + String str = new String("good"); + char [] ch = {'t','e','s','t'}; + + public void change(String str, char ch []) { + str = "test ok"; + ch[0] = 'b'; + } + + public static void main(String[] args) { + StringExer ex = new StringExer(); + ex.change(ex.str, ex.ch); + System.out.println(ex.str); + System.out.println(ex.ch); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringGCTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringGCTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4e18b2a8eb9b248a31c733ef13b77e97f94c7156 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringGCTest.java @@ -0,0 +1,15 @@ +package com.atguigu.java.chapter13; + +/** + * String的垃圾回收 + * -Xms15m -Xmx15m -XX:+PrintStringTableStatistics -XX:+PrintGCDetails + * @author: 陌溪 + * @create: 2020-07-11-16:55 + */ +public class StringGCTest { + public static void main(String[] args) { + for (int i = 0; i < 100000; i++) { + String.valueOf(i).intern(); + } + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringIntern.java b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringIntern.java new file mode 100644 index 0000000000000000000000000000000000000000..be8ea14c7ce892b5fca731bb9eb924032b2588dd --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringIntern.java @@ -0,0 +1,19 @@ +package com.atguigu.java.chapter13; + +/** + * @author: 陌溪 + * @create: 2020-07-11-11:16 + */ +public class StringIntern { + public static void main(String[] args) { + String s = new String("1"); + s = s.intern(); + String s2 = "1"; + System.out.println(s == s2); // true + + String s3 = new String("1") + new String("1"); + s3.intern(); + String s4 = "11"; + System.out.println(s3 == s4); // true + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringIntern2.java b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringIntern2.java new file mode 100644 index 0000000000000000000000000000000000000000..62cf907bc8a2a509ad46197b57d824fd920a8213 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringIntern2.java @@ -0,0 +1,27 @@ +package com.atguigu.java.chapter13; + +/** + * 使用Intern() 测试执行效率 + * @author: 陌溪 + * @create: 2020-07-11-15:19 + */ +public class StringIntern2 { + static final int MAX_COUNT = 1000 * 10000; + static final String[] arr = new String[MAX_COUNT]; + + public static void main(String[] args) { + Integer [] data = new Integer[]{1,2,3,4,5,6,7,8,9,10}; + long start = System.currentTimeMillis(); + for (int i = 0; i < MAX_COUNT; i++) { + arr[i] = new String(String.valueOf(data[i%data.length])).intern(); + } + long end = System.currentTimeMillis(); + System.out.println("花费的时间为:" + (end - start)); + + try { + Thread.sleep(1000000); + } catch (Exception e) { + e.getStackTrace(); + } + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringNewTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringNewTest.java new file mode 100644 index 0000000000000000000000000000000000000000..068393c7a5ef4d38d1193e9f3ad7948029d06b4a --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringNewTest.java @@ -0,0 +1,13 @@ +package com.atguigu.java.chapter13; + +/** + * new String("ab") 会创建几个对象? 看字节码就知道是2个对象 + * + * @author: 陌溪 + * @create: 2020-07-11-11:17 + */ +public class StringNewTest { + public static void main(String[] args) { + String str = new String("a") + new String("b"); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringTest1.java b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringTest1.java new file mode 100644 index 0000000000000000000000000000000000000000..74e183d9bc5f307fef6d4022f64959c9dfd5deec --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringTest1.java @@ -0,0 +1,45 @@ +package com.atguigu.java.chapter13; + +/** + * String的不可变性 + * + * @author: 陌溪 + * @create: 2020-07-11-8:57 + */ +public class StringTest1 { + + public static void test1() { + // 字面量定义的方式,“abc”存储在字符串常量池中 + String s1 = "abc"; + String s2 = "abc"; + System.out.println(s1 == s2); + s1 = "hello"; + System.out.println(s1 == s2); + System.out.println(s1); + System.out.println(s2); + System.out.println("----------------"); + } + + public static void test2() { + String s1 = "abc"; + String s2 = "abc"; + // 只要进行了修改,就会重新创建一个对象,这就是不可变性 + s2 += "def"; + System.out.println(s1); + System.out.println(s2); + System.out.println("----------------"); + } + + public static void test3() { + String s1 = "abc"; + String s2 = s1.replace('a', 'm'); + System.out.println(s1); + System.out.println(s2); + } + + public static void main(String[] args) { + test1(); + test2(); + test3(); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringTest5.java b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringTest5.java new file mode 100644 index 0000000000000000000000000000000000000000..b0e1fee51bf9b2d0bdc075fd24c1ce262aeec0ae --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter13/StringTest5.java @@ -0,0 +1,71 @@ +package com.atguigu.java.chapter13; + +/** + * 字符串拼接 + * + * @author: 陌溪 + * @create: 2020-07-11-9:53 + */ +public class StringTest5 { + + public static void test1() { + String s1 = "a" + "b" + "c"; // 得到 abc的常量池 + String s2 = "abc"; // abc存放在常量池,直接将常量池的地址返回 + /** + * 最终java编译成.class,再执行.class + */ + System.out.println(s1 == s2); // true,因为存放在字符串常量池 + System.out.println(s1.equals(s2)); // true + } + + public static void test2() { + String s1 = "javaEE"; + String s2 = "hadoop"; + String s3 = "javaEEhadoop"; + String s4 = "javaEE" + "hadoop"; + String s5 = s1 + "hadoop"; + String s6 = "javaEE" + s2; + String s7 = s1 + s2; + + System.out.println(s3 == s4); // true + System.out.println(s3 == s5); // false + System.out.println(s3 == s6); // false + System.out.println(s3 == s7); // false + System.out.println(s5 == s6); // false + System.out.println(s5 == s7); // false + System.out.println(s6 == s7); // false + + String s8 = s6.intern(); + System.out.println(s3 == s8); // true + } + + public static void test4() { + final String s1 = "a"; + final String s2 = "b"; + String s3 = "ab"; + String s4 = s1 + s2; + System.out.println(s3 == s4); + } + + public static void test6() { + + } + + public static void method1(int highLevel) { + String src = ""; + for (int i = 0; i < highLevel; i++) { + src += "a"; // 每次循环都会创建一个StringBuilder对象 + } + } + + public static void method2(int highLevel) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < highLevel; i++) { + sb.append("a"); + } + } + + public static void main(String[] args) { + test4(); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter15/CanReliveObj.java b/JVM/Code/src/main/java/com/atguigu/java/chapter15/CanReliveObj.java new file mode 100644 index 0000000000000000000000000000000000000000..3f161dd7a58dcda25dcd5fe34c6b7222a0a2f7a4 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter15/CanReliveObj.java @@ -0,0 +1,46 @@ +package com.atguigu.java.chapter15; + +/** + * 测试Object类中finalize()方法 + * 对象复活场景 + * + * @author: 陌溪 + * @create: 2020-07-12-11:06 + */ +public class CanReliveObj { + // 类变量,属于GC Roots的一部分 + public static CanReliveObj canReliveObj; + + @Override + protected void finalize() throws Throwable { + super.finalize(); + System.out.println("调用当前类重写的finalize()方法"); + canReliveObj = this; + } + + public static void main(String[] args) throws InterruptedException { + canReliveObj = new CanReliveObj(); + canReliveObj = null; + System.gc(); + System.out.println("-----------------第一次gc操作------------"); + // 因为Finalizer线程的优先级比较低,暂停2秒,以等待它 + Thread.sleep(2000); + if (canReliveObj == null) { + System.out.println("obj is dead"); + } else { + System.out.println("obj is still alive"); + } + + System.out.println("-----------------第二次gc操作------------"); + canReliveObj = null; + System.gc(); + // 下面代码和上面代码是一样的,但是 canReliveObj却自救失败了 + Thread.sleep(2000); + if (canReliveObj == null) { + System.out.println("obj is dead"); + } else { + System.out.println("obj is still alive"); + } + + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter15/HeapOOM.java b/JVM/Code/src/main/java/com/atguigu/java/chapter15/HeapOOM.java new file mode 100644 index 0000000000000000000000000000000000000000..76e2e674440e03ebe5894e3efd18f95c795af97d --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter15/HeapOOM.java @@ -0,0 +1,28 @@ +package com.atguigu.java.chapter15; + +import java.util.ArrayList; + +/** + * 内存溢出排查 + * -Xms8m -Xmx8m -XX:HeapDumpOnOutOfMemoryError + * @author: 陌溪 + * @create: 2020-07-12-14:56 + */ +public class HeapOOM { + // 创建1M的文件 + byte [] buffer = new byte[1 * 1024 * 1024]; + + public static void main(String[] args) { + ArrayList list = new ArrayList<>(); + int count = 0; + try { + while (true) { + list.add(new HeapOOM()); + count++; + } + } catch (Exception e) { + e.getStackTrace(); + System.out.println("count:" + count); + } + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter15/LocalVarGC.java b/JVM/Code/src/main/java/com/atguigu/java/chapter15/LocalVarGC.java new file mode 100644 index 0000000000000000000000000000000000000000..68d2217e48e6d5314247bc271a9da2cc82846ae1 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter15/LocalVarGC.java @@ -0,0 +1,61 @@ +package com.atguigu.java.chapter15; + +/** + * 局部变量回收 + * + * @author: 陌溪 + * @create: 2020-07-12-19:12 + */ +public class LocalVarGC { + + /** + * 触发Minor GC没有回收对象,然后在触发Full GC将该对象存入old区 + */ + public void localvarGC1() { + byte[] buffer = new byte[10*1024*1024]; + System.gc(); + } + + /** + * 触发YoungGC的时候,已经被回收了 + */ + public void localvarGC2() { + byte[] buffer = new byte[10*1024*1024]; + buffer = null; + System.gc(); + } + + /** + * 不会被回收,因为它还存放在局部变量表索引为1的槽中 + */ + public void localvarGC3() { + { + byte[] buffer = new byte[10*1024*1024]; + } + System.gc(); + } + + /** + * 会被回收,因为它还存放在局部变量表索引为1的槽中,但是后面定义的value把这个槽给替换了 + */ + public void localvarGC4() { + { + byte[] buffer = new byte[10*1024*1024]; + } + int value = 10; + System.gc(); + } + + /** + * localvarGC5中的数组已经被回收 + */ + public void localvarGC5() { + localvarGC1(); + System.gc(); + } + + public static void main(String[] args) { + LocalVarGC localVarGC = new LocalVarGC(); + localVarGC.localvarGC3(); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter15/PhantomReferenceTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter15/PhantomReferenceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..89d24f0f4f5694eab5e244912111d62f9b56da1c --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter15/PhantomReferenceTest.java @@ -0,0 +1,74 @@ +package com.atguigu.java.chapter15; + +import java.lang.ref.PhantomReference; +import java.lang.ref.ReferenceQueue; + +/** + * @author: 陌溪 + * @create: 2020-07-12-21:42 + */ +public class PhantomReferenceTest { + // 当前类对象的声明 + public static PhantomReferenceTest obj; + // 引用队列 + static ReferenceQueue phantomQueue = null; + + @Override + protected void finalize() throws Throwable { + super.finalize(); + System.out.println("调用当前类的finalize方法"); + obj = this; + } + + public static void main(String[] args) { + Thread thread = new Thread(() -> { + while(true) { + if (phantomQueue != null) { + PhantomReference objt = null; + try { + objt = (PhantomReference) phantomQueue.remove(); + } catch (Exception e) { + e.getStackTrace(); + } + if (objt != null) { + System.out.println("追踪垃圾回收过程:PhantomReferenceTest实例被GC了"); + } + } + } + }, "t1"); + thread.setDaemon(true); + thread.start(); + + phantomQueue = new ReferenceQueue<>(); + obj = new PhantomReferenceTest(); + // 构造了PhantomReferenceTest对象的虚引用,并指定了引用队列 + PhantomReference phantomReference = new PhantomReference<>(obj, phantomQueue); + try { + System.out.println(phantomReference.get()); + // 去除强引用 + obj = null; + // 第一次进行GC,由于对象可复活,GC无法回收该对象 + System.out.println("第一次GC操作"); + System.gc(); + Thread.sleep(1000); + if (obj == null) { + System.out.println("obj 是 null"); + } else { + System.out.println("obj 不是 null"); + } + System.out.println("第二次GC操作"); + obj = null; + System.gc(); + Thread.sleep(1000); + if (obj == null) { + System.out.println("obj 是 null"); + } else { + System.out.println("obj 不是 null"); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + + } + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter15/RefCountGC.java b/JVM/Code/src/main/java/com/atguigu/java/chapter15/RefCountGC.java new file mode 100644 index 0000000000000000000000000000000000000000..126da59ae004f84c5ae9cf7e360577224c174501 --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter15/RefCountGC.java @@ -0,0 +1,26 @@ +package com.atguigu.java.chapter15; + +/** + * 引用计数算法测试 + * + * @author: 陌溪 + * @create: 2020-07-12-10:26 + */ +public class RefCountGC { + // 这个成员属性的唯一作用就是占用一点内存 + private byte[] bigSize = new byte[5*1024*1024]; + // 引用 + Object reference = null; + + public static void main(String[] args) { + RefCountGC obj1 = new RefCountGC(); + RefCountGC obj2 = new RefCountGC(); + obj1.reference = obj2; + obj2.reference = obj1; + obj1 = null; + obj2 = null; + // 显示的执行垃圾收集行为,判断obj1 和 obj2是否被回收? + System.gc(); + } +} + diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter16/SystemGCTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter16/SystemGCTest.java new file mode 100644 index 0000000000000000000000000000000000000000..35f93a1f26e3021b1eef0c93b0d81ed2f4cba10e --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter16/SystemGCTest.java @@ -0,0 +1,22 @@ +package com.atguigu.java.chapter16; + +/** + * System.gc() + * + * @author: 陌溪 + * @create: 2020-07-12-19:07 + */ +public class SystemGCTest { + public static void main(String[] args) { + new SystemGCTest(); + // 提醒JVM进行垃圾回收 + System.gc(); +// System.runFinalization(); + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + System.out.println("SystemGCTest 执行了 finalize方法"); + } +} diff --git a/JVM/Code/src/main/java/com/atguigu/java/chapter17/GCUseTest.java b/JVM/Code/src/main/java/com/atguigu/java/chapter17/GCUseTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d5924f0dc28bdc9c869b22f8df7fb62838eea1eb --- /dev/null +++ b/JVM/Code/src/main/java/com/atguigu/java/chapter17/GCUseTest.java @@ -0,0 +1,17 @@ +package com.atguigu.java.chapter17; + +/** + * GC垃圾收集过程 + * @author: 陌溪 + * @create: 2020-07-14-8:35 + */ +public class GCUseTest { + static final Integer _1MB = 1024 * 1024; + public static void main(String[] args) { + byte [] allocation1, allocation2, allocation3, allocation4; + allocation1 = new byte[2 *_1MB]; + allocation2 = new byte[2 *_1MB]; + allocation3 = new byte[2 *_1MB]; + allocation4 = new byte[6 *_1MB]; + } +} diff --git a/JVM/Code/web/WEB-INF/web.xml b/JVM/Code/web/WEB-INF/web.xml new file mode 100644 index 0000000000000000000000000000000000000000..d80081d1318531b6c30eaf0d748bf80a0b2e042a --- /dev/null +++ b/JVM/Code/web/WEB-INF/web.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git "a/JVM/JVM\351\224\231\345\210\253\345\255\227\345\213\230\350\257\257.md" "b/JVM/JVM\351\224\231\345\210\253\345\255\227\345\213\230\350\257\257.md" new file mode 100644 index 0000000000000000000000000000000000000000..c6e335fa1f4de17e83afb61ac05691d22f0d7195 --- /dev/null +++ "b/JVM/JVM\351\224\231\345\210\253\345\255\227\345\213\230\350\257\257.md" @@ -0,0 +1,64 @@ +## JVM与Java体系结构 + +### Java生态圈 + +作为灯种文化 -> 作为一种文化 + +令人咋舌 -> 令人咂舌 + +### 虚拟机与Java虚拟机 + +Mware -> VMware + +### JVM的架构模型 + +以零地址指令为主方水洋 -> 以零地址指令为主 + +### JVM生命周期 + +由于操作系统用现错误 -> 由于操作系统出现错误 + +## 程序计数器 + +### 介绍 + +undefned -> undefined + +outotMemoryError -> OutOfMemoryError + +## 虚拟机栈 + +### 虚拟机栈概述 + +Java战 -> Java栈 + +### 栈的存储单位 + +#### 栈中存储什么? + +栈颜 -> 栈帧 + +### 静态变量与局部变量的对比 + +linking的paper阶段 -> linking的prepare阶段 + +### 方法调用:解析与分配 + +#### 链接:静态链接 + +克制 -> 可知 + +### 早晚期绑定的发展历史 + +既然这一类的编程语言具备多态特悄 -> 既然这一类的编程语言具备多态特性 + +## 本地方法接口 + +### 什么是本地方法 + +Native Methodt -> Native Method + +### Sun's Java + +setpriorityo() -> setPriority0() + diff --git a/JVM/README.md b/JVM/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2bc0e6728eef160595b36c64751421d796c72e94 --- /dev/null +++ b/JVM/README.md @@ -0,0 +1,31 @@ +## 介绍 + +> 来源Bilibili尚硅谷宋红康老师JVM教程:[硅谷2020最新版宋红康JVM教程](https://www.bilibili.com/video/BV1PJ411n7xZ) + +## 目录 + +### 内存与垃圾回收篇 + +- [JVM与Java体系结构](./1_内存与垃圾回收篇/1_JVM与Java体系结构) +- [类加载子系统](./1_内存与垃圾回收篇/2_类加载子系统) +- [运行时数据区概述及线程](./1_内存与垃圾回收篇/3_运行时数据区概述及线程) +- [程序计数器](./1_内存与垃圾回收篇/4_程序计数器) +- [虚拟机栈](./1_内存与垃圾回收篇/5_虚拟机栈) +- [本地方法接口](./1_内存与垃圾回收篇/6_本地方法接口) +- [本地方法栈](./1_内存与垃圾回收篇/7_本地方法栈) +- [堆](./1_内存与垃圾回收篇/8_堆) +- [方法区](./1_内存与垃圾回收篇/9_方法区) +- [对象实例化内存布局与访问定位](./1_内存与垃圾回收篇/10_对象实例化内存布局与访问定位) +- [直接内存](./1_内存与垃圾回收篇/11_直接内存) +- [执行引擎](./1_内存与垃圾回收篇/12_执行引擎) +- [StringTable](./1_内存与垃圾回收篇/13_StringTable) +- [垃圾回收概述](./1_内存与垃圾回收篇/14_垃圾回收概述) +- [垃圾回收相关算法](./1_内存与垃圾回收篇/15_垃圾回收相关算法) +- [垃圾回收相关概念](./1_内存与垃圾回收篇/16_垃圾回收相关概念) +- [垃圾回收器](./1_内存与垃圾回收篇/17_垃圾回收器) + +## 字节码与类的加载篇 + +## 性能监控与调优篇 + +## 大厂面试篇 \ No newline at end of file diff --git "a/Java/ArrayList\346\211\251\345\256\271\346\234\272\345\210\266/README.md" "b/Java/ArrayList\346\211\251\345\256\271\346\234\272\345\210\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..830b2abe1b17c9d2cd8b290ee66f86a1b3df852e --- /dev/null +++ "b/Java/ArrayList\346\211\251\345\256\271\346\234\272\345\210\266/README.md" @@ -0,0 +1,213 @@ +# 浅谈ArrayList及扩容机制 + +## ArrayList + +ArrayList就是动态数组,其实就是Array的复杂版本,它提供了动态的添加元素和删除元素的方法,同时实现了Collection 和 List接口,能够灵活的设置数组的大小。 + +通过源码的分析,我们可以看到ArrayList有三种构造方法 + +- 空的构造函数 +- 根据传入的数值大小,创建指定长度的数组 +- 通过传入Collection元素列表进行生成 + +```java +// 默认的容量大小 +private static final int DEFAULT_CAPACITY = 10; +// 定义的空的数组 +private static final Object[] EMPTY_ELEMENTDATA = {}; +// 不可以被序列化的数组,相当于存储元素的缓冲区 +transient Object[] elementData; +// 这个list集合的长度 +private int size; + + /** + * 空的构造函数 + */ + public ArrayList() { + this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; + } + + /** + * 根据用户传入的容量大小构造一个list集合,长度可以大于等于0,但是如果为负数会抛出异常 + */ + public ArrayList(int initialCapacity) { + // 如果初始容量大于0 + if (initialCapacity > 0) { + // 创建一个大小为initialCapacity的数组 + this.elementData = new Object[initialCapacity]; + } else if (initialCapacity == 0) { + // 创建一个空数组 + this.elementData = EMPTY_ELEMENTDATA; + } else { + // 如果为负数,直接抛出异常 + throw new IllegalArgumentException("Illegal Capacity: "+ + initialCapacity); + } + } + + + /** + * 构造包含指定collection元素的列表,这些元素利用该集合的迭代器按顺序返回 + * 如果指定的集合为null,throws NullPointerException。 + */ + public ArrayList(Collection c) { + elementData = c.toArray(); + if ((size = elementData.length) != 0) { + // c.toArray might (incorrectly) not return Object[] (see 6260652) + if (elementData.getClass() != Object[].class) + elementData = Arrays.copyOf(elementData, size, Object[].class); + } else { + // replace with empty array. + this.elementData = EMPTY_ELEMENTDATA; + } + } + +``` + +## ArrayList相关问题 + +### ArrayList优缺点 + +#### 优点 + +ArrayList底层是以数组实现,是一种随机访问模式,再加上它实现了RandomAccess接口,因此在执行get方法的时候很快。 + +ArrayList在顺序添加元素的时候非常场面,只是往数组中添加了一个元素而已,根据下标遍历元素,效率高。 + +可以自动扩容,默认为每次扩容为原来的1.5倍 + +#### 缺点 + +数组里面(除了末尾)插入和删除元素效率不高,因为需要移动大量的元素 + +> ArrayList在小于扩容容量的情况下,其实增加操作效率非常高,在涉及扩容的情况下,添加操作效率确实低,删除操作需要移位拷贝。 +> +> 同时因为ArrayList中增加(扩容)或者删除元素要调用System.arrayCopy()这种效率很低的方法进行处理,所以遇到数据量略大 或者 需要频繁插入和删除操作的时候,效率就比较低了,如果遇到上述的场景,那么就需要使用LinkedList来代替 +> +> 因为ArrayList的优点在于构造好数组后,频繁的访问元素的效率非常高。 + +### ArrayList和Vector的区别 + +首先List接口一共有三个实现类:ArrayList、Vector、LinkedList + +Vector 和 ArrayList一样,都是通过数组来实现的,不同的是 Vector支持线程的同步,也就是说某一个时刻下,只有一个线程能够写Vector,避免了多线程同时写而引起的不一致的问题,但实现同步需要很高的代Synchronized 因此,Vector的效率比ArrayList慢 + +同时Vector 和 ArrayList的扩容机制有差异的,Vector每次扩容为数组长度的一倍,而ArrayList则是原来数组长度的1.5倍。 + +## 扩容机制 + +### add方法 + +首先我们来看看ArrayList中的add方法是如何添加元素的 + +```java + // 将指定的元素加到列表的末尾 + public boolean add(E e) { + // 添加元素之前,先调用ensureCapacityInternal方法 + ensureCapacityInternal(size + 1); // Increments modCount!! + // 这里看到的ArrayList添加元素的实质相当于为数组赋值 + elementData[size++] = e; + return true; +} +``` + +### ensureCapacityInternal方法 + +当add进一个元素的时候,minCapacity为1,此时取两者的最大值 + +```java +// 得到最小的扩容量 +private void ensureCapacityInternal(int minCapacity) { + // 当一开始是默认空的列表 + if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { + // 获取默认的容量和传入参数的最大值 + // DEFAULT_CAPACITY: 10 , minCapacity: 1 + minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); + } + ensureExplicitCapacity(minCapacity); +} +``` + +### ensureExplicitCapacity方法 + +我们看到,上述的操作在执行完后,会调用 ensureExplicitCapacity方法,该方法主要就是为了判断是否触发扩容 + +```java +// 判断是否需要扩容 +private void ensureExplicitCapacity(int minCapacity) { + modCount++; + + // overflow-conscious code + if (minCapacity - elementData.length > 0) + // 调用grow方法进行扩容 + grow(minCapacity); +} +``` + +### grow方法 + +当添加元素的时候,大于当前数组的长度,就会触发grow操作,该操作将会对数组进行扩容 + +``` +int newCapacity = oldCapacity + (oldCapacity >> 1) +``` + +核心代码是上面这句,将原来的数组长度,进行扩容到1.5倍,然后在执行拷贝命令,将旧数组中的内容,拷贝到新的数组中,实现元素的扩容操作。 + +```java +elementData = Arrays.copyOf(elementData, newCapacity); +``` + +> 关于:System.arrayCopy()和Arrays.copyOf()方法 +> +> 看两者源代码可以发现 copyOf() 内部实际调用了 System.arraycopy() 方法 +> +> arraycopy() 需要目标数组,将原数组拷贝到你自己定义的数组里或者原数组,而且可以选择拷贝的起点和长度以及放入新数组中的位置 copyOf() 是系统自动在内部新建一个数组,并返回该数 + +完整代码如下 + +```java +// 需要分配的数组大小 +private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + +private void grow(int minCapacity) { + // 集合的容量 + int oldCapacity = elementData.length; + // 新的集合的容量(在这里运用了位运算,位运算是计算机最快的,右移一位,所以新容量是1.5倍) + int newCapacity = oldCapacity + (oldCapacity >> 1); + // 如果新容量小于添加的集合的容量,则把该容量替换 + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + + /** 如果新容量大于 MAX_ARRAY_SIZE,进入(执行) `hugeCapacity()` 方法来比较 minCapacity 和 * MAX_ARRAY_SIZE,如果minCapacity大于最大容量,则新容量则为`Integer.MAX_VALUE`,否则, * 新容量大小则为 MAX_ARRAY_SIZE 即为 `Integer.MAX_VALUE - 8`。 + */ + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + // minCapacity is usually close to size, so this is a win: + // 将原数组copy到新的数组中 + elementData = Arrays.copyOf(elementData, newCapacity); + } + + /** 如果新容量大于 MAX_ARRAY_SIZE,进入(执行) `hugeCapacity()` 方法来比较 minCapacity 和 * MAX_ARRAY_SIZE,如果minCapacity大于最大容量,则新容量则为`Integer.MAX_VALUE`,否则, * 新容量大小则为 MAX_ARRAY_SIZE 即为 `Integer.MAX_VALUE - 8`。 + */ + private static int hugeCapacity(int minCapacity) { + if (minCapacity < 0) // overflow + throw new OutOfMemoryError(); + return (minCapacity > MAX_ARRAY_SIZE) ? + Integer.MAX_VALUE : + MAX_ARRAY_SIZE; + } +``` + +### 总结 + +通过将上面的方法进行梳理,我们能够总结出以下的几点 + +- 当我们add进第一个元素到ArrayList的时候,elementData.length为0(因为还是一个空的list,有种懒加载的感觉??),但是此时执行了ensureCapacityInternal() 方法,通过默认的比较,此时会得到minCapacity为10,此时minCapacity - elementData.length > 0满足,所以会进入grow(minCapacity)方法 +- 当add第二个元素的时候,minCapacity为2,此时elementData.length()在添加第一个元素后,扩容变成了10,此时minCapacity - elementData.length > 0 不成立,所以不会进入(执行)grow(minCapacity)方法。 +- 同时我们继续添加元素 3,4 .... 11,到第11个元素的时候,minCapacity(11) 比 10更大,那么会触发grow操作 + +## 参考 + +- https://blog.csdn.net/jmlqqs/article/details/107128147 +- https://www.cnblogs.com/clover-forever/p/13155160.html \ No newline at end of file diff --git "a/Java/JVM\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266/README.md" "b/Java/JVM\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..2676d6347af3e80a6672635f801cf94a1a365425 --- /dev/null +++ "b/Java/JVM\347\261\273\345\212\240\350\275\275\346\234\272\345\210\266/README.md" @@ -0,0 +1,65 @@ +# JVM类加载机制 + +## 类加载器 + +虚拟机设计团队把加载动作放到JVM外部实现,以便于引用程序决定如何获取所需的类,JVM提供了三种类加载器 + +### 启动类加载器 + +Bootstrap ClassLoader,负责加载JAVA_HOME\lib目录中的,或通过-Xbootclasspath 参数指定路径下的,且被虚拟机认可(按文件名识别,如tr.jar)的类 + +### 扩展类加载器 + +Extension ClassLoader,负责加载JAVA_HOME\lib\ext目录中的,或通过java.ext.dirs系统变量指定路径中的类库。 + +### 应用程序类加载器 + +Application ClassLoader,负责加载用户路径(classpath)上的类库。JVM通过双亲委派进行类的加载,当然我们也可以通过继承java.lang.ClassLoader实现自定义的类加载器。 + +## 类加载过程 + +JVM类加载机制主要分为以下五个部分:加载、验证、准备、解析、初始化 + +### 加载 + +加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的入口。注意这里不一定非得要从一个Class文件获取,这里既可以从ZIP包中读取(例如从jar包或者war包中读取),也可以在运行时计算生成(动态代理),也可以由其它文件生成(比如将JSP文件转换成对应的Class类) + +### 验证 + +这一阶段的主要目的就是为了确保Class文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。 + +### 准备 + +准备阶段是正式为类变量分配内存并设置类变量的初始值阶段,即在方法区中分配这些变量所使用的内存空间。 + +注意这里所说的初始值概念,比如一个类变量定义为: v = 8080,实际上变量v在准备阶段过后的初始值为0,而不是8080,将v赋值为808的put static指令是在程序被编译后,存放在类构造器方法之中。 + +但是注意如果使用的是以下申明 + +``` +public static final int v = 8080; +``` + +在编译阶段会给v生成ConstantValue属性,在准备阶段虚拟机会根据ConstantValue属性将v赋值为8080 + +### 解析 + +解析阶段是指虚拟机将常量池中的符号引用替换为直接引用的过程。符号引用就是class文件中的类型常量 + +``` +CONSTANT_CLASS_info +CONSTANT_Field_info +CONSTANT_Method_info +``` + +#### 符号引用 + +符号引用与虚拟机实现的布局无关,引用的目标并不一定要已经加载到内存中。各种虚拟机实现的内存布局可以各不相同,但是它们能接受的符号引用必须一致的,因为符号引用的字面量形式明确定义在Java虚拟机规范的Class的文件格式中。编译时,java类并不知道所引用的类的实际地址,因此只能使用符号引用来代替。比如org.simple.People类引用了org.simple.Language类,在编译时People类并不知道Language类的实际内存地址,因此只能使用符号org.simple.Language(假设是这个,当然实际中是由类似于CONSTANT_Class_info的常量来表示的)来表示Language类的地址。各种虚拟机实现的内存布局可能有所不同,但是它们能接受的符号引用都是一致的,因为符号引用的字面量形式明确定义在Java虚拟机规范的Class文件格式中 + +#### 直接引用 + +直接引用可以是指向目标的指针,相对于偏移量或是一个能直接定位到目标的句柄,如果有了直接引用,那引用的目标必定已经在内存中存在了。 + +### 初始化 + +初始化阶段是类加载的最后一个阶段,前面的类加载阶段之后,除了在加载阶段可以自定义类加载器以外,其它操作都是由JVM主导,到了初始化阶段,才开始真正指定类中定义的Java程序代码。 \ No newline at end of file diff --git "a/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/README.md" "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..823a588ef9af29db0c55dbfb0ac3151382a36274 --- /dev/null +++ "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/README.md" @@ -0,0 +1,263 @@ +# Java中的双亲委派机制以及如何打破 + +## 什么是双亲委派机制 + +当一个类收到了类的加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一层的类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试自己去加载。 + +采用双亲委派机制的一个好处是比如加载位于 rt.jar 包中的类 java.lang.Object,不管是哪个加载器加载这个类,最终都是委托顶层的启动类加载器进行加载,这样保证了使用不同的类加载器最终得到的都是同一个Object对象。 + +![image-20200714165606650](images/image-20200714165606650.png) + +## 工作原理 + +- 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行; +- 如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器; +- 如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。 + +![image-20200714171803291](images/image-20200714171803291.png) + +## Java类加载器 + +Java的类加载器有四种 + +- Bootstrap ClassLoader:根类加载器,负责加载Java的核心类,它不是java.lang.ClassLoader的子类,而是由JVM自身实现 +- Extension ClassLoader:扩展类加载器,扩展类加载器的加载路径是JDK目录下 jre/lib/ext,通过扩展类加载器的getParent() 方法返回的是null,实际上扩展类加载器的父类是根加载器 +- System ClassLoader:系统(应用)类加载器,它负责在JVM启动时加载来自java 命令的 -classpath选项,或者通过CLASSPATH环境变量所指定的jar包和类路径。 +- User ClassLoader:自定义类加载器,加载用户创建的自定义类 + +## 双亲委派机制举例 + +当我们加载jdbc.jar 用于实现数据库连接的时候,首先我们需要知道的是 jdbc.jar是基于SPI接口进行实现的,所以在加载的时候,会进行双亲委派,最终从根加载器中加载 SPI核心类,然后在加载SPI接口类,接着在进行反向委派,通过线程上下文类加载器进行实现类 jdbc.jar的加载。 + +![image-20200714171918988](images/image-20200714171918988.png) + +## 沙箱机制 + +我们创建一个自定义string类,但是在加载自定义String类的时候会率先使用引导类加载器加载,而引导类加载器在加载的过程中会先加载jdk自带的文件(rt.jar包中java\lang\String.class),报错信息说没有main方法,就是因为加载的是rt.jar包中的string类。这样可以保证对java核心源代码的保护,这就是沙箱安全机制。 + +## 双亲委派机制的优势 + +通过上面的例子,我们可以知道,双亲机制可以 + +- 避免类的重复加载 +- 保护程序安全,防止核心API被随意篡改 + - 自定义类:java.lang.String + - 自定义类:java.lang.ShkStart(报错:阻止创建 java.lang开头的类) + +## 为什么要打破双亲委派机制? + +打破双亲委派机制的场景有很多:JDBC、JNDI、Tomcat等,我们以Tomcat为例来说明 + +### Tomcat为什么要打破双亲委派机制 + +首先tomcat是一个web容器,主要是需要解决以下问题 + +- 一个web容器可能要部署两个或多个应用程序,不同的应用程序之间可能会依赖同一个第三方类库的不同版本,因此要保证每个应用程序的类库都是独立的、相互隔离的 +- 部署在同一个web容器中的相同类库的相同版本可以共享,否则,会有重复的类库被加载进JVM中 +- web容器也有自己的类库,不能和应用程序的类库混淆,需要相互隔离 +- web容器支持jssp文件修改后不用重启,jsp文件也要编译成.class文件的,支持HotSwap功能 + +### Tomcat使用Java默认加载器的问题 + +默认的类加载器无法加载两个相同类库的不同版本,它只在乎类的全限定类名,并且只有一份,所以无法解决上面的问题1和问题3,也就是相关隔离的问题。 + +同时在修改jsp文件后,因为类名一样,默认的类加载器不会重新加载,而是使用方法区中已经存在的类,所以需要每个jsp对应一个唯一的类加载器,当修改jsp的时候,直接卸载唯一的类加载器,然后重新创建类加载器,并加载jsp文件。 + +### Tomcat的类加载机制 + +![image-20200714194835227](images/image-20200714194835227.png) + +tomcat有多个自定义类加载器 + +- CommonClassLoader:tomcat最基本的类加载器,加载路径中class可以被tomcat和各个webapp访问 +- CatalinaClassLoader:tomcat私有类加载器,webapp不能访问其加载路径下的class,即对webapp不可见 +- SharedClassLoader:各个webapp共享的类加载器,对tomcat不可见 +- WebappClassLoader:webapp私有的类加载器,只对当前webapp可见 +- JasperClassLoader:JSP的类加载器 + +每个web应用程序都对应一个WebappClassLoader,每一个jsp文件对应一个JasperClassLoader,所以这两个类加载器有多个实例。 + +### 工作原理 + +- CommonClassLoader能加载的类都可以被CatalinaClassLoader使用,从而实现了公有类库的共用。 +- CatalinaClassLoader 和 SharedClassLoader 自己能加载的类则与对方相互隔离 +- WebappClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader实例之间相互隔离,多个WebAppClassLoader是同级关系。 +- JspClassLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.class文件,它出现的目的就是为了被丢弃;当web容器检测到JSP文件被修改时,会替换掉目前的JasperClassLoader实例,并通过在创建一个Jsp类加载器来实现JSP文件的HotSwap功能 +- tomcat目录结构,与上面的类加载器对应 + - /common/* + - /server/* + - /shared/* + - WEB-INF/* +- 默认情况下,conf目录下的catalina.properties文件,没有指定server.loader以及shared.loader,所以tomcat没有建立CatalinaClassLoader和SharedClassLoader实例,这两个都会使用CommonClassLoader来代替。Tomcat6之后,把common、shared、server目录合成一个lib目录,所以我们服务器里看不到common、shared、server目录。 + +### Tomcat应用的默认加载顺序 + +- 先从JVM的BootStrapClassLoader中加载。 +- 加载Web应用下`/WEB-INF/classes`中的类。 +- 加载Web应用下`/WEB-INF/lib/*.jap`中的jar包中的类。 +- 加载上面定义的System路径下面的类。 +- 加载上面定义的Common路径下面的类。 + +### Tomcat类加载过程 + +- 先在本地缓存中查找是否已经加载过该类(对于一些已经加载了的类,会被缓存在resourceEntries这个数据结构中),如果已经加载即返回,否则继续下一步 +- 让系统类加载器(ApplicationClassLoader)尝试加载该类,主要是为了防止一些基础类会被web中的类覆盖,如果加载到即返回,返回继续 +- 前两步均没有加载到目标列,主要是为了防止一些基础类会被web中的类覆盖,如果加载到即返回,返回继续 +- 前两步均没加载到目标类,那么web应用的类加载器将自行加载,如果加载到则返回,否则继续下一步 +- 最后还是加载不到的话,则委托父类父类加载器(Common ClassLoader)去加载 + +## Tomcat打破双亲委派 + +![img](images/1187916-20200701044305758-214059128.png) + +如上图所示,上面的橙色部分还是和原来一样,采用的双亲委派机制, + +黄色部分是tomcat第一部分自定义的类加载器,这部分主要是加载tomcat包中的类,这一部分依然采用的是双亲委派机制 + +而绿色部分是tomcat第二部分自定义类加载器,正是这一部分,**打破了类的双亲委派机制** + +### Tomcat第一部分自定义类加载器(黄色部分) + +这部分类加载器,在tomcat7及以前是tomcat自定义的三个类加载器,分别在不同文件加载的jar包,而到了tomcat8及以后,tomcat将这三个文件夹合并了,合并成一个lib包,也就是我们现在看到的lib包 + +![img](images/1187916-20200701044717389-314223877.png) + +我们来看看这三个类加载器 的主要作用 + +- CommonClassLoader:tomcat最基本的类加载器,加载路径中的class可以被tomcat容器本身和各个webapp访问 +- CatalinaClassLoader:tomcat容器中私有的类加载器,加载路径中的class对webapp不可见 +- SharedClassLoader:各个webapps共享的类加载器,加载路径中的class对所有的webapp都课件,但是对tomcat容器不可见 + +这一部分类加载器,依然采用的是双亲委派机制,原因是它只有一份,如果有重复那也是以这一份为准 + +### Tomcat第二部分自定义类加载器(绿色部分) + +绿色是Java项目在打war包的时候,tomcat自动生成的类加载器,也就是说,每一个项目打成war包,tomcat都会自动生成一个类加载器,专门用来加载这个war包,而这个类加载器打破了双亲委派机制,我们可以想象一下,加入这个webapp类没有打破双亲委派机制会怎么样? + +如果没有打破,它就会委托父类加载器去加载,一旦加载到了,紫烈加载器就没有机会加载了,那么Spring4和Spring5的项目就没有可能共存了。 + +所以,这一部分它打破了双亲委派机制,这样一来webapp类加载器就不需要在让上级类去加载,它自己就可以加载对应的war里的class文件,当然了,其它的项目文件还是要委托上级加载的。 + +### 举例 + +我们首先列举一个场景,比如现在我有一个自定义类加载器,加载的是 /com/lxl/jvm/User1.class类,而在应用程序的target目录下也有一个 com/lxl/jvm/User1.class,那么最终User1.class这个类将被哪个类加载器加载呢?根据双亲委派机制,我们知道它一定是被应用程序类加载器AppClassLoader加载,而不是我们自定义的类加载器,为什么呢?因为他要向上寻找,向下委托,当找到以后,便不再向后执行了。 + +而我们要打破双亲委派机制,就是要让自定义类加载器来加载我们的User1.class,而不是应用程序类加载器来加载。 + +接下来分析,如何打破双亲委派机制?双亲委派机制是在那里实现的呢? + +双亲委派机制是在ClassLoader类的loadClass()中实现的,如果我们不想使用系统自带的双亲委派模型,只需要重新实现ClassLoader的loadClass()方法即可,下面是ClassLoader中定义的loadClass()方法,里面实现了双亲委派机制 + +![img](images/1187916-20200630063024959-377229775.png) + +下面给DefinedClassLoaderTest.java增加一个loadClass方法, 拷贝上面的代码即可. 删除掉中间实现双亲委派机制的部分 + +![img](images/1187916-20200630064955278-658375195.png) + +这里需要注意的是,com.lxl.jvm是自定义的雷暴,只有我们自己定义的类才可以从这里加载,如果是系统类,依然使用双亲委派机制来加载,下面来看看运行结果 + +```bash +# 调用user1的sout方法 +com.lxl.jvm.DefinedClassLoaderTest +``` + +现在User1方法确实是由自定义类加载器加载的了,源码如下 + +```java +package com.lxl.jvm; + +import java.io.FileInputStream; +import java.lang.reflect.Method; + +/** + * 自定义的类加载器 + */ +public class DefinedClassLoaderTest extends ClassLoader{ + + private String classPath; + + public DefinedClassLoaderTest(String classPath) { + this.classPath = classPath; + } + + /** + * 重写findClass方法 + * + * 如果不会写, 可以参考URLClassLoader中是如何加载AppClassLoader和ExtClassLoader的 + * @param name + * @return + * @throws ClassNotFoundException + */ + @Override + protected Class findClass(String name) throws ClassNotFoundException { + try { + byte[] data = loadBytes(name); + return defineClass(name, data, 0, data.length); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + + private byte[] loadBytes(String name) throws Exception { + // 我们需要读取类的路径 + String path = name.replace('.', '/').concat(".class"); + //String path = ""; + // 去路径下查找这个类 + FileInputStream fileInputStream = new FileInputStream(classPath + "/" + path); + int len = fileInputStream.available(); + + byte[] data = new byte[len]; + fileInputStream.read(data); + fileInputStream.close(); + + return data; + } + + protected Class loadClass(String name, boolean resolve) + throws ClassNotFoundException + { + synchronized (getClassLoadingLock(name)) { + // First, check if the class has already been loaded + Class c = findLoadedClass(name); + if (c == null) { + /** + * 直接执行findClass()...什么意思呢? 首先会使用自定义类加载器加载类, 不在向上委托, 直接由 + * 自己执行 + * + * jvm自带的类还是需要由引导类加载器自动加载 + */ + if (!name.startsWith("com.lxl.jvm")) { + c = this.getParent().loadClass(name); + } else { + c = findClass(name); + } + } + if (resolve) { + resolveClass(c); + } + return c; + } + } + + public static void main(String[] args) throws Exception { + DefinedClassLoaderTest classLoader = new DefinedClassLoaderTest("/Users/luoxiaoli"); + Class clazz = classLoader.loadClass("com.lxl.jvm.User1"); + Object obj = clazz.newInstance(); + Method sout = clazz.getDeclaredMethod("sout", null); + sout.invoke(obj, null); + System.out.println(clazz.getClassLoader().getClass().getName()); + } + +} +``` + + + +## 参考 + +- [打破双亲委派机制](https://www.cnblogs.com/ITPower/p/13211490.html) +- [tomcat是如何打破双亲委派机制的?](https://www.cnblogs.com/ITPower/p/13217145.html) +- + diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/006C8119.png" "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/006E1565.png" similarity index 100% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/006C8119.png" rename to "Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/006E1565.png" diff --git "a/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/1187916-20200630063024959-377229775.png" "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/1187916-20200630063024959-377229775.png" new file mode 100644 index 0000000000000000000000000000000000000000..078eab55c93890f7d407afee1ea0f860dd4097ca Binary files /dev/null and "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/1187916-20200630063024959-377229775.png" differ diff --git "a/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/1187916-20200630064955278-658375195.png" "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/1187916-20200630064955278-658375195.png" new file mode 100644 index 0000000000000000000000000000000000000000..351f32e5cf5232a9605fd876e7a56b739eb23d12 Binary files /dev/null and "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/1187916-20200630064955278-658375195.png" differ diff --git "a/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/1187916-20200701044305758-214059128.png" "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/1187916-20200701044305758-214059128.png" new file mode 100644 index 0000000000000000000000000000000000000000..9478f1011b41111b4158c029942af84b4e50fbbe Binary files /dev/null and "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/1187916-20200701044305758-214059128.png" differ diff --git "a/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/1187916-20200701044717389-314223877.png" "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/1187916-20200701044717389-314223877.png" new file mode 100644 index 0000000000000000000000000000000000000000..5db272844962589bfda2eb52208f104419632398 Binary files /dev/null and "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/1187916-20200701044717389-314223877.png" differ diff --git "a/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/image-20200714165606650.png" "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/image-20200714165606650.png" new file mode 100644 index 0000000000000000000000000000000000000000..c5a1db8bacd9d8c2ef3004743b951c3f33f13f18 Binary files /dev/null and "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/image-20200714165606650.png" differ diff --git "a/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/image-20200714171803291.png" "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/image-20200714171803291.png" new file mode 100644 index 0000000000000000000000000000000000000000..af7b4ea2e04ffdd5ff66fb86e0e75b1ba3c0bbd4 Binary files /dev/null and "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/image-20200714171803291.png" differ diff --git "a/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/image-20200714171918988.png" "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/image-20200714171918988.png" new file mode 100644 index 0000000000000000000000000000000000000000..d55d32294ca8b72a9d4543d67f2992a68cf9a656 Binary files /dev/null and "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/image-20200714171918988.png" differ diff --git "a/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/image-20200714194835227.png" "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/image-20200714194835227.png" new file mode 100644 index 0000000000000000000000000000000000000000..559c6f20c8bfbd353d07f4528aab0fcb6a609bc6 Binary files /dev/null and "b/Java/Java\344\270\255\347\232\204\345\217\214\344\272\262\345\247\224\346\264\276\346\234\272\345\210\266\344\273\245\345\217\212\345\246\202\344\275\225\346\211\223\347\240\264/images/image-20200714194835227.png" differ diff --git "a/Java/Java\344\275\277\347\224\250Redis\345\210\240\351\231\244\346\214\207\345\256\232\345\211\215\347\274\200Key/README.md" "b/Java/Java\344\275\277\347\224\250Redis\345\210\240\351\231\244\346\214\207\345\256\232\345\211\215\347\274\200Key/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..cd3aa9328d2218a5bee87e15b8650c061f550cda --- /dev/null +++ "b/Java/Java\344\275\277\347\224\250Redis\345\210\240\351\231\244\346\214\207\345\256\232\345\211\215\347\274\200Key/README.md" @@ -0,0 +1,18 @@ +前言 +-- + +最近很多模块使用了Redis进行数据的缓存,然后遇到一个问题就是删除缓存,有的键是这样的方式进行存储的 + +![](http://image.moguit.cn/e1b0b0ee535f44e2b168dcb4ee4e2e11) + +我们能发现,它们都是有特定的前缀的,如果我们需要根据指定前缀删除的话,因为redis没有提供根据前缀来删除key的方法 + +但是提供了另外一个方法,就是根据模糊查询出符合条件的key,然后在调用delete方法删除,具体代码为 + + // 获取Redis中特定前缀 + Set keys = stringRedisTemplate.keys("BLOG_SORT_BY_MONTH:" + "*"); + + // 删除 + stringRedisTemplate.delete(keys); + +> 需要注意的是:keys的操作会导致数据库暂时被锁住,其他的请求都会被堵塞;业务量大的时候会出问题 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/README.md" "b/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/README.md" similarity index 100% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/README.md" rename to "Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/README.md" diff --git "a/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/006C8119.png" "b/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/006C8119.png" new file mode 100644 index 0000000000000000000000000000000000000000..2f5a0909e69c926b7f5da44494b396d0e9c4686a Binary files /dev/null and "b/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/006C8119.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200328232620190.png" "b/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200328232620190.png" similarity index 100% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200328232620190.png" rename to "Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200328232620190.png" diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329093212035.png" "b/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329093212035.png" similarity index 100% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329093212035.png" rename to "Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329093212035.png" diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329105217945.png" "b/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329105217945.png" similarity index 100% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329105217945.png" rename to "Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329105217945.png" diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329113526771.png" "b/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329113526771.png" similarity index 100% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329113526771.png" rename to "Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329113526771.png" diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329114720558.png" "b/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329114720558.png" similarity index 100% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329114720558.png" rename to "Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329114720558.png" diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329114953888.png" "b/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329114953888.png" similarity index 100% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329114953888.png" rename to "Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329114953888.png" diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329122029227.png" "b/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329122029227.png" similarity index 100% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329122029227.png" rename to "Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329122029227.png" diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329144428207.png" "b/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329144428207.png" similarity index 100% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329144428207.png" rename to "Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329144428207.png" diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329153301047.png" "b/Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329153301047.png" similarity index 100% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329153301047.png" rename to "Java/Java\346\263\250\350\247\243\345\222\214\345\217\215\345\260\204/images/image-20200329153301047.png" diff --git "a/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/README.md" "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..062c8038acca9e6343688b7c2e20ea974eadefa7 --- /dev/null +++ "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/README.md" @@ -0,0 +1,95 @@ +# VisualVM安装VisualGC插件 + +## 前言 + +在我们安装的JDK中,提供了一个很棒的JVM调优工具,也就是 Java VisualVM,通过它我们能够看到很多关于我们Java程序的信息,比如查看 Eden,Survivor From, Survivor To区的空间使用情况,以及排查程序中那些对象造成OOM。 + +## VisualVM位置 + +我们可以通过找到安装JDK的目录 + +![image-20200707081132456](images/image-20200707081132456.png) + +或者使用cmd命令来打开图形化界面 + +```bash +jvisualvm +``` + +启动完成后,会有这样一个界面 + +![image-20200707081348427](images/image-20200707081348427.png) + +这就代表Java VisualVM启动成功 + +## 安装VisualGC插件 + +VIsualGC插件,是能够让我们通过图形化的页面,来查看我们的堆内存,以及各区使用情况 + +### 下载插件 + +首先我们需要到Visual的 [插件官网](https://visualvm.github.io/pluginscenters.html) 下载,我们需要找到自己的JDK版本 + +比如我的是JDK1.8,那么我就选择这里 + +![image-20200707081657123](images/image-20200707081657123.png) + +然后在找到VisualGC插件 + +![image-20200707081729473](images/image-20200707081729473.png) + +下载完成后,我们把插件放在下面目录下 + +```bash +C:\Users\Administrator\AppData\Roaming\VisualVM +``` + +![image-20200707081808350](images/image-20200707081808350.png) + +### 安装 + +然后在到我们刚刚打开的Visual VM图形化页面,点击工具 -> 插件 + +![image-20200707081904022](images/image-20200707081904022.png) + +然后在点击已下载 -> 添加插件 + +![image-20200707081952582](images/image-20200707081952582.png) + +找到刚刚我们的这个文件,然后选择安装 + +![image-20200707080814813](images/image-20200707080814813.png) + +安装成功后,我们通过写一个代码来进行检测 + +```java +/** + * OOM测试 + * + * @author: 陌溪 + * @create: 2020-07-06-21:11 + */ +public class OOMTest { + public static void main(String[] args) throws InterruptedException { + List list = new ArrayList<>(); + while(true) { + Thread.sleep(1); + list.add(999999999); + } + } +} +``` + +设置启动的JVM参数 + +```bash +-Xms100m -Xmx100m +``` + +最后点击Visual GC查看我们的堆内存情况 + +![image-20200707082203000](images/image-20200707082203000.png) + +等待一会后,我们发现S1区中,有了对象,说明JVM已经进行了第一次垃圾收集 + +![image-20200707082406853](images/image-20200707082406853.png) \ No newline at end of file diff --git "a/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707080814813.png" "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707080814813.png" new file mode 100644 index 0000000000000000000000000000000000000000..733a2a3fb34b691e032bcce3885946a2c6174234 Binary files /dev/null and "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707080814813.png" differ diff --git "a/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081132456.png" "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081132456.png" new file mode 100644 index 0000000000000000000000000000000000000000..5eaf9db57b8bd1315466971282790a78b8638bcb Binary files /dev/null and "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081132456.png" differ diff --git "a/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081348427.png" "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081348427.png" new file mode 100644 index 0000000000000000000000000000000000000000..9c19da3fd988a91fcab02c5b6a8f3c8713cb6765 Binary files /dev/null and "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081348427.png" differ diff --git "a/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081657123.png" "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081657123.png" new file mode 100644 index 0000000000000000000000000000000000000000..d14d04f6adb37af748cac08ee146397e937aae9b Binary files /dev/null and "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081657123.png" differ diff --git "a/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081729473.png" "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081729473.png" new file mode 100644 index 0000000000000000000000000000000000000000..9f35edb0d282666cf938b59ddc53cacad1cbe03f Binary files /dev/null and "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081729473.png" differ diff --git "a/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081808350.png" "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081808350.png" new file mode 100644 index 0000000000000000000000000000000000000000..5e9ec0d61bbd066ed3e5473699c4e1ab624afb58 Binary files /dev/null and "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081808350.png" differ diff --git "a/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081904022.png" "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081904022.png" new file mode 100644 index 0000000000000000000000000000000000000000..0df5ae5ff0946b7ee1353f9096dce8afb1197f3e Binary files /dev/null and "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081904022.png" differ diff --git "a/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081952582.png" "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081952582.png" new file mode 100644 index 0000000000000000000000000000000000000000..bb3cd9c4bf5625ec843774d706c0fa47cfa6e01f Binary files /dev/null and "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707081952582.png" differ diff --git "a/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707082203000.png" "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707082203000.png" new file mode 100644 index 0000000000000000000000000000000000000000..f803c5e3974ec1a4a7b70f83765c2a9f9ca26c7d Binary files /dev/null and "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707082203000.png" differ diff --git "a/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707082406853.png" "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707082406853.png" new file mode 100644 index 0000000000000000000000000000000000000000..2c0ef4691aaefdfa2960df83d4af20c7254bf7cb Binary files /dev/null and "b/Java/VisualVM\345\256\211\350\243\205VisualGC\346\217\222\344\273\266/images/image-20200707082406853.png" differ diff --git a/Java/images/1586532809883.png b/Java/images/1586532809883.png deleted file mode 100644 index ed79310f7bd7654e26aa79bd4f5951c44f20ed32..0000000000000000000000000000000000000000 Binary files a/Java/images/1586532809883.png and /dev/null differ diff --git a/Java/images/1586532838610.png b/Java/images/1586532838610.png deleted file mode 100644 index aba2037d0091636e4f678c7422fb47b3d8a01807..0000000000000000000000000000000000000000 Binary files a/Java/images/1586532838610.png and /dev/null differ diff --git a/Java/images/1586532855864.png b/Java/images/1586532855864.png deleted file mode 100644 index ab7703cf21695bd99aeca63ca7ec6604ad6a0a4c..0000000000000000000000000000000000000000 Binary files a/Java/images/1586532855864.png and /dev/null differ diff --git a/Java/images/1586532865716.png b/Java/images/1586532865716.png deleted file mode 100644 index f0b855b6ee5aecfb18711b16e463c3c48c1918eb..0000000000000000000000000000000000000000 Binary files a/Java/images/1586532865716.png and /dev/null differ diff --git a/Java/images/1586532880409.png b/Java/images/1586532880409.png deleted file mode 100644 index 64f7088519270a836bc5b29131eb27c782de644e..0000000000000000000000000000000000000000 Binary files a/Java/images/1586532880409.png and /dev/null differ diff --git a/Java/images/1586532894138.png b/Java/images/1586532894138.png deleted file mode 100644 index 95313920f1717881f43493b83beae40d79c18676..0000000000000000000000000000000000000000 Binary files a/Java/images/1586532894138.png and /dev/null differ diff --git a/Java/images/1586532906785.png b/Java/images/1586532906785.png deleted file mode 100644 index ff3afb56047013e07d7b4384b7b2f1838a81c3ec..0000000000000000000000000000000000000000 Binary files a/Java/images/1586532906785.png and /dev/null differ diff --git a/Java/images/1586532920198.png b/Java/images/1586532920198.png deleted file mode 100644 index 08aaf2e3d75a43cb874e8b5873c781aa08ac74e5..0000000000000000000000000000000000000000 Binary files a/Java/images/1586532920198.png and /dev/null differ diff --git a/Java/images/1586532929437.png b/Java/images/1586532929437.png deleted file mode 100644 index 46a502f5da694b7b62eb912196dcc3572eca694b..0000000000000000000000000000000000000000 Binary files a/Java/images/1586532929437.png and /dev/null differ diff --git a/Java/images/1586532942126.png b/Java/images/1586532942126.png deleted file mode 100644 index 793b124274af7de0d2e2bc01a0441d99154ee34d..0000000000000000000000000000000000000000 Binary files a/Java/images/1586532942126.png and /dev/null differ diff --git a/Java/images/1586532954258.png b/Java/images/1586532954258.png deleted file mode 100644 index fd5fee9d2eaf84dd0d0c1fbc9fe60ffd486d3272..0000000000000000000000000000000000000000 Binary files a/Java/images/1586532954258.png and /dev/null differ diff --git a/Java/images/1586532964536.png b/Java/images/1586532964536.png deleted file mode 100644 index 7a2771bdfe1166761ec5ff653a8e1660252675e3..0000000000000000000000000000000000000000 Binary files a/Java/images/1586532964536.png and /dev/null differ diff --git a/Java/images/image-20200410095255234.png b/Java/images/image-20200410095255234.png deleted file mode 100644 index fc5d3150d6b6c222bed355577ac2dffe928f3681..0000000000000000000000000000000000000000 Binary files a/Java/images/image-20200410095255234.png and /dev/null differ diff --git a/Java/images/image-20200411085724059.png b/Java/images/image-20200411085724059.png deleted file mode 100644 index 182436f81210b18d3b46799f7966010c5675dd5b..0000000000000000000000000000000000000000 Binary files a/Java/images/image-20200411085724059.png and /dev/null differ diff --git a/Java/test.md b/Java/test.md deleted file mode 100644 index 3d4b1a4b54f171d49bd7ba6efd802ac86c1d53ed..0000000000000000000000000000000000000000 --- a/Java/test.md +++ /dev/null @@ -1,222 +0,0 @@ -# 主要特性 - -- Lambda表达式 -- 函数式接口 -- 方法引用与构造器引用 -- Stream API -- 接口中默认方法与静态方法 -- 新时间日期API -- 最大化减少空指针异常(Optional) -- 。。。。 - -## HashMap优化 - -### HashMap1.7 - -在JDK1.7 到 JDK1.8的时候,对HashMap做了优化 - -首先JDK1.7的HashMap当出现Hash碰撞的时候,最后插入的元素会放在前面,这个称为 “头插法” - -> JDK7用头插是考虑到了一个所谓的热点数据的点(新插入的数据可能会更早用到),但这其实是个伪命题,因为JDK7中rehash的时候,旧链表迁移新链表的时候,如果在新表的数组索引位置相同,则链表元素会倒置(就是因为头插) 所以最后的结果 还是打乱了插入的顺序 所以总的来看支撑JDK7使用头插的这点原因也不足以支撑下去了 所以就干脆换成尾插 一举多得 - -![img](images/1586532809883.png) - -### HashMap1.7存在死链问题 - -参考:[hashmap扩容时死循环问题](https://blog.csdn.net/chenyiminnanjing/article/details/82706942) - -在JDK1.8以后,由头插法改成了尾插法,因为头插法还存在一个死链的问题 - -在说死链问题时,我们先从Hashmap存储数据说起,下面这个是HashMap的put方法 - -``` -public V put(K key, V value) -{ - ...... - //计算Hash值 - int hash = hash(key.hashCode()); - int i = indexFor(hash, table.length); - //各种校验吧 - for (Entry e = table[i]; e != null; e = e.next) { - Object k; - if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { - V oldValue = e.value; - e.value = value; - e.recordAccess(this); - return oldValue; - } - } - modCount++; - //该key不存在,需要增加一个结点 - addEntry(hash, key, value, i); - return null; -} -``` - -这里添加一个节点需要检查是否超出容量,出现一个负载因子 - -``` -void addEntry(int hash, K key, V value, int bucketIndex) -{ - Entry e = table[bucketIndex]; - table[bucketIndex] = new Entry(hash, key, value, e); - //查看当前的size是否超过了我们设定的阈值threshold,如果超过,需要resize - if (size++ >= threshold) - resize(2 * table.length);//扩容都是2倍2倍的来的, -} -``` - -> HashMap有 负载因子:0.75,以及 初始容量:16,扩容阈值:16*0.75 = 12,当HashMap达到扩容的条件时候,会把HashMap中的每个元素,重新进行运算Hash值,打入到扩容后的数组中。 - -既然新建了一个更大尺寸的hash表,然后把数据从老的Hash表中迁移到新的Hash表中。 - -``` -void resize(int newCapacity) -{ - Entry[] oldTable = table; - int oldCapacity = oldTable.length; - ...... - //创建一个新的Hash Table - Entry[] newTable = new Entry[newCapacity]; - - //将Old Hash Table上的数据迁移到New Hash Table上 - transfer(newTable); - table = newTable; - threshold = (int)(newCapacity * loadFactor); -} -``` - -重点在这个transfer()方法 - -``` -void transfer(Entry[] newTable) -{ - Entry[] src = table; - int newCapacity = newTable.length; - //下面这段代码的意思是: - // 从OldTable里摘一个元素出来,然后放到NewTable中 - for (int j = 0; j < src.length; j++) { - Entry e = src[j]; - if (e != null) { - src[j] = null; - do { - Entry next = e.next; - int i = indexFor(e.hash, newCapacity); - e.next = newTable[i]; - newTable[i] = e; - e = next; - } while (e != null); - } - } -} -``` - -do循环里面的是最能说明问题的,当只有一个线程的时候: - -![img](images/1586532838610.png) - -最上面的是old hash 表,其中的Hash表的size=2, 所以key = 3, 7, 5,在mod 2以后都冲突在table[1]这里了。接下来的三个步骤是Hash表 扩容变成4,然后在把所有的元素放入新表 - -``` -do { - Entry next = e.next; // <--假设线程一执行到这里就被调度挂起了 - int i = indexFor(e.hash, newCapacity); - e.next = newTable[i]; - newTable[i] = e; - e = next; -} while (e != null); -``` - -而我们的线程二执行完成了。于是我们有下面的这个样子 - -![img](images/1586532855864.png) - -![img](images/1586532865716.png) - -注意,因为Thread1的 e 指向了key(3),而next指向了key(7),其在线程二rehash后,指向了线程二重组后的链表。我们可以看到链表的顺序被反转后。 这里的意思是线程1这会还没有完全开始扩容,但e和next已经指向了,线程2是正常的扩容的,那这会在3这个位置上,就是7->3这个顺序。 然后线程一被调度回来执行: - -先是执行 newTalbe[i] = e; 然后是e = next,导致了e指向了key(7), 而下一次循环的next = e.next导致了next指向了key(3) 注意看图里面的线,线程1指向线程2里面的key3. - -![img](images/1586532880409.png) - -线程一接着工作。把key(7)摘下来,放到newTable[i]的第一个,然后把e和next往下移。 - -![img](images/1586532894138.png) - -这时候,原来的线程2里面的key7的e和key3的next没了,e=key3,next=null。 - -当继续执行,需要将key3加回到key7的前面。 e.next = newTable[i] 导致 key(3).next 指向了 key(7) - -注意:此时的key(7).next 已经指向了key(3), 环形链表就这样出现了。 - -![img](images/1586532906785.png) - -线程2生成的e和next的关系影响到了线程1里面的情况。从而打乱了正常的e和next的链。于是,当我们的线程一调用到,HashTable.get(11)时,即又到了3这个位置,需要插入新的,那这会就e 和next就乱了 - -### HashMap每次扩容为什么是2倍 - -参考:[HashMap初始容量为什么是2的n次幂](https://blog.csdn.net/apeopl/article/details/88935422) - -首先看向HashMap中添加元素是怎么存放的 - -![img](images/1586532920198.png) - -![img](images/1586532929437.png) - -第一个截图是向HashMap中添加元素putVal()方法的部分源码,可以看出,向集合中添加元素时,会使用(n - 1) & hash的计算方法来得出该元素在集合中的位置;而第二个截图是HashMap扩容时调用resize()方法中的部分源码,可以看出会新建一个tab,然后遍历旧的tab,将旧的元素进过e.hash & (newCap - 1)的计算添加进新的tab中,也就是(n - 1) & hash的计算方法,其中n是集合的容量,hash是添加的元素进过hash函数计算出来的hash值 - -HashMap的容量为什么是2的n次幂,和这个(n - 1) & hash的计算方法有着千丝万缕的关系,符号&是按位与的计算,这是位运算,计算机能直接运算,特别高效,按位与&的计算方法是,只有当对应位置的数据都为1时,运算结果也为1,当HashMap的容量是2的n次幂时,(n-1)的2进制也就是1111111***111这样形式的,这样与添加元素的hash值进行位运算时,能够充分的散列,使得添加的元素均匀分布在HashMap的每个位置上,减少hash碰撞,下面举例进行说明。 - -当HashMap的容量是16时,它的二进制是10000,(n-1)的二进制是01111,与hash值得计算结果如下: - -![img](images/1586532942126.png) - -上面四种情况我们可以看出,不同的hash值,和(n-1)进行位运算后,能够得出不同的值,使得添加的元素能够均匀分布在集合中不同的位置上,避免hash碰撞,下面就来看一下HashMap的容量不是2的n次幂的情况,当容量为10时,二进制为01010,(n-1)的二进制是01001,向里面添加同样的元素,结果为: - -![img](images/1586532954258.png) - -可以看出,有三个不同的元素进过&运算得出了同样的结果,严重的hash碰撞了。 - -终上所述,HashMap计算添加元素的位置时,使用的位运算,这是特别高效的运算;另外,HashMap的初始容量是2的n次幂,扩容也是2倍的形式进行扩容,是因为容量是2的n次幂,可以使得添加的元素均匀分布在HashMap中的数组上,减少hash碰撞,避免形成链表的结构,使得查询效率降低 - -### JDK1.8结构变化 - -由JDK1.7的,数组 + 链表 - -JDK1.8变为:数组 + 链表 + 红黑树 - -具体触发条件为:某个链表连接的个数大于8,并且总的容量大于64的时候,那么会把原来的链表转换成红黑树 - -这么做的好处是什么:除了添加元素外,查询和删除效率比链表快 - -红黑树查询、增加和删除的时间复杂度:O(log2n) - -链表的查询和删除的时间复杂度: O(n),插入为:O(1) - -### ConcurrentHashMap变化 - -#### 为何JDK8要放弃分段锁? - -由原来的分段锁,变成了CAS,也就是通过无锁化设计替代了阻塞同步的加锁操作,性能得到了提高。 - -通过分段锁的方式提高了并发度。分段是一开始就确定的了,后期不能再进行扩容的,其中的段Segment继承了重入锁ReentrantLock,有了锁的功能,同时含有类似HashMap中的数组加链表结构(这里没有使用红黑树),虽然Segment的个数是不能扩容的,但是单个Segment里面的数组是可以扩容的。 - -JDK1.8的ConcurrentHashMap摒弃了1.7的segment设计,而是JDK1.8版本的HashMap的基础上实现了线程安全的版本,即也是采用**数组+链表+红黑树**的形式,虽然ConcurrentHashMap的读不需要锁,但是需要保证能读到最新数据,所以必须加volatile。即数组的引用需要加volatile,同时一个Node节点中的val和next属性也必须要加volatile。 - -至于为什么抛弃Segment的设计,是因为分段锁的这个段不太好评定,如果我们的Segment设置的过大,那么隔离级别也就过高,那么就有很多空间被浪费了,也就是会让某些段里面没有元素,如果太小容易造成冲突 - -## 内存结构优化 - -取消永久区,把方法区 放在 元空间中 - -> 方法区主要用于存储一些类模板 - -![img](images/1586532964536.png) - -OOM错误发生概率降低 - -同时相关JVM调优命令变为: - -> MetaspaceSize -> -> MaxMetaspaceSize \ No newline at end of file diff --git "a/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/README.md" "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b49bfb386862faa34be1426a7a56f3845c6ebdfd --- /dev/null +++ "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/README.md" @@ -0,0 +1,272 @@ +# Java使用Ip2region替代淘宝IP接口 + +## 前言 + +前段时间淘宝的IP接口宕机,导致无法直接获取到IP信息,同时调用淘宝的ip也返回缓慢,直接拖慢了系统的运行效率,导致我只能注释掉原来通过淘宝获取ip的接口。 + +![image-20200531084039501](images/image-20200531084039501.png) + +这段时间貌似淘宝的IP接口又悄悄的上线了 + +![image-20200531084132125](images/image-20200531084132125.png) + +但是通过观察我发现,貌似需要通过accessKey才能够继续访问了,然后我找了一段时间,也没有看到哪里能够申请访问的密钥,故此打算放弃淘宝IP接口了。 + +后面通过Github发现一款非常不错的IP转换工具:[Ip2region](https://github.com/lionsoul2014/ip2region),它能够让原来IP转换成城市信息直接离线计算,而不需要通过网络请求的方式,这样大大降低了我们的网络开销。 + +## 介绍 + +ip2region - 准确率99.9%的离线IP地址定位库,0.0x毫秒级查询,ip2region.db数据库只有数MB。 + +全部的查询客户端单次查询都在0.x毫秒级别,内置了三种查询算法 + +- memory算法:整个数据库全部载入内存,单次查询都在0.1x毫秒内,C语言的客户端单次查询在0.00x毫秒级别。 +- binary算法:基于二分查找,基于ip2region.db文件,不需要载入内存,单次查询在0.x毫秒级别。 +- b-tree算法:基于btree算法,基于ip2region.db文件,不需要载入内存,单词查询在0.x毫秒级别,比binary算法更快。 + +## 引入 + +首先我们需要引入对应的Maven依赖 + +``` + + org.lionsoul + ip2region + 1.7.2 + +``` + +然后我们再去[ip2region的官网](https://github.com/lionsoul2014/ip2region/tree/master/data)下载到ip数据库,也就是这个文件 + +![image-20200531084709141](images/image-20200531084709141.png) + +然后我们放在我们工具类的resource目录下,创建一个city文件夹存放 + +![image-20200531084752121](images/image-20200531084752121.png) + +然后在原来的IP工具类中,添加下面方法 + +``` + public static String getCityInfo(String ip) { + + //db + String dbPath = IpUtils.class.getResource("/city/ip2region.db").getPath(); + + File file = new File(dbPath); + if (file.exists() == false) { + System.out.println("Error: Invalid ip2region.db file"); + } + + //查询算法 + //B-tree, B树搜索(更快) + int algorithm = DbSearcher.BTREE_ALGORITHM; + + //Binary,使用二分搜索 + //DbSearcher.BINARY_ALGORITHM + + //Memory,加载内存(最快) + //DbSearcher.MEMORY_ALGORITYM + try { + DbConfig config = new DbConfig(); + DbSearcher searcher = new DbSearcher(config, dbPath); + + //define the method + Method method = null; + switch (algorithm) { + case DbSearcher.BTREE_ALGORITHM: + method = searcher.getClass().getMethod("btreeSearch", String.class); + break; + case DbSearcher.BINARY_ALGORITHM: + method = searcher.getClass().getMethod("binarySearch", String.class); + break; + case DbSearcher.MEMORY_ALGORITYM: + method = searcher.getClass().getMethod("memorySearch", String.class); + break; + } + + DataBlock dataBlock = null; + if (Util.isIpAddress(ip) == false) { + System.out.println("Error: Invalid ip address"); + } + + dataBlock = (DataBlock) method.invoke(searcher, ip); + String ipInfo = dataBlock.getRegion(); + if (!StringUtils.isEmpty(ipInfo)) { + ipInfo = ipInfo.replace("|0", ""); + } + return ipInfo; + + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } +``` + +最后通过main方法进行测试 + +``` + public static void main(String args[]) { + String ip="220.248.12.158"; + String cityIpString = getCityInfo(ip); + System.out.println(cityIpString); + } +``` + +运行结果 + +![image-20200531084854577](images/image-20200531084854577.png) + +在上述方法中,还提供了三种查询的策略,具体介绍在上文已经说过 + +``` +//查询算法 +//B-tree, B树搜索(更快) +int algorithm = DbSearcher.BTREE_ALGORITHM; + +//Binary,使用二分搜索 +//DbSearcher.BINARY_ALGORITHM + +//Memory,加载内存(最快) +//DbSearcher.MEMORY_ALGORITYM +``` + +我目前采用的是B树进行查找,然后将查询出来的IP存储在redis中,同时设置过期时间为1天,这样能够降低我们的内存消耗,虽然可能就是第一次查询的时候稍微慢一些。 + +``` + //从Redis中获取IP来源 + String jsonResult = redisUtil.get(SysConf.IP_SOURCE + BaseSysConf.REDIS_SEGMENTATION + ip); + if (StringUtils.isEmpty(jsonResult)) { + String addresses = IpUtils.getAddresses(SysConf.IP + SysConf.EQUAL_TO + ip, SysConf.UTF_8); + if (StringUtils.isNotEmpty(addresses)) { + exception.setIpSource(addresses); + redisUtil.setEx(SysConf.IP_SOURCE + BaseSysConf.REDIS_SEGMENTATION + ip, addresses, 24, TimeUnit.HOURS); + } + } else { + exception.setIpSource(jsonResult); + } +``` + +## 遇到的坑 + +上面的操作在IDEA中运行是没有问题的,但是如果你打包成jar包,部署到服务器中!!!就会出错 + +![image-20200531092458482](images/image-20200531092458482.png) + +也就是打包后的jar包,无法获取到我们的 `ip2region.db` 文件,那么我们需要做的就是把文件内容重新创建一个目录,然后通过IO流进行读取,下次读取的时候,会判断文件是否存在,如果存在的话,那么就直接返回该路径 + +``` + /** + * 创建ip2region文件 + * @return + */ + public static String createFtlFileByFtlArray() { + String ftlPath = "city/"; + return createFtlFile(ftlPath, "ip2region.db"); + } + + /** + * 创建文件 + * @param ftlPath + * @param ftlName + * @return + */ + private static String createFtlFile(String ftlPath, String ftlName) { + InputStream certStream = null; + try { + //获取当前项目所在的绝对路径 + String proFilePath = System.getProperty("user.dir"); + + //获取模板下的路径,然后存放在temp目录下  + String newFilePath = proFilePath + File.separator + "temp" + File.separator + ftlPath; + newFilePath = newFilePath.replace("/", File.separator); + //检查项目运行时的src下的对应路径 + File newFile = new File(newFilePath + ftlName); + if (newFile.isFile() && newFile.exists()) { + return newFilePath; + } + //当项目打成jar包会运行下面的代码,并且复制一份到src路径下(具体结构看下面图片) + certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(ftlPath + ftlName); + byte[] certData = org.apache.commons.io.IOUtils.toByteArray(certStream); + org.apache.commons.io.FileUtils.writeByteArrayToFile(newFile, certData); + return newFilePath; + } catch (Exception e) { + log.error(e.getMessage()); + } finally { + try { + certStream.close(); + } catch (Exception e) { + log.error(e.getMessage()); + } + } + return null; + } +``` + +然后是修改原来的getCityInfo接口 + +``` + public static String getCityInfo(String ip) { + + String dbPath = createFtlFileByFtlArray() + "ip2region.db"; + File file = new File(dbPath); + if (file.exists() == false) { + System.out.println("Error: Invalid ip2region.db file"); + } + + //查询算法 + //B-tree, B树搜索(更快) + int algorithm = DbSearcher.BTREE_ALGORITHM; + + //Binary,使用二分搜索 + //DbSearcher.BINARY_ALGORITHM + + //Memory,加载内存(最快) + //DbSearcher.MEMORY_ALGORITYM + try { + DbConfig config = new DbConfig(); + DbSearcher searcher = new DbSearcher(config, dbPath); + + //define the method + Method method = null; + switch (algorithm) { + case DbSearcher.BTREE_ALGORITHM: + method = searcher.getClass().getMethod("btreeSearch", String.class); + break; + case DbSearcher.BINARY_ALGORITHM: + method = searcher.getClass().getMethod("binarySearch", String.class); + break; + case DbSearcher.MEMORY_ALGORITYM: + method = searcher.getClass().getMethod("memorySearch", String.class); + break; + } + + DataBlock dataBlock = null; + if (Util.isIpAddress(ip) == false) { + System.out.println("Error: Invalid ip address"); + } + + dataBlock = (DataBlock) method.invoke(searcher, ip); + String ipInfo = dataBlock.getRegion(); + if (!StringUtils.isEmpty(ipInfo)) { + ipInfo = ipInfo.replace("|0", ""); + ipInfo = ipInfo.replace("0|", ""); + } + return ipInfo; + + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } +``` + +最后运行后,会发现在项目的根目录下,会创建一个temp目录,用于存放我们的`.db`文件 + +![image-20200531095340010](images/image-20200531095340010.png) + +我们再次打包部署服务器后,发现能够成功获取到IP城市信息了~ + +![image-20200531100104493](images/image-20200531100104493.png) \ No newline at end of file diff --git "a/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084039501.png" "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084039501.png" new file mode 100644 index 0000000000000000000000000000000000000000..c0edb0d17a571ad8593d3412f03b118ec9fa52a4 Binary files /dev/null and "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084039501.png" differ diff --git "a/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084132125.png" "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084132125.png" new file mode 100644 index 0000000000000000000000000000000000000000..408edbb5f7703e032c3638de0caa116f2955e789 Binary files /dev/null and "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084132125.png" differ diff --git "a/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084709141.png" "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084709141.png" new file mode 100644 index 0000000000000000000000000000000000000000..74fc6ced283cdc3f8324f4347134ab2548f7738d Binary files /dev/null and "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084709141.png" differ diff --git "a/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084752121.png" "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084752121.png" new file mode 100644 index 0000000000000000000000000000000000000000..66fef4ff3a4c763db073618b66109dda2a47dbea Binary files /dev/null and "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084752121.png" differ diff --git "a/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084854577.png" "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084854577.png" new file mode 100644 index 0000000000000000000000000000000000000000..fb27d3a9cb49196bd1fc4bfe13ef89ab89674645 Binary files /dev/null and "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531084854577.png" differ diff --git "a/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531092458482.png" "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531092458482.png" new file mode 100644 index 0000000000000000000000000000000000000000..b4be350e7f32df5d1e7abd442d5b3d6f37758970 Binary files /dev/null and "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531092458482.png" differ diff --git "a/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531095340010.png" "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531095340010.png" new file mode 100644 index 0000000000000000000000000000000000000000..a83fef237ff065d7510bdb2d49cce4aa30457c79 Binary files /dev/null and "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531095340010.png" differ diff --git "a/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531100104493.png" "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531100104493.png" new file mode 100644 index 0000000000000000000000000000000000000000..e0ffaf557685c486c41422f0bdcd02d0fffdbedf Binary files /dev/null and "b/Java/\344\275\277\347\224\250Ip2region\346\233\277\344\273\243\346\267\230\345\256\235IP\346\216\245\345\217\243/images/image-20200531100104493.png" differ diff --git "a/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/README.md" "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..94e8eee0285c8668d40a68d6e66b9f88edd0868f --- /dev/null +++ "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/README.md" @@ -0,0 +1,179 @@ +# 前后端分离项目解决跨域问题 + +## 前言 + +首先感谢群里小伙伴 **新** 反馈的问题,关于token刷新写入Cookie,以及图片裁剪出现跨域请求的问题。 + +作为前后端分离的项目,经常会遇到跨域问题,例如下面这样的 + +![image-20200612112134628](images/image-20200612112134628.png) + +因为使用vue启动的前端项目运行在 9528端口,而后台项目运行在8601端口,这样因为不同端口的原因就造成了跨域请求。 + +同时及时在相同的域名或者端口上,也有可能会遇到跨域问题,例如下面这个 + +![image-20200612112305182](images/image-20200612112305182.png) + +这是是因为在请求图片的时候遇到的一个跨域问题,但是这个图片只有在使用nginx静态代理到服务器上的图片时才会遇到,如果使用的是七牛云图片则不会出现问题。问题具体的场景是在图片裁剪的时候出现的。 + +![image-20200612112448397](images/image-20200612112448397.png) + +点击裁剪后,无法正常的显示图片 + +![image-20200612112437488](images/image-20200612112437488.png) + +## 关于跨域 + +跨域资源共享([CORS](https://developer.mozilla.org/zh-CN/docs/Glossary/CORS)) 是一种机制,它使用额外的 [HTTP](https://developer.mozilla.org/zh-CN/docs/Glossary/HTTP) 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器**不同的域、协议或端口**请求一个资源时,资源会发起一个**跨域 HTTP 请求**。 + +比如,站点 http://domain-a.com 的某 HTML 页面通过 [ 的 src ](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/Img#Attributes)请求 http://domain-b.com/image.jpg。网络上的许多页面都会加载来自不同域的CSS样式表,图像和脚本等资源。 + +出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非响应报文包含了正确CORS响应头。 + +Spring 中对 CORS 规则的校验,都是通过委托给 DefaultCorsProcessor实现的。 + +DefaultCorsProcessor 处理过程如下: + +- 判断依据是 Header中是否包含 Origin。如果包含则说明为 CORS请求,转到 2;否则,说明不是 CORS 请求,不作任何处理。 + +- 判断 response 的 Header 是否已经包含 Access-Control-Allow-Origin,如果包含,证明已经被处理过了, 转到 3,否则不再处理。 + +- 判断是否同源,如果是则转交给负责该请求的类处理 + 是否配置了 CORS 规则,如果没有配置,且是预检请求,则拒绝该请求,如果没有配置,且不是预检请求,则交给负责该请求的类处理。如果配置了,则对该请求进行校验。 + 校验就是根据 CorsConfiguration 这个类的配置进行判断: + + - 判断 origin 是否合法 + + - 判断 method 是否合法 + + - 判断 header是否合法 + +如果全部合法,则在 response header中添加响应的字段,并交给负责该请求的类处理,如果不合法,则拒绝该请求 + +## 前后端跨域问题 + +### 方法一 + +针对第一个问题,我们可以在我们后台的启动类上添加下面这个Bean即可, + +``` + @Bean + public WebMvcConfigurer corsConfigurer() { + return new WebMvcConfigurer() { + @Override + public void addCorsMappings(CorsRegistry registry) { + //配置允许跨域访问的路径 + registry.addMapping("/**/**") + .allowedOrigins("*") + .allowedMethods("*") + .allowedHeaders("*") + .allowCredentials(true) + .exposedHeaders("") + .maxAge(3600); + } + }; + } +``` + +### 方法二 + +或者使用下面的方法 + +``` + private CorsConfiguration buildConfig() { + CorsConfiguration corsConfiguration = new CorsConfiguration(); + corsConfiguration.addAllowedOrigin("*"); + corsConfiguration.addAllowedHeader("*"); + corsConfiguration.addAllowedMethod("*"); + return corsConfiguration; + } + + /** + * 跨域过滤器 + * + * @return + */ + @Bean + public CorsFilter corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", buildConfig()); + return new CorsFilter(source); + } +``` + +### 注意 + +在这里我推荐使用的是第一种方法,最开始我使用的是第二个方法来解决跨域的问题的,但是后面有了一个新的需求时,也就是我的token需要在将要过期的时候刷新,然后我需要在token刷新后,后台将token传递到前台,我后端代码是这样编写的 + +``` + if(StringUtils.isNotEmpty(onlineAdmin) && !jwtHelper.isExpiration(token, audience.getBase64Secret())) { + /** + * 得到过期时间 + */ + Date expirationDate = jwtHelper.getExpiration(token, audience.getBase64Secret()); + long nowMillis = System.currentTimeMillis(); + Date nowDate = new Date(nowMillis); + // 得到两个日期相差的间隔,秒 + Integer second = DateUtils.getSecondByTwoDay(expirationDate, nowDate); + // 如果小于5分钟,那么更新过期时间 + if(second < refreshSecond) { + // 生成一个新的Token + String newToken = tokenHead + jwtHelper.refreshToken(token, audience.getBase64Secret(), expiresSecond * 1000); + // 生成新的token,发送到客户端 + CookieUtils.setCookie("Admin-Token", newToken, expiresSecond.intValue()); + // 重新更新Redis中的过期时间 + redisUtil.setEx(RedisConf.LOGIN_TOKEN_KEY + RedisConf.SEGMENTATION + newToken, onlineAdmin, expiresSecond, TimeUnit.SECONDS); + } + } else { + chain.doFilter(request, response); + return; + } +``` + +这个时候就需要我在axios中进行如下配置,即添加 withCredentials=true 这样才能够让后端的token传递到前端 + +``` +// 创建axios实例 +const service = axios.create({ + baseURL: '', // api 的 base_url + withCredentials: true, //允许后台的cookie传递到前端 + timeout: 100000 // 请求超时时间 +}) + +``` + +关于 withCredentials + +>#### XMLHttpRequest 的 withCredentials 属性 +> +>- 默认值为false。在获取同域资源时设置 withCredentials 没有影响。 +>- true:在跨域请求时,会携带用户凭证 +>- false:在跨域请求时,不会携带用户凭证;返回的 response 里也会忽略 cookie + +但是如果我使用的是第二种解决跨域的方法,那么在我将这个值设置成true的时候,将无法进行登录,还是出现如下的问题,最后通过查阅资料,发现设置了第一种解决跨域的方法,能成功将token传递到前端,并且存入到Application 的 Cookie中。 + +![image-20200612152510503](images/image-20200612152510503.png) + +## 图片跨域问题 + +关于图片跨域问题的解决方法,主要是需要在nginx配置允许跨域,因为蘑菇博客的图片是存储在本地服务器中的,然后通过nginx进行静态资源映射过去的,从而出现上面的图片跨域问题。 + +解决方法,就是需要在nginx.conf文件中进行修改,添加如下内容 + +``` + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; + add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,lang,access-token'; + if ($request_method = 'OPTIONS') { + return 204; + } + +``` + +例如,我在 demoadmin.moguit.cn 和 demopicture.moguit.cn的nginx中的配置 + +![image-20200612151605982](images/image-20200612151605982.png) + +添加完成后,我们重启nginx,然后等待一段时间后,即可正常显示图片了~ + +![image-20200612151912943](images/image-20200612151912943.png) \ No newline at end of file diff --git "a/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612112134628.png" "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612112134628.png" new file mode 100644 index 0000000000000000000000000000000000000000..d960158015d65e24ec90b2d07ce9320b52d143c7 Binary files /dev/null and "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612112134628.png" differ diff --git "a/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612112305182.png" "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612112305182.png" new file mode 100644 index 0000000000000000000000000000000000000000..a211dd2a9619e6e51d0aced21e2d7c4bc885bde9 Binary files /dev/null and "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612112305182.png" differ diff --git "a/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612112437488.png" "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612112437488.png" new file mode 100644 index 0000000000000000000000000000000000000000..dd8cc06739f3f66e89fc357cec7064d4ec0c81e1 Binary files /dev/null and "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612112437488.png" differ diff --git "a/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612112448397.png" "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612112448397.png" new file mode 100644 index 0000000000000000000000000000000000000000..55f5a0a1a90c62142f8a6a90186d8c307fb480f7 Binary files /dev/null and "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612112448397.png" differ diff --git "a/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612151605982.png" "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612151605982.png" new file mode 100644 index 0000000000000000000000000000000000000000..0b6ed89695e99b90ef0011c4a576b3ae9be132d0 Binary files /dev/null and "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612151605982.png" differ diff --git "a/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612151912943.png" "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612151912943.png" new file mode 100644 index 0000000000000000000000000000000000000000..a5fea194fb94ccbd7f10459a5322ddb7dbf1d09d Binary files /dev/null and "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612151912943.png" differ diff --git "a/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612152510503.png" "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612152510503.png" new file mode 100644 index 0000000000000000000000000000000000000000..d960158015d65e24ec90b2d07ce9320b52d143c7 Binary files /dev/null and "b/Java/\345\211\215\347\253\257\347\232\204\344\270\200\344\272\233\350\267\250\345\237\237\351\227\256\351\242\230/images/image-20200612152510503.png" differ diff --git "a/Java/\346\263\233\345\236\213\347\232\204\347\261\273\345\236\213\346\223\246\351\231\244/README.md" "b/Java/\346\263\233\345\236\213\347\232\204\347\261\273\345\236\213\346\223\246\351\231\244/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..da1a859030c334c658e23b8fdaebce64a84b02bf --- /dev/null +++ "b/Java/\346\263\233\345\236\213\347\232\204\347\261\273\345\236\213\346\223\246\351\231\244/README.md" @@ -0,0 +1,158 @@ +前言 +-- + +Java 泛型(Generic)的引入加强了参数类型的安全性,减少了类型的转换,但有一点需要注意:Java 的泛型在编译器有效,在运行期被删除,也就是说所有泛型参数类型在编译后都会被清除掉,看下面一个列子,代码如下: + + public class Foo { + public void listMethod(List stringList){ + } + public void listMethod(List intList) { + } + } + +代码很简单,看起来没什么问题,但是编译器却报出如下错误信息: + + Method listMethod(List) has the same erasure listMethod(List) as another method in type Foo + +此错误的意思是说listMethod(List) 方法在编译时擦除类型后的方法是listMethod(List),它与另外一个方法重复,也就是方法签名重复。反编译之后的方法代码如下: + + public void listMethod(List list){ + } + +从上面代码可以看出 Java 编译后的字节码中已经没有泛型的任何信息,在编译后所有的泛型类型都会做相应的转化,转化如下: + +* List、List 擦除后的类型为 List。 +* List、List\[\] 擦除后的类型为 List\[\]。 +* List、List 擦除后的类型为 List。 +* List 擦除后类型为 List。 + +        Java 为什么这么处理呢?有以下两个原因: + +避免 JVM 的大换血。如果 JVM 将泛型类型延续到运行期,那么到运行期时 JVM 就需要进行大量的重构工作了,提高了运行期的效率。 +版本兼容。 在编译期擦除可以更好地支持原生类型(Raw Type)。 + +明白了 Java 泛型是类型擦除的,下面的问题就很好理解了: + +泛型的 class 对象是相同的 +---------------- + + 每个类都有一个 class 属性,泛型化不会改变 class 属性的返回值,例如: + + public static void main(String[] args) { + List ls = new ArrayList(); + List li = new ArrayList(); + System.out.println(ls.getClass() == li.getClass()); + } + +代码返回值为 true,原因很简单,List 和 List 擦除后的类型都是 List。 + + 泛型数组初始化时不能声明泛型类型 +----------------- + +如下代码编译时通不过: + + List[] list = new List[]; + +在这里可以声明一个带有泛型参数的数组,但是不能初始化该数组,因为执行了类型擦除操作后,List\[\] 与 List\[\] 就是同一回事了,编译器拒绝如此声明。 + +instanceof 不允许存在泛型参数 +-------------------- + +以下代码不能通过编译,原因一样,泛型类型被擦除了。 + + List list = new ArrayList(); + System.out.println(list instanceof List); + +错误信息如下: +Cannot perform instanceof check against parameterized type List. Use the form List instead since further generic type information will be erased at runtime + +类型擦除 +---- + +正确理解泛型概念的首要前提是理解类型擦除(type erasure)。 Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节代码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉。这个过程就称为类型擦除。如在代码中定义的List和List等类型,在编译之后都会变成List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法避免在运行时刻出现类型转换异常的情况。类型擦除也是Java的泛型实现方式与[C++模板机制](http://www.cplusplus.com/doc/tutorial/templates/)实现方式之间的重要区别。 + +很多泛型的奇怪特性都与这个类型擦除的存在有关,包括: + +* 泛型类并没有自己独有的Class类对象。比如并不存在List.class或是List.class,而只有List.class。 +* 静态变量是被泛型类的所有实例所共享的。对于声明为MyClass的类,访问其中的静态变量的方法仍然是 MyClass.myStaticVar。不管是通过new MyClass还是new MyClass创建的对象,都是共享一个静态变量。 +* 泛型的类型参数不能用在Java异常处理的catch语句中。因为异常处理是由JVM在运行时刻来进行的。由于类型信息被擦除,JVM是无法区分两个异常类型MyException和MyException的。对于JVM来说,它们都是 MyException类型的。也就无法执行与异常对应的catch语句。 + +类型擦除的基本过程也比较简单,首先是找到用来替换类型参数的具体类。这个具体类一般是Object。如果指定了类型参数的上界的话,则使用这个上界。把代码中的类型参数都替换成具体的类。同时去掉出现的类型声明,即去掉<>的内容。比如T get()方法声明就变成了Object get();List就变成了List。接下来就可能需要生成一些桥接方法(bridge method)。这是由于擦除了类型之后的类可能缺少某些必须的方法。比如考虑下面的代码: + + class MyString implements Comparable { + public int compareTo(String str) { + return 0; + } + } + +当类型信息被擦除之后,上述类的声明变成了class MyString implements Comparable。但是这样的话,类MyString就会有编译错误,因为没有实现接口Comparable声明的String compareTo(Object)方法。这个时候就由编译器来动态生成这个方法。 + +#### 实例分析 + +了解了类型擦除机制之后,就会明白编译器承担了全部的类型检查工作。编译器禁止某些泛型的使用方式,正是为了确保类型的安全性。以上面提到的List和List为例来具体分析: + + public void inspect(List list) { + for (Object obj : list) { + System.out.println(obj); + } + list.add(1); //这个操作在当前方法的上下文是合法的。 + } + public void test() { + List strs = new ArrayList(); + inspect(strs); //编译错误 + } + +这段代码中,inspect方法接受List作为参数,当在test方法中试图传入List的时候,会出现编译错误。假设这样的做法是允许的,那么在inspect方法就可以通过list.add(1)来向集合中添加一个数字。这样在test方法看来,其声明为List的集合中却被添加了一个Integer类型的对象。这显然是违反类型安全的原则的,在某个时候肯定会抛出[ClassCastException](http://download.oracle.com/javase/1.5.0/docs/api/java/lang/ClassCastException.html)。因此,编译器禁止这样的行为。编译器会尽可能的检查可能存在的类型安全问题。对于确定是违反相关原则的地方,会给出编译错误。当编译器无法判断类型的使用是否正确的时候,会给出警告信息。 + +#### 通配符与上下界 + +在使用泛型类的时候,既可以指定一个具体的类型,如List就声明了具体的类型是String;也可以用通配符?来表示未知类型,如List就声明了List中包含的元素类型是未知的。 通配符所代表的其实是一组类型,但具体的类型是未知的。List所声明的就是所有类型都是可以的。但是List并不等同于List。List实际上确定了List中包含的是Object及其子类,在使用的时候都可以通过Object来进行引用。而List则其中所包含的元素类型是不确定。其中可能包含的是String,也可能是 Integer。如果它包含了String的话,往里面添加Integer类型的元素就是错误的。正因为类型未知,就不能通过new ArrayList()的方法来创建一个新的ArrayList对象。因为编译器无法知道具体的类型是什么。但是对于 List中的元素确总是可以用Object来引用的,因为虽然类型未知,但肯定是Object及其子类。考虑下面的代码: + + public void wildcard(List list) { + list.add(1);//编译错误 + } + +如上所示,试图对一个带通配符的泛型类进行操作的时候,总是会出现编译错误。其原因在于通配符所表示的类型是未知的。 + +因为对于List中的元素只能用Object来引用,在有些情况下不是很方便。在这些情况下,可以使用上下界来限制未知类型的范围。 如List说明List中可能包含的元素类型是Number及其子类。而List则说明List中包含的是Number及其父类。当引入了上界之后,在使用类型的时候就可以使用上界类中定义的方法。比如访问 List的时候,就可以使用Number类的intValue等方法。 + +#### 类型系统 + +在Java中,大家比较熟悉的是通过继承机制而产生的类型体系结构。比如String继承自Object。根据[Liskov替换原则](http://en.wikipedia.org/wiki/Liskov_substitution_principle),子类是可以替换父类的。当需要Object类的引用的时候,如果传入一个String对象是没有任何问题的。但是反过来的话,即用父类的引用替换子类引用的时候,就需要进行强制类型转换。编译器并不能保证运行时刻这种转换一定是合法的。这种自动的子类替换父类的类型转换机制,对于数组也是适用的。 String\[\]可以替换Object\[\]。但是泛型的引入,对于这个类型系统产生了一定的影响。正如前面提到的List是不能替换掉List的。 + +引入泛型之后的类型系统增加了两个维度:一个是类型参数自身的继承体系结构,另外一个是泛型类或接口自身的继承体系结构。第一个指的是对于 List和List这样的情况,类型参数String是继承自Object的。而第二种指的是 List接口继承自Collection接口。对于这个类型系统,有如下的一些规则: + +* 相同类型参数的泛型类的关系取决于泛型类自身的继承体系结构。即List是Collection 的子类型,List可以替换Collection。这种情况也适用于带有上下界的类型声明。 +* 当泛型类的类型声明中使用了通配符的时候, 其子类型可以在两个维度上分别展开。如对Collection来说,其子类型可以在Collection这个维度上展开,即List和Set等;也可以在Number这个层次上展开,即Collection和 Collection等。如此循环下去,ArrayList和 HashSet等也都算是Collection的子类型。 +* 如果泛型类中包含多个类型参数,则对于每个类型参数分别应用上面的规则。 + +理解了上面的规则之后,就可以很容易的修正实例分析中给出的代码了。只需要把List改成List即可。List是List的子类型,因此传递参数时不会发生错误。 + +#### 开发自己的泛型类 + +泛型类与一般的Java类基本相同,只是在类和接口定义上多出来了用<>声明的类型参数。一个类可以有多个类型参数,如 MyClass。 每个类型参数在声明的时候可以指定上界。所声明的类型参数在Java类中可以像一般的类型一样作为方法的参数和返回值,或是作为域和局部变量的类型。但是由于类型擦除机制,类型参数并不能用来创建对象或是作为静态变量的类型。考虑下面的泛型类中的正确和错误的用法。 + + class ClassTest { + private X x; + private static Y y; //编译错误,不能用在静态变量中 + public X getFirst() { + //正确用法 + return x; + } + public void wrong() { + Z z = new Z(); //编译错误,不能创建对象 + } + } + +#### 泛型传递 + +即泛型可以当作参数在不同的实例化的类中传递,理论上来说可以无限制层次的传递下去。最终会约束每一层的方法或者类型的泛型确定,在《[泛型传递](http://www.raychase.net/2446)》这篇文章中对具体的用法进行详尽的描述。 + +#### 最佳实践 + +在使用泛型的时候可以遵循一些基本的原则,从而避免一些常见的问题。 + +* 在代码中避免泛型类和原始类型的混用。比如List和List不应该共同使用。这样会产生一些编译器警告和潜在的运行时异常。当需要利用JDK 5之前开发的遗留代码,而不得不这么做时,也尽可能的隔离相关的代码。 +* 在使用带通配符的泛型类的时候,需要明确通配符所代表的一组类型的概念。由于具体的类型是未知的,很多操作是不允许的。 +* 泛型类最好不要同数组一块使用。你只能创建new List\[10\]这样的数组,无法创建new List\[10\]这样的。这限制了数组的使用能力,而且会带来很多费解的问题。因此,当需要类似数组的功能时候,使用集合类即可。 +* 不要忽视编译器给出的警告信息。 \ No newline at end of file diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271AQS\347\232\204\347\220\206\350\247\243/README.md" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271AQS\347\232\204\347\220\206\350\247\243/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..9a8e67f1d4092b5bcc9af76d9d0dbbcabc3ee343 --- /dev/null +++ "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271AQS\347\232\204\347\220\206\350\247\243/README.md" @@ -0,0 +1,354 @@ +# 谈谈你对AQS的理解 + +## 前言 + +AQS:AbstractQueuedSynchronizer 抽象队列同步器 + +AQS是一个抽象类,是我们用到的锁的基础,例如我们经常用到的 + +- ReentrantLock +- Semaphore +- CountdownLatch +- ReentrantReadWriteLock +- ..... + +上述的提到的这些,其实内部都是基于AQS来实现的。 + +我们举下面的一个例子 + +```java +public class Main { + public static int m = 0; + + public static void main(String[] args) throws InterruptedException { + Thread[] threads = new Thread[100]; + for (int i = 0; i < threads.length; i++) { + threads[i] = new Thread(() -> { + for (int j = 0; j < 100; j++) { + m++; + } + }); + } + for (Thread t: threads) { + t.start(); + } + // 等待所有线程结束 + for (Thread t: threads) { + t.join(); + } + System.out.println(m); + } +} +``` + +运行结果,我们发现并不一样,这就是多线程在获取临界资源出现异常的情况 + +```bash +# 第一次 +9985 +# 第二次 +10000 +``` + +那么为什么会出现这样的问题呢? + +![image-20200717161505347](images/image-20200717161505347.png) + +## 解决方法1 + +针对上述的问题,就是因为线程来操作临界资源的时候,因为线程并发修改而造成数据不一致的问题,其实最简单的方法,就是通过引入Synchronized来给我们的对象上锁 + +```java +public class Main2 { + public static int m = 0; + + public static void main(String[] args) throws InterruptedException { + Thread[] threads = new Thread[100]; + for (int i = 0; i < threads.length; i++) { + threads[i] = new Thread(() -> { + synchronized (Main2.class) { + for (int j = 0; j < 100; j++) { + m++; + } + } + }); + } + for (Thread t: threads) { + t.start(); + } + // 等待所有线程结束 + for (Thread t: threads) { + t.join(); + } + System.out.println(m); + } +} +``` + +最后不管怎么执行,得到的结果都是 10000,为什么引入Synchronized就能让其保证数据一致呢? + +通过Synchronized我们可以看到,它其实是对我们整个对象上锁,因为 m 是属于static修饰的静态变量,在class初始化的时候就已经创建,当第一个线程过来的时候,首先判断Main2.class 是否已经加锁了,如果没有加锁,那么就进入,同时给对象加锁,关于Synchronized加锁 我们通过转换成字节码可以看到,其实就是添加两个关键字 + +``` +MonitorEnter +..... 被加锁的代码 +MonitorExit +``` + +当第一个线程加锁后,其它线程在获取Main2.class对象的时候,就会进行阻塞,但是这里我们需要明白的是,因为Synchronized属于非公平锁,因此每个线程来的时候,都会尝试先获取锁,假设线程1还没有被执行,出现就绪状态,那么又可能会被其他线程剥夺CPU执行权,从而进入阻塞队列中。 + +但是如果线程1已经在执行的时候,它是不能被剥夺CPU执行权的,其它线程必须等待线程1执行完成后,释放锁才能够进入。 + +### 补充 + +关于Synchronized加锁,其实不是一来就是添加的重量级锁,而是有一个锁升级的过程 + +- 首先第一个线程将会尝试添加一个偏向锁,也就是对当前获取的线程1有偏向的功能,即不进行复杂加锁校验等,在线程的头部信息中,是有这么一个记录用于记录偏向的线程的 +- 但是假设有多个线程来访问这个资源的时候,偏向锁就会升级成 CAS轻量级锁,也就是我们所说的自旋锁,会不断的自旋操作来获取CPU资源 +- 但是假设某个线程长期进行自旋操作,而没有获取到锁,一般原来的版本是可以指定自旋次数的,后面的JDK进行优化,引入了适应性自旋。当某个线程长期获取不到资源的时候,就会升级成重量级锁,这个时候只要其它线程过来后,获取不到资源就会直接阻塞。 + +## 解决方法2 + +除了刚刚说的引入Synchronized以外,还可以使用的就是引入ReentrantLock来实现,这里用到了可重入锁,也就是已获得锁的线程可以直接进入,其它的线程则需要等待该线程释放锁 + +```java +public class Main3 { + public static int m = 0; + // ReentrantLock默认是非公平锁 + public static void main(String[] args) throws InterruptedException { + Thread[] threads = new Thread[100]; + ReentrantLock lock = new ReentrantLock(); + for (int i = 0; i < threads.length; i++) { + threads[i] = new Thread(() -> { + lock.lock(); + try { + for (int j = 0; j < 100; j++) { + m++; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + }); + } + + for (Thread t: threads) { + t.start(); + } + // 等待所有线程结束 + for (Thread t: threads) { + t.join(); + } + System.out.println(m); + } +} +``` + +### 疑问 + +为什么已经有了Synchronized加锁了,在后面又引入了很多新的锁呢,如 ReentrantLock 等 + +- Synchronized加锁是需要JVM调用底层的OS来进行加锁的,这样就存在一些开销 + - 程序需要从 用户态 -> 内核态 进行切换,这一部分是比较消耗时间的 +- 因为ReentrantLock属于API层面,不需要从进行资源的切换,也就是不用从 用户态 切换到 内核态 + +## 解决方法3 + +另外一种方法,就是自己实现一把锁,也就是实现Lock接口 + +```java +/** + * 自定义锁 + * + * @author: 陌溪 + * @create: 2020-07-17-17:06 + */ +public class MyLock implements Lock { + private volatile int i = 0; + @Override + public void lock() { + synchronized (this) { + // 判断是否有线程已经占用了锁 + while(i != 0) { + try { + // 如果有线程占有锁,可以直接阻塞 + this.wait(); + } catch (Exception e) { + e.printStackTrace(); + } + } + i = 1; + } + } + + @Override + public void lockInterruptibly() throws InterruptedException { + + } + + @Override + public boolean tryLock() { + return false; + } + + @Override + public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { + return false; + } + + @Override + public void unlock() { + synchronized (this) { + i = 0; + // 唤醒所有线程 + this.notifyAll(); + } + } + + @Override + public Condition newCondition() { + return null; + } +} +``` + +上述只是简单的实现了一下,还是用了Synchronized,但是例如ReentrantLock这样的代码,Main4.java的代码如下 + +```java +public class Main4 { + public static int m = 0; + // ReentrantLock默认是非公平锁 + public static void main(String[] args) throws InterruptedException { + Thread[] threads = new Thread[100]; + Lock lock = new MyLock(); + for (int i = 0; i < threads.length; i++) { + threads[i] = new Thread(() -> { + lock.lock(); + try { + for (int j = 0; j < 100; j++) { + m++; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + }); + } + + for (Thread t: threads) { + t.start(); + } + // 等待所有线程结束 + for (Thread t: threads) { + t.join(); + } + System.out.println(m); + } +} +``` + +## AQS + +上面我们提到了,例如 ReentrantLock、CountDownLatch、CycleBarrier 底层都是通过AQS来实现的,我们我们编写一个类,继承AQS,用于实现一把锁 + +**AQS的核心思想**:如果被请求的共享资源空闲,则将当前请求的资源的线程设置为有效的工作线程,并将共享资源设置为锁定状态,如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及唤醒时锁分配的机制,这个AQS是用CLH队列锁实现的,即将暂时获取不到的锁的线程加入到队列中。CLH队列是一个虚拟的双向队列,虚拟的双向队列即不存在队列的实例,仅存在节点之间的关联关系。 + +AQS是将每一条请求共享资源的线程封装成一个CLH锁队列的一个结点(Node),来实现锁的分配 + +用大白话来说,AQS就是基于CLH队列,用volatile修饰共享变量state,线程通过CAS去改变状态符,成功则获取锁成功,失败则进入等待队列,同时等待被唤醒。 + +注意:AQS是自旋锁,在等待唤醒的时候,经常会使用自旋的方式,不断的尝试获取锁,直到被其它线程获取成功 + +实现了AQS的锁有:自旋锁、互斥锁、读写锁、条件变量、信号量、栅栏都是AQS的衍生物,具体实现如下 + +![image-20200717210530013](images/image-20200717210530013.png) + +如上图所示,AQS维护了一个volatile int state的变量 和 一个FIFO线程等待队列,多线程争用资源被阻塞的时候,就会进入这个队列中。state就是共享资源,其访问方式有如下三种: + +- getState() +- setState() +- compareAndSetState() + +AQS定义了两种资源共享方式 + +- Exclusive:独占,只有一个线程能执行,如ReentrantLock +- Share:共享,多个线程可以同时执行,如Semaphore、CountDownLatch、ReadWriteLock、CycleBarrier + +不同的自定义同步器争用共享资源的方式也不同 + +## AQS底层实现 + +AQS使用了基于模板方法的设计模式,如果需要自定义同步器,一般的方式如下 + +- 继承AbstractQueuedSynchronizer,并重写指定的方法,在这里重写的方法就是对共享资源state获取和释放 +- 将AQS组合在自定义同步组件的实现中,并调用其模板方法,而这些模板方法会调用使用者重写的方法。 + +我们通过下面的代码,来进行查看 + +```java +/** + * AQS + */ +public class Sync extends AbstractQueuedSynchronizer { + + @Override + protected boolean tryAcquire(int arg) { + // 使用自旋锁 ,同时CAS必须保证原子性 + // 目前的CPU底层汇编都有这条指令了,即支持原语操作 + if (compareAndSetState(0, 1)) { + // 设置排它的拥有者,也就是互斥锁 + setExclusiveOwnerThread(Thread.currentThread()); + return true; + } + return false; + } + + @Override + protected boolean tryRelease(int arg) { + assert arg == 1; + if(!isHeldExclusively()) { + throw new IllegalMonitorStateException(); + } + // 释放锁 + setExclusiveOwnerThread(null); + setState(0); + return super.tryRelease(arg); + } + + @Override + protected boolean isHeldExclusively() { + // 判断当前线程 是不是和排它锁的线程一样 + return getExclusiveOwnerThread() == Thread.currentThread(); + } +} +``` + +自定义同步器在实现的时候,只需要实现共享资源state的获取和释放即可,至于具体线程等待队列的维护,AQS已经在顶层实现好了。自定义同步器实现的时候,主要实现下面几种方法: + +- isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要实现它 +- tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回false。 +- tryRelease(int):独占方式,尝试释放资源,成功则返回true,失败则返回false +- tryAcquireShared(int):共享方式,尝试获取资源。负数表示失败,0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。 +- tryReleaseShared(int):共享方式。尝试释放资源,如果允许释放后允许唤醒后续等待节点返回true,否则返回false。 + +### ReentrantLock + +以ReentrantLock(可重入独占式锁)为例,state初始化为0,表示未锁定状态,A线程lock()时,会调用tryAcquire()独占锁,并将state + 1,之后其它线程在想通过tryAcquire的时候就会失败,知道A线程unlock() 到 state = 0 为止,其它线程才有机会获取到该锁。A释放锁之前,自己也是可以重复获取此锁(state累加),这就是可重入的概念。 + +> 注意:获取多少次锁就需要释放多少次锁,保证state是能够回到0 + +### CountDownLatch + +以CountDownLatch为例,任务分N个子线程执行,state就初始化为N,N个线程并行执行,每个线程执行完之后 countDown() 一次,state 就会CAS减1,当N子线程全部执行完毕,state = 0,hui unpark() 主调动线程,主调用线程就会从await()函数返回,继续之后的动作。 + +## 总结 + +一般来说,自定义同步器要么独占方式,要么共享方式,他们也需要实现 tryAcquire 和 tryRelease、 tryAcquireShared 和 tryReleaseShared中的一种即可。但AQS也支持自定义同步器实现独占和共享两种方式,比如ReentrantLockReadWriteLock。 + +- acquire() 和 acquireShared() 两种方式下,线程在等待队列中都是忽略中断的 +- acquireInterruptibly() 和 acquireSharedInterruptibly() 是支持响应中断的 + + + diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271AQS\347\232\204\347\220\206\350\247\243/images/image-20200717161505347.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271AQS\347\232\204\347\220\206\350\247\243/images/image-20200717161505347.png" new file mode 100644 index 0000000000000000000000000000000000000000..c4035d4765293e868a8168f2a124517163811551 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271AQS\347\232\204\347\220\206\350\247\243/images/image-20200717161505347.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271AQS\347\232\204\347\220\206\350\247\243/images/image-20200717210530013.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271AQS\347\232\204\347\220\206\350\247\243/images/image-20200717210530013.png" new file mode 100644 index 0000000000000000000000000000000000000000..9d4cec23a4186e75f7bc28f3d8b8496183fb4f30 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271AQS\347\232\204\347\220\206\350\247\243/images/image-20200717210530013.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/README.md" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..192c5d65781c479b495765040b50ef77619bc872 --- /dev/null +++ "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/README.md" @@ -0,0 +1,664 @@ +# 谈谈你对ThreadLocal的理解 + +## ThreadLocal介绍 + +从Java官方文档中的描述:ThreadLocal类用来提供线程内部的局部变量。这种变量在多线程环境下访问(通过get和set方法访问)时能保证各个线程的变量相对独立于其他线程内的变量。ThreadLocal实例通常来说都是private static类型的,用于关联线程和线程上下文。 + +我们可以得知ThreadLocal的作用是:提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂度。 + +- 线程并发:在多线程并发的场景下 +- 传递数据:我们可以通过ThreadLocal在同一线程,不同组件之间传递公共变量(有点类似于Session?) +- 线程隔离:每个线程的变量都是独立的,不会互相影响 + +## 基本使用 + +在介绍Thread使用之前,我们首先认识几个Thread的常见方法 + +| 方法声明 | 描述 | +| ------------------------ | -------------------------- | +| ThreadLocal() | 创建ThreadLocal对象 | +| public void set(T value) | 设置当前线程绑定的局部变量 | +| public T get() | 获取当前线程绑定的局部变量 | +| public void remove() | 移除当前线程绑定的局部变量 | + +## 使用案例 + +我们来看下面这个案例,感受一下ThreadLocal线程隔离的特点 + +```java +/** + * 需求:线程隔离 + * 在多线程并发的场景下,每个线程中的变量都是相互独立的 + * 线程A:设置变量1,获取变量2 + * 线程B:设置变量2,获取变量2 + * @author: 陌溪 + * @create: 2020-07-10-17:03 + */ +public class MyDemo01 { + // 变量 + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public static void main(String[] args) { + MyDemo01 myDemo01 = new MyDemo01(); + for (int i = 0; i < 5; i++) { + new Thread(() -> { + myDemo01.setContent(Thread.currentThread().getName() + "的数据"); + System.out.println("-----------------------------------------"); + System.out.println(Thread.currentThread().getName() + "\t " + myDemo01.getContent()); + }, String.valueOf(i)).start(); + } + } +} +``` + +运行后的效果 + +```bash +----------------------------------------- +----------------------------------------- +----------------------------------------- +3 4的数据 +----------------------------------------- +2 4的数据 +----------------------------------------- +1 4的数据 +4 4的数据 +0 4的数据 +``` + +从上面我们可以看到,出现了线程不隔离的问题,也就是线程1取出了线程4的内,那么如何解决呢? + +这个时候就可以用到ThreadLocal了,我们通过 set 将变量绑定到当前线程中,然后 get 获取当前线程绑定的变量 + +```java +/** + * 需求:线程隔离 + * 在多线程并发的场景下,每个线程中的变量都是相互独立的 + * 线程A:设置变量1,获取变量2 + * 线程B:设置变量2,获取变量2 + * @author: 陌溪 + * @create: 2020-07-10-17:03 + */ +public class MyDemo01 { + // 变量 + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public static void main(String[] args) { + MyDemo01 myDemo01 = new MyDemo01(); + ThreadLocal threadLocal = new ThreadLocal<>(); + for (int i = 0; i < 5; i++) { + new Thread(() -> { + threadLocal.set(Thread.currentThread().getName() + "的数据"); + System.out.println("-----------------------------------------"); + System.out.println(Thread.currentThread().getName() + "\t " + threadLocal.get()); + }, String.valueOf(i)).start(); + } + } +} +``` + +我们引入ThreadLocal后,查看运行结果 + +``` +----------------------------------------- +----------------------------------------- +4 4的数据 +----------------------------------------- +3 3的数据 +----------------------------------------- +2 2的数据 +----------------------------------------- +1 1的数据 +0 0的数据 +``` + +我们发现不会出现上面的情况了,也就是当前线程只能获取线程线程存储的对象 + +## ThreadLocal类和Synchronized关键字 + +### Synchronized同步方式 + +对于上述的例子,我们完全可以通过加锁的方式来实现这个功能,我们来看一下用Synchronized代码块实现的效果: + +```java + public static void main(String[] args) { + MyDemo03 myDemo01 = new MyDemo03(); + for (int i = 0; i < 5; i++) { + new Thread(() -> { + synchronized (MyDemo03.class) { + myDemo01.setContent(Thread.currentThread().getName() + "的数据"); + System.out.println("-----------------------------------------"); + System.out.println(Thread.currentThread().getName() + "\t " + myDemo01.getContent()); + } + }, String.valueOf(i)).start(); + } + } +``` + +运行结果如下所示,我们发现我们可以看到同样实现了功能,但是并发性降低了 + +``` +----------------------------------------- +0 0的数据 +----------------------------------------- +4 4的数据 +----------------------------------------- +3 3的数据 +----------------------------------------- +2 2的数据 +----------------------------------------- +1 1的数据 +``` + +### ThreadLocal与Synchronized的区别 + +虽然ThreadLocal模式与Synchronized关键字都用于处理多线程并发访问变量的问题,不过两者处理问题的角度和思路不同。 + +| | Synchronized | ThreadLocal | +| ------ | ------------------------------------------------------------ | ------------------------------------------------------------ | +| 原理 | 同步机制采用 以空间换时间 的方式,只提供了一份变量,让不同的线程排队访问 | ThreadLocal采用以空间换时间的概念,为每个线程都提供一份变量副本,从而实现同时访问而互不干扰 | +| 侧重点 | 多个线程之间访问资源的同步 | 多线程中让每个线程之间的数据相互隔离 | + +总结:在刚刚的案例中,虽然使用ThreadLocal和Synchronized都能解决问题,但是使用ThreadLocal更为合适,因为这样可以使程序拥有更高的并发性。 + +## 运用场景 + +通过以上的介绍,我们已经基本了解ThreadLocal的特点,但是它具体是运用在什么场景中的呢?接下来让我们看一个案例:事务操作 + +### 转账案例 + +这里们先构建一个简单的转账场景:有一个数据表account,里面有两个用户 jack 和 Rose,用户Jack给用户Rose转账。案例的实现主要是用mysql数据库,JDBC和C3P0框架,以下是详细代码 + +![image-20200710204941153](images/image-20200710204941153.png) + +### 引入事务 + +案例中转账涉及两个DML操作:一个转出,一个转入。这些操作是需要具备原子性的,不可分割。不然有可能出现数据修改异常情况。 + +```java +public class AccountService { + public boolean transfer(String outUser, String isUser, int money) { + AccountDao ad = new AccountDao(); + try { + // 转出 + ad.out(outUser, money); + // 模拟转账过程中的异常 + int i = 1/0; + // 转入 + ad.in(inUser, money); + } catch(Exception e) { + e.printStackTrace(); + return false; + } + return true; + } +} +``` + +所以这里就需要操作事务,来保证转入和转出具备原子性,要么成功,要么失败。 + +JDBC中关于事务操作的API + +| Connection接口的方法 | 作用 | +| ------------------------- | -------------------------------- | +| void setAutoCommit(false) | 禁用事务自动提交(改为手动提交) | +| void commit() | 提交事务 | +| void rollbakc() | 回滚事务 | + +开启事务的注意点 + +为了保证所有操作在一个事务中,案例中使用的连接必须是同一个;service层开启事务的connection需要跟dao层访问数据库的connection保持一致 + +线程并发情况下,每个线程只能操作各自的connection,也就是线程隔离 + +### 常规解决方法 + +基于上面给出的前提,大家通常想到的解决方法 + +- 从service层将connection对象向dao层传递 +- 加锁 + +### 常规解决方法的弊端 + +- 提高代码的耦合度(因为我们需要从service 层 传入 connection参数) +- 降低程序的性能(加了同步代码块,失去了并发性) + +这个时候就可以通过ThreadLocal和当前线程进行绑定,来降低代码之间的耦合 + +![image-20200710212423494](images/image-20200710212423494.png) + +### 使用ThreadLocal解决 + +针对上面出现的情况,我们需要对原来的JDBC连接池对象进行更改 + +- 将原来从连接池中获取对象,改成直接获取当前线程绑定的连接对象 +- 如果连接对象是空的 + - 再去连接池中获取连接 + - 将此连接对象跟当前线程进行绑定 + +```java +ThreadLocal tl = new ThreadLocal(); +public static Connection getConnection() { + Connection conn = tl.get(); + if(conn == null) { + conn = ds.getConnection(); + tl.set(conn); + } + return conn; +} +``` + +### ThreadLocal实现的好处 + +从上述的案例中我们可以看到,在一些特定场景下,ThreadLocal方案有两个突出的优势: + +- 传递数据:保存每个线程绑定的数据,在需要的地方可以直接获取,避免参数直接传递带来的代码耦合问题 +- 线程隔离:各线程之间的数据相互隔离却又具备并发性,避免同步方式带来的性能损失 + +## ThreadLocal的内部结构 + +通过以上的学习,我们对ThreadLocal的作用有了一定的认识。现在我们一起来看一下ThreadLocal的内部结构,探究它能够实现线程数据隔离的原理。 + +### 常见误解 + +如果我们不去看源代码的话,可能会猜测 ThreadLocal 是这样子设计的:每个ThreadLocal都创建一个Map,然后用线程作为Map的key,要存储的局部变量作为Map的value,这样就能达到各个线程的局部变量隔离的效果。这是最简单的设计方法,JDK最早期的ThreadLocal确实是这样设计的,但现在早已不是了。 + +![image-20200710214857638](images/image-20200710214857638.png) + +### 现在的设计 + +但是,JDK后面优化了设计方案,在JDK8中 ThreadLocal的设计是:每个Thread维护一个ThreadLocalMap,这个Map的key是ThreadLocal实例本身,value 才是真正要存储的值object。具体的过程是这样的: + +- 每个Thread线程内部都有一个Map(ThreadLocalMap) +- Map里面存储ThreadLocal对象(key)和线程的变量副本(value) +- Thread内部的Map是由ThreadLocal维护的,由ThreadLocal负责向map获取和设置线程的变量值。 +- 对于不同的线程,每次获取副本值时,别的线程并不能获取到当前线程的副本值,形成了副本的隔离,互不干扰。 + +![image-20200710215038748](images/image-20200710215038748.png) + +### 对比 + +![image-20200710215128743](images/image-20200710215128743.png) + +从上面变成JDK8的设计有什么好处? + +- 每个Map存储的Entry数量变少,因为原来的Entry数量是由Thread决定,而现在是由ThreadLocal决定的 + - 真实开发中,Thread的数量远远大于ThreadLocal的数量 +- 当Thread销毁的时候,ThreadLocalMap也会随之销毁,因为ThreadLocal是存放在Thread中的,随着Thread销毁而消失,能降低开销。 + +## ThreadLocal核心方法源码 + +基于ThreadLocal的内部结构,我们继续分析它的核心方法源码,更深入的了解其操作原理。 +除了构造方法之外,ThreadLocal对外暴露的方法有以下4个 + +| 方法声明 | 描述 | +| -------------------------- | ---------------------------- | +| protected T initialValue() | 返回当前线程局部变量的初始值 | +| public void set(T value) | 返回当前线程绑定的局部变量 | +| public T get() | 获取当前线程绑定的局部变量 | +| public void remove() | 移除当前线程绑定的局部变量 | + +以下是这4个方法的详细源码分析(为了保证思路清晰,ThreadLocalMap部分暂时不展开,下一个知识点详解) + +### set方法 + +![image-20200710215706026](images/image-20200710215706026.png) + +![image-20200710215827494](images/image-20200710215827494.png) + +代码流程 + +- 首先获取当前线程,并根据当前线程获取一个Map +- 如果获取的Map不为空,则将参数设置到Map中(当前ThreadLocal的引用作为key) +- 如果Map为空,则给该线程创建Map,并设置初始化值 + +### get方法 + +![image-20200710220037887](images/image-20200710220037887.png) + +![image-20200710220201472](images/image-20200710220201472.png) + +代码执行流程 + +- 首先获取当前线程,根据当前线程获取一个Map +- 如果获取的Map不为空,则在Map中以ThreadLocal的引用作为key来在Map中获取对应的Entrye,否则转到第四步 +- 如果e不为null,则返回e.value,否则转到第四步 +- Map为空或者e为空,则通过initialValue函数获取初始值value,然后用ThreadLocal的引用和value作为firstKey和firstValue创建一个新的Map + +总结:先获取当前线程的ThreadLocal变量,如果存在则返回值,不存在则创建并返回初始值 + +### remove方法 + +![image-20200710220519229](images/image-20200710220519229.png) + +代码执行流程 + +- 首先获取当前线程,并根据当前线程获取一个Map +- 如果获取的Map不为空,则移除当前ThreadLocal对象对应的Entry + +### initialValue方法 + +![image-20200710220639455](images/image-20200710220639455.png) + +此方法的作用是返回该线程局部变量的初始值。 + +- 这个方法是一个延迟调用方法,从上面的代码我们得知,在set方法还未调用而先调用了get方法时才执行,并且仅执行1次。 +- 这个方法缺省实现直接返回一个null。 +- 如果想要一个除null之外的初始值,可以重写此方法。(备注:该方法是一个protected的方法,显然是为了让子类覆盖而设计的) + +## ThreadLocalMap源码分析 + +在分析ThreadLocal方法的时候,我们了解到ThreadLocal的操作实际上是围绕ThreadLocalMap展开的。 +ThreadLocalMap的源码相对比较复杂,我们从以下三个方面进行讨论。 + +### 基本结构 + +ThreadLocalMap是ThreadLocal的内部类,没有实现Map接口,用独立的方式实现了Map的功能,其内部的Entry也是独立实现。 + +![image-20200710220856315](images/image-20200710220856315.png) + +#### 成员变量 + +```java +/** +* 初始容量 - 必须是2的整次幂 +**/ +private static final int INITIAL_CAPACITY = 16; + +/** +*存放数据的table ,Entry类的定义在下面分析,同样,数组的长度必须是2的整次幂 +**/ +private Entry[] table; + +/** +*数组里面entrys的个数,可以用于判断table当前使用量是否超过阈值 +**/ +private int size = 0; + +/** +*进行扩容的阈值,表使用量大于它的时候进行扩容 +**/ +private int threshold; // Default to 0 +``` + +跟HashMap类似,INITIAL_CAPACITY代表这个Map的初始容量;table是一个Entry类型的数组,用于存储数据;size代表表中的存储数目;threshold代表需要扩容时对应的size的阈值。 + +### 存储结构 - Entry + +```java +/* +*Entry继承WeakRefefence,并且用ThreadLocal作为key. +如果key为nu11(entry.get()==nu11),意味着key不再被引用, +*因此这时候entry也可以从table中清除。 +*/ +static class Entry extends weakReference>{ + +object value;Entry(ThreadLocal<?>k,object v){ + super(k); + value = v; +}} +``` + +在ThreadLocalMap中,也是用Entry来保存K-V结构数据的。不过Entry中的key只能是ThreadLocal对象,这点在构造方法中已经限定死了。 + +另外,Entry继承WeakReference,也就是key(ThreadLocal)是弱引用,其目的是将ThreadLocal对象的生命周期和线程生命周期解绑。 + +## 弱引用和内存泄漏 + +有些程序员在使用ThreadLocal的过程中会发现有内存泄漏的情况发生,就猜测这个内存泄漏跟Entry中使用了弱引用的key有关系。这个理解其实是不对的。 + +我们先来回顾这个问题中涉及的几个名词概念,再来分析问题。 + +### 内存泄漏相关概念 + +Memory overflow:内存溢出,没有足够的内存提供申请者使用。 + +Memory leak:内存泄漏是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统溃等严重后果。I内存泄漏的堆积终将导致内存溢出。 + +### 弱引用相关概念 + +Java中的引用有4种类型:强、软、弱、虚。当前这个问题主要涉及到强引用和弱引用: + +强引用("Strong"Reference),就是我们最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾回收器就不会回收这种对象。 + +弱引用(WeakReference),垃圾回收器一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。 + +### 如果key使用强引用,那么会出现内存泄漏? + +假设ThreadLocalMap中的key使用了强引用,那么会出现内存泄漏吗? + +此时ThreadLocal的内存图(实线表示强引用)如下: + +![image-20200710222559109](images/image-20200710222559109.png) + +- 假设在业务代码中使用完ThreadLocal,threadLocal Ref被回收了 +- 但是因为threadLocalMap的Entry强引用了threadLocal,造成threadLocal无法被回收。 +- 在没有手动删除这个Entry以及CurrentThread依然运行的前提下,始终有强引用链 threadRef->currentThread->threadLocalMap->entry,Entry就不会被回收(Entry中包括了ThreadLocal实例和value),导致Entry内存泄漏。 + +也就是说,ThreadLocalMap中的key使用了强引用,是无法完全避免内存泄漏的。 + +### 如果key使用弱引用,那么会出现内存泄漏? + +![image-20200710222847567](images/image-20200710222847567.png) + +- 同样假设在业务代码中使用完ThreadLocal,threadLocal Ref被回收了。 +- 由于ThreadLocalMap只持有ThreadLocal的弱引用,没有任何强引用指向threadlocal实例,所以threadloca就可以顺利被gc回收,此时Entry中的key=null。 +- 但是在没有手动删除这个Entry以及CurrentThread依然运行的前提下,也存在有强引用链 threadRef->currentThread->threadLocalMap->entry-> value,value不会被回收,而这块value永远不会被访问到了,导致value内存泄漏。 + +也就是说,ThreadLocalMap中的key使用了弱引用,也有可能内存泄漏。 + +### 出现内存泄漏的真实原因 + +比较以上两种情况,我们就会发现,内存泄漏的发生跟ThreadLocalMap中的key是否使用弱引用是没有关系的。那么内存泄漏的的真正原因是什么呢? + +细心的同学会发现,在以上两种内存泄漏的情况中,都有两个前提: + +- 没有手动删除这个Entry +- CurrentThread依然运行 + +第一点很好理解,只要在使用完ThreadLocal,调用其remove方法删除对应的Entry,就能避免内存泄漏。 + +第二点稍微复杂一点,由于ThreadLocalMap是Thread的一个属性,被当前线程所引用,所以它的生命周期跟Thread一样长。那么在使用完ThreadLocal的使用,如果当前Thread也随之执行结束,ThreadLocalMap自然也会被gc回收,从根源上避免了内存泄漏。 + +综上,ThreadLocal内存泄漏的根源是:由于ThreadLocalMap的生命周期跟Thread-样长,如果没有手动删除对应key就会导致内存泄漏。 + +### 为什么要使用弱引用? + +根据刚才的分析,我们知道了:无论ThreadLocalMap中的key使用哪种类型引用都无法完全避免内存泄漏,跟使用弱引用没有关系。 + +要避免内存泄漏有两种方式: + +- 使用完ThreadLocal,调用其remove方法删除对应的Entry +- 使用完ThreadLocal,当前Thread也随之运行结束 + +相对第一种方式,第二种方式显然更不好控制,特别是使用线程池的时候,线程结束是不会销毁的,而是接着放入了线程池中。 + +也就是说,只要记得在使用完ThreadLocal及时的调用remove,无论key是强引用还是弱引用都不会有问题。 +那么为什么key要用弱引用呢? + +事实上,在ThreadLocalMap中的 set / getEntry方法中,会对key为null(也即是ThreadLocal为null)进行判断,如果为null的话,那么是会对value置为nul的。 + +这就意味着使用完ThreadLocal,CurrentThread依然运行的前提下,就算忘记调用remove方法,弱引用比强引用可以多一层保障:弱引用的ThreadLocal会被回收,对应的value在下一次ThreadLocalMap调用set,get,remove中的任一方法的时候会被清除,从而避免内存泄漏。 + +## Hash冲突的解决 + +hash冲突的解决是Map中的一个重要内容。我们以hash冲突的解决为线索,来研究一下ThreadLocalMap的核心源码。 + +首先从ThreadLocal的set方法入手 + +```java +public void set(T value){ + Threadt=Thread.currentThread(); + ThreadLoca1.ThreadLocalMap map=getMap(t); + if(mapl @= nu11) +//调用了ThreadLocalMap的set方法I + map.set(this,value); + else + createMap(t,value); +} + +ThreadLocal.ThreadLocalMap getMap(Thread t){ + return t.threadLocals; +} + +void createMap(Thread t,T firstValue){ +//调用了ThreadLocalMap的构造方法 +t.threadlocals=new ThreadLocal.ThreadtocalMap(this,firstValue); +``` + +这个方法我们刚才分析过,其作用是设置当前线程绑定的局部变量 + +- 首先获取当前线程,并根据当前线程获取一个Map +- 如果获取的Map不为空,则将参数设置到Map中(当前ThreadLocal的引用作为key)(这里调用了ThreadLocalMap的set方法) +- 如果Map为空,则给该线程创建Map,并设置初始值(这里调用了ThreadLocalMap的构造方法) + +这段代码有两个地方分别涉及到ThreadLocalMap的两个方法,我们接着分析这两个方法 + +### 构造方法 + +ThreadLocalMap(ThreadLocal firstKey, Object firstValue) + +![image-20200710224030132](images/image-20200710224030132.png) + +构造函数首先创建一个长度为16的Entry数组,然后计算出firstKey对应的索引,然后存储到table中,并设置size和threshold。 + +重点分析:int i = firstKey.threadLocalHashCode & ( INITIAL_CAPACITY - 1) + +**关于:threadLocalHashCode** + +![image-20200710224257493](images/image-20200710224257493.png) + +这里定义了一个Atomiclnteger类型,每次获取当前值并加上HASHINCREMENT,HASH_INCREMENT = +0x61c88647,这个值跟斐波那契数列(黄金分割数)有关,其主要目的就是为了让哈希码能均匀的分布在2的n次方的数组里,也就是EntryI table中,这样做可以尽量避免hash冲突。 + +**关于&(INITIAL_CAPACITY-1)** + +计算hash的时候里面采用了hashCode&(size-1)的算法,这相当于取模运算hashCode%size的一个更高效的实现。正是因为这种算法,我们要求size必须是2的整次幂,这也能保证保证在索引不越界的前提下,使得hash发生冲突的次数减小。 + +### Get方法 + +![image-20200710224609317](images/image-20200710224609317.png) + +![image-20200710224724127](images/image-20200710224724127.png) + +代码执行流程 + +- 首先还是根据key计算出索引i,然后查找位置上的Entry, +- 若是Entry已经存在并且key等于传入的key,那么这时候直接给这个Entry赋新的value值, +- 若是Entry存在,但是key为null,则调用replaceStaleEntry来更换这个key为空的Entry, +- 不断循环检测,直到遇到为null的地方,这时候要是还没在循环过程中return,那么就在这个null的位置新建一个Entry,并且插入,同时size增加1。 + +最后调用cleanSomeSlots,清理key为null的Entry,最后返回是否清理了Entry,接下来再判断sz是否>= +thresgold达到了rehash的条件,达到的话就会调用rehash函数执行一次全表的扫描清理。 + +### 线性探测法解决Hash冲突 + +该方法一次探测下一个地址,直到有空的地址后插入,若整个空间都找不到空余的地址,则产生溢出。 + +举个例子,假设当前table长度为16,也就是说如果计算出来key的hash值为14,如果table[14]上已经有值,并且其key与当前key不一致,那么就发生了hash冲突,这个时候将1401得到15,取table[15]进行判断,这个时候如果还是冲突会回到0,取table[0],以此类推,直到可以插入。 + +按照上面的描述,可以把Entry table看成一个环形数组。 + +## ThreadLocal使用场景 + +### 源码使用场景 + +ThreadLocal的作用主要是做数据隔离,填充的数据只属于当前线程,变量的数据对别的线程而言是相对隔离的,在多线程环境下,如何防止自己的变量被其它线程篡改。 + +例如,用于 Spring实现事务隔离级别的源码 + +Spring采用Threadlocal的方式,来保证单个线程中的数据库操作使用的是同一个数据库连接,同时,采用这种方式可以使业务层使用事务时不需要感知并管理connection对象,通过传播级别,巧妙地管理多个事务配置之间的切换,挂起和恢复。 + +Spring框架里面就是用的ThreadLocal来实现这种隔离,主要是在`TransactionSynchronizationManager`这个类里面,代码如下所示: + +```java +private static final Log logger = LogFactory.getLog(TransactionSynchronizationManager.class); + + private static final ThreadLocal> resources = + new NamedThreadLocal<>("Transactional resources"); + + private static final ThreadLocal> synchronizations = + new NamedThreadLocal<>("Transaction synchronizations"); + + private static final ThreadLocal currentTransactionName = + new NamedThreadLocal<>("Current transaction name"); +``` + +Spring的事务主要是ThreadLocal和AOP去做实现的,我这里提一下,大家知道每个线程自己的链接是靠ThreadLocal保存的就好了 + +### 用户使用场景1 + + 除了源码里面使用到ThreadLocal的场景,你自己有使用他的场景么? + +之前我们上线后发现部分用户的日期居然不对了,排查下来是SimpleDataFormat的锅,当时我们使用SimpleDataFormat的parse()方法,内部有一个Calendar对象,调用SimpleDataFormat的parse()方法会先调用Calendar.clear(),然后调用Calendar.add(),如果一个线程先调用了add()然后另一个线程又调用了clear(),这时候parse()方法解析的时间就不对了。 + +其实要解决这个问题很简单,让每个线程都new 一个自己的 SimpleDataFormat就好了,但是1000个线程难道new1000个SimpleDataFormat? + +所以当时我们使用了线程池加上ThreadLocal包装SimpleDataFormat,再调用initialValue让每个线程有一个SimpleDataFormat的副本,从而解决了线程安全的问题,也提高了性能。 + +### 用户使用场景2 + +我在项目中存在一个线程经常遇到横跨若干方法调用,需要传递的对象,也就是上下文(Context),它是一种状态,经常就是是用户身份、任务信息等,就会存在过渡传参的问题。 + +使用到类似责任链模式,给每个方法增加一个context参数非常麻烦,而且有些时候,如果调用链有无法修改源码的第三方库,对象参数就传不进去了,所以我使用到了ThreadLocal去做了一下改造,这样只需要在调用前在ThreadLocal中设置参数,其他地方get一下就好了。 + +```java +before + +void work(User user) { + getInfo(user); + checkInfo(user); + setSomeThing(user); + log(user); +} + +then + +void work(User user) { +try{ + threadLocalUser.set(user); + // 他们内部 User u = threadLocalUser.get(); 就好了 + getInfo(); + checkInfo(); + setSomeThing(); + log(); + } finally { + threadLocalUser.remove(); + } +} +``` + +我看了一下很多场景的cookie,session等数据隔离都是通过ThreadLocal去做实现的 + +在Android中,Looper类就是利用了ThreadLocal的特性,保证每个线程只存在一个Looper对象。 + +```java +static final ThreadLocal sThreadLocal = new ThreadLocal(); +private static void prepare(boolean quitAllowed) { + if (sThreadLocal.get() != null) { + throw new RuntimeException("Only one Looper may be created per thread"); + } + sThreadLocal.set(new Looper(quitAllowed)); +} +``` + +## 参考 + +https://blog.csdn.net/qq_35190492/article/details/107599875 + diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710204941153.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710204941153.png" new file mode 100644 index 0000000000000000000000000000000000000000..4f2bd1d0255ffccbc23e8c8a66dd24f55f931655 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710204941153.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710212423494.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710212423494.png" new file mode 100644 index 0000000000000000000000000000000000000000..5a1fbd0d7e4ad75524f03a55c7f57b0806676f7a Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710212423494.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710214857638.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710214857638.png" new file mode 100644 index 0000000000000000000000000000000000000000..4912a55fea33e4d5a89cb62f37a7f2c99ce56284 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710214857638.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710215038748.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710215038748.png" new file mode 100644 index 0000000000000000000000000000000000000000..e6ed0b7b5ed0ac1118a5b2f7474b8aa472bc539a Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710215038748.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710215128743.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710215128743.png" new file mode 100644 index 0000000000000000000000000000000000000000..49ea1b7225f8e627fe3c01d170ab32bb4f8ba048 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710215128743.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710215706026.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710215706026.png" new file mode 100644 index 0000000000000000000000000000000000000000..86347dfcd04b4c98b5ae0b82105a7f447b59687b Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710215706026.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710215827494.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710215827494.png" new file mode 100644 index 0000000000000000000000000000000000000000..2abeb3b847769876bd4389dc26c86eace380298b Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710215827494.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220037887.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220037887.png" new file mode 100644 index 0000000000000000000000000000000000000000..d14fde76ef23fec49ec3b3914ecd44f38ce1c682 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220037887.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220201472.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220201472.png" new file mode 100644 index 0000000000000000000000000000000000000000..e31cdc18ff70680dffe834de921588484f9ee4bc Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220201472.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220519229.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220519229.png" new file mode 100644 index 0000000000000000000000000000000000000000..0644e72e5e540ead97a27306e80fa362ca81d5f6 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220519229.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220639455.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220639455.png" new file mode 100644 index 0000000000000000000000000000000000000000..3df334f21a59f18fc3e31c40e202008b6b7cd7d6 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220639455.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220856315.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220856315.png" new file mode 100644 index 0000000000000000000000000000000000000000..7e56ab3c66e155dcac2daed3e8670e134e32621d Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710220856315.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710222559109.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710222559109.png" new file mode 100644 index 0000000000000000000000000000000000000000..d36ea936ebab8d17953e962c5079f82e8769c580 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710222559109.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710222847567.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710222847567.png" new file mode 100644 index 0000000000000000000000000000000000000000..fcde503d2ffd5614b775e4b6d94a6d388ec7f058 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710222847567.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710224030132.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710224030132.png" new file mode 100644 index 0000000000000000000000000000000000000000..faaa72686d339437aa4afa6239e64cb889f0b6f5 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710224030132.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710224257493.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710224257493.png" new file mode 100644 index 0000000000000000000000000000000000000000..c4ceb1341434c909987e73ce32780f0ec91cde61 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710224257493.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710224609317.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710224609317.png" new file mode 100644 index 0000000000000000000000000000000000000000..de02af77977ce00414a268fb102de54a64894781 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710224609317.png" differ diff --git "a/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710224724127.png" "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710224724127.png" new file mode 100644 index 0000000000000000000000000000000000000000..2b31a0eb7d941c12bed6906f2e63c515c0d866c1 Binary files /dev/null and "b/Java/\350\260\210\350\260\210\344\275\240\345\257\271ThreadLocal\347\232\204\347\220\206\350\247\243/images/image-20200710224724127.png" differ diff --git "a/JavaScript/Js\350\256\276\347\275\256\344\272\214\347\272\247\345\237\237\345\220\215\345\222\214\351\241\266\347\272\247\345\237\237\345\220\215\344\270\213\345\205\261\344\272\253Cookie/README.md" "b/JavaScript/Js\350\256\276\347\275\256\344\272\214\347\272\247\345\237\237\345\220\215\345\222\214\351\241\266\347\272\247\345\237\237\345\220\215\344\270\213\345\205\261\344\272\253Cookie/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..347f5b4172f4941ed6fb4ce8e1766fa06f004f7a --- /dev/null +++ "b/JavaScript/Js\350\256\276\347\275\256\344\272\214\347\272\247\345\237\237\345\220\215\345\222\214\351\241\266\347\272\247\345\237\237\345\220\215\344\270\213\345\205\261\344\272\253Cookie/README.md" @@ -0,0 +1,115 @@ +前言 +-- + +今天在蘑菇博客进行登录的时候,发现一个BUG,就是在用户登录后,有登录信息,但是刷新页面后,就没有头像了,F12打开调试页面,查看token也没有了 + +开始感觉非常的怪异,以为是chrome的原因,因为token是存储在cookie中的,而且也设置了有效期为7天,不可能退出浏览器就删除了,但是在我点开一个页面的时候 + +发现cookie有出现了,而且用户也正常登录,后面经过排查发现,是因为cookie二级域名和顶级域名不共享的原因而引起的 + +原理 +-- + +首先Js在设置cookie的时候,默认会存放在当前的域名下,因为我登录后,会返回www.moguit.cn的页面,同时附带token信息,那么我们的token也就值保存在了 www.moguit.cn页面,而我们通过浏览器输入www.moguit.cn其实访问的是moguit.cn的顶级域名 + +那么就会造成:二级子域名下的cookie和顶级域名不共享的。同理 a.example.com下设置cookie, 在b.example.com下也是无法正常使用的 + +要避免这样的原因,我们就需要设置cookie的domain + +下面是关于cookie的一些配置 + +* name    Cookie的名称,Cookie一旦创建,名称便不可更改 +* value    Cookie的值,如果值为Unicode字符,需要为字符编码。如果为二进制数据,则需要使用BASE64编码 +* maxAge    Cookie失效的时间,单位秒。如果为整数,则该Cookie在maxAge秒后失效。如果为负数,该Cookie为临时Cookie,关闭浏览器即失效,浏览器也不会以任何形式保存该Cookie。如果为0,表示删除该Cookie。默认为-1。 +* secure    该Cookie是否仅被使用安全协议传输。安全协议。安全协议有HTTPS,SSL等,在网络上传输数据之前先将数据加密。默认为false。 +* path    Cookie的使用路径。如果设置为“/sessionWeb/”,则只有contextPath为“/sessionWeb”的程序可以访问该Cookie。如果设置为“/”,则本域名下contextPath都可以访问该Cookie。注意最后一个字符必须为“/”。 +* domain    可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.”。 +* comment    该Cookie的用处说明,浏览器显示Cookie信息的时候显示该说明。 +* version    Cookie使用的版本号。0表示遵循Netscape的Cookie规范,1表示遵循W3C的RFC 2109规范 + +我们通过domain的属性可能看到,当我们设置 .google.com的时候,那么以google.com结尾的域名都能够访问该cookie + +那么如果我们想要让cookie进行共享的话,就必须以 .moguit.cn进行共享 + + host = location.host; + domainParts = host.split('.'); + domainParts.shift(); + domain = '.'+domainParts.join('.'); + +我们通过这段代码,就能够截取到蘑菇博客的顶级域名了,同时我们需要加上 . + +![](http://image.moguit.cn/f004ce6dc7b24445805f193f09a02fa4) + +完整的CookieUtil代码为: + + /** + * CookieUtil常用的一些工具类 + */ + + export function setCookie(name, value, days) { + // var exp = new Date(); + // exp.setTime(exp.getTime() + days * 24 * 60 * 60 * 1000); + // document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString(); + + var domain, domainParts, date, expires, host; + + if (days) + { + date = new Date(); + date.setTime(date.getTime()+(days*24*60*60*1000)); + expires = "; expires="+date.toGMTString(); + } + else + { + expires = ""; + } + + host = location.host; + if (host.split('.').length === 1) + { + // no "." in a domain - it's localhost or something similar + document.cookie = name+"="+value+expires+"; path=/"; + } + else + { + // Remember the cookie on all subdomains. + // + // Start with trying to set cookie to the top domain. + // (example: if user is on foo.com, try to set + // cookie to domain ".com") + // + // If the cookie will not be set, it means ".com" + // is a top level domain and we need to + // set the cookie to ".foo.com" + domainParts = host.split('.'); + domainParts.shift(); + domain = '.'+domainParts.join('.'); + + document.cookie = name+"="+value+expires+"; path=/; domain="+domain; + + // check if cookie was successfuly set to the given domain + // (otherwise it was a Top-Level Domain) + if (getCookie(name) == null || getCookie(name) != value) + { + // append "." to current domain + domain = '.'+host; + document.cookie = name+"="+value+expires+"; path=/; domain="+domain; + } + } + } + + export function getCookie(name) { + var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)") + if (arr = document.cookie.match(reg)) + return unescape(arr[2]) + else + return null + } + + export function delCookie(name) { + var exp = new Date(); + exp.setTime(exp.getTime() - 1); + var cval = getCookie(name); + if (cval != null) + document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString(); + } \ No newline at end of file diff --git "a/JavaScript/\345\246\202\344\275\225\351\200\232\350\277\207Js\345\260\206\346\227\266\351\227\264\350\275\254\346\215\242\344\270\272\345\210\232\345\210\232_\345\207\240\345\210\206\351\222\237\345\211\215_\345\207\240\345\260\217\346\227\266\345\211\215/README.md" "b/JavaScript/\345\246\202\344\275\225\351\200\232\350\277\207Js\345\260\206\346\227\266\351\227\264\350\275\254\346\215\242\344\270\272\345\210\232\345\210\232_\345\207\240\345\210\206\351\222\237\345\211\215_\345\207\240\345\260\217\346\227\266\345\211\215/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..0c469ab7a0be98c1a5c638726cabf1f101a18260 --- /dev/null +++ "b/JavaScript/\345\246\202\344\275\225\351\200\232\350\277\207Js\345\260\206\346\227\266\351\227\264\350\275\254\346\215\242\344\270\272\345\210\232\345\210\232_\345\207\240\345\210\206\351\222\237\345\211\215_\345\207\240\345\260\217\346\227\266\345\211\215/README.md" @@ -0,0 +1,67 @@ +前言 +-- + +今天弄了一天的评论模块,我们常见的评论或者朋友圈都能看到的发送时间是刚刚,几分钟前,几小时前,所以我在做评论模块的时候也想进行这样的转换,其实转换的方法也挺简单的,就是获取到评论发送的时间戳和当前的时间戳进行对比,然后在除分、时、天、周、月所对应的时间戳,就能得到我们想要的效果了,最终效果如下所示 + +![](http://image.moguit.cn/1578831128367.png) + +代码 +-- + +首先需要传入的是我们评论的时间,格式如:2020-01-12 20:10:15 + + /** + * dateTimeStamp是评论的发送时间 2020-01-12 20:10:15 这样的形式 + * @param dateTimeStamp + * @returns {string} + */ + timeAgo(dateTimeStamp) { + let result = ""; + let minute = 1000 * 60; //把分,时,天,周,半个月,一个月用毫秒表示 + let hour = minute * 60; + let day = hour * 24; + let week = day * 7; + let halfamonth = day * 15; + let month = day * 30; + let now = new Date().getTime(); //获取当前时间毫秒 + + dateTimeStamp = dateTimeStamp.substring(0, 18); + //必须把日期'-'转为'/' + dateTimeStamp = dateTimeStamp.replace(/-/g, '/'); + let timestamp = new Date(dateTimeStamp).getTime(); + + let diffValue = now - timestamp;//时间差 + + if (diffValue < 0) { + return result; + } + let minC = diffValue / minute; //计算时间差的分,时,天,周,月 + let hourC = diffValue / hour; + let dayC = diffValue / day; + let weekC = diffValue / week; + let monthC = diffValue / month; + if (monthC >= 1 && monthC <= 3) { + result = " " + parseInt(monthC) + "月前" + } else if (weekC >= 1 && weekC <= 3) { + result = " " + parseInt(weekC) + "周前" + } else if (dayC >= 1 && dayC <= 6) { + result = " " + parseInt(dayC) + "天前" + } else if (hourC >= 1 && hourC <= 23) { + result = " " + parseInt(hourC) + "小时前" + } else if (minC >= 1 && minC <= 59) { + result = " " + parseInt(minC) + "分钟前" + } else if (diffValue >= 0 && diffValue <= minute) { + result = "刚刚" + } else { + let datetime = new Date(); + datetime.setTime(dateTimeStamp); + let Nyear = datetime.getFullYear(); + let Nmonth = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1; + let Ndate = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate(); + let Nhour = datetime.getHours() < 10 ? "0" + datetime.getHours() : datetime.getHours(); + let Nminute = datetime.getMinutes() < 10 ? "0" + datetime.getMinutes() : datetime.getMinutes(); + let Nsecond = datetime.getSeconds() < 10 ? "0" + datetime.getSeconds() : datetime.getSeconds(); + result = Nyear + "-" + Nmonth + "-" + Ndate + } + return result; + }, \ No newline at end of file diff --git "a/K8S/1_Kubernetes\347\256\200\344\273\213/README.md" "b/K8S/1_Kubernetes\347\256\200\344\273\213/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..39c1d55c323450c0979042fef08462c02c04c891 --- /dev/null +++ "b/K8S/1_Kubernetes\347\256\200\344\273\213/README.md" @@ -0,0 +1,158 @@ +# Kubernetes简介 + +## 介绍 + +K8S主要讲的就是Kubernetes,首先Kubernetes首字母为K,末尾为s,中间一共有8个字母,所以简称K8s + +## 前置知识 + +- Linux操作系统 +- Docker + +## 课程简介 + +- K8s概念和架构 +- 从零搭建K8s集群 + - 基于客户端工具kubeadm搭建(简单,最多半小时) + - 基于二进制包方式(能看到内部的架构) + +- K8s核心概念 + - Pod:K8s管理的最小单位级,是所有业务类型的基础 + - Controller:控制器,有状态,无状态,一次任务,定时任务,守护进程 + - Service Ingress:对外暴露端口 + - RBAC:安全机制,权限模型 + - Helm:下载机制 + - 持久化存储 + +- 搭建集群监控平台系统 +- 从零搭建高可用K8s集群 +- 在集群环境部署项目 + +## K8S概念和特性 + +### 概述 + +kubernetes,简称K8s,是用8 代替8 个字符“ubernete”而成的缩写。是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes 的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes 提供了应用部署,规划,更新,维护的一种机制。 + +传统的应用部署方式是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等操作,当然也可以通过创建虚拟机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。 + +新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进行迁移。 + +容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间成一对一关系也使容器有更大优势,使用容器可以在build 或release 的阶段,为应用创建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,这使得从研发到测试、生产能提供一致环境。类似地,容器比虚拟机轻量、更“透明”,这更便于监控和管理。 + +Kubernetes 是Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。在Kubernetes 中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。 + +> 总结: +> +> - K8s是谷歌在2014年开业的容器化集群管理系统 +> - 使用k8s进行容器化应用部署 +> - 使用k8s利于应用扩展 +> - k8s目标实施让部署容器化应用更加简洁和高效 + +### K8S概述 + +Kubernetes 是一个轻便的和可扩展的开源平台,用于管理容器化应用和服务。通过Kubernetes 能够进行应用的自动化部署和扩缩容。在Kubernetes 中,会将组成应用的容器组合成一个逻辑单元以更易管理和发现。Kubernetes 积累了作为Google 生产环境运行工作负载15 年的经验,并吸收了来自于社区的最佳想法和实践。 + +### K8S功能 + +#### 自动装箱 + +基于容器对应用运行环境的资源配置要求自动部署应用容器 + +#### 自我修复(自愈能力) + +当容器失败时,会对容器进行重启 + +当所部署的Node 节点有问题时,会对容器进行重新部署和重新调度 + +当容器未通过监控检查时,会关闭此容器直到容器正常运行时,才会对外提供服务 + +![image-20200928101336750](images/image-20200928101336750.png) + +#### 水平扩展 + +通过简单的命令、用户UI 界面或基于CPU 等资源使用情况,对应用容器进行规模扩大或规模剪裁 + +> 当我们有大量的请求来临时,我们可以增加副本数量,从而达到水平扩展的效果 + +#### 服务发现 + +用户不需使用额外的服务发现机制,就能够基于Kubernetes 自身能力实现服务发现和负载均衡 + +> 对外提供统一的入口,让它来做节点的调度和负载均衡, 相当于微服务里面的网关? + +![image-20200928101711968](images/image-20200928101711968.png) + +#### 滚动更新 + +可以根据应用的变化,对应用容器运行的应用,进行一次性或批量式更新 + +> 添加应用的时候,不是加进去就马上可以进行使用,而是需要判断这个添加进去的应用是否能够正常使用 + +#### 版本回退 + +可以根据应用部署情况,对应用容器运行的应用,进行历史版本即时回退 + +> 类似于Git中的回滚 + +#### 密钥和配置管理 + +在不需要重新构建镜像的情况下,可以部署和更新密钥和应用配置,类似热部署。 + +#### 存储编排 + +自动实现存储系统挂载及应用,特别对有状态应用实现数据持久化非常重要 +存储系统可以来自于本地目录、网络存储(NFS、Gluster、Ceph 等)、公共云存储服务 + +#### 批处理 + +提供一次性任务,定时任务;满足批量数据处理和分析的场景 + +## K8S架构组件 + +### 完整架构图 + +![image-20200928103059652](images/image-20200928103059652.png) + + + +![image-20200928110124821](images/image-20200928110124821.png) + +### 架构细节 + +K8S架构主要包含两部分:Master(主控节点)和 node(工作节点) + +k8s 集群控制节点,对集群进行调度管理,接受集群外用户去集群操作请求; + +- **master**:主控节点 + - API Server:集群统一入口,以restful风格进行操作,同时交给etcd存储 + - scheduler:节点的调度,选择node节点应用部署 + - controller-manager:处理集群中常规后台任务,一个资源对应一个控制器 + - etcd:存储系统,用于保存集群中的相关数据 +- **Work node**:工作节点 + - Kubeelet:master派到node节点代表,管理本机容器 + - kube-proxy:提供网络代理,负载均衡等操作 + - + +## K8S核心概念 + +### Pod + +- Pod是K8s中最小的单元 +- 一组容器的集合 +- 共享网络 +- 生命周期是短暂的(服务器重启后,就找不到了) + +### Controller + +- 确保预期的pod副本数量 +- 无状态应用部署 + - 无状态就是指,不需要依赖于网络或者ip +- 有状态应用部署 + - 有状态需要特定的条件 +- 确保所有的node运行同一个pod +- 一次性任务和定时任务 + +### Service + +- 定义一组pod的访问规则 \ No newline at end of file diff --git "a/K8S/1_Kubernetes\347\256\200\344\273\213/images/image-20200928101336750.png" "b/K8S/1_Kubernetes\347\256\200\344\273\213/images/image-20200928101336750.png" new file mode 100644 index 0000000000000000000000000000000000000000..9788551de039971b712edfe3be35a2cdec7cdc78 Binary files /dev/null and "b/K8S/1_Kubernetes\347\256\200\344\273\213/images/image-20200928101336750.png" differ diff --git "a/K8S/1_Kubernetes\347\256\200\344\273\213/images/image-20200928101711968.png" "b/K8S/1_Kubernetes\347\256\200\344\273\213/images/image-20200928101711968.png" new file mode 100644 index 0000000000000000000000000000000000000000..df6587831e9b58be229c4427dce2075fe0fd6825 Binary files /dev/null and "b/K8S/1_Kubernetes\347\256\200\344\273\213/images/image-20200928101711968.png" differ diff --git "a/K8S/1_Kubernetes\347\256\200\344\273\213/images/image-20200928103059652.png" "b/K8S/1_Kubernetes\347\256\200\344\273\213/images/image-20200928103059652.png" new file mode 100644 index 0000000000000000000000000000000000000000..f5bbe79ff8cc87fbc0e082417ae00490a5632c15 Binary files /dev/null and "b/K8S/1_Kubernetes\347\256\200\344\273\213/images/image-20200928103059652.png" differ diff --git "a/K8S/1_Kubernetes\347\256\200\344\273\213/images/image-20200928110124821.png" "b/K8S/1_Kubernetes\347\256\200\344\273\213/images/image-20200928110124821.png" new file mode 100644 index 0000000000000000000000000000000000000000..50b932ec80a56e66503918bd71dd27b5bfdb193a Binary files /dev/null and "b/K8S/1_Kubernetes\347\256\200\344\273\213/images/image-20200928110124821.png" differ diff --git "a/K8S/2_\346\220\255\345\273\272K8S\351\233\206\347\276\244\345\211\215\347\275\256\347\237\245\350\257\206/README.md" "b/K8S/2_\346\220\255\345\273\272K8S\351\233\206\347\276\244\345\211\215\347\275\256\347\237\245\350\257\206/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..cf6bfecc624c4a871649786ad73663fdaceb76a3 --- /dev/null +++ "b/K8S/2_\346\220\255\345\273\272K8S\351\233\206\347\276\244\345\211\215\347\275\256\347\237\245\350\257\206/README.md" @@ -0,0 +1,62 @@ +# 搭建K8S集群 + +## 搭建k8s环境平台规划 + +### 单master集群 + +单个master节点,然后管理多个node节点 + +![image-20200928110456495](images/image-20200928110456495.png) + + + +### 多master集群 + +多个master节点,管理多个node节点,同时中间多了一个负载均衡的过程 + +![image-20200928110543829](images/image-20200928110543829.png) + +## 服务器硬件配置要求 + +### 测试环境 + +master:2核 4G 20G + +node: 4核 8G 40G + +### 生产环境 + +master:8核 16G 100G + +node: 16核 64G 200G + +目前生产部署Kubernetes集群主要有两种方式 + +### kubeadm + +kubeadm是一个K8S部署工具,提供kubeadm init 和 kubeadm join,用于快速部署Kubernetes集群 + +官网地址:[点我传送](https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/) + +### 二进制包 + +从github下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。 + +Kubeadm降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可控,推荐使用二进制包部署Kubernetes集群,虽然手动部署麻烦点,期间可以学习很多工作原理,也利于后期维护。 + +## Kubeadm部署集群 + +kubeadm 是官方社区推出的一个用于快速部署kubernetes 集群的工具,这个工具能通过两条指令完成一个kubernetes 集群的部署: + +- 创建一个Master 节点kubeadm init +- 将Node 节点加入到当前集群中$ kubeadm join + +## 安装要求 + +在开始之前,部署Kubernetes集群机器需要满足以下几个条件 + +- 一台或多台机器,操作系统为Centos7.X +- 硬件配置:2GB或更多GAM,2个CPU或更多CPU,硬盘30G +- 集群中所有机器之间网络互通 +- 可以访问外网,需要拉取镜像 +- 禁止swap分区 \ No newline at end of file diff --git "a/K8S/2_\346\220\255\345\273\272K8S\351\233\206\347\276\244\345\211\215\347\275\256\347\237\245\350\257\206/images/image-20200928110456495.png" "b/K8S/2_\346\220\255\345\273\272K8S\351\233\206\347\276\244\345\211\215\347\275\256\347\237\245\350\257\206/images/image-20200928110456495.png" new file mode 100644 index 0000000000000000000000000000000000000000..81e5f22c6f49bac7b69efb2855146a1d7b607fd1 Binary files /dev/null and "b/K8S/2_\346\220\255\345\273\272K8S\351\233\206\347\276\244\345\211\215\347\275\256\347\237\245\350\257\206/images/image-20200928110456495.png" differ diff --git "a/K8S/2_\346\220\255\345\273\272K8S\351\233\206\347\276\244\345\211\215\347\275\256\347\237\245\350\257\206/images/image-20200928110543829.png" "b/K8S/2_\346\220\255\345\273\272K8S\351\233\206\347\276\244\345\211\215\347\275\256\347\237\245\350\257\206/images/image-20200928110543829.png" new file mode 100644 index 0000000000000000000000000000000000000000..89717dc63af678ccbac9390d915557c60cd2d74f Binary files /dev/null and "b/K8S/2_\346\220\255\345\273\272K8S\351\233\206\347\276\244\345\211\215\347\275\256\347\237\245\350\257\206/images/image-20200928110543829.png" differ diff --git "a/K8S/3_\344\275\277\347\224\250kubeadm\346\226\271\345\274\217\346\220\255\345\273\272K8S\351\233\206\347\276\244/README.md" "b/K8S/3_\344\275\277\347\224\250kubeadm\346\226\271\345\274\217\346\220\255\345\273\272K8S\351\233\206\347\276\244/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ea80a4cfa5be4c736a8964d0b29c574b7818df1f --- /dev/null +++ "b/K8S/3_\344\275\277\347\224\250kubeadm\346\226\271\345\274\217\346\220\255\345\273\272K8S\351\233\206\347\276\244/README.md" @@ -0,0 +1,365 @@ +# 使用kubeadm方式搭建K8S集群 + +kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。 + +这个工具能通过两条指令完成一个kubernetes集群的部署: + +```bash +# 创建一个 Master 节点 +kubeadm init + +# 将一个 Node 节点加入到当前集群中 +kubeadm join +``` + +## 安装要求 + +在开始之前,部署Kubernetes集群机器需要满足以下几个条件: + +- 一台或多台机器,操作系统 CentOS7.x-86_x64 +- 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多【注意master需要两核】 +- 可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点 +- 禁止swap分区 + +## 准备环境 + +| 角色 | IP | +| ------ | -------------- | +| master | 202.193.57.11 | +| node1 | 202.193.57.198 | +| node2 | 202.193.57.92 | + +```bash +# 关闭防火墙 +systemctl stop firewalld +systemctl disable firewalld + +# 关闭selinux +# 永久关闭 +sed -i 's/enforcing/disabled/' /etc/selinux/config +# 临时关闭 +setenforce 0 + +# 关闭swap +# 临时 +swapoff -a +# 临时 +sed -ri 's/.*swap.*/#&/' /etc/fstab + +# 根据规划设置主机名 +hostnamectl set-hostname + +# 在master添加hosts +cat >> /etc/hosts << EOF +202.193.57.11 k8smaster +202.193.57.198 k8snode1 +202.193.57.92 k8snode2 +EOF + +202.193.57.11 +202.193.57.254 +202.193.64.62 + +192.168.31.216 +192.168.31.1 +192.168.31.1 + + +# 将桥接的IPv4流量传递到iptables的链 +cat > /etc/sysctl.d/k8s.conf << EOF +net.bridge.bridge-nf-call-ip6tables = 1 +net.bridge.bridge-nf-call-iptables = 1 +EOF +# 生效 +sysctl --system + +# 时间同步 +yum install ntpdate -y +ntpdate time.windows.com +``` + +## 安装Docker/kubeadm/kubelet + +所有节点安装Docker/kubeadm/kubelet + +Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker + +### 安装Docker + +首先配置一下Docker的阿里yum源 + +```bash +cat >/etc/yum.repos.d/docker.repo<> /etc/docker/daemon.json << EOF +{ + "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"] +} +EOF +``` + +然后重启docker + +```bash +systemctl restart docker +``` + +### 添加kubernetes软件源 + +然后我们还需要配置一下yum的k8s软件源 + +```bash +cat > /etc/yum.repos.d/kubernetes.repo << EOF +[kubernetes] +name=Kubernetes +baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 +enabled=1 +gpgcheck=0 +repo_gpgcheck=0 +gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg +EOF +``` + +### 安装kubeadm,kubelet和kubectl + +由于版本更新频繁,这里指定版本号部署: + +```bash +# 安装kubelet、kubeadm、kubectl,同时指定版本 +yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0 +# 设置开机启动 +systemctl enable kubelet +``` + +## 部署Kubernetes Master【master节点】 + +在202.193.57.11执行,也就是master节点 + +```bash +kubeadm init --apiserver-advertise-address=202.193.57.11 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.18.0 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16 + + +kubeadm init --apiserver-advertise-address=192.168.31.216 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.18.0 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16 +``` + +由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址,【执行上述命令会比较慢,因为后台其实已经在拉取镜像了】,我们 docker images 命令即可查看已经拉取的镜像 + +![image-20200929094302491](images/image-20200929094302491.png) + +当我们出现下面的情况时,表示kubernetes的镜像已经安装成功 + +![image-20200929094620145](images/image-20200929094620145.png) + +使用kubectl工具 【master节点操作】 + +```bash +mkdir -p $HOME/.kube +sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config +sudo chown $(id -u):$(id -g) $HOME/.kube/config +``` + +执行完成后,我们使用下面命令,查看我们正在运行的节点 + +```bash +kubectl get nodes +``` + +![image-20200929094933142](images/image-20200929094933142.png) + +能够看到,目前有一个master节点已经运行了,但是还处于未准备状态 + +下面我们还需要在Node节点执行其它的命令,将node1和node2加入到我们的master节点上 + +## 加入Kubernetes Node + +下面我们需要到 node1 和 node2服务器,执行下面的代码向集群添加新节点 + +执行在kubeadm init输出的kubeadm join命令: + +> 注意,以下的命令是在master初始化完成后,每个人的都不一样!!!需要复制自己生成的 + +```bash +kubeadm join 202.193.57.11:6443 --token tby0x1.30ly7c1b5ftbxvj4 \ + --discovery-token-ca-cert-hash sha256:9782cab7ca747236851738e94d2a70594a7c32b0d7e718f915de4391957ca7f8 +``` + +默认token有效期为24小时,当过期之后,该token就不可用了。这时就需要重新创建token,操作如下: + +``` +kubeadm token create --print-join-command +``` + +## 部署CNI网络插件 + +``` +wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml +``` + +默认镜像地址无法访问,sed命令修改为docker hub镜像仓库。 + +``` +kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml + +kubectl get pods -n kube-system +NAME READY STATUS RESTARTS AGE +kube-flannel-ds-amd64-2pc95 1/1 Running 0 72s +``` + +## 测试kubernetes集群 + +在Kubernetes集群中创建一个pod,验证是否正常运行: + +``` +$ kubectl create deployment nginx --image=nginx +$ kubectl expose deployment nginx --port=80 --type=NodePort +$ kubectl get pod,svc +``` + +访问地址:http://NodeIP:Port + +## 错误汇总 + +### 错误一 + +在执行Kubernetes init方法的时候,出现这个问题 + +```bash +error execution phase preflight: [preflight] Some fatal errors occurred: + [ERROR NumCPU]: the number of available CPUs 1 is less than the required 2 +``` + +是因为VMware设置的核数为1,而K8S需要的最低核数应该是2,调整核数重启系统即可 + +### 错误二 + +我们在给node1节点使用 kubernetes join命令的时候,出现以下错误 + +```bash +error execution phase preflight: [preflight] Some fatal errors occurred: + [ERROR Swap]: running with swap on is not supported. Please disable swap +``` + +错误原因是我们需要关闭swap + +```bash +# 关闭swap +# 临时 +swapoff -a +# 临时 +sed -ri 's/.*swap.*/#&/' /etc/fstab +``` + +### 错误三 + +在给node1节点使用 kubernetes join命令的时候,出现以下错误 + +```bash +The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get http://localhost:10248/healthz: dial tcp [::1]:10248: connect: connection refused +``` + +解决方法,首先需要到 master 节点,创建一个文件 + +```bash +# 创建文件夹 +mkdir /etc/systemd/system/kubelet.service.d + +# 创建文件 +vim /etc/systemd/system/kubelet.service.d/10-kubeadm.conf + +# 添加如下内容 +Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true --fail-swap-on=false" + +# 重置 +kubeadm reset +``` + +然后删除刚刚创建的配置目录 + +```bash +rm -rf $HOME/.kube +``` + +然后 在master重新初始化 + +```bash +kubeadm init --apiserver-advertise-address=202.193.57.11 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.18.0 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16 +``` + +初始完成后,我们再到 node1节点,执行 kubeadm join命令,加入到master + +```bash +kubeadm join 202.193.57.11:6443 --token c7a7ou.z00fzlb01d76r37s \ + --discovery-token-ca-cert-hash sha256:9c3f3cc3f726c6ff8bdff14e46b1a856e3b8a4cbbe30cab185f6c5ee453aeea5 +``` + +添加完成后,我们使用下面命令,查看节点是否成功添加 + +```bash +kubectl get nodes +``` + +### 错误四 + +我们再执行查看节点的时候, kubectl get nodes 会出现问题 + +```bash +Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes") +``` + +这是因为我们之前创建的配置文件还存在,也就是这些配置 + +```bash +mkdir -p $HOME/.kube +sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config +sudo chown $(id -u):$(id -g) $HOME/.kube/config +``` + +我们需要做的就是把配置文件删除,然后重新执行一下 + +```bash +rm -rf $HOME/.kube +``` + +然后再次创建一下即可 + +```bash +mkdir -p $HOME/.kube +sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config +sudo chown $(id -u):$(id -g) $HOME/.kube/config +``` + +这个问题主要是因为我们在执行 kubeadm reset 的时候,没有把 $HOME/.kube 给移除掉,再次创建时就会出现问题了 + diff --git "a/K8S/3_\344\275\277\347\224\250kubeadm\346\226\271\345\274\217\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200929094302491.png" "b/K8S/3_\344\275\277\347\224\250kubeadm\346\226\271\345\274\217\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200929094302491.png" new file mode 100644 index 0000000000000000000000000000000000000000..b4883dee4b6d56202cf1341c2df51f8685b370f1 Binary files /dev/null and "b/K8S/3_\344\275\277\347\224\250kubeadm\346\226\271\345\274\217\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200929094302491.png" differ diff --git "a/K8S/3_\344\275\277\347\224\250kubeadm\346\226\271\345\274\217\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200929094620145.png" "b/K8S/3_\344\275\277\347\224\250kubeadm\346\226\271\345\274\217\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200929094620145.png" new file mode 100644 index 0000000000000000000000000000000000000000..5ca60a7d950b2e2c24974a93d02ec3624533ee69 Binary files /dev/null and "b/K8S/3_\344\275\277\347\224\250kubeadm\346\226\271\345\274\217\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200929094620145.png" differ diff --git "a/K8S/3_\344\275\277\347\224\250kubeadm\346\226\271\345\274\217\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200929094933142.png" "b/K8S/3_\344\275\277\347\224\250kubeadm\346\226\271\345\274\217\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200929094933142.png" new file mode 100644 index 0000000000000000000000000000000000000000..cc35193b8ae8fb2c2daad74a5613c66ded6d9010 Binary files /dev/null and "b/K8S/3_\344\275\277\347\224\250kubeadm\346\226\271\345\274\217\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200929094933142.png" differ diff --git "a/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/README.md" "b/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..17a02044da37c09357abac4eb012c32024e20b5e --- /dev/null +++ "b/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/README.md" @@ -0,0 +1,170 @@ +# 使用Docker搭建K8S集群 + +## 前言 + +今天打算使用Docker来搭建K8S集群,因为同时用VMware创建几个服务器,感觉比较麻烦,所以就打算使用Docker来把这些软件安装一波~ + +## 安装Docker + +首先配置一下docker阿里云yum源 + +```bash +cat >>/etc/yum.repos.d/docker.repo< 上图打开的4个窗口,一个代表宿主机,其它三个就是我们创建的容器 + +## 操作容器 + +下面我们需要进入到每个容器里面,执行下面的代码 + +```bash +# 临时 关闭swap +swapoff -a + +# 根据规划设置主机名 +hostnamectl set-hostname k8s_master +hostnamectl set-hostname k8s_node1 +hostnamectl set-hostname k8s_node2 + +# 在master节点添加hosts +vi /etc/hosts +172.18.0.2 k8s_master +172.18.0.3 k8s_node1 +172.18.0.4 k8s_node2 + +# 时间同步 +yum install ntpdate -y +ntpdate time.windows.com +``` + +## 容器中安装软件 + +### 安装Docker + +在我们制作好容器后,我们需要在容器中,继续安装Docker,然后在里面安装Kibernetes、Kubelet 和 Kubectl + +安装Docker的步骤,和上面是一样的 + +首先配置一下docker阿里云yum源 + +```bash +cat >>/etc/yum.repos.d/docker.repo<> /etc/yum.repos.d/kubernetes.repo << EOF +[kubernetes] +name=Kubernetes +baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 +enabled=1 +gpgcheck=0 +repo_gpgcheck=0 +gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg +EOF +``` + +### 安装Kubeadm + diff --git "a/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200928155946327.png" "b/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200928155946327.png" new file mode 100644 index 0000000000000000000000000000000000000000..3a763a100c26873b3a20c7669d42c47a32c4c4f3 Binary files /dev/null and "b/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200928155946327.png" differ diff --git "a/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200928161210703.png" "b/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200928161210703.png" new file mode 100644 index 0000000000000000000000000000000000000000..75acaf100fd613f01a0b67591b5f89c0d48ff7f7 Binary files /dev/null and "b/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200928161210703.png" differ diff --git "a/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200928161253936.png" "b/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200928161253936.png" new file mode 100644 index 0000000000000000000000000000000000000000..b31514b0f105e4a0bc13b5629378e58af305890f Binary files /dev/null and "b/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200928161253936.png" differ diff --git "a/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200928161427136.png" "b/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200928161427136.png" new file mode 100644 index 0000000000000000000000000000000000000000..b4e5fa94e585761272f3e0f9c104d17ec21dc2f1 Binary files /dev/null and "b/K8S/4_\344\275\277\347\224\250Docker\346\220\255\345\273\272K8S\351\233\206\347\276\244/images/image-20200928161427136.png" differ diff --git "a/K8S/5_\344\275\277\347\224\250kubeadm\346\220\255\345\273\272\351\253\230\345\217\257\347\224\250\347\232\204K8s\351\233\206\347\276\244/\344\275\277\347\224\250kubeadm\346\220\255\345\273\272\351\253\230\345\217\257\347\224\250\347\232\204K8s\351\233\206\347\276\244.md" "b/K8S/5_\344\275\277\347\224\250kubeadm\346\220\255\345\273\272\351\253\230\345\217\257\347\224\250\347\232\204K8s\351\233\206\347\276\244/\344\275\277\347\224\250kubeadm\346\220\255\345\273\272\351\253\230\345\217\257\347\224\250\347\232\204K8s\351\233\206\347\276\244.md" new file mode 100644 index 0000000000000000000000000000000000000000..62e6cbde7d064d6f304f32c578d80c991d9db1a0 --- /dev/null +++ "b/K8S/5_\344\275\277\347\224\250kubeadm\346\220\255\345\273\272\351\253\230\345\217\257\347\224\250\347\232\204K8s\351\233\206\347\276\244/\344\275\277\347\224\250kubeadm\346\220\255\345\273\272\351\253\230\345\217\257\347\224\250\347\232\204K8s\351\233\206\347\276\244.md" @@ -0,0 +1,518 @@ +# 使用kubeadm搭建高可用的K8s集群 + +kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。 + +这个工具能通过两条指令完成一个kubernetes集群的部署: + +``` +# 创建一个 Master 节点 +$ kubeadm init + +# 将一个 Node 节点加入到当前集群中 +$ kubeadm join +``` + +## 安装要求 + +在开始之前,部署Kubernetes集群机器需要满足以下几个条件: + +- 一台或多台机器,操作系统 CentOS7.x-86_x64 +- 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多 +- 可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点 +- 禁止swap分区 + +## 准备环境 + +| 角色 | IP | +| ------------- | -------------- | +| master1 | 192.168.44.155 | +| master2 | 192.168.44.156 | +| node1 | 192.168.44.157 | +| VIP(虚拟ip) | 192.168.44.158 | + +``` +# 关闭防火墙 +systemctl stop firewalld +systemctl disable firewalld + +# 关闭selinux +sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久 +setenforce 0 # 临时 + +# 关闭swap +swapoff -a # 临时 +sed -ri 's/.*swap.*/#&/' /etc/fstab # 永久 + +# 根据规划设置主机名 +hostnamectl set-hostname + +# 在master添加hosts +cat >> /etc/hosts << EOF +192.168.44.158 master.k8s.io k8s-vip +192.168.44.155 master01.k8s.io master1 +192.168.44.156 master02.k8s.io master2 +192.168.44.157 node01.k8s.io node1 +EOF + +# 将桥接的IPv4流量传递到iptables的链 +cat > /etc/sysctl.d/k8s.conf << EOF +net.bridge.bridge-nf-call-ip6tables = 1 +net.bridge.bridge-nf-call-iptables = 1 +EOF +sysctl --system # 生效 + +# 时间同步 +yum install ntpdate -y +ntpdate time.windows.com +``` + + + +## 所有master节点部署keepalived + +### 安装相关包和keepalived + +``` +yum install -y conntrack-tools libseccomp libtool-ltdl + +yum install -y keepalived +``` + +### 配置master节点 + +master1节点配置 + +``` +cat > /etc/keepalived/keepalived.conf < /etc/keepalived/keepalived.conf < /etc/haproxy/haproxy.cfg << EOF +#--------------------------------------------------------------------- +# Global settings +#--------------------------------------------------------------------- +global + # to have these messages end up in /var/log/haproxy.log you will + # need to: + # 1) configure syslog to accept network log events. This is done + # by adding the '-r' option to the SYSLOGD_OPTIONS in + # /etc/sysconfig/syslog + # 2) configure local2 events to go to the /var/log/haproxy.log + # file. A line like the following can be added to + # /etc/sysconfig/syslog + # + # local2.* /var/log/haproxy.log + # + log 127.0.0.1 local2 + + chroot /var/lib/haproxy + pidfile /var/run/haproxy.pid + maxconn 4000 + user haproxy + group haproxy + daemon + + # turn on stats unix socket + stats socket /var/lib/haproxy/stats +#--------------------------------------------------------------------- +# common defaults that all the 'listen' and 'backend' sections will +# use if not designated in their block +#--------------------------------------------------------------------- +defaults + mode http + log global + option httplog + option dontlognull + option http-server-close + option forwardfor except 127.0.0.0/8 + option redispatch + retries 3 + timeout http-request 10s + timeout queue 1m + timeout connect 10s + timeout client 1m + timeout server 1m + timeout http-keep-alive 10s + timeout check 10s + maxconn 3000 +#--------------------------------------------------------------------- +# kubernetes apiserver frontend which proxys to the backends +#--------------------------------------------------------------------- +frontend kubernetes-apiserver + mode tcp + bind *:16443 + option tcplog + default_backend kubernetes-apiserver +#--------------------------------------------------------------------- +# round robin balancing between the various backends +#--------------------------------------------------------------------- +backend kubernetes-apiserver + mode tcp + balance roundrobin + server master01.k8s.io 192.168.44.155:6443 check + server master02.k8s.io 192.168.44.156:6443 check +#--------------------------------------------------------------------- +# collection haproxy statistics message +#--------------------------------------------------------------------- +listen stats + bind *:1080 + stats auth admin:awesomePassword + stats refresh 5s + stats realm HAProxy\ Statistics + stats uri /admin?stats +EOF +``` + +### 4.3 启动和检查 + +两台master都启动 + +``` +# 设置开机启动 +$ systemctl enable haproxy +# 开启haproxy +$ systemctl start haproxy +# 查看启动状态 +$ systemctl status haproxy +``` + +检查端口 + +``` +netstat -lntup|grep haproxy +``` + + + +## 5. 所有节点安装Docker/kubeadm/kubelet + +Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker。 + +### 5.1 安装Docker + +``` +$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo +$ yum -y install docker-ce-18.06.1.ce-3.el7 +$ systemctl enable docker && systemctl start docker +$ docker --version +Docker version 18.06.1-ce, build e68fc7a +``` + +``` +$ cat > /etc/docker/daemon.json << EOF +{ + "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"] +} +EOF +``` + +### 5.2 添加阿里云YUM软件源 + +``` +$ cat > /etc/yum.repos.d/kubernetes.repo << EOF +[kubernetes] +name=Kubernetes +baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 +enabled=1 +gpgcheck=0 +repo_gpgcheck=0 +gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg +EOF +``` + +### 5.3 安装kubeadm,kubelet和kubectl + +由于版本更新频繁,这里指定版本号部署: + +``` +$ yum install -y kubelet-1.16.3 kubeadm-1.16.3 kubectl-1.16.3 +$ systemctl enable kubelet +``` + + + +## 6. 部署Kubernetes Master + +### 6.1 创建kubeadm配置文件 + +在具有vip的master上操作,这里为master1 + +``` +$ mkdir /usr/local/kubernetes/manifests -p + +$ cd /usr/local/kubernetes/manifests/ + +$ vi kubeadm-config.yaml + +apiServer: + certSANs: + - master1 + - master2 + - master.k8s.io + - 192.168.44.158 + - 192.168.44.155 + - 192.168.44.156 + - 127.0.0.1 + extraArgs: + authorization-mode: Node,RBAC + timeoutForControlPlane: 4m0s +apiVersion: kubeadm.k8s.io/v1beta1 +certificatesDir: /etc/kubernetes/pki +clusterName: kubernetes +controlPlaneEndpoint: "master.k8s.io:16443" +controllerManager: {} +dns: + type: CoreDNS +etcd: + local: + dataDir: /var/lib/etcd +imageRepository: registry.aliyuncs.com/google_containers +kind: ClusterConfiguration +kubernetesVersion: v1.16.3 +networking: + dnsDomain: cluster.local + podSubnet: 10.244.0.0/16 + serviceSubnet: 10.1.0.0/16 +scheduler: {} +``` + + + +### 6.2 在master1节点执行 + +``` +$ kubeadm init --config kubeadm-config.yaml +``` + + + +按照提示配置环境变量,使用kubectl工具: + +```bash +mkdir -p $HOME/.kube +sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config +sudo chown $(id -u):$(id -g) $HOME/.kube/config +$ kubectl get nodes +$ kubectl get pods -n kube-system +``` + + + +**按照提示保存以下内容,一会要使用:** + +```bash +kubeadm join master.k8s.io:16443 --token jv5z7n.3y1zi95p952y9p65 \ + --discovery-token-ca-cert-hash sha256:403bca185c2f3a4791685013499e7ce58f9848e2213e27194b75a2e3293d8812 \ + --control-plane +``` + +查看集群状态 + +```bash +kubectl get cs + +kubectl get pods -n kube-system +``` + + + +## 7.安装集群网络 + +从官方地址获取到flannel的yaml,在master1上执行 + +```bash +mkdir flannel +cd flannel +wget -c https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml +``` + + + +安装flannel网络 + +```bash +kubectl apply -f kube-flannel.yml +``` + +检查 + +```bash +kubectl get pods -n kube-system +``` + + + +## 8、master2节点加入集群 + +### 8.1 复制密钥及相关文件 + +从master1复制密钥及相关文件到master2 + +```bash +# ssh root@192.168.44.156 mkdir -p /etc/kubernetes/pki/etcd + +# scp /etc/kubernetes/admin.conf root@192.168.44.156:/etc/kubernetes + +# scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@192.168.44.156:/etc/kubernetes/pki + +# scp /etc/kubernetes/pki/etcd/ca.* root@192.168.44.156:/etc/kubernetes/pki/etcd +``` + +### 8.2 master2加入集群 + +执行在master1上init后输出的join命令,需要带上参数`--control-plane`表示把master控制节点加入集群 + +``` +kubeadm join master.k8s.io:16443 --token ckf7bs.30576l0okocepg8b --discovery-token-ca-cert-hash sha256:19afac8b11182f61073e254fb57b9f19ab4d798b70501036fc69ebef46094aba --control-plane +``` + +检查状态 + +``` +kubectl get node + +kubectl get pods --all-namespaces +``` + +## + +## 5. 加入Kubernetes Node + +在node1上执行 + +向集群添加新节点,执行在kubeadm init输出的kubeadm join命令: + +``` +kubeadm join master.k8s.io:16443 --token ckf7bs.30576l0okocepg8b --discovery-token-ca-cert-hash sha256:19afac8b11182f61073e254fb57b9f19ab4d798b70501036fc69ebef46094aba +``` + +**集群网络重新安装,因为添加了新的node节点** + +检查状态 + +``` +kubectl get node + +kubectl get pods --all-namespaces +``` + +## + +## 7. 测试kubernetes集群 + +在Kubernetes集群中创建一个pod,验证是否正常运行: + +``` +$ kubectl create deployment nginx --image=nginx +$ kubectl expose deployment nginx --port=80 --type=NodePort +$ kubectl get pod,svc +``` + +访问地址:http://NodeIP:Port + + + + diff --git "a/LeetCode/102_\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206/README.md" "b/LeetCode/102_\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..386bc3ef8b1bdce6ca4d9aeca84ad80cfe79b146 --- /dev/null +++ "b/LeetCode/102_\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206/README.md" @@ -0,0 +1,52 @@ +# 二叉树的层次遍历 + +## 来源 + +https://leetcode-cn.com/problems/binary-tree-level-order-traversal/ + +## 描述 + +给你一个二叉树,请你返回其按 层次遍历 得到的节点值(即逐层地,从做到右访问所有节点) + +![image-20200715210522932](images/image-20200715210522932.png) + +## 代码 + +通过两个数组来交替打印 + +```python +class Solution(object): + def levelOrder(self, root): + if root == None: + return [] + stack = [root] + secondStack = [] + ret = [[root.val]] + while stack or secondStack: + tempList = [] + while stack: + node = stack.pop(0) + if node.left: + secondStack.append(node.left) + tempList.append(node.left.val) + if node.right: + secondStack.append(node.right) + tempList.append(node.right.val) + + if tempList != []: + ret.append(tempList) + + tempList = [] + while secondStack: + node = secondStack.pop(0) + if node.left: + stack.append(node.left) + tempList.append(node.left.val) + if node.right: + stack.append(node.right) + tempList.append(node.right.val) + if tempList != []: + ret.append(tempList) + return ret +``` + diff --git "a/LeetCode/102_\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206/images/image-20200715210522932.png" "b/LeetCode/102_\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206/images/image-20200715210522932.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a5a4f83d6a05a85a6db62340bc39e3dc6a4b7b2 Binary files /dev/null and "b/LeetCode/102_\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\346\254\241\351\201\215\345\216\206/images/image-20200715210522932.png" differ diff --git "a/LeetCode/112_\350\267\257\345\276\204\346\200\273\345\222\214/README.md" "b/LeetCode/112_\350\267\257\345\276\204\346\200\273\345\222\214/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..f9059eda6385765d550bd440bab627e2b97ec324 --- /dev/null +++ "b/LeetCode/112_\350\267\257\345\276\204\346\200\273\345\222\214/README.md" @@ -0,0 +1,26 @@ +# 路径总和 + +## 来源 + +https://leetcode-cn.com/problems/path-sum/ + +## 描述 + +给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和 + +说明:叶子节点是指没有子节点的节点 + +```bash +示例 +给定如下二叉树,以及目标和 sum = 22 + 5 + / \ + 4 8 + / / \ + 11 13 4 + / \ \ + 7 2 1 + +返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。 +``` + diff --git "a/LeetCode/1252_\345\245\207\346\225\260\345\200\274\345\215\225\345\205\203\346\240\274\347\232\204\346\225\260\347\233\256/README.md" "b/LeetCode/1252_\345\245\207\346\225\260\345\200\274\345\215\225\345\205\203\346\240\274\347\232\204\346\225\260\347\233\256/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..d967b13979e1c5e1d0f468eee61bafe78d0f876a --- /dev/null +++ "b/LeetCode/1252_\345\245\207\346\225\260\345\200\274\345\215\225\345\205\203\346\240\274\347\232\204\346\225\260\347\233\256/README.md" @@ -0,0 +1,67 @@ +# 奇数值单元格的数目 + +## 题目 + +https://leetcode-cn.com/problems/cells-with-odd-values-in-a-matrix/ + +## 描述 + +给你一个 n 行 m 列的矩阵,最开始的时候,每个单元格中的值都是 0。 + +另有一个索引数组 indices,indices[i] = [ri, ci] 中的 ri 和 ci 分别表示指定的行和列(从 0 开始编号)。 + +你需要将每对 [ri, ci] 指定的行和列上的所有单元格的值加 1。 + +请你在执行完所有 indices 指定的增量操作后,返回矩阵中 「奇数值单元格」 的数目。 + +![image-20200703190036895](images/image-20200703190036895.png) + +``` +输入:n = 2, m = 3, indices = [[0,1],[1,1]] +输出:6 +解释:最开始的矩阵是 [[0,0,0],[0,0,0]]。 +第一次增量操作后得到 [[1,2,1],[0,1,0]]。 +最后的矩阵是 [[1,3,1],[1,3,1]],里面有 6 个奇数。 +``` + +示例2: + +![image-20200703190100428](images/image-20200703190100428.png) + +``` +输入:n = 2, m = 2, indices = [[1,1],[0,0]] +输出:0 +解释:最后的矩阵是 [[2,2],[2,2]],里面没有奇数。 +``` + +## 代码 + +### 解法1 + +首先想到的就是暴力法 + +- 既然给我一个矩阵,那我就先构造一下呗 +- 然后遍历indices里面每个元素,拆包ri和ci +- 根据要求,对构造的矩阵进行行列+1操作 +- 最后对矩阵的内容进行遍历,数奇数的个数 + +``` +class Solution(object): + def oddCells(self, n, m, indices): + matrix = [[0 for i in range(m)] for j in range(n)] + + for i in indices: + for j in range(len(matrix[i[0]])): + matrix[i[0]][j] += 1 + + for j in range(len(matrix)): + matrix[j][i[1]] += 1 + + count = 0 + for i in range(len(matrix)): + for j in range(len(matrix[0])): + if matrix[i][j] % 2 == 1: + count += 1 + return count +``` + diff --git "a/LeetCode/1252_\345\245\207\346\225\260\345\200\274\345\215\225\345\205\203\346\240\274\347\232\204\346\225\260\347\233\256/images/image-20200703190036895.png" "b/LeetCode/1252_\345\245\207\346\225\260\345\200\274\345\215\225\345\205\203\346\240\274\347\232\204\346\225\260\347\233\256/images/image-20200703190036895.png" new file mode 100644 index 0000000000000000000000000000000000000000..6751cc364edcdcdba0b6ef7eaa81c149b013c63e Binary files /dev/null and "b/LeetCode/1252_\345\245\207\346\225\260\345\200\274\345\215\225\345\205\203\346\240\274\347\232\204\346\225\260\347\233\256/images/image-20200703190036895.png" differ diff --git "a/LeetCode/1252_\345\245\207\346\225\260\345\200\274\345\215\225\345\205\203\346\240\274\347\232\204\346\225\260\347\233\256/images/image-20200703190100428.png" "b/LeetCode/1252_\345\245\207\346\225\260\345\200\274\345\215\225\345\205\203\346\240\274\347\232\204\346\225\260\347\233\256/images/image-20200703190100428.png" new file mode 100644 index 0000000000000000000000000000000000000000..02c5faa7fea59ab13da1f66b9ef0ab5cd3b8675f Binary files /dev/null and "b/LeetCode/1252_\345\245\207\346\225\260\345\200\274\345\215\225\345\205\203\346\240\274\347\232\204\346\225\260\347\233\256/images/image-20200703190100428.png" differ diff --git "a/LeetCode/1266_\350\256\277\351\227\256\346\211\200\346\234\211\347\202\271\347\232\204\346\234\200\345\260\217\346\227\266\351\227\264/README.md" "b/LeetCode/1266_\350\256\277\351\227\256\346\211\200\346\234\211\347\202\271\347\232\204\346\234\200\345\260\217\346\227\266\351\227\264/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..c1bdb6a9925642e61cd088368c27d12bd98745e1 --- /dev/null +++ "b/LeetCode/1266_\350\256\277\351\227\256\346\211\200\346\234\211\347\202\271\347\232\204\346\234\200\345\260\217\346\227\266\351\227\264/README.md" @@ -0,0 +1,49 @@ +# 访问所有点的最小时间 + +## 题目 + +https://leetcode-cn.com/problems/minimum-time-visiting-all-points/ + +## 描述 + +平面上有 n 个点,点的位置用整数坐标表示 points[i] = [xi, yi]。请你计算访问所有这些点需要的最小时间(以秒为单位)。 + +你可以按照下面的规则在平面上移动: + +每一秒沿水平或者竖直方向移动一个单位长度,或者跨过对角线(可以看作在一秒内向水平和竖直方向各移动一个单位长度)。 +必须按照数组中出现的顺序来访问这些点。 + + +示例 1: + +![image-20200703152246832](images/image-20200703152246832.png) + +``` +输入:points = [[1,1],[3,4],[-1,0]] +输出:7 +解释:一条最佳的访问路径是: [1,1] -> [2,2] -> [3,3] -> [3,4] -> [2,3] -> [1,2] -> [0,1] -> [-1,0] +从 [1,1] 到 [3,4] 需要 3 秒 +从 [3,4] 到 [-1,0] 需要 4 秒 +一共需要 7 秒 + +示例 2: +输入:points = [[3,2],[-2,2]] +输出:5 +``` + +## 代码 + +``` +class Solution(object): + def minTimeToVisitAllPoints(self, points): + time = 0 + for i in range(len(points) - 1): + time1 = abs(points[i][0] - points[i+1][0]) + time2 = abs(points[i][1] - points[i+1][1]) + if time1 > time2: + time += time1 + else: + time += time2 + return time +``` + diff --git "a/LeetCode/1266_\350\256\277\351\227\256\346\211\200\346\234\211\347\202\271\347\232\204\346\234\200\345\260\217\346\227\266\351\227\264/images/image-20200703152246832.png" "b/LeetCode/1266_\350\256\277\351\227\256\346\211\200\346\234\211\347\202\271\347\232\204\346\234\200\345\260\217\346\227\266\351\227\264/images/image-20200703152246832.png" new file mode 100644 index 0000000000000000000000000000000000000000..12a5200a54b7605dc976534a780dc25159d91a2a Binary files /dev/null and "b/LeetCode/1266_\350\256\277\351\227\256\346\211\200\346\234\211\347\202\271\347\232\204\346\234\200\345\260\217\346\227\266\351\227\264/images/image-20200703152246832.png" differ diff --git "a/LeetCode/1295_\347\273\237\350\256\241\344\275\215\346\225\260\344\270\272\345\201\266\346\225\260\347\232\204\346\225\260\345\255\227/README.md" "b/LeetCode/1295_\347\273\237\350\256\241\344\275\215\346\225\260\344\270\272\345\201\266\346\225\260\347\232\204\346\225\260\345\255\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..8f34978b6a1f0fb688ffcb2f34f7985d11945071 --- /dev/null +++ "b/LeetCode/1295_\347\273\237\350\256\241\344\275\215\346\225\260\344\270\272\345\201\266\346\225\260\347\232\204\346\225\260\345\255\227/README.md" @@ -0,0 +1,43 @@ +# 统计位数为偶数的数组 + +## 题目 + +https://leetcode-cn.com/problems/find-numbers-with-even-number-of-digits/ + +## 描述 + +给你一个整数数组 nums,请你返回其中位数为 偶数 的数字的个数。 + +``` +示例 1: +输入:nums = [12,345,2,6,7896] +输出:2 +解释: +12 是 2 位数字(位数为偶数) +345 是 3 位数字(位数为奇数) +2 是 1 位数字(位数为奇数) +6 是 1 位数字 位数为奇数) +7896 是 4 位数字(位数为偶数) +因此只有 12 和 7896 是位数为偶数的数字 + +示例 2: +输入:nums = [555,901,482,1771] +输出:1 +解释: +只有 1771 是位数为偶数的数字。 +``` + +## 代码 + +用到了转换成字符串求长度的方法 + +``` +class Solution(object): + def findNumbers(self, nums): + ret = 0 + for i in nums: + if len(str(i)) % 2 ==0: + ret += 1 + return ret +``` + diff --git "a/LeetCode/1299_\345\260\206\346\257\217\344\270\252\345\205\203\347\264\240\346\233\277\346\215\242\344\270\272\345\217\263\344\276\247\346\234\200\345\244\247\345\205\203\347\264\240/README.md" "b/LeetCode/1299_\345\260\206\346\257\217\344\270\252\345\205\203\347\264\240\346\233\277\346\215\242\344\270\272\345\217\263\344\276\247\346\234\200\345\244\247\345\205\203\347\264\240/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..13b7d2712f4e473b1d5812114769aece6161e163 --- /dev/null +++ "b/LeetCode/1299_\345\260\206\346\257\217\344\270\252\345\205\203\347\264\240\346\233\277\346\215\242\344\270\272\345\217\263\344\276\247\346\234\200\345\244\247\345\205\203\347\264\240/README.md" @@ -0,0 +1,37 @@ +# 将每个元素替换为右侧最大的元素 + +## 来源 + +https://leetcode-cn.com/problems/replace-elements-with-greatest-element-on-right-side/ + +## 描述 + +给你一个数组 arr ,请你将每个元素用它右边最大的元素替换,如果是最后一个元素,用 -1 替换。 + +完成所有替换操作后,请你返回这个数组。 + +``` +示例: + +输入:arr = [17,18,5,4,6,1] +输出:[18,6,6,6,1,-1] +``` + +## 代码 + +我们就是从右到左遍历数组,同时使用 + +```python +class Solution(object): + def replaceElements(self, arr): + max = -1 + arrLen = len(arr) + ret = [0 for i in range(arrLen)] + ret[-1] = -1 + for i in range(arrLen - 1, 0, -1): + if arr[i] > max: + max = arr[i] + ret[i-1] = max + return ret +``` + diff --git "a/LeetCode/1313_\350\247\243\345\216\213\347\274\226\347\240\201\345\210\227\350\241\250/README.md" "b/LeetCode/1313_\350\247\243\345\216\213\347\274\226\347\240\201\345\210\227\350\241\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..db5afc474f9be6732160a9bdf2e8bbe5608814e7 --- /dev/null +++ "b/LeetCode/1313_\350\247\243\345\216\213\347\274\226\347\240\201\345\210\227\350\241\250/README.md" @@ -0,0 +1,39 @@ +# 解压编码列表 + +## 来源 + +https://leetcode-cn.com/problems/decompress-run-length-encoded-list/ + +## 描述 + +给你一个以行程长度编码压缩的整数列表 nums 。 + +考虑每对相邻的两个元素 [freq, val] = [nums[2*i], nums[2*i+1]] (其中 i >= 0 ),每一对都表示解压后子列表中有 freq 个值为 val 的元素,你需要从左到右连接所有子列表以生成解压后的列表。 + +请你返回解压后的列表。 + +``` +示例: +输入:nums = [1,2,3,4] +输出:[2,4,4,4] +解释:第一对 [1,2] 代表着 2 的出现频次为 1,所以生成数组 [2]。 +第二对 [3,4] 代表着 4 的出现频次为 3,所以生成数组 [4,4,4]。 +最后将它们串联到一起 [2] + [4,4,4] = [2,4,4,4]。 + +示例 2: +输入:nums = [1,1,2,3] +输出:[1,3,3] +``` + +## 代码 + +```python +class Solution(object): + def decompressRLElist(self, nums): + ret = [] + for i in range(1, len(nums), 2): + for j in range(nums[i-1]): + ret.append(nums[i]) + return ret +``` + diff --git "a/LeetCode/1351_\347\273\237\350\256\241\346\234\211\345\272\217\347\237\251\351\230\265\344\270\255\347\232\204\350\264\237\346\225\260/README.md" "b/LeetCode/1351_\347\273\237\350\256\241\346\234\211\345\272\217\347\237\251\351\230\265\344\270\255\347\232\204\350\264\237\346\225\260/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..1e21f291f8f9fa67be0cca7bd596d8434a1b0f12 --- /dev/null +++ "b/LeetCode/1351_\347\273\237\350\256\241\346\234\211\345\272\217\347\237\251\351\230\265\344\270\255\347\232\204\350\264\237\346\225\260/README.md" @@ -0,0 +1,73 @@ +# 统计有序矩阵中的负数 + +## 来源 + +## 描述 + +给你一个 `m * n` 的矩阵 `grid`,矩阵中的元素无论是按行还是按列,都以非递增顺序排列。 + +请你统计并返回 `grid` 中 **负数** 的数目 + +``` +示例 1: +输入:grid = [[4,3,2,-1],[3,2,1,-1],[1,1,-1,-2],[-1,-1,-2,-3]] +输出:8 +解释:矩阵中共有 8 个负数。 + +示例 2: +输入:grid = [[3,2],[1,0]] +输出:0 + +示例 3: +输入:grid = [[1,-1],[-1,-1]] +输出:3 + +示例 4: +输入:grid = [[-1]] +输出:1 +``` + + + +## 代码 + +最简单的就是暴力破解,但是这个因为有序,所以当我们找到是负数的时候,直接后面可以不判断了 + +``` +class Solution(object): + def countNegatives(self, grid): + count = 0 + for i in range(len(grid)): + for j in range(len(grid[0])): + if grid[i][j] < 0: + count += len(grid[0]) - j + break + return count +``` + +当然因为是不递增的,我们还可以想到使用二分查找法,时间复杂度是 O(logn) + +``` +class Solution(object): + def getIndex(self, line): + lineLen = len(line) + left = 0 + right = lineLen - 1 + + while left <= right: + mid = (left + right) // 2 + if line[mid] < 0 and ((mid != 0 and line[mid -1] >= 0) or (mid == 0)): + return lineLen - mid + elif line[mid] < 0: + right = mid -1 + else: + left = mid + 1 + return 0 + + def countNegatives(self, grid): + count = 0 + for i in range(len(grid)): + count += self.getIndex(grid[i]) + return count +``` + diff --git "a/LeetCode/1365_\346\234\211\345\244\232\345\260\221\345\260\217\344\272\216\345\275\223\345\211\215\346\225\260\345\255\227\347\232\204\346\225\260\345\255\227/README.md" "b/LeetCode/1365_\346\234\211\345\244\232\345\260\221\345\260\217\344\272\216\345\275\223\345\211\215\346\225\260\345\255\227\347\232\204\346\225\260\345\255\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ca429290a8179224174c2471b0336e19ca11b529 --- /dev/null +++ "b/LeetCode/1365_\346\234\211\345\244\232\345\260\221\345\260\217\344\272\216\345\275\223\345\211\215\346\225\260\345\255\227\347\232\204\346\225\260\345\255\227/README.md" @@ -0,0 +1,69 @@ +# 有多少小于当前数字的数字 + +## 来源 + +https://leetcode-cn.com/problems/how-many-numbers-are-smaller-than-the-current-number/ + +## 描述 + +给你一个数组 nums,对于其中每个元素 nums[i],请你统计数组中比它小的所有数字的数目。 + +换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != i 且 nums[j] < nums[i] 。 + +以数组形式返回答案。 + +```java +示例 1: +输入:nums = [8,1,2,2,3] +输出:[4,0,1,1,3] +解释: +对于 nums[0]=8 存在四个比它小的数字:(1,2,2 和 3)。 +对于 nums[1]=1 不存在比它小的数字。 +对于 nums[2]=2 存在一个比它小的数字:(1)。 +对于 nums[3]=2 存在一个比它小的数字:(1)。 +对于 nums[4]=3 存在三个比它小的数字:(1,2 和 2) + +示例 2: +输入:nums = [6,5,4,8] +输出:[2,1,0,3] + +示例 3: +输入:nums = [7,7,7,7] +输出:[0,0,0,0] +``` + +## 代码 + +### 方法1 + +暴力解法,两层for循环完事 + +``` +class Solution(object): + def smallerNumbersThanCurrent(self, nums): + ret = [] + for i in range(len(nums)): + sum = 0 + for j in range(len(nums)): + if i == j: + continue + if nums[i] > nums[j]: + sum += 1 + ret.append(sum) + return ret +``` + +### 方法2 + +使用排序算法,先进行排序,完成后在统计小于的即可,排序后时间复杂度就可以由原来的 O(n^2) 变成 O(n logN)。 + +```java +class Solution(object): + def smallerNumbersThanCurrent(self, nums): + ret = [] + nums2 = sorted(nums) + for i in nums: + ret.append(nums2.index(i)) + return ret +``` + diff --git "a/LeetCode/1389_\346\214\211\346\227\242\345\256\232\351\241\272\345\272\217\345\210\233\345\273\272\347\233\256\346\240\207\346\225\260\347\273\204/README.md" "b/LeetCode/1389_\346\214\211\346\227\242\345\256\232\351\241\272\345\272\217\345\210\233\345\273\272\347\233\256\346\240\207\346\225\260\347\273\204/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b41f2fc45da3f6e880376e6f60725d1cab6f0a16 --- /dev/null +++ "b/LeetCode/1389_\346\214\211\346\227\242\345\256\232\351\241\272\345\272\217\345\210\233\345\273\272\347\233\256\346\240\207\346\225\260\347\273\204/README.md" @@ -0,0 +1,62 @@ +# 按既定顺序逛街目标数组 + +## 来源 + +https://leetcode-cn.com/problems/create-target-array-in-the-given-order/ + +## 描述 + +给你两个整数数组 nums 和 index。你需要按照以下规则创建目标数组: + +目标数组 target 最初为空。 +按从左到右的顺序依次读取 nums[i] 和 index[i],在 target 数组中的下标 index[i] 处插入值 nums[i] 。 +重复上一步,直到在 nums 和 index 中都没有要读取的元素。 +请你返回目标数组。 + +题目保证数字插入位置总是存在 + +``` +示例 1: +输入:nums = [0,1,2,3,4], index = [0,1,2,2,1] +输出:[0,4,1,3,2] +解释: +nums index target +0 0 [0] +1 1 [0,1] +2 2 [0,1,2] +3 2 [0,1,3,2] +4 1 [0,4,1,3,2] + +示例 2: +输入:nums = [1,2,3,4,0], index = [0,1,2,3,0] +输出:[0,1,2,3,4] +解释: +nums index target +1 0 [1] +2 1 [1,2] +3 2 [1,2,3] +4 3 [1,2,3,4] +0 0 [0,1,2,3,4] + +示例 3: +输入:nums = [1], index = [0] +输出:[1] +``` + +来源:力扣(LeetCode) +链接:https://leetcode-cn.com/problems/create-target-array-in-the-given-order +著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 + +## 代码 + +```python +class Solution(object): + def createTargetArray(self, nums, index): + ret = [] + for i in range(len(index)): + ret.insert(index[i], nums[i]) + return ret +``` + + + diff --git "a/LeetCode/1431_\346\213\245\346\234\211\346\234\200\345\244\232\347\263\226\346\236\234\347\232\204\345\255\251\345\255\220/README.md" "b/LeetCode/1431_\346\213\245\346\234\211\346\234\200\345\244\232\347\263\226\346\236\234\347\232\204\345\255\251\345\255\220/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..98a337330344629cb637e719f6db8725a6aeb500 --- /dev/null +++ "b/LeetCode/1431_\346\213\245\346\234\211\346\234\200\345\244\232\347\263\226\346\236\234\347\232\204\345\255\251\345\255\220/README.md" @@ -0,0 +1,57 @@ +# 拥有糖果最多的孩子 + +## 来源 + +https://leetcode-cn.com/problems/kids-with-the-greatest-number-of-candies/ + +## 描述 + +给你一个数组 candies 和一个整数 extraCandies ,其中 candies[i] 代表第 i 个孩子拥有的糖果数目。 + +对每一个孩子,检查是否存在一种方案,将额外的 extraCandies 个糖果分配给孩子们之后,此孩子有 最多 的糖果。注意,允许有多个孩子同时拥有 最多 的糖果数目。 + +``` +示例 1: + +输入:candies = [2,3,5,1,3], extraCandies = 3 +输出:[true,true,true,false,true] +解释: +孩子 1 有 2 个糖果,如果他得到所有额外的糖果(3个),那么他总共有 5 个糖果,他将成为拥有最多糖果的孩子。 +孩子 2 有 3 个糖果,如果他得到至少 2 个额外糖果,那么他将成为拥有最多糖果的孩子。 +孩子 3 有 5 个糖果,他已经是拥有最多糖果的孩子。 +孩子 4 有 1 个糖果,即使他得到所有额外的糖果,他也只有 4 个糖果,无法成为拥有糖果最多的孩子。 +孩子 5 有 3 个糖果,如果他得到至少 2 个额外糖果,那么他将成为拥有最多糖果的孩子。 +示例 2: + +输入:candies = [4,2,1,1,2], extraCandies = 1 +输出:[true,false,false,false,false] +解释:只有 1 个额外糖果,所以不管额外糖果给谁,只有孩子 1 可以成为拥有糖果最多的孩子。 +示例 3: + +输入:candies = [12,1,12], extraCandies = 10 +输出:[true,false,true] +``` + +## 代码 + +``` +class Solution(object): + def kidsWithCandies(self, candies, extraCandies): + """ + :type candies: List[int] + :type extraCandies: int + :rtype: List[bool] + """ + max = 0 + for i in candies: + if i > max: + max = i + + for i in range(len(candies)): + if candies[i] + extraCandies >= max: + candies[i] = True + else: + candies[i] = False + return candies +``` + diff --git "a/LeetCode/1450_\345\234\250\346\227\242\345\256\232\346\227\266\351\227\264\345\201\232\344\275\234\344\270\232\347\232\204\345\255\246\347\224\237\344\272\272\346\225\260/README.md" "b/LeetCode/1450_\345\234\250\346\227\242\345\256\232\346\227\266\351\227\264\345\201\232\344\275\234\344\270\232\347\232\204\345\255\246\347\224\237\344\272\272\346\225\260/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ed9b5f3e9c2f2b2956c9f83e1c3137d628726d2e --- /dev/null +++ "b/LeetCode/1450_\345\234\250\346\227\242\345\256\232\346\227\266\351\227\264\345\201\232\344\275\234\344\270\232\347\232\204\345\255\246\347\224\237\344\272\272\346\225\260/README.md" @@ -0,0 +1,51 @@ +# 在既定时间做作业的学生人数 + +## 来源 + +https://leetcode-cn.com/problems/number-of-students-doing-homework-at-a-given-time/ + +## 描述 + +给你两个整数数组 startTime(开始时间)和 endTime(结束时间),并指定一个整数 queryTime 作为查询时间。 + +已知,第 i 名学生在 startTime[i] 时开始写作业并于 endTime[i] 时完成作业。 + +请返回在查询时间 queryTime 时正在做作业的学生人数。形式上,返回能够使 queryTime 处于区间 [startTime[i], endTime[i]](含)的学生人数。 + + ``` +示例 1: +输入:startTime = [1,2,3], endTime = [3,2,7], queryTime = 4 +输出:1 +解释:一共有 3 名学生。 +第一名学生在时间 1 开始写作业,并于时间 3 完成作业,在时间 4 没有处于做作业的状态。 +第二名学生在时间 2 开始写作业,并于时间 2 完成作业,在时间 4 没有处于做作业的状态。 +第三名学生在时间 3 开始写作业,预计于时间 7 完成作业,这是是唯一一名在时间 4 时正在做作业的学生。 + +示例 2: +输入:startTime = [4], endTime = [4], queryTime = 4 +输出:1 +解释:在查询时间只有一名学生在做作业。 + +示例 3: +输入:startTime = [4], endTime = [4], queryTime = 5 +输出:0 + +示例 4: +输入:startTime = [1,1,1,1], endTime = [1,3,2,4], queryTime = 7 +输出:0 + ``` + +## 代码 + +```python +class Solution(object): + def busyStudent(self, startTime, endTime, queryTime): + count = 0 + for i in range(len(startTime)): + if startTime[i] > queryTime: + continue + if startTime[i] <= queryTime and endTime[i] >= queryTime: + count += 1 + return count +``` + diff --git "a/LeetCode/1460_\351\200\232\350\277\207\347\277\273\350\275\254\345\255\220\346\225\260\347\273\204\344\275\277\344\270\244\344\270\252\346\225\260\347\273\204\347\233\270\347\255\211/README.md" "b/LeetCode/1460_\351\200\232\350\277\207\347\277\273\350\275\254\345\255\220\346\225\260\347\273\204\344\275\277\344\270\244\344\270\252\346\225\260\347\273\204\347\233\270\347\255\211/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..3dd467f79416aecd6c11908b834e4a216ea127cb --- /dev/null +++ "b/LeetCode/1460_\351\200\232\350\277\207\347\277\273\350\275\254\345\255\220\346\225\260\347\273\204\344\275\277\344\270\244\344\270\252\346\225\260\347\273\204\347\233\270\347\255\211/README.md" @@ -0,0 +1,65 @@ +# 通过翻转子数组使两个数组相等 + +## 来源 + +https://leetcode-cn.com/problems/make-two-arrays-equal-by-reversing-sub-arrays/ + +## 描述 + +给你两个长度相同的整数数组 target 和 arr 。 + +每一步中,你可以选择 arr 的任意 非空子数组 并将它翻转。你可以执行此过程任意次。 + +如果你能让 arr 变得与 target 相同,返回 True;否则,返回 False 。 + +``` +示例 1: +输入:target = [1,2,3,4], arr = [2,4,1,3] +输出:true +解释:你可以按照如下步骤使 arr 变成 target: +1- 翻转子数组 [2,4,1] ,arr 变成 [1,4,2,3] +2- 翻转子数组 [4,2] ,arr 变成 [1,2,4,3] +3- 翻转子数组 [4,3] ,arr 变成 [1,2,3,4] +上述方法并不是唯一的,还存在多种将 arr 变成 target 的方法 + +示例 2: +输入:target = [7], arr = [7] +输出:true +解释:arr 不需要做任何翻转已经与 target 相等 + +示例 3: +输入:target = [1,12], arr = [12,1] +输出:true + +示例 4: +输入:target = [3,7,9], arr = [3,7,11] +输出:false +解释:arr 没有数字 9 ,所以无论如何也无法变成 target + +示例 5: +输入:target = [1,1,1,1,1], arr = [1,1,1,1,1] +输出:true +``` + +## 代码 + +首先看着这道题,差点把我唬住了。。其实最后发现就是判断这两个数组的元素是否都相同 + +证明也很简单,需要知道冒泡排序的过程。 + +>冒泡排序的所有操作都是不断交换相邻两个元素的过程,交换相邻两个元素的操作也是反转子数组的一种。 +>考虑数组target,它一定可以通过冒泡排序变成递增(递减)的数组。假设我们记录下每一次的交换,记为操作序列A。 +>考虑数组 arr,它也一定可以通过冒泡排序变成递增(递减)的数组。 +>如果target与arr元素相同,那么最终冒泡排序结果也相同。将数组arr进行冒泡排序,再进行操作序列A的逆过程,就一定可以得到target。 +>如果数组target的元素与数组arr的元素不同,显然无法通过arr得到target + +所以代码就很简单了,只需要将他们排序后判断一下即可 + +``` +class Solution(object): + def canBeEqual(self, target, arr): + target = sorted(target) + arr = sorted(arr) + return target == arr +``` + diff --git "a/LeetCode/1464_\346\225\260\347\273\204\344\270\255\344\270\244\345\205\203\347\264\240\347\232\204\346\234\200\345\244\247\344\271\230\347\247\257/README.md" "b/LeetCode/1464_\346\225\260\347\273\204\344\270\255\344\270\244\345\205\203\347\264\240\347\232\204\346\234\200\345\244\247\344\271\230\347\247\257/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..36a538d296ac3e6bde5831766909dac5178b1da4 --- /dev/null +++ "b/LeetCode/1464_\346\225\260\347\273\204\344\270\255\344\270\244\345\205\203\347\264\240\347\232\204\346\234\200\345\244\247\344\271\230\347\247\257/README.md" @@ -0,0 +1,51 @@ +# 数组中两元素的最大乘积 + +## 题目 + +https://leetcode-cn.com/problems/maximum-product-of-two-elements-in-an-array/ + +## 描述 + +给你一个整数数组 nums,请你选择数组的两个不同下标 i 和 j,使 (nums[i]-1)*(nums[j]-1) 取得最大值。 + +请你计算并返回该式的最大值。 + +``` +示例 1: +输入:nums = [3,4,5,2] +输出:12 +解释:如果选择下标 i=1 和 j=2(下标从 0 开始),则可以获得最大值,(nums[1]-1)*(nums[2]-1) = (4-1)*(5-1) = 3*4 = 12 。 + +示例 2: +输入:nums = [1,5,4,5] +输出:16 +解释:选择下标 i=1 和 j=3(下标从 0 开始),则可以获得最大值 (5-1)*(5-1) = 16 。 + +示例 3: +输入:nums = [3,7] +输出:12 +``` + +## 代码 + +```python +class Solution(object): + def maxProduct(self, nums): + maxValue = 0 + maxIndex = 0 + secondValue = 0 + + for i in range(len(nums)): + if nums[i] > maxValue: + maxValue = nums[i] + maxIndex = i + + del nums[maxIndex] + + for i in range(len(nums)): + if nums[i] > secondValue: + secondValue = nums[i] + + return (maxValue -1) * (secondValue-1) +``` + diff --git "a/LeetCode/146_LRU\347\274\223\345\255\230\346\234\272\345\210\266/README.md" "b/LeetCode/146_LRU\347\274\223\345\255\230\346\234\272\345\210\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..614347bb1e0ce20433d01c90191fa500021fc3bb --- /dev/null +++ "b/LeetCode/146_LRU\347\274\223\345\255\230\346\234\272\345\210\266/README.md" @@ -0,0 +1,286 @@ +# LRU缓存机制 + +## 来源 + +https://leetcode-cn.com/problems/lru-cache/ + +## 描述 + +运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。 + +获取数据 get(key) - 如果关键字 (key) 存在于缓存中,则获取关键字的值(总是正数),否则返回 -1。 +写入数据 put(key, value) - 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字/值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。 + +>**进阶:** 你是否可以在 **O(1)** 时间复杂度内完成这两种操作? + +```bash +LRUCache cache = new LRUCache( 2 /* 缓存容量 */ ); + +cache.put(1, 1); +cache.put(2, 2); +cache.get(1); // 返回 1 +cache.put(3, 3); // 该操作会使得关键字 2 作废 +cache.get(2); // 返回 -1 (未找到) +cache.put(4, 4); // 该操作会使得关键字 1 作废 +cache.get(1); // 返回 -1 (未找到) +cache.get(3); // 返回 3 +cache.get(4); // 返回 4 +``` + + + +## 代码 + +使用数组+哈希来实现,如果要时间复杂度为O(N),可以使用 双向链表 + Hash来记录 + +```python +class LRUCache(object): + + def __init__(self, capacity): + self.capacity = capacity + self.map = {} + self.array = [] + self.size = 0 + + def get(self, key): + if self.map.get(key): + index = self.array.index(key) + # 将该元素移动到最新使用的 + del self.array[index] + self.array.append(key) + return self.map.get(key) + else: + return -1 + + def put(self, key, value): + if self.size < self.capacity: + if self.map.get(key): + # 将该元素移动到最新使用的 + index = self.array.index(key) + del self.array[index] + self.array.append(key) + # 更新key + self.map[key] = value + + else: + self.map[key] = value + self.array.append(key) + self.size += 1 + else: + if self.map.get(key): + # 将该元素移动到最新使用的 + index = self.array.index(key) + del self.array[index] + self.array.append(key) + # 更新key + self.map[key] = value + + else: + # 淘汰第一个,在最后插入元素 + deleteKey = self.array.pop(0) + del self.map[deleteKey] + self.map[key] = value + self.array.append(key) + +if __name__ == '__main__': + cache = LRUCache(2) + print(cache.get(2)) + cache.put(2, 6) + print(cache.get(1)) + cache.put(1, 5) + cache.put(1, 2) + print(cache.get(1)) + print(cache.get(2)) +``` + +## 代码2 + +上面使用的是数组,我们知道使用数组的时间复杂度在O(n),因为删除元素需要进行移动,那么我们就可以使用双向链表 + 哈希 来实现 + +```python +# 双向List +class Node(object): + def __init__(self, val=None, key=None, left=None, right=None): + # 键 + self.key = key + # 值 + self.val = val + self.left = left + self.right = right + +class LRUCache(object): + def __init__(self, capacity): + self.capacity = capacity + self.map = {} + self.array = [] + self.size = 0 + self.root = None + + def get(self, key): + if self.map.get(key): + node = self.map.get(key) + # 判断要删除的是不是根节点 + if key != self.root.key: + # 移除使用的节点,将其移动到最后 + leftNode = node.left + rightNode = node.right + leftNode.right = rightNode + rightNode.left = leftNode + + # 将该节点放到最后 + leftRoot = self.root.left + leftRoot.right = node + node.left = leftRoot + node.right = self.root + self.root.left = node + return node.val + else: + leftNode = node.left + rightNode = node.right + leftNode.right = rightNode + rightNode.left = leftNode + + # 将该节点放到最后 + leftRoot = self.root.left + rightRoot = self.root.right + leftRoot.right = node + node.left = leftRoot + node.right = rightRoot + self.root = rightRoot + return node.val + + else: + return -1 + + def put(self, key, value): + if self.size < self.capacity: + if self.size == 0: + # 插入的是第一个节点,那么就是root节点,双向循环链表 + node = Node() + node.key = key + node.val = value + node.left = node + node.right = node + self.root = node + self.map[key] = node + self.size += 1 + elif self.map.get(key): + # 将该元素移动到最新使用的 + node = self.map.get(key) + node.val = value + + # 判断要删除的是不是根节点 + if key != self.root.key: + # 移除使用的节点,将其移动到最后 + leftNode = node.left + rightNode = node.right + leftNode.right = rightNode + rightNode.left = leftNode + + # 将该节点放到最后 + leftRoot = self.root.left + leftRoot.right = node + node.left = leftRoot + node.right = self.root + self.root.left = node + self.map[key] = node + else: + leftNode = node.left + rightNode = node.right + leftNode.right = rightNode + rightNode.left = leftNode + + # 将该节点放到最后 + leftRoot = self.root.left + rightRoot = self.root.right + leftRoot.right = node + node.left = leftRoot + node.right = rightRoot + self.root = rightRoot + self.map[key] = node + + # # 将该元素移动到最新使用的 + # node = self.map.get(key) + # # 更新元素中的值 + # node.val = value + # node.key = key + # # 移除使用的节点,将其移动到最后 + # leftNode = node.left + # rightNode = node.right + # leftNode.right = rightNode + # rightNode.left = leftNode + # + # # 将该节点放到最后 + # leftRoot = self.root.left + # leftRoot.left = node + # node.left = leftRoot + # node.right = self.root + # self.root.left = node + + + else: + leftRoot = self.root.left + node = Node() + node.val = value + node.key = key + node.left = leftRoot + node.right = self.root + leftRoot.right = node + self.root.left = node + self.map[key] = node + self.size += 1 + else: + # 以下代码是淘汰策略,当不需要淘汰的时候 + if self.map.get(key): + # 将该元素移动到最新使用的 + node = self.map.get(key) + + leftRoot = self.root.left + rightRoot = self.root.right + + # 更新元素中的值 + node.val = value + # 移除使用的节点,将其移动到最后 + leftNode = node.left + rightNode = node.right + leftNode.right = rightNode + rightNode.left = leftNode + + # 将该节点放到最后 + leftRoot = self.root.left + leftRoot.left = node + node.left = leftRoot + node.right = rightRoot + self.root.left = node + self.root = rightNode + + else: + deleteKey = self.root.key + del self.map[deleteKey] + leftRoot = self.root.left + rightRoot = self.root.right + node = Node() + node.key = key + node.val = value + node.left = leftRoot + node.right = rightRoot + leftRoot.right = node + rightRoot.left = node + self.root = rightRoot + self.map[key] = node + self.size += 1 + + +if __name__ == '__main__': + cache = LRUCache(2) + cache.put(1, 1) + cache.put(2, 2) + print(cache.get(1)) + cache.put(3, 3) + print(cache.get(2)) + cache.put(4, 4) + print(cache.get(1)) + print(cache.get(3)) + print(cache.get(4)) +``` + diff --git "a/LeetCode/1470_\351\207\215\346\226\260\346\216\222\345\210\227\346\225\260\347\273\204/README.md" "b/LeetCode/1470_\351\207\215\346\226\260\346\216\222\345\210\227\346\225\260\347\273\204/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..e1032b962245511be567b800536bf5f41f895a4e --- /dev/null +++ "b/LeetCode/1470_\351\207\215\346\226\260\346\216\222\345\210\227\346\225\260\347\273\204/README.md" @@ -0,0 +1,39 @@ +# 重新排列数组 + +## 来源 + +https://leetcode-cn.com/problems/shuffle-the-array/ + +## 描述 + +给你一个数组 nums ,数组中有 2n 个元素,按 [x1,x2,...,xn,y1,y2,...,yn] 的格式排列。 + +请你将数组按 [x1,y1,x2,y2,...,xn,yn] 格式重新排列,返回重排后的数组。 + + ``` +示例 1: +输入:nums = [2,5,1,3,4,7], n = 3 +输出:[2,3,5,4,1,7] +解释:由于 x1=2, x2=5, x3=1, y1=3, y2=4, y3=7 ,所以答案为 [2,3,5,4,1,7] + +示例 2: +输入:nums = [1,2,3,4,4,3,2,1], n = 4 +输出:[1,4,2,3,3,2,4,1] + +示例 3: +输入:nums = [1,1,2,2], n = 2 +输出:[1,2,1,2] + ``` + +## 代码 + +``` +class Solution(object): + def shuffle(self, nums, n): + ret = [] + for i in range(n): + ret.append(nums[i]) + ret.append(nums[i + n]) + return ret +``` + diff --git "a/LeetCode/1480_\344\270\200\347\273\264\346\225\260\347\273\204\347\232\204\345\212\250\346\200\201\345\222\214/README.md" "b/LeetCode/1480_\344\270\200\347\273\264\346\225\260\347\273\204\347\232\204\345\212\250\346\200\201\345\222\214/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..0a19c03b027ed440763e81d5ffa38d38db05885f --- /dev/null +++ "b/LeetCode/1480_\344\270\200\347\273\264\346\225\260\347\273\204\347\232\204\345\212\250\346\200\201\345\222\214/README.md" @@ -0,0 +1,41 @@ +# 一维数组的动态和 + +## 来源 + +https://leetcode-cn.com/problems/running-sum-of-1d-array + +## 描述 + +给你一个数组 nums 。数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i]) 。 + +请返回 nums 的动态和。 + +``` +示例 1: +输入:nums = [1,2,3,4] +输出:[1,3,6,10] +解释:动态和计算过程为 [1, 1+2, 1+2+3, 1+2+3+4] + +示例 2: +输入:nums = [1,1,1,1,1] +输出:[1,2,3,4,5] +解释:动态和计算过程为 [1, 1+1, 1+1+1, 1+1+1+1, 1+1+1+1+1] + +示例 3: +输入:nums = [3,1,2,10,1] +输出:[3,4,6,16,17] +``` + +## 代码 + +``` +class Solution(object): + def runningSum(self, nums): + ret = [] + sum = 0 + for i in nums: + sum += i + ret.append(sum) + return ret +``` + diff --git "a/LeetCode/1486_\346\225\260\347\273\204\345\274\202\346\210\226\346\223\215\344\275\234/README.md" "b/LeetCode/1486_\346\225\260\347\273\204\345\274\202\346\210\226\346\223\215\344\275\234/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..55abf8b493d0dfcb6458765d5c6c40a7068dc6bc --- /dev/null +++ "b/LeetCode/1486_\346\225\260\347\273\204\345\274\202\346\210\226\346\223\215\344\275\234/README.md" @@ -0,0 +1,48 @@ +# 数组异或操作 + +## 来源 + +https://leetcode-cn.com/problems/xor-operation-in-an-array/ + +## 描述 + +给你两个整数,n 和 start 。 + +数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == nums.length 。 + +请返回 nums 中所有元素按位异或(XOR)后得到的结果。 + +``` +示例 1: +输入:n = 5, start = 0 +输出:8 +解释:数组 nums 为 [0, 2, 4, 6, 8],其中 (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8 。 + "^" 为按位异或 XOR 运算符。 + +示例 2: +输入:n = 4, start = 3 +输出:8 +解释:数组 nums 为 [3, 5, 7, 9],其中 (3 ^ 5 ^ 7 ^ 9) = 8. + +示例 3: +输入:n = 1, start = 7 +输出:7 + +示例 4: +输入:n = 10, start = 5 +输出:2 +``` + +## 代码 + +``` +class Solution(object): + def xorOperation(self, n, start): + if n==1: + return start + value = start + for i in range(1, n): + value ^=(start + 2*i) + return value +``` + diff --git "a/LeetCode/189_\346\227\213\350\275\254\346\225\260\347\273\204/README.md" "b/LeetCode/189_\346\227\213\350\275\254\346\225\260\347\273\204/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..c39935b5d2bd72740cae278b0782c7b8d3d97f02 --- /dev/null +++ "b/LeetCode/189_\346\227\213\350\275\254\346\225\260\347\273\204/README.md" @@ -0,0 +1,76 @@ +# 旋转数组 + +## 来源 + +https://leetcode-cn.com/problems/rotate-array/ + +## 描述 + +给定一个数组,将数组中的元素向右移动 *k* 个位置,其中 *k* 是非负数。 + +``` +示例 1: +输入: [1,2,3,4,5,6,7] 和 k = 3 +输出: [5,6,7,1,2,3,4] +解释: +向右旋转 1 步: [7,1,2,3,4,5,6] +向右旋转 2 步: [6,7,1,2,3,4,5] +向右旋转 3 步: [5,6,7,1,2,3,4] + +示例 2: +输入: [-1,-100,3,99] 和 k = 2 +输出: [3,99,-1,-100] +解释: +向右旋转 1 步: [99,-1,-100,3] +向右旋转 2 步: [3,99,-1,-100] + +说明: +尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。 +要求使用空间复杂度为 O(1) 的 原地 算法。 +``` + +## 解法1 + +解法1就是需要重新创建一个数组,然后通过模运算得到角标,在填入到新数组中 + +```python +class Solution(object): + def rotate(self, nums, k): + arrLen = len(nums) + if k == arrLen: + return nums + arr=[0 for i in range(arrLen)] + for index in range(arrLen): + newIndex = (index + k) % arrLen + arr[newIndex] = nums[index] + return arr +``` + +## 解决2 + +解法2就不需要创建数组了,而是直接在原来数组上进行出列和插入操作。这样可以保证空间复杂度为 O(1) + +```python +class Solution(object): + def rotate(self, nums, k): + arrLen = len(nums) + if k == arrLen: + return nums + k = k % arrLen + for index in range(k): + nums.insert(0, nums.pop()) + return nums +``` + +## 解法3 + +解法3就是截取数组,然后进行拼接 + +```python +class Solution: + def rotate(self, nums: List[int], k: int) -> None: + n = len(nums) + k %= n + nums[:] = nums[-k:] + nums[:-k] +``` + diff --git "a/LeetCode/199_\344\272\214\345\217\211\346\240\221\347\232\204\345\217\263\350\247\206\345\233\276/README.md" "b/LeetCode/199_\344\272\214\345\217\211\346\240\221\347\232\204\345\217\263\350\247\206\345\233\276/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..70d1b049532b80e9500f642ef7c0930ef4dbb1ff --- /dev/null +++ "b/LeetCode/199_\344\272\214\345\217\211\346\240\221\347\232\204\345\217\263\350\247\206\345\233\276/README.md" @@ -0,0 +1,99 @@ +# 二叉树的右视图 + +## 来源 + +https://leetcode-cn.com/problems/binary-tree-right-side-view/ + +## 描述 + +给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 + +```bash +示例: + +输入: [1,2,3,null,5,null,4] +输出: [1, 3, 4] +解释: + + 1 <--- + / \ +2 3 <--- + \ \ + 5 4 <--- +``` + + + +## 代码1(错误) + +最开始的想法就是一直匹配最右边,当该节点没有最右侧的子树时,再去匹配它的左子树,然后再去寻找最右侧 + +```python +class Solution(object): + def rightSideView(self, root): + if root == None: + return [] + ret = [root.val] + while root.right or root.left: + rightNode = root.right + if rightNode == None: + leftNode = root.left + ret.append(leftNode.val) + root = root.left + else: + ret.append(rightNode.val) + root = root.right + return ret +``` + +但是遇到这样的情况的话,是有问题的 + +``` + 1 <--- + / \ +2 3 <--- + \ + 4 <--- +``` + +也就是上面的程序只会输出 1 3 而最后的结果应该是 1 3 4 + +## 代码2 + +因为之前还做过二叉树的层次遍历这道题,想着右侧视图,不就是层次遍历时候的最右侧的节点么?想到这里,就重新复现了一下二叉树的层次遍历的代码~,然后通过一个状态位来记录 最右侧的节点 + +```python +class Solution(object): + def rightSideView(self, root): + if root == None: + return [] + ret = [] + stack = [root] + secondStack = [] + while stack or secondStack: + count = 0 + while stack: + node = stack.pop() + if count == 0: + ret.append(node.val) + count += 1 + + if node.right: + secondStack.insert(0, node.right) + if node.left: + secondStack.insert(0, node.left) + + count = 0 + while secondStack: + node = secondStack.pop() + if count == 0: + ret.append(node.val) + count += 1 + + if node.right: + stack.insert(0, node.right) + if node.left: + stack.insert(0, node.left) + return ret +``` + diff --git "a/LeetCode/215_\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240/README.md" "b/LeetCode/215_\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..324c2e8b3df0b3f555520d74b5b8f2fa1596333e --- /dev/null +++ "b/LeetCode/215_\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240/README.md" @@ -0,0 +1,38 @@ +# 数组中的第K个最大元素 + +## 来源 + +https://leetcode-cn.com/problems/kth-largest-element-in-an-array/ + +## 描述 + +在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 + +``` +示例 1: +输入: [3,2,1,5,6,4] 和 k = 2 +输出: 5 + +示例 2: +输入: [3,2,3,1,2,4,5,5,6] 和 k = 4 +输出: 4 +说明: + +你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。 +``` + +## 代码1 + +最简单的方法就是排序后,然后输出TopK + +```python +class Solution(object): + def findKthLargest(self, nums, k): + nums = sorted(nums) + return nums[-k] +``` + +## 代码2 + +第二种方式就是构建最小堆 + diff --git "a/LeetCode/415_\345\255\227\347\254\246\344\270\262\347\233\270\345\212\240/README.md" "b/LeetCode/415_\345\255\227\347\254\246\344\270\262\347\233\270\345\212\240/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..8c3a07aa87e271825b1608e4a7698a22f1295bc3 --- /dev/null +++ "b/LeetCode/415_\345\255\227\347\254\246\344\270\262\347\233\270\345\212\240/README.md" @@ -0,0 +1,71 @@ +# 字符串相加 + +## 来源 + +https://leetcode-cn.com/problems/add-strings/ + +## 描述 + +给定两个字符串形式的非负整数 num1 和 num2,计算他们的和 + +注意: + +num1 和num2 的长度都小于 5100. + +num1 和num2 都只包含数字 0-9. + +num1 和num2 都不包含任何前导零。 + +你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式 + +## 代码 + +我们首先将其转换成字符串数组,然后从末尾开始计算,执行加法操作,同时设置一个进位标志 + +```python +class Solution(object): + def addStrings(self, num1, num2): + """ + :type num1: str + :type num2: str + :rtype: str + """ + list1 = [] + list2 = [] + for i in num1: + list1.append(i) + for i in num2: + list2.append(i) + + len1 = len(list1) + len2 = len(list2) + + count = len1 - len2 + if count > 0: + for i in range(count): + list2.insert(0, 0) + elif count < 0: + for i in range(-count): + list1.insert(0, 0) + + # 进位 + flag = 0 + ret = [] + while list1 and list2: + params1 = int(list1.pop()) + params2 = int(list2.pop()) + sum = params1 + params2 + flag + if sum >= 10: + flag = 1 + sum = sum - 10 + else: + flag = 0 + + ret.insert(0, str(sum)) + + if flag == 1: + ret.insert(0, '1') + + return ''.join(ret) +``` + diff --git "a/Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/.gitignore" b/LeetCode/Code/.gitignore similarity index 100% rename from "Ant/G2/Vue\345\246\202\344\275\225\344\275\277\347\224\250G2\347\273\230\345\210\266\345\233\276\347\211\207/my-g2-study/.gitignore" rename to LeetCode/Code/.gitignore diff --git a/LeetCode/Code/215_findKthLargest.py b/LeetCode/Code/215_findKthLargest.py new file mode 100644 index 0000000000000000000000000000000000000000..d25f96998af7c9badc5bc5072132939860d72948 --- /dev/null +++ b/LeetCode/Code/215_findKthLargest.py @@ -0,0 +1,22 @@ +# 在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 +class Solution(object): + def findKthLargest(self, nums, k): + map = {} + + for i in nums: + if map.get(i): + count = map[i] + 1 + map[i] = count + else: + map[i] = 1 + + for i in range(len(nums), 0, -1): + if map.get(i): + k = k - map[i] + if k <= 0: + return i + +if __name__ == '__main__': + print(Solution().findKthLargest([99,99], 1)) + + diff --git a/LeetCode/Code/LRU.py b/LeetCode/Code/LRU.py new file mode 100644 index 0000000000000000000000000000000000000000..db12c432ccbd0e3ed9394a41447b09d06355b33c --- /dev/null +++ b/LeetCode/Code/LRU.py @@ -0,0 +1,56 @@ +class LRUCache(object): + def __init__(self, capacity): + self.capacity = capacity + self.map = {} + self.array = [] + self.size = 0 + + def get(self, key): + if self.map.get(key): + index = self.array.index(key) + # 将该元素移动到最新使用的 + del self.array[index] + self.array.append(key) + return self.map.get(key) + else: + return -1 + + def put(self, key, value): + if self.size < self.capacity: + if self.map.get(key): + # 将该元素移动到最新使用的 + index = self.array.index(key) + del self.array[index] + self.array.append(key) + # 更新key + self.map[key] = value + + else: + self.map[key] = value + self.array.append(key) + self.size += 1 + else: + if self.map.get(key): + # 将该元素移动到最新使用的 + index = self.array.index(key) + del self.array[index] + self.array.append(key) + # 更新key + self.map[key] = value + + else: + # 淘汰第一个,在最后插入元素 + deleteKey = self.array.pop(0) + del self.map[deleteKey] + self.map[key] = value + self.array.append(key) + +if __name__ == '__main__': + cache = LRUCache(2) + print(cache.get(2)) + cache.put(2, 6) + print(cache.get(1)) + cache.put(1, 5) + cache.put(1, 2) + print(cache.get(1)) + print(cache.get(2)) \ No newline at end of file diff --git a/LeetCode/Code/LRU2.py b/LeetCode/Code/LRU2.py new file mode 100644 index 0000000000000000000000000000000000000000..e2618d0ba7efb182912ecd4f1801b4c4d90e52c3 --- /dev/null +++ b/LeetCode/Code/LRU2.py @@ -0,0 +1,184 @@ +# 双向List +class Node(object): + def __init__(self, val=None, key=None, left=None, right=None): + # 键 + self.key = key + # 值 + self.val = val + self.left = left + self.right = right + +class LRUCache(object): + def __init__(self, capacity): + self.capacity = capacity + self.map = {} + self.array = [] + self.size = 0 + self.root = None + + def get(self, key): + if self.map.get(key): + node = self.map.get(key) + # 判断要删除的是不是根节点 + if key != self.root.key: + # 移除使用的节点,将其移动到最后 + leftNode = node.left + rightNode = node.right + leftNode.right = rightNode + rightNode.left = leftNode + + # 将该节点放到最后 + leftRoot = self.root.left + leftRoot.right = node + node.left = leftRoot + node.right = self.root + self.root.left = node + return node.val + else: + leftNode = node.left + rightNode = node.right + leftNode.right = rightNode + rightNode.left = leftNode + + # 将该节点放到最后 + leftRoot = self.root.left + rightRoot = self.root.right + leftRoot.right = node + node.left = leftRoot + node.right = rightRoot + self.root = rightRoot + return node.val + + else: + return -1 + + def put(self, key, value): + if self.size < self.capacity: + if self.size == 0: + # 插入的是第一个节点,那么就是root节点,双向循环链表 + node = Node() + node.key = key + node.val = value + node.left = node + node.right = node + self.root = node + self.map[key] = node + self.size += 1 + elif self.map.get(key): + # 将该元素移动到最新使用的 + node = self.map.get(key) + node.val = value + + # 判断要删除的是不是根节点 + if key != self.root.key: + # 移除使用的节点,将其移动到最后 + leftNode = node.left + rightNode = node.right + leftNode.right = rightNode + rightNode.left = leftNode + + # 将该节点放到最后 + leftRoot = self.root.left + leftRoot.right = node + node.left = leftRoot + node.right = self.root + self.root.left = node + self.map[key] = node + else: + leftNode = node.left + rightNode = node.right + leftNode.right = rightNode + rightNode.left = leftNode + + # 将该节点放到最后 + leftRoot = self.root.left + rightRoot = self.root.right + leftRoot.right = node + node.left = leftRoot + node.right = rightRoot + self.root = rightRoot + self.map[key] = node + + # # 将该元素移动到最新使用的 + # node = self.map.get(key) + # # 更新元素中的值 + # node.val = value + # node.key = key + # # 移除使用的节点,将其移动到最后 + # leftNode = node.left + # rightNode = node.right + # leftNode.right = rightNode + # rightNode.left = leftNode + # + # # 将该节点放到最后 + # leftRoot = self.root.left + # leftRoot.left = node + # node.left = leftRoot + # node.right = self.root + # self.root.left = node + + + else: + leftRoot = self.root.left + node = Node() + node.val = value + node.key = key + node.left = leftRoot + node.right = self.root + leftRoot.right = node + self.root.left = node + self.map[key] = node + self.size += 1 + else: + # 以下代码是淘汰策略,当不需要淘汰的时候 + if self.map.get(key): + # 将该元素移动到最新使用的 + node = self.map.get(key) + + leftRoot = self.root.left + rightRoot = self.root.right + + # 更新元素中的值 + node.val = value + # 移除使用的节点,将其移动到最后 + leftNode = node.left + rightNode = node.right + leftNode.right = rightNode + rightNode.left = leftNode + + # 将该节点放到最后 + leftRoot = self.root.left + leftRoot.left = node + node.left = leftRoot + node.right = rightRoot + self.root.left = node + self.root = rightNode + + else: + deleteKey = self.root.key + del self.map[deleteKey] + leftRoot = self.root.left + rightRoot = self.root.right + node = Node() + node.key = key + node.val = value + node.left = leftRoot + node.right = rightRoot + leftRoot.right = node + rightRoot.left = node + self.root = rightRoot + self.map[key] = node + self.size += 1 + + +if __name__ == '__main__': + cache = LRUCache(2) + cache.put(1, 1) + cache.put(2, 2) + print(cache.get(1)) + cache.put(3, 3) + print(cache.get(2)) + cache.put(4, 4) + print(cache.get(1)) + print(cache.get(3)) + print(cache.get(4)) \ No newline at end of file diff --git "a/Linux/CentOS\344\270\213\345\246\202\344\275\225\345\256\211\350\243\205Nginx/README.md" "b/Linux/CentOS\344\270\213\345\246\202\344\275\225\345\256\211\350\243\205Nginx/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..06216bec90f7d190afce74d7f52347e5cc47efcd --- /dev/null +++ "b/Linux/CentOS\344\270\213\345\246\202\344\275\225\345\256\211\350\243\205Nginx/README.md" @@ -0,0 +1,132 @@ +1、下载nginx +--------- + +官方网站  http://nginx.org + +下载链接:[http://nginx.org/download/](http://nginx.org/download/) + +下载完成后的安装包: + +![](http://image.moguit.cn/1556796571439.png) + +2、使用解压命令进行解压 +------------ + + tar -zxvf nginx-1.13.7.tar.gz + +3、在安装所需的安装环境 +------------ + +### 安装gcc环境 + + yum install gcc-c++ + +### 安装第三方开发包 + +\- **PCRE**(Perl Compatible Regular Expressions)是一个Perl库,包括 perl 兼容的正则表达式库。nginx的http模块使用pcre来解析正则表达式,所以需要在linux上安装pcre库 + +注:pcre-devel是使用pcre开发的一个二次开发库。nginx也需要此库。 + + yum install -y pcre pcre-devel + +\- **zlib**库提供了很多种压缩和解压缩的方式,nginx使用zlib对http包的内容进行gzip,所以需要在linux上安装zlib库。 + + yum install -y zlib zlib-devel + +\- **OpenSSL** 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。nginx不仅支持http协议,还支持https(即在ssl协议上传输http),所以需要在linux安装openssl库。 + + yum install -y openssl openssl-devel + +安装好上面的依赖后,进入解压的好的nginx目录中 +------------------------- + +![](http://image.moguit.cn/1556797681396.png) + +然后执行下面的代码,使用configure命令创建makeFile文件 + + ./configure \ + --prefix=/soft/nginx \ + --pid-path=/var/run/nginx/nginx.pid \ + --lock-path=/var/lock/nginx.lock \ + --error-log-path=/var/log/nginx/error.log \ + --http-log-path=/var/log/nginx/access.log \ + --with-http_gzip_static_module \ + --http-client-body-temp-path=/var/temp/nginx/client \ + --http-proxy-temp-path=/var/temp/nginx/proxy \ + --http-fastcgi-temp-path=/var/temp/nginx/fastcgi \ + --http-uwsgi-temp-path=/var/temp/nginx/uwsgi \ + --http-scgi-temp-path=/var/temp/nginx/scgi + + +如果小伙伴需要使用Nginx配置https的话,那么这里需要安装SSL模块哦,在上面加上这句话(如果不需要,请忽略) + + ./configure \ + --prefix=/soft/nginx \ + --pid-path=/var/run/nginx/nginx.pid \ + --lock-path=/var/lock/nginx.lock \ + --error-log-path=/var/log/nginx/error.log \ + --http-log-path=/var/log/nginx/access.log \ + --with-http_gzip_static_module \ + --http-client-body-temp-path=/var/temp/nginx/client \ + --http-proxy-temp-path=/var/temp/nginx/proxy \ + --http-fastcgi-temp-path=/var/temp/nginx/fastcgi \ + --http-uwsgi-temp-path=/var/temp/nginx/uwsgi \ + --http-scgi-temp-path=/var/temp/nginx/scgi \ + --with-http_ssl_module + +在安装完上面的模块后,然后nginx.conf这样进行配置 + +tip:不需要配置 https的小伙伴,下面的代码也不需要修改 + + server { + listen 443 ssl; + server_name admin.moguit.cn; + ssl on; + + ssl_certificate /home/ssl/admin/2181043_admin.moguit.cn.pem; + ssl_certificate_key /home/ssl/admin/2181043_admin.moguit.cn.key; + + ssl_session_timeout 5m; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + root /home/mogu_blog/vue_mogu_admin/dist; + + } + + +注意:启动nginx之前,上边将临时文件目录指定为/var/temp/nginx,需要在/var下创建temp及nginx目录 + + mkdir /var/temp/nginx/client -p + +然后执行make命令已经编译和安装 + + #编译 + make + #安装 + make install + + +启动Nginx +------- + +进入 /soft/nginx/sbin目录下,使用下面命令进行启动 + + ./nginx + +我们在查看端口号,发现nginx已经成功启动了 + +![](http://image.moguit.cn/1556797881757.png) + +nginx常用命令 +--------- + + 启动nginx + ./nginx + # 关闭nginx + ./nginx -s stop + #退出nginx + ./nginx -s quit + # 重启nginx(重启用户基本感觉不到) + ./nginx -s reload \ No newline at end of file diff --git "a/Linux/CentOS\344\270\213\345\256\211\350\243\205Nacos/README.md" "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Nacos/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a9796e9d56a970c41780dc74937ab00c6b511093 --- /dev/null +++ "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Nacos/README.md" @@ -0,0 +1,135 @@ +# CentOS下安装Nacos + +## 前言 + +这阵子因为蘑菇博客的镜像越来越大,所以就打算重新构建一下蘑菇博客的Docker镜像,这里就打算在Centos下安装配置Nacos,之前写过一篇博客关于Window下配置蘑菇博客的Nacos,感兴趣的小伙伴可以参考一下 + +[Window蘑菇博客Nacos部署指南](http://moguit.cn/#/info?blogUid=8dc52bd61e36fa56cfc7699815375572) + +[【SpringCloud】使用Nacos实现服务注册发现以及配置中心等功能](http://moguit.cn/#/info?blogUid=e6e619349d31dded928c9265c5a9c672) + +## 下载Linux版Nacos + +首先我们到Nacos的 [Github页面](https://github.com/alibaba/nacos/releases),找到我们需要安装的版本 + +![image-20200822112106696](images/image-20200822112106696.png) + +我们也可以右键复制到链接,然后通过wget命令进行下载 + +```bash +wget https://github.com/alibaba/nacos/releases/download/1.3.2/nacos-server-1.3.2.tar.gz +``` + +下载完成后,我们使用下面的命令进行解压 + +```bash +#解压 +tar -zxvf nacos-server-1.3.2.tar.gz +``` + +解压完成后,进入nacos文件夹里 + +```bash +cd nacos/bin +``` + +然后修改startup.sh中jvm的内存大小,根据自己的机器情况决定。 + +```bash +vim startup.sh +``` + +这里我设置的是最小堆内存128m,最大堆内存256m + +```bash +if [[ "${MODE}" == "standalone" ]]; then + JAVA_OPT="${JAVA_OPT} -Xms128m -Xmx256m -Xmn256m" + JAVA_OPT="${JAVA_OPT} -Dnacos.standalone=true" +else + if [[ "${EMBEDDED_STORAGE}" == "embedded" ]]; then + JAVA_OPT="${JAVA_OPT} -DembeddedStorage=true" + fi + JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx512m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m" + JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${BASE_DIR}/logs/java_heapdump.hprof" + JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages" +``` + +## Nacos+MySQL配置持久化 + +原来的配置文件是存储在内置的数据库SQLite中,我们如果要移动起来,可能不方便,下面我们可以配置一下nacos的mysql存储, + +我们找到数据库新建脚本nacos/conf/nacos-mysql.sql,创建数据库nacos_config并执行脚本 + +### 导入遇到问题 + +tip:我们在导入的时候,可能会遇到这个错误 + +>Error occured at:2020-08-22 11:37:11 +>Line no.:190 +>Error Code: 1071 - Specified key was too long; max key length is 767 bytes + +先检查一下是不是数据库被限制了索引的大小 + +``` +SHOW variables like 'innodb_large_prefix' +``` + +如果查询的值是OFF的话 执行下面命令 + +``` +SET GLOBAL INNODB_LARGE_PREFIX = ON; +``` + +执行完了 之后 还得查看当前的innodb_file_format引擎格式类型是不是BARRACUDA执行 + +``` +SHOW variables like 'innodb_file_format' +``` + +如果不是的话则需要修改 + +``` +SET GLOBAL innodb_file_format = BARRACUDA; +``` + +然后再次尝试导入,则成功导入到数据库中 + +### 修改nacos配置 + +下面我们需要到nacos的配置目录 + +```bash +vim nacos/conf/application.properties +``` + +然后在末尾添加我们的mysql的配置信息 + +```bash +spring.datasource.platform=mysql +db.num=1 +db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC +db.user=root +db.password=mogu2018 +``` + +修改完成后,回到bin目录,启动nacos,启动命令standalone代表着单机模式运行,非集群模式): + +```bash +sh startup.sh -m standalone +``` + +然后我们输入地址 + +```bash +http://youip:8848/nacos +``` + +会跳转到登录页面,输入默认账号和密码 nacos nacos即可进入 + +![image-20200822115650579](images/image-20200822115650579.png) + + + +到这里linux下的nacos已经成功安装~ + +![image-20200822120856725](images/image-20200822120856725.png) \ No newline at end of file diff --git "a/Linux/CentOS\344\270\213\345\256\211\350\243\205Nacos/images/image-20200822112106696.png" "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Nacos/images/image-20200822112106696.png" new file mode 100644 index 0000000000000000000000000000000000000000..a0d42dea560668fe49bec7e0edc95dcb41a509dc Binary files /dev/null and "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Nacos/images/image-20200822112106696.png" differ diff --git "a/Linux/CentOS\344\270\213\345\256\211\350\243\205Nacos/images/image-20200822115650579.png" "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Nacos/images/image-20200822115650579.png" new file mode 100644 index 0000000000000000000000000000000000000000..b42d39b7e52f9b73ba15e3e0477f5b5f578bc5d5 Binary files /dev/null and "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Nacos/images/image-20200822115650579.png" differ diff --git "a/Linux/CentOS\344\270\213\345\256\211\350\243\205Nacos/images/image-20200822120856725.png" "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Nacos/images/image-20200822120856725.png" new file mode 100644 index 0000000000000000000000000000000000000000..dcec1ee0280f086a4f091a1f83e4289d2b1f1f68 Binary files /dev/null and "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Nacos/images/image-20200822120856725.png" differ diff --git "a/Linux/CentOS\344\270\213\345\256\211\350\243\205Sentinel/README.md" "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Sentinel/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..50058ef1ca479042c5d1a20fa8163dec02c4ede6 --- /dev/null +++ "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Sentinel/README.md" @@ -0,0 +1,44 @@ +# CentOS下安装Sentinel + +## 前言 + +Sentinel被称为分布式系统的流量防卫兵,这里主要讲的是CentOS下如何安装Sentinel,关于Windows下的安装以及Sentinel的介绍,可以参考下面的博客 + +[【SpringCloud】使用Sentinel实现熔断和限流](http://moguit.cn/#/info?blogUid=408e9c889ebf96a66af2adfdc258ba5f) + +[Windows下蘑菇博客Sentinel安装指南](http://moguit.cn/#/info?blogUid=7135efc7f536769efd0d0483c687ba07) + +## 下载Sentinel + +Sentinel的安装非常简单,只需要去[官网](https://github.com/alibaba/Sentinel/releases)下载好对应的可执行jar包 + +![image-20200822150208675](images/image-20200822150208675.png) + +然后在配置启动脚本和关闭脚本,同时设置启动端口号8070 + +启动脚本:startup.sh + +```bash +#!/bin/bash +nohup java -jar sentinel-dashboard-1.8.0.jar --server.port=8070 > catalina.out 2>&1 & +``` + +关闭脚本:shutdown.sh + +```bash +#!/bin/bash +PID=$(ps -ef | grep sentinel-dashboard-1.8.0.jar | grep -v grep | awk '{ print $2 }') +if [ -z "$PID" ] +then + echo Application is already stopped +else + echo kill $PID + kill $PID +fi +``` + +启动成功后,访问地址:http://youip:8070,即可打开sentinel的管理页面 + +![image-20200822151430102](images/image-20200822151430102.png) + +输入sentinel sentinel进入即可 \ No newline at end of file diff --git "a/Linux/CentOS\344\270\213\345\256\211\350\243\205Sentinel/images/image-20200822150208675.png" "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Sentinel/images/image-20200822150208675.png" new file mode 100644 index 0000000000000000000000000000000000000000..c66b2791db31be3b5ae6a4d043403d11091f14d5 Binary files /dev/null and "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Sentinel/images/image-20200822150208675.png" differ diff --git "a/Linux/CentOS\344\270\213\345\256\211\350\243\205Sentinel/images/image-20200822151430102.png" "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Sentinel/images/image-20200822151430102.png" new file mode 100644 index 0000000000000000000000000000000000000000..2c08a3524e240b418a563c9c5666fa2a13192551 Binary files /dev/null and "b/Linux/CentOS\344\270\213\345\256\211\350\243\205Sentinel/images/image-20200822151430102.png" differ diff --git "a/Linux/Linux\344\270\213\346\237\245\347\234\213\346\226\207\344\273\266\345\222\214\346\226\207\344\273\266\345\244\271\345\215\240\347\224\250\347\251\272\351\227\264\345\244\247\345\260\217/README.md" "b/Linux/Linux\344\270\213\346\237\245\347\234\213\346\226\207\344\273\266\345\222\214\346\226\207\344\273\266\345\244\271\345\215\240\347\224\250\347\251\272\351\227\264\345\244\247\345\260\217/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b7ad8f6eca005a71af3cd60af16160fa2d624bac --- /dev/null +++ "b/Linux/Linux\344\270\213\346\237\245\347\234\213\346\226\207\344\273\266\345\222\214\346\226\207\344\273\266\345\244\271\345\215\240\347\224\250\347\251\272\351\227\264\345\244\247\345\260\217/README.md" @@ -0,0 +1,29 @@ +前言 +-- + +最近制作的Docker镜像体积已经快到达7G了,这几天想着能否将里面的内容进行一些删减,以此来达到降低容量的功能 + +然后通过了解,首先得使用Linux命令,查看文件磁盘所占的空间大小,下面可以通过以下命令进行操作 + +* df 可以查看一级文件夹大小、使用比例、档案系统及其挂入点,但对文件束手无策 +* du 查看文件和文件夹的磁盘使用空间 + +在使用中,一般是df命令和du命令一起联合使用的 + +查看文件磁盘使用情况 +---------- + + # 查看分区的文件系统,显示目前所有文件系统的可用空间及使用情形 + # 参数 -h 表示使用「Human-readable」的输出,也就是在档案系统大小使用 GB、MB 等易读的格式 + df -h + +![](http://image.moguit.cn/1577332994777.png) + +或者使用du命令来对每个文件及文件夹大小进行查看: + + # 仅列出/ 目录下面所有的一级目录文件大小, --max-depth=1 是指定深度 + du -h --max-depth=1 / + +![](http://image.moguit.cn/1577333099896.png) + +通过上面显示的,我们就能够大致了解每个文件夹的大小了,然后在进去里面把一些不必要的内容删除即可 ~ \ No newline at end of file diff --git "a/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/README.md" "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..48167be7924cdb63294eaf884a823e12bb113af8 --- /dev/null +++ "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/README.md" @@ -0,0 +1,126 @@ +# Linux下通过nginx配置https + +## 前言 + +这阵子在做蘑菇博客的小程序端,因为小程序的发布需要接口采用https加密的方式,因此打算通过nginx配置一下ssl安全证书 + +## 证书购买 + +证书一般都需要到对应的云服务厂商进行购买,当然貌似也可以自己生成证书,但是好像生成的证书也会出现不安全的提示,所以还是去云服务厂商购买 + +本着能不花钱就不花钱的态度,我们来到了 [腾讯云SSL证书](https://cloud.tencent.com/product/ssl) (ps:阿里云免费的证书找了一阵子没找到) + +![image-20200806143806254](images/image-20200806143806254.png) + +我们点击立即选购按钮,来到了我们的购买页面 + +![image-20200806143919814](images/image-20200806143919814.png) + +需要注意的是,免费型的域名证书,只能支持单个域名,也就是如果我们多个域名需要绑定SSL的话,那么就需要购买多个证书,下面就是填写我们哪个域名需要用到https,这是我是图片服务用到了,所以就填写图片服务器 + +![image-20200806144401828](images/image-20200806144401828.png) + +然后我们选择手动DNS验证,然后确认 + +![image-20200806144507660](images/image-20200806144507660.png) + +确认后,我们就需要到我们的域名管理添加一条解析 + +![image-20200806144529801](images/image-20200806144529801.png) + +![image-20200806144615582](images/image-20200806144615582.png) + +因为我的域名是在阿里云购买的,所以我需要到阿里云的域名解析处进行配置,添加上述的记录到阿里云解析中 + +![image-20200806144844883](images/image-20200806144844883.png) + +然后点击确定 + +![image-20200806145000357](images/image-20200806145000357.png) + +在等待一段时间后,即可完成证书域名证书的认证 + +![image-20200806150616092](images/image-20200806150616092.png) + +认证完成后,我们需要下载我们的证书,点击右侧的下载按钮,下载完成后,有多个方式的配置,我们进入nginx文件夹 + +![image-20200806145932184](images/image-20200806145932184.png) + +然后把里面的内容拷贝到我们的服务器上,首先我们先到服务器中,创建一个目录 + +```bash +mkdir /home/ssl/uniapp/web +``` + +创建完成后,将刚刚nginx文件夹中的公钥和私钥拷贝到该目录下 + +然后我们就需要安装nginx的https模块了,关于nginx的https模块的安装可以参考下面的博客 + + [CentOS下如何安装Nginx?](http://moguit.cn/#/info?blogUid=e8d3e38ba35b4765ae128256eb44e341) + +然后使用下面的配置 + +```bash +./configure \ +--prefix=/soft/nginx \ +--pid-path=/var/run/nginx/nginx.pid \ +--lock-path=/var/lock/nginx.lock \ +--error-log-path=/var/log/nginx/error.log \ +--http-log-path=/var/log/nginx/access.log \ +--with-http_gzip_static_module \ +--http-client-body-temp-path=/var/temp/nginx/client \ +--http-proxy-temp-path=/var/temp/nginx/proxy \ +--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \ +--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \ +--http-scgi-temp-path=/var/temp/nginx/scgi \ +--with-http_ssl_module +``` + +然后在进行make 和 make install,安装完成nginx后,我们进入到nginx的配置文件中 + +```bash + server { + listen 443 ssl; + server_name apiweb.moguit.cn; + ssl on; + + ssl_certificate /home/ssl/uniapp/web/1_apiweb.moguit.cn_bundle.crt; + ssl_certificate_key /home/ssl/uniapp/web/2_apiweb.moguit.cn.key; + + ssl_session_timeout 5m; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + location / { + proxy_pass http://127.0.0.1:8603; + } + + } +``` + +配置完成后,我们通过https,即可访问我们的项目了~ + +同理,如果配置 https://apipicture.moguit.cn 我们也是按照上述的操作再次执行一遍,然后最后在nginx中添加如下的配置信息 + +```bash + server { + listen 443 ssl; + server_name apipicture.moguit.cn; + ssl on; + + ssl_certificate /home/ssl/uniapp/picture/1_apipicture.moguit.cn_bundle.crt; + ssl_certificate_key /home/ssl/uniapp/picture/2_apipicture.moguit.cn.key; + + ssl_session_timeout 5m; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + location / { + proxy_pass http://127.0.0.1:8602; + } + + } +``` + diff --git "a/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806143806254.png" "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806143806254.png" new file mode 100644 index 0000000000000000000000000000000000000000..2818d7a4fb04397aa502aa51366563fd5dd04c6e Binary files /dev/null and "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806143806254.png" differ diff --git "a/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806143919814.png" "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806143919814.png" new file mode 100644 index 0000000000000000000000000000000000000000..5bc1e0d13364151cc6355a834447a75aa3ba74d9 Binary files /dev/null and "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806143919814.png" differ diff --git "a/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144401828.png" "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144401828.png" new file mode 100644 index 0000000000000000000000000000000000000000..f8efc86019fd8f6119dcd1d00082585c0bc581f2 Binary files /dev/null and "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144401828.png" differ diff --git "a/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144507660.png" "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144507660.png" new file mode 100644 index 0000000000000000000000000000000000000000..659038f1bcd223e4a7247c41708cebe36e4d584c Binary files /dev/null and "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144507660.png" differ diff --git "a/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144529801.png" "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144529801.png" new file mode 100644 index 0000000000000000000000000000000000000000..46e46897516e6fffa0f773863aed9ee6aab4e3e5 Binary files /dev/null and "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144529801.png" differ diff --git "a/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144615582.png" "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144615582.png" new file mode 100644 index 0000000000000000000000000000000000000000..8fa55f89c8ef148eeb6d6c31e1f941adfbda953d Binary files /dev/null and "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144615582.png" differ diff --git "a/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144844883.png" "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144844883.png" new file mode 100644 index 0000000000000000000000000000000000000000..1d5cb4d3b3b3728448c424dd25aaeec07b44cd88 Binary files /dev/null and "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806144844883.png" differ diff --git "a/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806145000357.png" "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806145000357.png" new file mode 100644 index 0000000000000000000000000000000000000000..84e875591dbe201a09578a3272e2f9b7128ee5b1 Binary files /dev/null and "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806145000357.png" differ diff --git "a/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806145932184.png" "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806145932184.png" new file mode 100644 index 0000000000000000000000000000000000000000..d113a7fa58d5a8487f455daadac96f80003b8fc6 Binary files /dev/null and "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806145932184.png" differ diff --git "a/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806150616092.png" "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806150616092.png" new file mode 100644 index 0000000000000000000000000000000000000000..be6449cf21a7f7965c6f3b7be933b97fc0dda810 Binary files /dev/null and "b/Linux/Linux\344\270\213\351\200\232\350\277\207nginx\351\205\215\347\275\256https/images/image-20200806150616092.png" differ diff --git "a/Linux/VmWare\347\273\231CentOS\346\211\251\345\256\271/README.md" "b/Linux/VmWare\347\273\231CentOS\346\211\251\345\256\271/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..369280d8930493fb54dba5b0bf396e289a28c243 --- /dev/null +++ "b/Linux/VmWare\347\273\231CentOS\346\211\251\345\256\271/README.md" @@ -0,0 +1,43 @@ +# VMWare给CentOS扩容 + +## 前言 + +今天因为自己的虚拟机满了,无法继续创建Docker镜像,就想着给虚拟机扩容,从原来的20G提升到40G + + + +## 扩容步骤 + +首先我们需要关闭我们正在运行的虚拟机,然后找到设置页面 + +## 取消分区 + +因为之前把分区错误的挂载了,所以我们需要取消分区 + +```bash +# 取消挂载 +umount /disk4 +``` + +然后删除分区 + +```bash +fdisk /dev/sda +``` + +然后选择p + +![image-20200927203406093](images/image-20200927203406093.png) + +在选择 d,输入4, 然后按w保存即可 + +然后删除我们刚刚创建的 + +最后打开下面的文件,把我们添加的删除了 + +```bash +vim /etc/fstab +``` + + + diff --git "a/Linux/VmWare\347\273\231CentOS\346\211\251\345\256\271/images/image-20200927203406093.png" "b/Linux/VmWare\347\273\231CentOS\346\211\251\345\256\271/images/image-20200927203406093.png" new file mode 100644 index 0000000000000000000000000000000000000000..5e5de24d30b7784577a216072dfdd5dc50beef02 Binary files /dev/null and "b/Linux/VmWare\347\273\231CentOS\346\211\251\345\256\271/images/image-20200927203406093.png" differ diff --git a/README.md b/README.md index 416448a4b212f8d7151bd773c82d6af2ece648a0..6d311b2d3ba0e6867787126ab5614835f45cea91 100644 --- a/README.md +++ b/README.md @@ -1,143 +1,408 @@ # 学习笔记 -我的个人学习笔记,主要用于记录平时一些学习和项目中遇到的问题,同步更新在[蘑菇博客](http://www.moguit.cn),如果对我的博客网站感兴趣的话,欢迎关注我的 [蘑菇博客源码](https://gitee.com/moxi159753/mogu_blog_v2) - -笔记主要涵盖:Java,Spring,SpringCloud,计算机网络,操作系统,数据结构,Vue等 - -如果笔记对您有帮助的话,欢迎star支持,谢谢~ - -## Java相关 - -### 基础 - -- [equals和等等的区别](./校招面试/基础面试题/1_equals和等等的区别) -- [代码块](./校招面试/基础面试题/2_代码块) -- [分布式锁](./校招面试/基础面试题/3_分布式锁) -- [MySQL的存储引擎](./校招面试/基础面试题/4_MySQL的存储引擎) -- [Java注解和反射](./校招面试/基础面试题/Java注解和反射) - -### Java8新特性 - -- [HashMap变化](./校招面试/Java8新特性/1_HashMap变化) -- [Lambda表达式](./校招面试/Java8新特性/2_Lambda表达式) -- [方法引用和构造器](./校招面试/Java8新特性/3_方法引用和构造器) -- [强大的Stream](./校招面试/Java8新特性/4_强大的Stream) -- [并行流](./校招面试/Java8新特性/5_并行流) -- [Optional容器类](./校招面试/Java8新特性/6_Optional容器类) - -### NIO - -- [NIO是什么](./校招面试/NIO/NIO是什么) -- [NIO的使用案例](./校招面试/NIO/NIO的使用案例) - -### JUC - -- [Volatile和JMM内存模型的可见性](./校招面试/JUC/1_谈谈Volatile/1_Volatile和JMM内存模型的可见性) -- [Volatile不保证原子性](./校招面试/JUC/1_谈谈Volatile/2_Volatile不保证原子性) -- [Volatile禁止指令重排](./校招面试/JUC/1_谈谈Volatile/3_Volatile禁止指令重排) -- [Volatile的应用](./校招面试/JUC/1_谈谈Volatile/4_Volatile的应用) -- [CAS底层原理](./校招面试/JUC/2_谈谈CAS/5_CAS底层原理) -- [原子类AtomicInteger的ABA问题](./校招面试/JUC/3_谈谈原子类的ABA问题/6_原子类AtomicInteger的ABA问题) -- [ArrayList线程不安全的举例](./校招面试/JUC/4_ArrayList为什么线程不安全/ArrayList线程不安全的举例) -- [TransferValue是什么](./校招面试/JUC/5_TransferValue是什么) -- [Java锁之读写锁](./校招面试/JUC/6_Java的锁/Java锁之读写锁) -- [Java锁之公平锁和非公平锁](./校招面试/JUC/6_Java的锁/Java锁之公平锁和非公平锁) -- [Java锁之可重入锁和递归锁](./校招面试/JUC/6_Java的锁/Java锁之可重入锁和递归锁) -- [Java锁之自旋锁](./校招面试/JUC/6_Java的锁/Java锁之自旋锁) -- [CountDownLatch是什么](./校招面试/JUC/7_CountDownLatch_CyclicBarrier_Semaphore使用/CountDownLatch) -- [CyclicBarrier是什么](./校招面试/JUC/7_CountDownLatch_CyclicBarrier_Semaphore使用/CyclicBarrier) -- [Semaphore是什么](./校招面试/JUC/7_CountDownLatch_CyclicBarrier_Semaphore使用/Semaphore) -- [阻塞队列](./校招面试/JUC/8_阻塞队列) -- [Synchronized和Lock的区别与好处](./校招面试/JUC/Synchronized和Lock的区别与好处) -- [线程池](./校招面试/JUC/10_线程池) -- [线程池](./校招面试/JUC/10_线程池) -- [死锁编码及快速定位](./校招面试/JUC/11_死锁编码及快速定位) -- [JVM体系结构](./校招面试/JUC/12_JVM/JVM体系结构) -- [什么是GCRoots能做什么](./校招面试/JUC/12_JVM/JVM面试题汇总/1_什么是GCRoots能做什么) -- [JVM参数调优](./校招面试/JUC/12_JVM/JVM面试题汇总/2_JVM参数调优) -- [Java中的强引用_软引用_弱引用_虚引用分别是什么](./校招面试/JUC/12_JVM/JVM面试题汇总/3_Java中的强引用_软引用_弱引用_虚引用分别是什么) -- [Java内存溢出OOM](./校招面试/JUC/12_JVM/JVM面试题汇总/4_Java内存溢出OOM) -- [垃圾回收器](./校招面试/JUC/12_JVM/JVM面试题汇总/5_垃圾回收器) -- [Linux相关命令](./校招面试/JUC/13_Linux相关命令) -- [Github学习](./校招面试/JUC/14_Github学习) -- [乐观锁和悲观锁](./校招面试/JUC/15_乐观锁和悲观锁) +## 项目介绍 + +Java学习笔记,主要来源于B站上视频的学习,同时会记录平时一些学习和项目中遇到的问题,同步更新在 [蘑菇博客](http://www.moguit.cn),如果对我的博客网站感兴趣的话,欢迎关注我的 [蘑菇博客源码](https://gitee.com/moxi159753/mogu_blog_v2),如果笔记对您有帮助的话,欢迎star支持,谢谢~ + +笔记主要涵盖:Java,JVM、JUC、Spring,SpringCloud,计算机网络,操作系统,数据结构,Vue等 + +本仓库有来源自己总结、网上收集、视频笔记,如果有侵权之处,可以联系我进行删除 + +因个人能力有限,笔记中可能还有很多错误的地方,还请大家能够多多指出交流,也欢迎各位小伙伴能够提交pull request请求进行完善 + +如果您要转载本仓库中的笔记到其它地方,欢迎添加笔记的仓库地址:[LearningNotes](https://gitee.com/moxi159753/LearningNotes) + +## 文档 + +为了更方便小伙伴的复习和查询,把本仓库做成一个在线的文档 + +- 在线文档:http://moxi159753.gitee.io/learningnotes + +## 仓库地址 + +本仓库同步托管在Github和Gitee中 + +- Gitee仓库:https://gitee.com/moxi159753/LearningNotes +- Github仓库:https://github.com/moxi624/LearningNotes + +## 个人博客搭建 + +如果想搭建个人的博客系统,可以购买优惠服务器后,参考 [教程](http://www.moguit.cn/#/info?blogUid=8100dcb585fff77e3fa25eed50e3708e) 在服务器搭建 [蘑菇博客项目](https://gitee.com/moxi159753/mogu_blog_v2) 用于知识点的梳理 + +> 【阿里云】 限量爆款低至91.8元/年 [点我进入](https://www.aliyun.com/minisite/goods?userCode=w7aungxw) +> +> 【腾讯云】十周年感恩回馈,1核2G云服务器首年95元 [点我进入](https://cloud.tencent.com/act/cps/redirect?redirect=1067&cps_key=4e9b8ce643afe47621493331d101dd6e&from=console) +> +> 【阿里云翼计划】 轻量级应用服务器 1核2G 5M / 年 (博主目前使用的) 仅需114元 [点我进入 ](https://promotion.aliyun.com/ntms/act/campus2018.html?spm=5176.10695662.1244717.1.641e5a06KpmU4A&accounttraceid=3ac1b990a4f445859080d2555566af8fiirr?userCode=w7aungxw&tag=share_component&share_source=copy_link?userCode=w7aungxw&tag=share_component&share_source=copy_link?userCode=w7aungxw&tag=share_component&share_source=copy_link&userCode=w7aungxw&tag=share_component&share_source=copy_link)`(仅限学生或未满24岁的用户)` + +## Java + +> 来源Bilibili尚硅谷周阳老师学习视频:[点我传送](https://www.bilibili.com/video/BV15J4112785) + +- [equals和等等的区别](校招面试/基础面试题/1_equals和等等的区别/README.md) +- [代码块](./校招面试/基础面试题/2_代码块/README.md) +- [分布式锁](./校招面试/基础面试题/3_分布式锁/README.md) +- [MySQL的存储引擎](./校招面试/基础面试题/4_MySQL的存储引擎/README.md) +- [JDK动态代理和CGLIB动态代理](./校招面试/基础面试题/5_JDK动态代理和CGLIB动态代理/README.md) +- [Java注解和反射](./Java/Java注解和反射/README.md) +- [泛型的类型擦除](./Java/泛型的类型擦除/README.md) +- [Java使用Redis删除指定前缀Key](./Java/Java使用Redis删除指定前缀Key/README.md) +- [前端的一些跨域问题](./Java/前端的一些跨域问题/README.md) +- [使用Ip2region替代淘宝IP接口](./Java/使用Ip2region替代淘宝IP接口/README.md) +- [聊一聊-Java泛型中的通配符T,E,K,V](http://www.moguit.cn/#/info?blogUid=0aa459dc0ae9f9ad82cd22665d08a20d) +- [JVM类加载机制](./Java/JVM类加载机制/README.md) +- [VisualVM安装VisualGC插件](./Java/VisualVM安装VisualGC插件/README.md) +- [谈谈你对ThreadLocal的理解](./Java/谈谈你对ThreadLocal的理解/README.md) +- [谈谈你对AQS的理解](./Java/谈谈你对AQS的理解/README.md) +- [ArrayList扩容机制](./Java/ArrayList扩容机制/README.md) + +## Java8新特性 + +> 来源Bilibili尚硅谷李贺飞老师学习视频:[Java8新特性](https://www.bilibili.com/video/BV1ut411g7E9) + +- [HashMap变化](./校招面试/Java8新特性/1_HashMap变化/README.md) +- [Lambda表达式](./校招面试/Java8新特性/2_Lambda表达式/README.md) +- [方法引用和构造器](./校招面试/Java8新特性/3_方法引用和构造器/README.md) +- [强大的Stream](./校招面试/Java8新特性/4_强大的Stream/README.md) +- [并行流](./校招面试/Java8新特性/5_并行流/README.md) +- [Optional容器类](./校招面试/Java8新特性/6_Optional容器类/README.md) + +## NIO + +- [NIO是什么](./校招面试/NIO/NIO是什么/README.md) +- [IO到NIO的演变](./校招面试/NIO/NIO的使用案例/README.md) +- [IO和NIO的区别](http://www.moguit.cn/#/info?blogUid=28d61ec002594fc5a9c441ec8560f3ad) + +## JVM + +> 来源Bilibili尚硅谷宋红康老师JVM教程:[硅谷2020最新版宋红康JVM教程](https://www.bilibili.com/video/BV1PJ411n7xZ) + +- [JVM与Java体系结构](JVM/1_内存与垃圾回收篇/1_JVM与Java体系结构/README.md) +- [类加载子系统](./JVM/1_内存与垃圾回收篇/2_类加载子系统/README.md) +- [运行时数据区概述及线程](./JVM/1_内存与垃圾回收篇/3_运行时数据区概述及线程/README.md) +- [程序计数器](./JVM/1_内存与垃圾回收篇/4_程序计数器/README.md) +- [虚拟机栈](./JVM/1_内存与垃圾回收篇/5_虚拟机栈/README.md) +- [本地方法接口](./JVM/1_内存与垃圾回收篇/6_本地方法接口/README.md) +- [本地方法栈](./JVM/1_内存与垃圾回收篇/7_本地方法栈/README.md) +- [堆](./JVM/1_内存与垃圾回收篇/8_堆/README.md) +- [方法区](./JVM/1_内存与垃圾回收篇/9_方法区/README.md) +- [对象实例化内存布局与访问定位](./JVM/1_内存与垃圾回收篇/10_对象实例化内存布局与访问定位/README.md) +- [直接内存](./JVM/1_内存与垃圾回收篇/11_直接内存/README.md) +- [执行引擎](./JVM/1_内存与垃圾回收篇/12_执行引擎/README.md) +- [StringTable](./JVM/1_内存与垃圾回收篇/13_StringTable/README.md) +- [垃圾回收概述](./JVM/1_内存与垃圾回收篇/14_垃圾回收概述/README.md) +- [垃圾回收相关算法](./JVM/1_内存与垃圾回收篇/15_垃圾回收相关算法/README.md) +- [垃圾回收相关概念](./JVM/1_内存与垃圾回收篇/16_垃圾回收相关概念/README.md) +- [垃圾回收器](./JVM/1_内存与垃圾回收篇/17_垃圾回收器/README.md) + +## JUC + +>来源Bilibili尚硅谷周阳老师学习视频:[尚硅谷Java大厂面试题第二季](https://www.bilibili.com/video/BV18b411M7xz) + +- [Volatile和JMM内存模型的可见性](./校招面试/JUC/1_谈谈Volatile/1_Volatile和JMM内存模型的可见性/README.md) +- [Volatile不保证原子性](./校招面试/JUC/1_谈谈Volatile/2_Volatile不保证原子性/README.md) +- [Volatile禁止指令重排](./校招面试/JUC/1_谈谈Volatile/3_Volatile禁止指令重排/README.md) +- [Volatile的应用](./校招面试/JUC/1_谈谈Volatile/4_Volatile的应用/README.md) +- [CAS底层原理](./校招面试/JUC/2_谈谈CAS/5_CAS底层原理/README.md) +- [原子类AtomicInteger的ABA问题](./校招面试/JUC/3_谈谈原子类的ABA问题/6_原子类AtomicInteger的ABA问题/README.md) +- [ArrayList为什么是线程不安全的](./校招面试/JUC/4_ArrayList为什么线程不安全/ArrayList线程不安全的举例/README.md) +- [TransferValue是什么](./校招面试/JUC/5_TransferValue是什么/README.md) +- [Java锁之读写锁](./校招面试/JUC/6_Java的锁/Java锁之读写锁/README.md) +- [Java锁之公平锁和非公平锁](./校招面试/JUC/6_Java的锁/Java锁之公平锁和非公平锁/README.md) +- [Java锁之可重入锁和递归锁](./校招面试/JUC/6_Java的锁/Java锁之可重入锁和递归锁/README.md) +- [Java锁之自旋锁](./校招面试/JUC/6_Java的锁/Java锁之自旋锁/README.md) +- [CountDownLatch是什么](./校招面试/JUC/7_CountDownLatch_CyclicBarrier_Semaphore使用/CountDownLatch/README.md) +- [CyclicBarrier是什么](./校招面试/JUC/7_CountDownLatch_CyclicBarrier_Semaphore使用/CyclicBarrier/README.md) +- [Semaphore是什么](./校招面试/JUC/7_CountDownLatch_CyclicBarrier_Semaphore使用/Semaphore/README.md) +- [Java中的阻塞队列](./校招面试/JUC/8_阻塞队列/README.md) +- [Synchronized和Lock的区别与好处](./校招面试/JUC/Synchronized和Lock的区别与好处/README.md) +- [Java线程池详解](./校招面试/JUC/10_线程池/README.md) +- [死锁编码及快速定位](./校招面试/JUC/11_死锁编码及快速定位/README.md) +- [JVM体系结构](./校招面试/JUC/12_JVM/JVM体系结构/README.md) +- [什么是GCRoots能做什么](./校招面试/JUC/12_JVM/JVM面试题汇总/1_什么是GCRoots能做什么/README.md) +- [JVM参数调优](./校招面试/JUC/12_JVM/JVM面试题汇总/2_JVM参数调优/README.md) +- [Java中的强引用_软引用_弱引用_虚引用分别是什么](./校招面试/JUC/12_JVM/JVM面试题汇总/3_Java中的强引用_软引用_弱引用_虚引用分别是什么/README.md) +- [Java内存溢出OOM](./校招面试/JUC/12_JVM/JVM面试题汇总/4_Java内存溢出OOM/README.md) +- [垃圾回收器](./校招面试/JUC/12_JVM/JVM面试题汇总/5_垃圾回收器/README.md) +- [Linux相关命令](./校招面试/JUC/13_Linux相关命令/README.md) +- [Github学习](./校招面试/JUC/14_Github学习/README.md) +- [乐观锁和悲观锁](./校招面试/JUC/15_乐观锁和悲观锁/README.md) - [源码](./校招面试/JUC/Code) +## 中间件 + +>来源Bilibili中华石杉老师学习视频:[Java工程师面试突击](https://www.bilibili.com/video/BV1UJ411X7M1) + +- [消息队列的面试连环炮](./校招面试/面试扫盲学习/1_消息队列的面试连环炮/README.md) +- [分布式搜索引擎的面试连环炮](./校招面试/面试扫盲学习/2_分布式搜索引擎的面试连环炮/README.md) +- [分布式缓存](./校招面试/面试扫盲学习/3_分布式缓存/README.md) +- [Redis的面试连环炮](./校招面试/面试扫盲学习/4_Redis的面试连环炮/README.md) +- [Redis的面试连环炮2](./校招面试/面试扫盲学习/5_Redis的面试连环炮2/README.md) +- [分布式系统的面试连环炮](./校招面试/面试扫盲学习/6_分布式系统的面试连环炮/README.md) +- [分布式系统幂等性与顺序性及分布式锁](./校招面试/面试扫盲学习/7_分布式系统幂等性与顺序性及分布式锁/README.md) +- [分布式Session解决方案](./校招面试/面试扫盲学习/8_分布式Session解决方案/README.md) +- [Spring中的事务](./校招面试/面试扫盲学习/9_Spring中的事务/README.md) +- [设计一个高并发系统](./校招面试/面试扫盲学习/10_设计一个高并发系统/README.md) +- [数据库分库分表的面试连环炮](./校招面试/面试扫盲学习/11_数据库分库分表的面试连环炮/README.md) +- [MySQL读写复制及主从同步时延](./校招面试/面试扫盲学习/12_MySQL读写复制及主从同步时延/README.md) +- [常见的消息队列有哪些?](http://www.moguit.cn/#/info?blogUid=3a309d5c258c58e7b03a99cda13f650c) +- [5个方案告诉你:高并发环境下,先操作数据库还是先操作缓存?](http://www.moguit.cn/#/info?blogUid=b73aba84b0890c3c282a18c4fb0aab3d) + ## SpringCloud -- [使用Zipkin搭建蘑菇博客链路追踪](./SpringCloud/使用Zipkin搭建蘑菇博客链路追踪) -- [SpringCloud是什么](./SpringCloud/SpringCloud2020/1_SpringCloud是什么) -- [搭建Eureka集群](./SpringCloud/SpringCloud2020/3_搭建Eureka集群) -- [Eureka停更后的替换](./SpringCloud/SpringCloud2020/4_Eureka停更后的替换) -- [Ribbon负载均衡](./SpringCloud/SpringCloud2020/5_Ribbon负载均衡) -- [OpenFeign实现服务调用](./SpringCloud/SpringCloud2020/6_OpenFeign实现服务调用) -- [Hystrix中的服务降级和熔断](./SpringCloud/SpringCloud2020/7_Hystrix中的服务降级和熔断) -- [服务网关Gateway](./SpringCloud/SpringCloud2020/8_服务网关Gateway) -- [分布式配置中心SpringCloudConfig](./SpringCloud/SpringCloud2020/9_分布式配置中心SpringCloudConfig) +> 来源Bilibili尚硅谷周阳老师学习视频:[尚硅谷2020最新版SpringCloud(H版&alibaba)框架](https://www.bilibili.com/video/BV18E411x7eT) + +- [SpringCloud是什么](./SpringCloud/SpringCloud2020/1_SpringCloud是什么/README.md) +- [搭建Eureka集群](./SpringCloud/SpringCloud2020/3_搭建Eureka集群/README.md) +- [Eureka停更后的替换](./SpringCloud/SpringCloud2020/4_Eureka停更后的替换/README.md) +- [Ribbon负载均衡](./SpringCloud/SpringCloud2020/5_Ribbon负载均衡/README.md) +- [OpenFeign实现服务调用](./SpringCloud/SpringCloud2020/6_OpenFeign实现服务调用/README.md) +- [Hystrix中的服务降级和熔断](./SpringCloud/SpringCloud2020/7_Hystrix中的服务降级和熔断/README.md) +- [服务网关Gateway](./SpringCloud/SpringCloud2020/8_服务网关Gateway/README.md) +- [分布式配置中心SpringCloudConfig](./SpringCloud/SpringCloud2020/9_分布式配置中心SpringCloudConfig/README.md) +- [消息总线Bus](./SpringCloud/SpringCloud2020/10_消息总线Bus/README.md) +- [消息驱动SpringCloudStream](./SpringCloud/SpringCloud2020/11_消息驱动SpringCloudStream/README.md) +- [SpringCloudSleuth分布式请求链路跟踪](./SpringCloud/SpringCloud2020/12_SpringCloudSleuth分布式请求链路跟踪/README.md) +- [使用Nacos实现服务注册发现以及服务配置等功能](./SpringCloud/SpringCloud2020/13_Nacos是什么/README.md) +- [SpringCloudAlibabaSentinel实现熔断和限流](./SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel实现熔断和限流/README.md) +- [SpringCloudAlibabaSeata处理分布式事务](./SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata处理分布式事务/README.md) +- [使用Zipkin搭建蘑菇博客链路追踪](./SpringCloud/使用Zipkin搭建蘑菇博客链路追踪/README.md) - [源码](./SpringCloud/SpringCloud2020/SpringCloud2020) +## SpringSecurity + +> 来源Bilibili黑马程序员视频教程:[手把手教你精通新版SpringSecurity](https://www.bilibili.com/video/BV1EE411u7YV) + +- [初识SpringSecurity](./SpringSecurity/1_初识SpringSecurity/README.md) +- [SpringSecurity在MVC项目中的使用](./SpringSecurity/2_SpringSecurity在MVC项目中的使用/README.md) +- [SpringSecurity在单机环境下的使用](./SpringSecurity/3_SpringSecurity在单机环境下的使用/README.md) +- [SpringSecurity在分布式环境下的使用](./SpringSecurity/4_SpringSecurity在分布式环境下的使用/README.md) +- [OAuth2.0介绍](./SpringSecurity/5_OAuth2.0介绍/README.md) + +## ElasticStack + +> 来源Bilibili黑马程序员的视频:[Elastic Stack(ELK)从入门到实践](https://www.bilibili.com/video/BV1iJ411c7Az) + +- [ElasticSearch介绍与安装](./ElasticStack/1_ElasticSearch介绍与安装) +- [Beats入门简介](./ElasticStack/2_Beats入门简介) +- [Kibana安装与介绍](./ElasticStack/3_Kibana安装与介绍) +- [Logstash入门简介](./ElasticStack/4_Logstash入门简介) +- [ElasticStack综合案例](./ElasticStack/5_ElasticStack综合案例) +- [使用ELK搭建蘑菇博客日志收集](./ElasticStack/6_使用ELK搭建蘑菇博客日志收集) + +## 算法学习 + +> 来源牛客网剑指offer的题目:  [点我传送](https://www.nowcoder.com/ta/coding-interviews?page=1) +> +> Bilibili视频学习解题思路(Python版本):  [点我传送](https://www.bilibili.com/video/BV1K4411o7KP) + +- [斐波那契数列](./数据结构/1_斐波那契数列/README.md) +- [青蛙跳台阶](./数据结构/2_青蛙跳台阶/README.md) +- [找出丑数](./数据结构/3_找出丑数/README.md) +- [二维数组中的查找](./数据结构/4_二维数组中的查找/README.md) +- [替换空格](./数据结构/5_替换空格/README.md) +- [两个栈实现一个队列](./数据结构/6_两个栈实现一个队列/README.md) +- [旋转数组的最小数字](./数据结构/7_旋转数组的最小数字/README.md) +- [调整数组顺序使奇数位于偶数前面](./数据结构/8_调整数组顺序使奇数位于偶数前面/README.md) +- [包含min函数的栈](./数据结构/9_包含min函数的栈/README.md) +- [栈的压入弹出序列](./数据结构/10_栈的压入弹出序列/README.md) +- [从尾到头打印链表](./数据结构/11_从尾到头打印链表/README.md) +- [链表中倒数第K个节点](./数据结构/12_链表中倒数第K个节点/README.md) +- [反转链表](./数据结构/13_反转链表/README.md) +- [合并两个排序的链表](./数据结构/14_合并两个排序的链表/README.md) +- [复杂链表的复制](./数据结构/15_复杂链表的复制/README.md) +- [两个链表的公共结点](./数据结构/16_两个链表的公共结点/README.md) +- [孩子们的游戏(圆圈中最后剩下的数)](./数据结构/17_孩子们的游戏(圆圈中最后剩下的数/README.md)) +- [链表中环的入口结点](./数据结构/18_链表中环的入口结点/README.md) +- [二进制中1的个数](./数据结构/19_二进制中1的个数/README.md) +- [不用加减乘除做加法](./数据结构/20_不用加减乘除做加法/README.md) +- [数组中出现次数超过一半的数字](./数据结构/21_数组中出现次数超过一半的数字/README.md) +- [整数中1出现的次数](./数据结构/22_整数中1出现的次数/README.md) +- [数组中只出现一次的数字](./数据结构/23_数组中只出现一次的数字/README.md) +- [树的遍历](./数据结构/24_树的遍历/README.md) +- [重建二叉树](./数据结构/25_重建二叉树/README.md) +- [树的子结构](./数据结构/26_树的子结构/README.md) +- [二叉树的镜像](./数据结构/27_二叉树的镜像/README.md) +- [从上往下打印二叉树](./数据结构/28_从上往下打印二叉树/README.md) +- [二叉搜索树的后序遍历序列](./数据结构/29_二叉搜索树的后序遍历序列/README.md) +- [二叉树中和为某一值的路径](./数据结构/30_二叉树中和为某一值的路径/README.md) +- [二叉搜索树与双向链表](./数据结构/31_二叉搜索树与双向链表/README.md) +- [最小的K个数](./数据结构/32_最小的K个数/README.md) +- [数据流中的中位数](./数据结构/33_数据流中的中位数/README.md) +- [ 二叉树的下一个节点](./数据结构/34_二叉树的下一个节点/README.md) +- [对称的二叉树](./数据结构/35_对称的二叉树/README.md) +- [按之字形顺序打印二叉树](./数据结构/36_按之字形顺序打印二叉树/README.md) +- [把二叉树打印成多行](./数据结构/37_把二叉树打印成多行/README.md) +- [二叉搜索树的第K个节点](./数据结构/38_二叉搜索树的第K个节点/README.md) +- [序列化二叉树](./数据结构/39_序列化二叉树/README.md) +- [连续子数组的最大和](./数据结构/40_连续子数组的最大和/README.md) +- [矩形覆盖](./数据结构/41_矩形覆盖/README.md) +- [排序算法-冒泡插入选择](./数据结构/42_排序算法-冒泡插入选择/README.md) +- [希尔排序](./数据结构/43_希尔排序/README.md) +- [归并排序](./数据结构/44_归并排序/README.md) +- [快速排序](./数据结构/45_快速排序/README.md) +- [动态规划算法](./数据结构/动态规划算法/README.md) +- [源码](./数据结构/NowCode) + ## SpringBoot -- [Eureka管理页面配置接口返回git信息](./SpringBoot/Eureka管理页面配置接口返回git信息) -- [Java如何通过IP地址获取地区](./SpringBoot/Java如何通过IP地址获取地区) -- [Spring Security造成无法使用iframe的内嵌页面的解决方法](./SpringBoot/Spring Security造成无法使用iframe的内嵌页面的解决方法) -- [SpringBoot解决时区问题](./SpringBoot/SpringBoot解决时区问题) -- [SpringBoot中使用注解的方式创建队列和交换机](./SpringBoot/SpringBoot中使用注解的方式创建队列和交换机) -- [使用DevTool实现SpringBoot项目热部署](./使用DevTool实现SpringBoot项目热部署) +- [Eureka管理页面配置接口返回git信息](./SpringBoot/Eureka管理页面配置接口返回git信息/README.md) +- [Java如何通过IP地址获取地区](./SpringBoot/Java如何通过IP地址获取地区/README.md) +- [SpringSecurity造成无法使用iframe的内嵌页面的解决方法](./SpringBoot/SpringSecurity造成无法使用iframe的内嵌页面的解决方法/README.md) +- [SpringBoot解决时区问题](./SpringBoot/SpringBoot解决时区问题/README.md) +- [SpringBoot项目中使用字符串占位符](./SpringBoot/SpringBoot项目中使用字符串占位符/README.md) +- [SpringBoot中使用注解的方式创建队列和交换机](./SpringBoot/SpringBoot中使用注解的方式创建队列和交换机/README.md) +- [解决升级SpringBoot2.X后无法向eureka注册服务的问题](./SpringBoot/解决升级SpringBoot2.X后无法向eureka注册服务的问题/README.md) +- [使用DevTool实现SpringBoot项目热部署](./SpringBoot/使用DevTool实现SpringBoot项目热部署/README.md) +- [使用自定义日志接口收集用户访问日志](./SpringBoot/使用自定义日志接口收集用户访问日志/README.md) +- [Bean的生命周期](./SpringBoot/Bean的生命周期/README.md) ## Vue -- [Axios中拦截器的使用](./Vue/Axios中拦截器的使用) -- [ElementUI中Upload如何批量上传](./Vue/ElementUI中Upload如何批量上传) -- [Vue对Element中的e-tag添加@click事件无效](./Vue/Vue对Element中的e-tag添加@click事件无效) -- [Vue使用Echarts制作一个文章贡献度表](./Vue/Vue使用Echarts制作一个文章贡献度表) -- [Vue中input框自动聚焦](./Vue/Vue中input框自动聚焦) -- [Vue使用vue-count-to插件对数字显示美化](./Vue/Vue使用vue-count-to插件对数字显示美化) -- [Vue项目如何关闭Eslint校验](./Vue/Vue项目如何关闭Eslint校验) -- [Vue项目使用阿里巴巴矢量图标库](./Vue/Vue项目使用阿里巴巴矢量图标库) -- [Vue制作一个评论模块](./Vue/Vue制作一个评论模块) -- [Vue中对数组变化监听](./Vue/Vue中对数组变化监听) -- [Vue中使用Vue-cropper进行图片裁剪](./Vue/Vue中使用Vue-cropper进行图片裁剪) -- [Vuex学习指南-实现一个计数器](./Vue/VueX/Vuex学习指南-实现一个计数器) -- [Vue如何使用G2绘制图片](./Ant/G2/Vue如何使用G2绘制图片) - -- ## 杂记 - -- [CKEditor前端样式和编辑器的样式不一致的问题](./杂记/CKEditor前端样式和编辑器的样式不一致的问题) - -- [Ckeidtor中上传图片添加token信息](./杂记/ckeidtor中上传图片添加token信息) - -- [CLion搭建C语言开发环境](./杂记/CLion搭建C语言开发环境) - -- [Elasticsearch介绍与安装](./杂记/Elasticsearch介绍与安装) - -- [Github项目配置Actions](./杂记/Github项目配置Actions) -- [SpringBoot+Vue如何集成第三方登录登录JustAuth](./杂记/SpringBoot+Vue如何集成第三方登录登录JustAuth) -- [SpringBoot项目启动增加自定义Banner](./杂记/SpringBoot项目启动增加自定义Banner) -- [蘑菇博客后台登录页面增加粒子特效](./杂记/蘑菇博客后台登录页面增加粒子特效) -- [蘑菇博客集成MarkDown编辑器tui-editor](./杂记/蘑菇博客集成MarkDown编辑器tui-editor) -- [蘑菇博客配置七牛云存储](./杂记/蘑菇博客配置七牛云存储) -- [蘑菇博客配置域名解析](./杂记/蘑菇博客配置域名解析) -- [蘑菇博客切换搜索模式](./杂记/蘑菇博客切换搜索模式) -- [蘑菇博客如何部署到阿里云服务器](./杂记/蘑菇博客如何部署到阿里云服务器) -- [蘑菇博客使用Github Action完成持续集成](./杂记/蘑菇博客使用Github Action完成持续集成) -- [蘑菇博客添加本地Markdown文件上传功能](./杂记/蘑菇博客添加本地Markdown文件上传功能) -- [如何使用docsify给蘑菇博客编写开发文档](./杂记/如何使用docsify给蘑菇博客编写开发文档) -- [如何制作github小徽章](./杂记/如何制作github小徽章) -- [使用开源项目申请JetBrains全家桶](./杂记/使用开源项目申请JetBrains全家桶) +- [Axios中拦截器的使用](./Vue/Axios中拦截器的使用/README.md) +- [ElementUI中Upload如何批量上传](./Vue/ElementUI中Upload如何批量上传/README.md) +- [el-select因为绑定的值为整数而无法默认选择](./Vue/el-select因为绑定的值为整数而无法默认选择/README.md) +- [Vue动态计算Table表格的高度](./Vue/Vue动态计算Table表格的高度/README.md) +- [Vue对Element中的e-tag添加@click事件无效](./Vue/Vue对Element中的e-tag添加@click事件无效/README.md) +- [Vue使用Echarts制作一个文章贡献度表](./Vue/Vue使用Echarts制作一个文章贡献度表/README.md) +- [Vue中input框自动聚焦](./Vue/Vue中input框自动聚焦/README.md) +- [Vue使用vue-count-to插件对数字显示美化](./Vue/Vue使用vue-count-to插件对数字显示美化/README.md) +- [Vue项目如何关闭Eslint校验](./Vue/Vue项目如何关闭Eslint校验/README.md) +- [Vue项目使用阿里巴巴矢量图标库](./Vue/Vue项目使用阿里巴巴矢量图标库/README.md) +- [Vue项目引入CDN加速](./Vue/Vue项目引入CDN加速/README.md) +- [Vue制作一个评论模块](./Vue/Vue制作一个评论模块/README.md) +- [Vue中Html和Markdown互相转换](./Vue/Vue中Html和Markdown互相转换/README.md) +- [Vue中对数组变化监听](./Vue/Vue中对数组变化监听/README.md) +- [Vue中使用Vue-cropper进行图片裁剪](./Vue/Vue中使用Vue-cropper进行图片裁剪/README.md) +- [Vuex学习指南-实现一个计数器](./Vue/VueX/Vuex学习指南-实现一个计数器/README.md) +- [Vue中防止XSS脚本攻击](./Vue/VueX/Vue中防止XSS脚本攻击/README.md) +- [Vue如何使用G2绘制图片](./Ant/G2/Vue如何使用G2绘制图片/README.md) +- [使用Vuex进行两个页面逻辑交互](./Vue/使用Vuex进行两个页面逻辑交互/README.md) + +## 杂记 + +- [Windows环境下搭建蘑菇博客](./杂记/Windows环境下搭建蘑菇博客/README.md) +- [Docker搭建蘑菇博客](./杂记/Docker搭建蘑菇博客/README.md) +- [CKEditor前端样式和编辑器的样式不一致的问题](./杂记/CKEditor前端样式和编辑器的样式不一致的问题/README.md) +- [Ckeidtor中上传图片添加token信息](./杂记/ckeidtor中上传图片添加token信息/README.md) +- [CLion搭建C语言开发环境](./杂记/CLion搭建C语言开发环境/README.md) +- [Elasticsearch介绍与安装](./杂记/Elasticsearch介绍与安装/README.md) +- [Github项目配置Actions](./杂记/Github项目配置Actions/README.md) +- [SpringBoot+Vue如何集成第三方登录登录JustAuth](./杂记/SpringBoot+Vue如何集成第三方登录登录JustAuth/README.md) +- [SpringBoot项目启动增加自定义Banner](./杂记/SpringBoot项目启动增加自定义Banner/README.md) +- [VSCode服务版搭建教程,让平板化为生产力工具](./杂记/VSCode服务版搭建教程/README.md) +- [Windows平台编写bat脚本让后台启动多个程序](./杂记/Windows平台编写bat脚本让后台启动多个程序/README.md) +- [记一次蘑菇博客差点被删库的经历](./杂记/记一次蘑菇博客差点被删库的经历/README.md) +- [解决git默认不区分大小写的问题](./杂记/解决git默认不区分大小写的问题/README.md) +- [蘑菇博客从Eureka迁移到Nacos](./杂记/蘑菇博客从Eureka迁移到Nacos/README.md) +- [蘑菇博客Nacos安装指南](./杂记/蘑菇博客Nacos安装指南/README.md) +- [蘑菇博客Sentinel安装指南](./杂记/蘑菇博客Sentinel安装指南/README.md) +- [蘑菇博客QQ小程序发布指南](./杂记/蘑菇博客QQ小程序发布指南/README.md) +- [蘑菇博客后台登录页面增加粒子特效](./杂记/蘑菇博客后台登录页面增加粒子特效/README.md) +- [蘑菇博客集成MarkDown编辑器tui-editor](./杂记/蘑菇博客集成MarkDown编辑器tui-editor/README.md) +- [蘑菇博客配置七牛云存储](./杂记/蘑菇博客配置七牛云存储/README.md) +- [蘑菇博客配置域名解析](./杂记/蘑菇博客配置域名解析/README.md) +- [蘑菇博客切换搜索模式](./杂记/蘑菇博客切换搜索模式/README.md) +- [蘑菇博客如何部署到阿里云服务器](./杂记/蘑菇博客如何部署到阿里云服务器/README.md) +- [蘑菇博客如何扩展新的功能和页面](./杂记/蘑菇博客如何扩展新的功能和页面/README.md) +- [蘑菇博客使用GithubAction完成持续集成](./杂记/蘑菇博客使用GithubAction完成持续集成/README.md) +- [蘑菇博客使用SQL语句进行搜索出的内容忽略大小写并添加高亮效果](./杂记/蘑菇博客使用SQL语句进行搜索出的内容忽略大小写并添加高亮效果/README.md) +- [蘑菇博客添加本地Markdown文件上传功能](./杂记/蘑菇博客添加本地Markdown文件上传功能/README.md) +- [如何给七牛云中的文件配置防盗链](./杂记/如何给七牛云中的文件配置防盗链/README.md) +- [如何使用docsify给蘑菇博客编写开发文档](./杂记/如何使用docsify给蘑菇博客编写开发文档/README.md) +- [如何制作github小徽章](./杂记/如何制作github小徽章/README.md) +- [使用JustAuth集成QQ登录](./杂记/使用JustAuth集成QQ登录/README.md) +- [使用开源项目申请JetBrains全家桶](./杂记/使用开源项目申请JetBrains全家桶/README.md) +- [什么是CICD](./杂记/什么是CICD/README.md) +- [罗技K380快捷键](./杂记/罗技K380快捷键/README.md) +- [将PDF转换为Kindle能识别的MOBI格式](./杂记/将PDF转换为Kindle能识别的MOBI格式/README.md) +- [OCR文字识别软件](./杂记/OCR文字识别软件/README.md) + +## Linux + +- [Linux下查看文件和文件夹占用空间大小](./Linux/Linux下查看文件和文件夹占用空间大小/README.md) +- [Linux下通过nginx配置https](./Linux/Linux下通过nginx配置https/README.md) +- [CentOS下如何安装Nginx](./Linux/CentOS下如何安装Nginx/README.md) +- [记一次因代码出错不断输出日志占满Docker容器硬盘的排查经历](./Linux/记一次因代码出错不断输出日志占满Docker容器硬盘的排查经历/README.md) +- [CentOS下安装Nacos](./Linux/CentOS下安装Nacos/README.md) + +## Redis + +- [Redis中的数据结构](./Redis/Redis中的数据结构/README.md) +- [Redis中的跳跃表](./Redis/Redis中的跳跃表/README.md) +- [Redis缓存穿透-布隆过滤器](./Redis/Redis缓存穿透-布隆过滤器/README.md) +- [大白话谈IO模型](./Redis/大白话谈IO模型/README.md) +- [IO多路复用底层原理](./Redis/IO多路复用底层原理/README.md) +- [Redis实现分布式锁](./Redis/Redis实现分布式锁/README.md) + +## JavaScript + +- [Js设置二级域名和顶级域名下共享Cookie](./JavaScript/Js设置二级域名和顶级域名下共享Cookie/README.md) +- [如何通过Js将时间转换为刚刚_几分钟前_几小时前](./JavaScript/如何通过Js将时间转换为刚刚_几分钟前_几小时前/README.md) + +## 数据库 + +- [MyBatis常见面试题](./数据库/MyBatis常见面试题/README.md) +- [MyBatis的缓存机制](./数据库/MyBatis的缓存机制/README.md) +- [MySQL索引](./数据库/MySQL索引/README.md) ## 操作系统 -- [进程和线程通信](./操作系统/1_进程和线程通信) +- [进程和线程通信](./操作系统/1_进程和线程通信/README.md) ## 计算机网络 -- [三次握手和四次挥手](./计算机网络/1_三次握手和四次挥手) -- [https和http](./计算机网络/2_https和http) - - - - - - +- [三次握手和四次挥手](./计算机网络/1_三次握手和四次挥手/README.md) +- [https和http](./计算机网络/2_https和http/README.md) +- [TCP中的拥塞控制和流量控制](./计算机网络/3_TCP中的拥塞控制和流量控制/README.md) +- [物理层](./计算机网络/4_物理层/README.md) +- [数据链路层](./计算机网络/5_数据链路层/README.md) +- [http中的状态码](./计算机网络/http中的状态码/README.md) + +## 面经 + +- [京东面经](./校招面试/面经汇总/1_京东面经/README.md) +- [字节跳动面试总结](./校招面试/面经汇总/2_字节跳动面试总结/README.md) +- [京东零售提前批Java一面](./校招面试/面经汇总/3_京东零售提前批Java一面/README.md) +- [京东零售提前批Java二面](./校招面试/面经汇总/4_京东零售提前批Java二面/README.md) +- [滴滴出行提前批Java123面](./校招面试/面经汇总/5_滴滴出行提前批Java123面/README.md) + +## Golang基础 + +> 来源Bilibili IT营 大地老师学习视频:[点我传送](https://www.bilibili.com/video/BV14T4y1g7h9) + +- [Go语言的安装](./Golang/Golang基础/0_Go语言的安装/README.md) +- [Go语言发展简史](./Golang/Golang基础/1_Go语言发展简史/README.md) +- [Go的变量](./Golang/Golang基础/2_Go的变量/README.md) +- [Go的数据类型](./Golang/Golang基础/3_Go的数据类型/README.md) +- [Go的运算符](./Golang/Golang基础/4_Go的运算符/README.md) +- [Go的流程控制](./Golang/Golang基础/5_Go的流程控制/README.md) +- [Go的数组](./Golang/Golang基础/6_Go的数组/README.md) +- [Go的切片](./Golang/Golang基础/7_Go的切片/README.md) +- [Go的map](./Golang/Golang基础/8_Go的map/README.md) +- [Go的函数](./Golang/Golang基础/9_Go的函数/README.md) +- [Go中的日期函数](./Golang/Golang基础/10_Go中的日期函数/README.md) +- [Go中的指针](./Golang/Golang基础/11_Go中的指针/README.md) +- [Go中的结构体](./Golang/Golang基础/12_Go中的结构体/README.md) +- [Go中的包以及GoMod](./Golang/Golang基础/13_Go中的包以及GoMod/README.md) +- [Go中的接口](./Golang/Golang基础/14_Go中的接口/README.md) +- [goroutine实现并行和并发](./Golang/Golang基础/15_goroutine实现并行和并发/README.md) +- [Golang中的反射](./Golang/Golang基础/16_Golang中的反射/README.md) +- [源码](./Golang/Golang基础/Code) + +## 关注&交流 + +刚刚创建了QQ群 (**加群备注**:`蘑菇博客`) 蘑菇博客交流群,目前项目还存在很多不足之处,欢迎各位老哥进群进行技术交流,为了防止广告进入,希望加群的时候能添加备注,谢谢~ + +| QQ群(加群备注:`蘑菇博客`) | QQ(加群备注:`蘑菇博客`) | +| :----------------------------------------------------: | :----------------------------------------------: | +| | | + +## 赞赏 + +如果觉得本仓库对您有帮助的话,希望朋友能够给博主喝一杯咖啡(ps.. 小伙伴赞赏的时候可以备注一下下~) + +| 微信 | 支付宝 | +| :----------------------------------------------: | :-----------------------------------------------: | +| | | diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/README.md" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..4a422876fb1401bdb3018dd834e1e9d84458f885 --- /dev/null +++ "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/README.md" @@ -0,0 +1,204 @@ +# 从底层了解IO多路复用模型 + +## 前言 + +当我们去面试的时候,问到了 redis,nginx,netty他们的底层模型分别是什么? + +- redis -> epoll +- nginx-> epoll +- netty-> epoll? + +需要从操作系统的层面上来谈 + +## BIO + +当我们开机的时候,首先被加载进内存的是我们的Kernel(内核),内核是用于管理我们的硬件的,同时内核还会创建一个GDT表,然后划分两个空间(用户空间和内核空间),同时空间中的内容是开启了保护模式,无法被修改的。 + +同时还有一个CPU的概念,CPU有自己的指令集,并且指令集是分了几个级别的,分别是从0~3的,Kernel属于0级别。APP只能用级别为3的指令集。 + +从上面我们可以知道,我们的应用程序是无法直接访问我们的Kernel的,也就是程序不能直接访问我们的磁盘,声卡,网卡等设备,只有内核才可以访问,那我们怎么办? + +只有APP通过调用Kernel提供的 syscall(系统软中断和硬中断)来获取硬件中的内容。 + +- 软中断 +- 硬中断:硬中断指的是我们的键盘,按下一个按键的时候,就会触发我们的硬中断,也就是内核会有一个中断号,然后得到一个callback的回调函数 + +说到这里,其实就是为了引出一个 概念,就是 IO 和 内核之间的成本问题 + +![image-20200701203511839](images/image-20200701203511839.png) + + + +```java +/** + * 服务器读取文件 + * @author: 陌溪 + * @create: 2020-07-01-20:40 + */ +public class TestSocket { + public static void main(String[] args) throws IOException { + ServerSocket server = new ServerSocket(8090); + System.out.println("step1: new ServerSocket(8090)"); + while(true) { + Socket client = server.accept(); + System.out.println("step2: client " + client.getPort()); + new Thread(() -> { + try { + InputStream in = client.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + while(true) { + System.out.println(reader.readLine()); + } + } catch (IOException e) { + e.printStackTrace(); + } + }, "t1").start(); + } + } +} +``` + +抓取程序对内核有没有系统调用,然后输出 + +``` +strace -ff -o ./ooxx java TestSocket +``` + +然后我们执行上面的程序,得到我们的结果 + +![image-20200701205141858](images/image-20200701205141858.png) + +然后我们在通过jps命令,查看当前TestSocket的进程号 + +``` +jps + +2912 Jps +2878 TestSocket +``` + +然后我们在进入下面的这个目录下,启动2878是线程的id号,这个目录就是存放该线程的一些信息 + +```bash +cd /proc/2878 +``` + +我们可以看到2878进程下的,通过查看task目录,可以看到所有线程数 + +![image-20200701205539126](images/image-20200701205539126.png) + +还有一个目录,就是 fd目录,在该目录下,就是我们的一些IO流 + +![image-20200701205750115](images/image-20200701205750115.png) + +上面的0,1,2,分别对应着 输入流,输出流和错误流。在java里面我们流就是对象,而在linux系统中,流就是一个个的文件。后面的4,5 就对应着我们的socket通信,分别对应着ipv4 和 ipv6 + +![image-20200701205958499](images/image-20200701205958499.png) + +通过netstat命令查看 + +![image-20200701210121933](images/image-20200701210121933.png) + +然后我们使用nc连接 8090端口 + +```bash +nc localhost 8090 +``` + +我们执行完后,通过netstat命令查看 ,发现多了个连接的状态 + +![image-20200701210428515](images/image-20200701210428515.png) + +然后在看文件里面,也多了一个socket + +![image-20200701210733202](images/image-20200701210733202.png) + +我们查看系统调用,发现通过系统调用接收了一个58181端口号的请求,在前面我们还能够看到5,这个5其实就是对应的上图里面的socket,走的是ipv4。 + +![image-20200701210907287](images/image-20200701210907287.png) + +从这里其实我们就可以知道了,我们原来调用中写的代码 + +```java +Socket client = server.accept(); +``` + +对应到系统层面,也是调用了系统的方法。 + +同时关于系统调用,有以下几种方式 + +- bind +- connect +- listen +- select +- socket + +首先我们需要知道,java其实是一种解释型语言,通过JVM 虚拟机将我们的.java文件转换为字节码文件,然后调用我们os中的syscall方法,我们必须明确的是,无论怎么调用,一定最后要通过调用内核的方法,然后调用我们的硬件。 + +![image-20200701213855739](images/image-20200701213855739.png) + +上述的模型,就是BIO的通信,是这里面有很多阻塞,我们只能够通过多个线程来避免主线程的阻塞。 + +但是从上面我们可以知道,如果有大量的连接过来,那服务器需要创建很多个线程与之对应,并且线程的创建也是需要消耗资源的,因为线程使用的栈是独占的(栈大小默认1MB),同时CPU的资源调度也是需要浪费。 + +最根本的原因就是因为 BIO是阻塞的,才会造成上面的问题。 + +## NIO + +因为BIO存在线程阻塞的问题,后面就提出了NIO的概念,在NIO中,有C10K的问题,C10K = 10000个客户端。但是在和你连接的服务器中,其实没有多少给你发送数据了,所以我们需要做的就是,每当有人发送消息的时候,我才和它进行连接。 + +![image-20200701215310148](images/image-20200701215310148.png) + +也就是每次都需要遍历10000个客户端,是非常耗费时间呢,因为很多客户端可能就没有请求的发送。 + +## 多路复用 + +这个时候,我们就不需要遍历10K个客户端了,而是把我们的fds文件发送给内核,然后内核去判断最后需要连接诶的客户端,这样就不用遍历全部的了。所以这里的Select就是多路复用器,通过多路复用返回的是状态,然后我们需要程序去判断这些状态。 + +说白了,就是通过一个多路复用器,来判断哪些路可以走通,然后不需要轮询全部的。 + +![image-20200701215254768](images/image-20200701215254768.png) + +这个模型,是通过select,将fds文件交给内核来做了,也就是内核需要完成10K个文件的主动遍历,这个10K个调用,对比之前的10K次系统调用来说,是更省时间的,存在以下的问题 + +- 每次传递很多数据(重复劳动) +- 然后内核需要主动去遍历( 复杂度O(N) ) + +解决方法,通过在内核中,开辟一个空间,当每次来一个客户端,就把这个文件丢到内核中,这样不需要每次把10K个文件传递到内核了。 + +然后在使用一个基于事件驱动的模型,如下图所示就是一个异步事件驱动的流程 + +![image-20200702081602327](images/image-20200702081602327.png) + +## 同样使用epoll,Redis是轮询,Nginx是阻塞? + +我们通过strace命令,查看nginx 和 redis的运行流程,能够发现 同样是使用了 epoll,但是nginx是阻塞的,而redis它是轮询(非阻塞)的。 + +首先那是因为Redis只有一个线程,而这个线程要做很多事情,例如 接收客户端,LRU,LFU(淘汰过滤)、RDB/AOF(fork线程进行数据备份)。 + +也就是说对于Redis中的C10K问题,redis也是通过epoll的事件驱动来进行处理的,也就是通过epoll将每个需要读取的客户端的操作放在一个原子串行化的队列中,并且一个客户端包含以下的几个操作:read、计算、write等 + +![image-20200702083635139](images/image-20200702083635139.png) + +在redis 6.X版本中,还有一个IO threads的概念,首先它为了留住串行化原子性的特点,也就是计算的时候还是串行化的处理,但是在读取数据的时候,使用的是多线程进行并发IO读取 + +为什么要多线程读呢?首先因为读操作需要发生CPU的系统调用,如果通过多个线程读取,能够充分发挥CPU的多核作用 + +![image-20200702084219155](images/image-20200702084219155.png) + +而nginx只需要做一件事,就是等着客户端过来,不需要做其他的事情,所以也就设置成阻塞。 + +## 零拷贝 + +用kafka来讲,首先这里面有两个角色,一个是消息生产者,一个是消息消费者 + +![image-20200702090307355](images/image-20200702090307355.png) + +也就是说,我们通过开辟了一个内存空间,能够直接抵达磁盘,能够减少kernel的系统调用。 + +在读取的时候,如果是原来的做法,就需要首先请求kernel,然后kernel发起一个read请求,读取磁盘的文件到内核中,然后kafka在读取kernel中的信息。 + +那么什么是零拷贝呢?零拷贝就是不发生拷贝的情况,零拷贝的前提就是数据不需要加工,在JVM中有一个RandomAccessFile,它能够直接开辟一个堆内空间,或者堆外空间。 + + + diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701203511839.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701203511839.png" new file mode 100644 index 0000000000000000000000000000000000000000..44e8a36770011e88ddac2fc2f27ad1e012183c42 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701203511839.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701205141858.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701205141858.png" new file mode 100644 index 0000000000000000000000000000000000000000..11bea65204f6aef6466f2b76fc02243a50d0d009 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701205141858.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701205539126.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701205539126.png" new file mode 100644 index 0000000000000000000000000000000000000000..6516280af5bd0d1351966a743c9452ec465daa46 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701205539126.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701205750115.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701205750115.png" new file mode 100644 index 0000000000000000000000000000000000000000..1c15846d1351bcb02404bb04295d32a6a4437eca Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701205750115.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701205958499.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701205958499.png" new file mode 100644 index 0000000000000000000000000000000000000000..00f90df667169b7731d8284658d766feb8ec8858 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701205958499.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701210121933.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701210121933.png" new file mode 100644 index 0000000000000000000000000000000000000000..0d012ccc25bd05a29cf8dc7630cb150652afa708 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701210121933.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701210428515.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701210428515.png" new file mode 100644 index 0000000000000000000000000000000000000000..85029e8d7abc715f7570b042eae380a6189c6801 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701210428515.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701210733202.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701210733202.png" new file mode 100644 index 0000000000000000000000000000000000000000..7472b928bffca5a1dba5c93717fc8793e88c5ac9 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701210733202.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701210907287.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701210907287.png" new file mode 100644 index 0000000000000000000000000000000000000000..7362c388bf8096d5982efa534c28523346cee8ff Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701210907287.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701213855739.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701213855739.png" new file mode 100644 index 0000000000000000000000000000000000000000..ef0f40a649e2d102b269d8c5aca1f37ae586de46 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701213855739.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701215252317.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701215252317.png" new file mode 100644 index 0000000000000000000000000000000000000000..89a9d2d995ad0f36433b7903d1d8be64b12eea47 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701215252317.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701215254768.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701215254768.png" new file mode 100644 index 0000000000000000000000000000000000000000..89a9d2d995ad0f36433b7903d1d8be64b12eea47 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701215254768.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701215310148.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701215310148.png" new file mode 100644 index 0000000000000000000000000000000000000000..9ac3451719eacf688e6fc5d5899728b679fde944 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200701215310148.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200702081602327.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200702081602327.png" new file mode 100644 index 0000000000000000000000000000000000000000..154ee77e17c4631800d48977706b8f8fc39e04ef Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200702081602327.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200702083635139.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200702083635139.png" new file mode 100644 index 0000000000000000000000000000000000000000..b06a5973ecaefcb09a6b21abd50db89d97c76770 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200702083635139.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200702084219155.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200702084219155.png" new file mode 100644 index 0000000000000000000000000000000000000000..5cc1b38ffda2c959a0c494a3d530ae902c8894e8 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200702084219155.png" differ diff --git "a/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200702090307355.png" "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200702090307355.png" new file mode 100644 index 0000000000000000000000000000000000000000..d959cce3c688f3ada7f47519361fc6bb80352945 Binary files /dev/null and "b/Redis/IO\345\244\232\350\267\257\345\244\215\347\224\250\345\272\225\345\261\202\345\216\237\347\220\206/images/image-20200702090307355.png" differ diff --git "a/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/README.md" "b/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..13056dffe3bf3b603f85966a67e9892be61e0533 --- /dev/null +++ "b/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/README.md" @@ -0,0 +1,118 @@ +# Redis中的数据结构 + +## 前言 + +Redis是一个高性能的分布式内存数据库,在国内外个大互联网公司中都有着广泛的使用,即使是一些非互联网公司也有着非常重要的使用场景。 + +Redis提供了五种主要的数据类型,它提供了强大且实用的功能,然而实际开发中,有大多数的开发者仅仅只会使用简单的 Redis String的 Get和Set,下面将回顾Redis五大对象,以便能够在实战中游刃有余。 + +- String(终究是我扛下来所有) +- Hash(存储对象我也行) +- List(栈和队列我都行) +- Set(标签系统我在行) +- Sort Set(排起名来我最棒) + +## 字符串 + +字符串类型是Redis最基础的数据结构,其他几种数据结构都是在字符串类型基础上构建的。字符串类型的值是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字(整数、浮点数),甚至是二进制(图片、音频、视频)等。 + +![image-20200626095844113](images/image-20200626095844113.png) + +字符串对象的内部编码有3种 :**int**、**raw** 和 **embstr**,Redis会根据当前值的类型和长度来决定使用哪种编码来实现 + +- int:如果一个字符串对象保存的是整数值,并且这个整数值可以用`long`类型来表示 +- raw:如果字符串对象保存的是一个字符串值,并且这个字符串值的长度大于32字节 +- embstr:如果字符串对象保存的是一个字符串值,并且这个字符申值的长度小于等于32字节 + +Reids字符串的使用场景是最为广泛的,甚至有些对redis其它几种对象不太熟悉的人,基本所有场景都会使用字符串(序列化一下直接扔进去),这让本身很单纯的字符串承受了它这个年纪本不该承受的重量。其实Redis的主要使用场景主要有以下几种: + +- 作为缓存层,缓存热点数据 +- Redis字符串可以自增自减的特性可以用来做计数器、限速器、自增ID生成等 +- 分布式系统的Session共享 +- 二进制数据的存储 + +关于更加详细的关于字符串结构的介绍,参考[这篇博客](https://blog.laoyu.site/2019/redis/Redis%E5%AF%B9%E8%B1%A1%E2%80%94%E2%80%94%E5%AD%97%E7%AC%A6%E4%B8%B2(String)) + +## 哈希 + +哈希对象用来存储一组数据对。每个数据对又包含键值两部分 + +![image-20200626101327742](images/image-20200626101327742.png) + +Hash对象也有两种实现方式:[ziplist(压缩列表)](https://blog.laoyu.site/2019/redis/Redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E2%80%94%E2%80%94%E5%8E%8B%E7%BC%A9%E5%88%97%E8%A1%A8)和 [hashtable(哈希表)](https://blog.laoyu.site/2018/redis/Redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E2%80%94%E2%80%94%E5%AD%97%E5%85%B8) + +同样,只有当存储的数据量比较小的情况下,Redis才使用压缩列表来实现哈希对象,具体需要满足两个条件 + +- 字典中保存的键和值的大小都要小于64字节 +- 字典中键值对的个数要小于512个 + +当不能同时满足上面的两个条件时,Redis就使用哈希表来实现Hash对象 + +当存储的内容是对象的时候,Redis字符串对象很多功能使用Redis 哈希对象也可以实现,如缓存用户信息的时候,使用Redis哈希对象存储,简单直观,如果使用合理可以减少内存空间的使用。 + +但是也有其缺点,就是要控制哈希在ziplist和hashtable两种内部编码的转换,hashtable将会消耗更多的内存。 + +此外,Hash对象还可以实现购物车和计数器等功能,更详细的介绍,参考[这篇博客](https://blog.laoyu.site/2020/redis/Redis%E5%AF%B9%E8%B1%A1%E2%80%94%E2%80%94%E5%93%88%E5%B8%8C(Hash)) + +## 列表 + +列表这种对象支持存储一组有序的,不重复的数据。因为其有序性,它可以获取指定范围的元素列表,可以在O(1)的时间复杂度获取指定索引的下标的元素等。 + +![image-20200626105857594](images/image-20200626105857594.png) + +在Redis3.2版本以前列表类型的内部编码有两种。当满足下面两个条件的时候,Redis 列表对象使用ziplist(压缩列表)来实现。 + +- 当列表的元素个数小于list-max-ziplist-entries配置(默认512个) +- 当列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节) + +当列表类型无法满足ziplist条件时,Redis会使用linkedList作为列表的内部实现。 + +而在Redis3.2版本开始怼列表数据结构进行改造,使用quickList代替了zipList和linkedList。 + +由于列表对象的有序且不可重复的特性,它比较适合用来做文章、商品等列表的存储。 + +列表类型可以lpush(左侧push),同时又可以使用rpop(右侧弹出)第一个元素,所以列表类型具有先进先出的特性,可以用来实现消息队列,也可以lpush(左侧push)和lpop(左侧弹出),具有后进先出的特性,因此开发中需要使用栈的时候,我们可以使用列表对象来实现。 + +关于List更详细的介绍,参考[这篇博客](https://blog.laoyu.site/2020/redis/Redis%E5%AF%B9%E8%B1%A1%E2%80%94%E2%80%94%E5%88%97%E8%A1%A8(List)) + +## 集合 + +集合对象是一个无序且唯一的键值集合。它的存储顺序不会按照插入的先后顺序进行存储,与列表不同的是它存储的数据是无序且不重复的。 + +![image-20200626122033221](images/image-20200626122033221.png) + +集合对象的内部编码也有两种,intest(整数集合)与hashtable(哈希表),当满足下面两个条件的时候,集合对象使用intset来实现 + +- 集合中的元素都是整数 +- 集合中元素的个数小于 set-maxintset-entries配置(默认512个) + +不满足上面两个条件时,集合对象使用hashtable来实现 + +集合对象的主要两个特性就是:**无序**,**不可重复**,**支持并交差**,因此可以用来做标签系统 + +而集合中的 [SPOP(随机移除并返回集合中一个或多个元素)](https://blog.laoyu.site/2020/redis_command/set/spop/) 和 [SRANDMEMBER(随机返回集合中一个或多个元素)](https://blog.laoyu.site/2020/redis_command/set/srandmember/) 命令可以帮助我们实现一个抽奖系统 + +有关Set更详细的介绍,参考[这篇博客](https://blog.laoyu.site/2020/redis/Redis%E5%AF%B9%E8%B1%A1%E2%80%94%E2%80%94%E9%9B%86%E5%90%88(Set)/) + +## 有序集合 + +有序集合类型 (Sorted Set或ZSet) 相比于集合类型多了一个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序结合的元素值,一个是排序值。有序集合保留了集合不能有重复成员的特性(分值可以重复),但不同的是,有序集合中的元素可以排序。 + +![image-20200626123309037](images/image-20200626123309037.png) + +有序集合是由 [ziplist (压缩列表)](http://blog.laoyu.site/2019/redis/Redis数据结构——压缩列表/) 或 [skiplist (跳跃表)](https://blog.laoyu.site/2019/redis/Redi数据结构——跳跃表/) 组成的。 + +当数据比较少时,有序集合使用的是 ziplist 存储的,有序集合使用 ziplist 格式存储必须满足以下两个条件: + +- 有序集合保存的元素个数要小于 128 个; +- 有序集合保存的所有元素成员的长度都必须小于 64 字节。 + +如果不能满足以上两个条件中的任意一个,有序集合将会使用 skiplist 结构进行存储。 + +有序集合比较典型的使用场景就是排行榜系统例如学生成绩的排名。某视频(博客等)网站的用户点赞、播放排名、电商系统中商品的销量排名等。 + +有关Redis有序集合对象的更详细的介绍,参考[这篇博客](https://blog.laoyu.site/2020/redis/Redis%E5%AF%B9%E8%B1%A1%E2%80%94%E2%80%94%E6%9C%89%E5%BA%8F%E9%9B%86%E5%90%88(ZSet)/) + +### 小结 + +Redis提供了五种最基础也是最常用的对象(数据类型):String、Hash、List、Set、ZSet。了解这五种对象的有助于我们更好的在日常开发中对Redis进行使用。而通过这篇文章我们可以看到每种对象都是通过多种数据结构来实现的,大家可以思考一下为什么。 \ No newline at end of file diff --git "a/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626095844113.png" "b/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626095844113.png" new file mode 100644 index 0000000000000000000000000000000000000000..45ed61359a668fc1f6fde107064b419d0f1157ad Binary files /dev/null and "b/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626095844113.png" differ diff --git "a/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626101327742.png" "b/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626101327742.png" new file mode 100644 index 0000000000000000000000000000000000000000..2b7d057f11b320e6fc2e0d365c332afd40e7efd3 Binary files /dev/null and "b/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626101327742.png" differ diff --git "a/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626105857594.png" "b/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626105857594.png" new file mode 100644 index 0000000000000000000000000000000000000000..03aad1c2f671da5fb2e327800119511fcb252d65 Binary files /dev/null and "b/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626105857594.png" differ diff --git "a/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626122033221.png" "b/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626122033221.png" new file mode 100644 index 0000000000000000000000000000000000000000..572bb299cbc5873d83fd16f6f153562336c666b8 Binary files /dev/null and "b/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626122033221.png" differ diff --git "a/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626123309037.png" "b/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626123309037.png" new file mode 100644 index 0000000000000000000000000000000000000000..e04993bb6b6233ca2a3e524a2fd1ef81a0303d4c Binary files /dev/null and "b/Redis/Redis\344\270\255\347\232\204\346\225\260\346\215\256\347\273\223\346\236\204/images/image-20200626123309037.png" differ diff --git "a/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/README.md" "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..76d33e12fcebb3dd6427d87d924945989dc45542 --- /dev/null +++ "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/README.md" @@ -0,0 +1,94 @@ +# Redis中的跳跃表 + +## 前言 + +跳跃表是一种有序的数据结构,它通过在每个节点维持多个指向其他节点的指针,从而达到快速访问节点的目的。 + +## 什么是跳跃表 + +对于单个链表来讲,即便链表中存储的数据是有序的,如果我们要向在其中查找某个数据,它只能从头到尾遍历链表。这样查找效率就会很低,时间复杂度会很高,达到了O(n)。 + +![image-20200626083207599](images/image-20200626083207599.png) + +如果我们想要提高其查询效率,可以考虑在链表上构建索引的 方式,每两个节点提取一个节点到上级,我们把抽出来的那一级就叫做索引。 + +![image-20200626083217149](images/image-20200626083217149.png) + +这个时候,我们假设要查找节点8,我们可以心在索引层遍历,当遍历到索引层中值为7的节点时,发现下一个节点是9,那么要查找的节点肯定在这两个节点之间,我们下降到链表层继续遍历就找到了8这个节点。。原来我们在单链表中找到8这个节点要遍历8个节点,而现在有了一级索引后,只需要遍历5个节点。 + +从上个例子中,我们可以看出,加来一层索引后,查找一个节点需要遍历的节点个数减少了,也就是说查询效率得到了提升,同理我们在一级索引的基础上,在加二级索引。 + +![image-20200626084038222](images/image-20200626084038222.png) + +从图中我们可以看出,查找效率又有了提升,因为在这里例子中我们的数据量很少,当有大量的数据时,我们可以增加多级索引,在查询时,效率可以得到明显的提升。 + +![image-20200626084148758](images/image-20200626084148758.png) + +像这种链表增加多种索引的结构,就是跳跃表。 + +## Redis中的跳跃表 + +从上面跳跃表的定义我们可以知道,如果使用跳跃表作为底层的数据结构,那么需要保证 元素之间的**有序性**,而且sortSet我们知道,他就是一个元素和元素之间排序好。 + +Redis中使用跳跃表作为有序集合键的底层实现之一,以下几种情况将会让Redis使用跳跃表作为有序集合键的底层实现 + +- 一个有序集合包含的元素数量比较多 +- 有序集合中元素的成员键比较长 + +跳跃表支持平均O(logN)、最坏O(N) 复杂度的节点查找,还可以通过顺序性操作来批量处理节点。在大部分情况下,跳跃表的效率可以和平衡树相媲美,并且因为跳跃表的实现比平衡树要来得更为简单,所以有不少程序都使用跳跃表来代替平衡树。 + +**那么为什么元素数量比较多或者比较长的字符串的时候,Redis要使用跳跃表来实现呢?** + +从上面我们知道,跳跃表就是在链表的基础上,增加了多级索引以提升查找的效率,其实就是一个空间换时间的方法,必然会带来一个问题 -- 索引是占内存的。 + +原始链表中存储的有可能是很大的对象,而索引节点只需要存储键值和几个指针,并不需要存储对象,因此当节点本身比较大或者元素数量比较多的时候,其优势必然会被放大,而缺点几乎可以忽略。 + +## Redis中跳跃表的实现 + +Redis的跳跃表由zSkipListNode和skipList两个结构定义,其中zSkipListNode结构用于表示跳跃表节点,而zSkipList结构则用于保存跳跃表节点的相关信息,比如节点的数量,以及指向表头节点和表尾节点的指针等等。 + +![image-20200626091014291](images/image-20200626091014291.png) + +上图展示了一个跳跃表的实例,其中最左边的是skipList结构,该结构包含以下属性 + +- header:指向跳跃表的表头节点,通过这个指针程序定位表头节点的时间复杂度就为O(1) +- tail:指向跳跃表的表尾节点,通过这个指针程序定位表尾节点的时间复杂度就为O(1) +- level:记录目前跳跃表内,层数最大的那个节点的层数(表头节点的层数不计算在内),通过这个属性可以再O(1)的时间复杂度内获取层高最好的节点的层数。 +- length:记录跳跃表的长度,也即是,跳跃表目前包含节点的数量(表头节点不计算在内),通过这个属性,程序可以再O(1)的时间复杂度内返回跳跃表的长度。 + +结构右方的是四个 zskiplistNode结构,该结构包含以下属性 + +- 层 + +节点中用L1、L2、L3等字样标记节点的各个层,L1代表第一层,L代表第二层,以此类推。 + +每个层都带有两个属性:前进指针和跨度。前进指针用于访问位于表尾方向的其他节点,而跨度则记录了前进指针所指向节点和当前节点的距离(跨度越大、距离越远)。在上图中,连线上带有数字的箭头就代表前进指针,而那个数字就是跨度。当程序从表头向表尾进行遍历时,访问会沿着层的前进指针进行。 + + 每次创建一个新跳跃表节点的时候,程序都根据幂次定律(powerlaw),越大的数出现的概率越小)随机生成一个介于1和32之间的值作为level数组的大小,这个大小就是层的“高度”。 + +- 后退(backward)指针 + +节点中用BW字样标记节点的后退指针,它指向位于当前节点的前一个节点。后退指针在程序从表尾向表头遍历时使用。与前进指针所不同的是每个节点只有一个后退指针,因此每次只能后退一个节点。 + +- 分值(score) + +各个节点中的1.0、2.0和3.0是节点所保存的分值。在跳跃表中,节点按各自所保存的分值从小到大排列。 + +- 成员对象(oj) + +各个节点中的o1、o2和o3是节点所保存的成员对象。在同一个跳跃表中,各个节点保存的成员对象必须是唯一的,但是多个节点保存的分值却可以是相同的:分值相同的节点将按照成员对象在字典序中的大小来进行排序,成员对象较小的节点会排在前面(靠近表头的方向),而成员对象较大的节点则会排在后面(靠近表尾的方向)。 + +![image-20200626092856081](images/image-20200626092856081.png) + +## 本文重点 + +- 跳跃表基于单链表加索引的方式实现 +- 跳跃表以空间换时间的方式提升了查找速度 +- Redis有序集合在节点元素较大或者元素数量较多时使用跳跃表实现 +- Redis的跳跃表实现由 zskiplist和 zskiplistnode两个结构组成,其中 zskiplist用于保存跳跃表信息(比如表头节点、表尾节点、长度),而zskiplistnode则用于表示跳跃表节点 +- Redis每个跳跃表节点的层高都是1至32之间的随机数 +- 在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是唯一的,跳跃表中的节点按照分值大小进行排序,当分值相同时,节点按照成员对象的大小进行排序。 + +## 来源 + +https://www.cnblogs.com/hunternet/p/11248192.html \ No newline at end of file diff --git "a/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626083207599.png" "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626083207599.png" new file mode 100644 index 0000000000000000000000000000000000000000..79a427d593d29cb2abdbd133901e88dfd7ef63d9 Binary files /dev/null and "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626083207599.png" differ diff --git "a/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626083217149.png" "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626083217149.png" new file mode 100644 index 0000000000000000000000000000000000000000..3246f9f11ab7854b9d54c2a03cac68ca7aec8330 Binary files /dev/null and "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626083217149.png" differ diff --git "a/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626084038222.png" "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626084038222.png" new file mode 100644 index 0000000000000000000000000000000000000000..1357f08a497d2f849d2f330e65b966934f7404e2 Binary files /dev/null and "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626084038222.png" differ diff --git "a/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626084148758.png" "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626084148758.png" new file mode 100644 index 0000000000000000000000000000000000000000..2689abdc23e59423522f1d29d560d21712df4ac0 Binary files /dev/null and "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626084148758.png" differ diff --git "a/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626091014291.png" "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626091014291.png" new file mode 100644 index 0000000000000000000000000000000000000000..36f5f63c5dc3333c7bddc7146f6698b59d5cf5db Binary files /dev/null and "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626091014291.png" differ diff --git "a/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626092856081.png" "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626092856081.png" new file mode 100644 index 0000000000000000000000000000000000000000..784c61775f09bbb42bc57291324dabb7ce18d2ac Binary files /dev/null and "b/Redis/Redis\344\270\255\347\232\204\350\267\263\350\267\203\350\241\250/images/image-20200626092856081.png" differ diff --git "a/Redis/Redis\345\256\236\347\216\260\345\210\206\345\270\203\345\274\217\351\224\201/README.md" "b/Redis/Redis\345\256\236\347\216\260\345\210\206\345\270\203\345\274\217\351\224\201/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..17984b1eb3be471e20d4021be656ff7e6f92aeb9 --- /dev/null +++ "b/Redis/Redis\345\256\236\347\216\260\345\210\206\345\270\203\345\274\217\351\224\201/README.md" @@ -0,0 +1,184 @@ +# Redis实现分布式锁 + +## 前言 + +分布式锁的实现有三种方式 + +- 数据库乐观锁 +- 基于Redis的分布式锁 +- 基于Zookeeper的分布式锁 + +## 分布式锁满足的条件 + +为了确保分布式锁可用,我们至少要保证锁的实现同时满足以下几个条件 + +- 互斥性:在任意时刻只有一个客户端能持有锁 +- 不会死锁:即使有一个客户端在持有锁的期间发生崩溃而没有主动解锁,也能保证后续其它客户端能加锁 +- 容错性:只要大部分的Redis节点正常运行,客户端就可以加锁和解锁 +- 解铃还须系铃人:加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解除 + +## 加锁代码 + +### 正确示例 + +Talk is cheap, show me the code。先展示代码,再带大家慢慢解释为什么这样实现: + +```java +public class RedisTool { + + private static final String LOCK_SUCCESS = "OK"; + private static final String SET_IF_NOT_EXIST = "NX"; + private static final String SET_WITH_EXPIRE_TIME = "PX"; + + /** + * 尝试获取分布式锁 + * @param jedis Redis客户端 + * @param lockKey 锁 + * @param requestId 请求标识 + * @param expireTime 超期时间 + * @return 是否获取成功 + */ + public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) { + + String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); + + if (LOCK_SUCCESS.equals(result)) { + return true; + } + return false; + } +} +``` + +可以看到,我们加锁就一行代码:`jedis.set(String key, String value, String nxxx, String expx, int time)`,这个set()方法一共有五个形参 + +- 第一个为key,我们使用key来当锁,因为key是唯一的。 +- 第二个为value,我们传的是requestId,很多童鞋可能不明白,有key作为锁不就够了吗,为什么还要用到value?原因就是我们在上面讲到可靠性时,分布式锁要满足第四个条件解铃还须系铃人,通过给value赋值为requestId,我们就知道这把锁是哪个请求加的了,在解锁的时候就可以有依据。requestId可以使用`UUID.randomUUID().toString()`方法生成。 +- 第三个为nxxx,这个参数我们填的是NX,意思是SET IF NOT EXIST,即当key不存在时,我们进行set操作;若key已经存在,则不做任何操作; +- 第四个为expx,这个参数我们传的是PX,意思是我们要给这个key加一个过期的设置,具体时间由第五个参数决定。 +- 第五个为time,与第四个参数相呼应,代表key的过期时间。 + +总的来说,执行上面的set()方法就只会导致两种结果:1. 当前没有锁(key不存在),那么就进行加锁操作,并对锁设置个有效期,同时value表示加锁的客户端。2. 已有锁存在,不做任何操作 + +心细的童鞋就会发现了,我们的加锁代码满足我们可靠性里描述的三个条件。首先,set()加入了NX参数,可以保证如果已有key存在,则函数不会调用成功,也就是只有一个客户端能持有锁,满足互斥性。其次,由于我们对锁设置了过期时间,即使锁的持有者后续发生崩溃而没有解锁,锁也会因为到了过期时间而自动解锁(即key被删除),不会发生死锁。最后,因为我们将value赋值为requestId,代表加锁的客户端请求标识,那么在客户端在解锁的时候就可以进行校验是否是同一个客户端。由于我们只考虑Redis单机部署的场景,所以容错性我们暂不考虑。 + +### 错误示例-1 + +比较常见的错误示例就是使用`jedis.setnx()`和`jedis.expire()`组合实现加锁,代码如下: + +```java +public static void wrongGetLock1(Jedis jedis, String lockKey, String requestId, int expireTime) { + + Long result = jedis.setnx(lockKey, requestId); + if (result == 1) { + // 若在这里程序突然崩溃,则无法设置过期时间,将发生死锁 + jedis.expire(lockKey, expireTime); + } +} +``` + +setnx()方法作用就是SET IF NOT EXIST,expire()方法就是给锁加一个过期时间。乍一看好像和前面的set()方法结果一样,然而由于这是两条Redis命令,不具有原子性,如果程序在执行完setnx()之后突然崩溃,导致锁没有设置过期时间。那么将会发生死锁。网上之所以有人这样实现,是因为低版本的jedis并不支持多参数的set()方法。 + +### 错误示例-2 + +```java +public static boolean wrongGetLock2(Jedis jedis, String lockKey, int expireTime) { + + long expires = System.currentTimeMillis() + expireTime; + String expiresStr = String.valueOf(expires); + + // 如果当前锁不存在,返回加锁成功 + if (jedis.setnx(lockKey, expiresStr) == 1) { + return true; + } + + // 如果锁存在,获取锁的过期时间 + String currentValueStr = jedis.get(lockKey); + if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) { + // 锁已过期,获取上一个锁的过期时间,并设置现在锁的过期时间 + String oldValueStr = jedis.getSet(lockKey, expiresStr); + if (oldValueStr != null && oldValueStr.equals(currentValueStr)) { + // 考虑多线程并发的情况,只有一个线程的设置值和当前值相同,它才有权利加锁 + return true; + } + } + // 其他情况,一律返回加锁失败 + return false; +} +``` + +这一种错误示例就比较难以发现问题,而且实现也比较复杂。实现思路:使用`jedis.setnx()`命令实现加锁,其中key是锁,value是锁的过期时间。执行过程:1. 通过setnx()方法尝试加锁,如果当前锁不存在,返回加锁成功。2. 如果锁已经存在则获取锁的过期时间,和当前时间比较,如果锁已经过期,则设置新的过期时间,返回加锁成功。 + +那么这段代码问题在哪里?1. 由于是客户端自己生成过期时间,所以需要强制要求分布式下每个客户端的时间必须同步。 2. 当锁过期的时候,如果多个客户端同时执行`jedis.getSet()`方法,那么虽然最终只有一个客户端可以加锁,但是这个客户端的锁的过期时间可能被其他客户端覆盖。3. 锁不具备拥有者标识,即任何客户端都可以解锁。 + +## 解锁代码 + +### 正确示例 + +还是先展示代码,再带大家慢慢解释为什么这样实现: + +```java +public class RedisTool { + + private static final Long RELEASE_SUCCESS = 1L; + + /** + * 释放分布式锁 + * @param jedis Redis客户端 + * @param lockKey 锁 + * @param requestId 请求标识 + * @return 是否释放成功 + */ + public static boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) { + + String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; + Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId)); + + if (RELEASE_SUCCESS.equals(result)) { + return true; + } + return false; + + } +} +``` + +可以看到,我们解锁只需要两行代码就搞定了!第一行代码,我们写了一个简单的Lua脚本代码,上一次见到这个编程语言还是在《黑客与画家》里,没想到这次居然用上了。第二行代码,我们将Lua代码传到`jedis.eval()`方法里,并使参数KEYS[1]赋值为lockKey,ARGV[1]赋值为requestId。eval()方法是将Lua代码交给Redis服务端执行。 + +那么这段Lua代码的功能是什么呢?其实很简单,首先获取锁对应的value值,检查是否与requestId相等,如果相等则删除锁(解锁)。那么为什么要使用Lua语言来实现呢?因为要确保上述操作是原子性的。关于非原子性会带来什么问题,可以阅读[【解锁代码-错误示例2】](http://wudashan.cn/2017/10/23/Redis-Distributed-Lock-Implement/#releaseLock-wrongDemo2) 。那么为什么执行eval()方法可以确保原子性? + +> 简单来说,就是在eval命令执行Lua代码的时候,Lua代码将被当成一个命令去执行,并且直到eval命令执行完成,Redis才会执行其他命令 + +### 错误示例1 + +最常见的解锁代码就是直接使用`jedis.del()`方法删除锁,这种不先判断锁的拥有者而直接解锁的方式,会导致任何客户端都可以随时进行解锁,即使这把锁不是它的。 + +```java +public static void wrongReleaseLock1(Jedis jedis, String lockKey) { + jedis.del(lockKey); +} +``` + +### 错误示例2 + +这种解锁代码乍一看也是没问题,甚至我之前也差点这样实现,与正确姿势差不多,唯一区别的是分成两条命令去执行,代码如下: + +```java +public static void wrongReleaseLock2(Jedis jedis, String lockKey, String requestId) { + + // 判断加锁与解锁是不是同一个客户端 + if (requestId.equals(jedis.get(lockKey))) { + // 若在此时,这把锁突然不是这个客户端的,则会误解锁 + // 也就是突然锁过期了,然后把别人的锁给干掉了 + jedis.del(lockKey); + } +} +``` + +如代码注释,问题在于如果调用`jedis.del()`方法的时候,这把锁已经不属于当前客户端的时候会解除他人加的锁。那么是否真的有这种场景?答案是肯定的,比如客户端A加锁,一段时间之后客户端A解锁,在执行`jedis.del()`之前,锁突然过期了,此时客户端B尝试加锁成功,然后客户端A再执行del()方法,则将客户端B的锁给解除了。 + +# 总结 + +本文主要介绍了如何使用Java代码正确实现Redis分布式锁,对于加锁和解锁也分别给出了两个比较经典的错误示例。其实想要通过Redis实现分布式锁并不难,只要保证能满足可靠性里的四个条件。互联网虽然给我们带来了方便,只要有问题就可以google,然而网上的答案一定是对的吗?其实不然,所以我们更应该时刻保持着质疑精神,多想多验证。 + +如果你的项目中Redis是多机部署的,那么可以尝试使用`Redisson`实现分布式锁,这是Redis官方提供的Java组件,链接在[参考阅读](http://wudashan.cn/2017/10/23/Redis-Distributed-Lock-Implement/#参考阅读)章节已经给出。 \ No newline at end of file diff --git "a/Redis/Redis\347\274\223\345\255\230\347\251\277\351\200\217-\345\270\203\351\232\206\350\277\207\346\273\244\345\231\250/README.md" "b/Redis/Redis\347\274\223\345\255\230\347\251\277\351\200\217-\345\270\203\351\232\206\350\277\207\346\273\244\345\231\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..c72e21cba65a9afb0a2d4d702fc1dca7cba370b0 --- /dev/null +++ "b/Redis/Redis\347\274\223\345\255\230\347\251\277\351\200\217-\345\270\203\351\232\206\350\277\207\346\273\244\345\231\250/README.md" @@ -0,0 +1,117 @@ +# Redis缓存穿透-布隆过滤器 + +## 缓存穿透 + +我举个蘑菇博客中的案例来说,我现在有一个博客详情页,然后博客详情页中的内容假设是存储在Redis中的,然后通过博客的Uid进行获取,正常的情况是:用户进入博客详情页,然后通过uid获取redis中缓存的文章详情,如果有内容就直接访问,如果不存在内容,那么需要访问数据库,然后从数据库中查询我们的博客详情后,然后在存储到redis中,最后在把数据返回给我们的页面。 + +但是可能存在一些非法用户,他可能会模拟出很多不存在的key,然后通过该key去请求后台,首先redis的缓存没有命中,那么就去请求数据库,最后数据库没有查询出该内容,这样很多个非法的请求直接打在数据库中,可能会导致数据库直接宕机,无法对外提供服务。这就是我们所说的缓存穿透问题 + +## 简单的解决方法 + +针对这个情况,我们有一种简单的解决方法就是,在数据库没有查询该条数据的时候,我们让该key缓存一个 空数据,这样用户再次以该key请求后台的时候,会直接返回null,避免了再次请求数据库。 + +## 布隆过滤器 + +### 什么是布隆过滤器? + +布隆过滤器的巨大作用 ,就是能够迅速判断一个元素是否存在一个集合中。因此次他有如下几个使用场景 + +- 网站爬虫对URL的去重,避免爬取相同的URL +- 反垃圾邮件,从数十亿个垃圾邮件列表中判断某邮箱是否是垃圾邮件(同理,垃圾短信) +- 缓存穿透,将所有可能的数据缓存放到布隆过滤器中,当黑客访问不存在的缓存时,迅速返回避免缓存以及DB挂掉。 + +### 原理 + +布隆过滤器其内部维护了一个全为0的bit数组,需要说明的是,布隆过滤器有一个误判的概念,误判率越低,则数组越长,所占空间越大。误判率越高则数组越小,所占的空间多少。 + +假设,根据误判率,我们生成一个10位的bit数组,以及2个hash函数 f1 和 f2,如下图所示:生成的数组的位数 和 hash函数的数量,我们不用去关心如何生成的,这是有数学论文进行验证。 + +![image-20200630082330207](images/image-20200630082330207.png) + +然后我们输入一个集合,集合中包含 N1 和 N2,我们通过计算 f1(N1) = 2,f2(N1) = 5,则将数组下标为2 和下标为5的位置设置成1,就得到了下图 + +![image-20200630082507698](images/image-20200630082507698.png) + +同理,我们再次进行计算 N2的值, f1(N2) = 3,f2(N2) = 6。得到如下所示的图 + +![image-20200630082643698](images/image-20200630082643698.png) + +这个时候,假设我们有第三个数N3过来了,我们需要判断N3是否在集合 [N1,N2]中,我们需要做的操作就是,使用f1 和 f2 计算出数组中的地址 + +- 若值恰巧都位于上图的红色位置,我们认为 N3在集合 [N1,N2] 中 +- 若值有一个不位于上图的红色部分,我们认为N3不在集合[N1,N2] 中 + +这就是布隆过滤器的计算原理 + +### 使用 + +在java中使用布隆过滤器,我们需要首先引入依赖,布隆过滤器拥有Google提供的一个开箱即用的组件,来帮助我们实现布隆过滤器,其实布隆过滤器的核心思想其实并不难,难的是在于如何设计随机映射函数,到底映射几次,二进制向量设置多少比较合适。 + +```xml + + + com.google.guava + guava + 22.0 + + +``` + +然后我们编写代码,测试某元素是否存在于百万元素集合中 + +```java + private static int size = 1000000;//预计要插入多少数据 + + private static double fpp = 0.01;//期望的误判率 + + private static BloomFilter bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, fpp); + + public static void main(String[] args) { + //插入数据 + for (int i = 0; i < 1000000; i++) { + bloomFilter.put(i); + } + int count = 0; + for (int i = 1000000; i < 2000000; i++) { + if (bloomFilter.mightContain(i)) { + count++; + System.out.println(i + "误判了"); + } + } + System.out.println("总共的误判数:" + count); + } +``` + +### 代码分析 + +上面的代码中,我们创建了一个布隆过滤器,其中有两个重要的参数,分别是我们要预计插入的数据和我们所期望的误判率,误判率率不能为0。 + +我们首先向布隆过滤器中插入 0 ~ 100万条数据,然后在用 100万 ~ 200万的数据进行测试 + +我们输出结果,查看一下误判率 + +``` +1999501误判了 +1999567误判了 +1999640误判了 +1999697误判了 +1999827误判了 +1999942误判了 +总共的误判数:10314 +``` + +现在有100万不存在的数据,误判了10314次,我们计算一下误判率 + +``` +10314 / 1000000 = 0.010314 +``` + +和我们之前定义的误判率为0.01相差无几 + +## 参考 + +https://www.cnblogs.com/rinack/p/9712477.html + +https://www.jianshu.com/p/2104d11ee0a2 + +https://www.cnblogs.com/CodeBear/p/10911177.html \ No newline at end of file diff --git "a/Redis/Redis\347\274\223\345\255\230\347\251\277\351\200\217-\345\270\203\351\232\206\350\277\207\346\273\244\345\231\250/images/image-20200630082330207.png" "b/Redis/Redis\347\274\223\345\255\230\347\251\277\351\200\217-\345\270\203\351\232\206\350\277\207\346\273\244\345\231\250/images/image-20200630082330207.png" new file mode 100644 index 0000000000000000000000000000000000000000..75c54221cca2a1eaacbee645742916295f683a01 Binary files /dev/null and "b/Redis/Redis\347\274\223\345\255\230\347\251\277\351\200\217-\345\270\203\351\232\206\350\277\207\346\273\244\345\231\250/images/image-20200630082330207.png" differ diff --git "a/Redis/Redis\347\274\223\345\255\230\347\251\277\351\200\217-\345\270\203\351\232\206\350\277\207\346\273\244\345\231\250/images/image-20200630082507698.png" "b/Redis/Redis\347\274\223\345\255\230\347\251\277\351\200\217-\345\270\203\351\232\206\350\277\207\346\273\244\345\231\250/images/image-20200630082507698.png" new file mode 100644 index 0000000000000000000000000000000000000000..d054f71abf92595569c932967c3a629e9057395b Binary files /dev/null and "b/Redis/Redis\347\274\223\345\255\230\347\251\277\351\200\217-\345\270\203\351\232\206\350\277\207\346\273\244\345\231\250/images/image-20200630082507698.png" differ diff --git "a/Redis/Redis\347\274\223\345\255\230\347\251\277\351\200\217-\345\270\203\351\232\206\350\277\207\346\273\244\345\231\250/images/image-20200630082643698.png" "b/Redis/Redis\347\274\223\345\255\230\347\251\277\351\200\217-\345\270\203\351\232\206\350\277\207\346\273\244\345\231\250/images/image-20200630082643698.png" new file mode 100644 index 0000000000000000000000000000000000000000..97536993b2b930e815665d0418c82ddf3d0364f9 Binary files /dev/null and "b/Redis/Redis\347\274\223\345\255\230\347\251\277\351\200\217-\345\270\203\351\232\206\350\277\207\346\273\244\345\231\250/images/image-20200630082643698.png" differ diff --git "a/Redis/\345\244\247\347\231\275\350\257\235\350\260\210IO\346\250\241\345\236\213/README.md" "b/Redis/\345\244\247\347\231\275\350\257\235\350\260\210IO\346\250\241\345\236\213/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..7c2ce88238b16d624be4996c2ae256d7f0382170 --- /dev/null +++ "b/Redis/\345\244\247\347\231\275\350\257\235\350\260\210IO\346\250\241\345\236\213/README.md" @@ -0,0 +1,151 @@ +# 通俗理解多种IO模型 + +## 前言 + +我们以故事来讲我们经常遇到的多种IO模型,首先故事的情节是 + +> 老李去买火车票,三天后买到一张退票,其中往返车站耗时1小时。 +> +> 里面主要包含的人员有:老李,黄牛,售票员,快递员 + + + +## 多种IO模型 + +### 阻塞IO模型 + +老李去火车站买票,排了三天队买到一张退票 + +> 耗费:在火车站等了三天,其它一件事都没做 + +### 非阻塞IO模型 + +老李去火车站买票,每隔12个小时去火车站问有没有退票,然后在三天后买到一张票。 + +> 耗费:往返车站6次,路上6小时,其它时间做了很多事 + +### IO复用模型 + +#### select 和 poll + +老李去火车站买票,委托黄牛,然后每个6小时打电话给黄牛咨询,黄牛在三天内买到票,然后老李去火车站交钱取票。 + +> 耗费:花费时间打电话17次,并往返火车站2次,黄牛手续费100元 + +#### epoll + +老李去火车站买票,委托黄牛,黄牛买到票后立即通知老李去领,然后老李去火车站交钱领取 + +> 耗费:无需打电话,但是还需要往返火车站2次,黄牛手续费100元 + +### 信号驱动IO模型 + +老李火车站买票,给售票员留下电话,有票后,售票员打电话通知老李,然后老李去火车站交钱领票 + +> 耗费:往返车站2次,路上2小时,不需要黄牛费,以及打电话 + +### 异步IO模型 + +老李去火车站买票,给售票员留下电话,有票后,售票员通知老李并快递送票上门 + +> 耗费:往返车站1次,无需黄牛费和电话费 + +### 总结 + +- 1和2的区别是:自己轮询 +- 2和3的区别是:委托黄牛 +- 3和4的区别是:电话代替黄牛 +- 4和5的区别是:电话通知还是送票上门 + +## Linux操作系统中的基础概念 + +在介绍select、poll、epoll之前,我们首先了解一下linux的基础概念 + +### 用户空间/内核空间 + +现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2^32) + +而操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核(Kernel),保证内核的安全,操作系统将虚拟空间划分为两部分,一部分是内核空间,一部分是用户空间 + +### 进程切换 + +为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行。这种行为被称为进程切换。因此可以说,任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的,并且经常切换是非常耗费资源的。 + +### 进程阻塞 + +正在执行的进程,由于期待的某些事情未发生,如请求系统资源失败、等待某种操作的完成、新数据尚未到达或无新工作做等,则由系统自动执行阻塞原语(Block),使自己由运行状态变成阻塞状态。可见进程的阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得了CPU资源),才可以将其转换为阻塞状态,当进程进入阻塞状态,是不占用CPU资源的。 + +### 文件描述符 + +文件描述符(File Descriptor)是计算机科学中的一个术语,是用一个表述指向文件的引用的抽象化概念。 + +文件描述符在形式上是一个非负函数。实际上,它是一个索引,指向内核中每一个进程所维护的该进程打开文件的记录表,当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念只适用于Unix和Linux这样的操作系统。 + +### 缓存IO + +缓存IO又称为标准IO,大多数文件系统的默认IO操作都是缓存IO,在Linux的缓存IO机制中,操作系统会将IO的数据缓存在文件系统的页缓存中,即数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核缓冲区拷贝到应用程序的内存地址。 + +## IO多路复用 + +如果一个IO流进来,我们就开启一个进程处理这个IO流,那么假设现在有100万个IO流进来,那我们就需要开启100万个进程去处理这些IO流了(这就是传统意义上的多进程并发处理)。思考一下,一百万个进程,你的CPU占有率会多高,这种实现方式极其不合理。所以我们提出了IO多路复用模型,一个线程,通过记录IO流的状态来同时管理多个IO,可以提高服务器的吞吐能力。 + +![img](images/11319096-c3fd7c0bf3904dfa.webp) + +我们通过分析一下上面的这张图 + +- 当进程调用select,进程就会被阻塞 +- 此时内核会监视所有select负责的socket,当socket的数据准备好后,就立即返回 +- 进程再调用read操作,数据就会从内核拷贝到进程 + +而多路复用的实现有多种方式,select,poll,epoll + +### select + +#### 概念 + +select() 的机制中提供一种fd_set的数据结构,实际上是一个long类型的数组,每一个数组元素都能与一打开的文件句柄(不管是Sokect句柄,还是其它文件、命名管道、设备句柄)建立联系,建立联系的工作由程序员完成,当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执行了select()的进程哪一Socket或文件可读。 + +从流程上来看,使用Select函数进行IO请求时 和 同步阻塞模型 没有太大的区别,甚至还多了添加监视Socket,以及调用select函数的额外操作,效率更差。但是使用select以后最大的优势是用户可以通过在同一个线程内同时处理多个socket的IO请求,用户可以注册多个Socket,然后不断地调用select读取被激活的socket,即可达到在同一线程内同时处理多个IO请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。 + +#### select机制存在的问题 + +- 每次调用select,都需要把fd_set集合从用户态拷贝到内核态,如果fd_set集合很大时,那这个开销也会很大 +- 同时每次调用select都需要在内核遍历所有传递过来的fd_set,如果fd_set很大时,那这个开销也很大 +- 为了减少数据拷贝带来的性能破坏,内核对监控的fd_set集合大小做了限制,并且这个是通过宏控制的,大小不可改变(限制为1024) + +### Poll + +Poll的机制和Select类似,与Select在本质上没有多大的差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数量的限制,也就是说,poll只是解决了上面说的第三个问题,并没有解决问题1和问题2 + +### Epoll + +epoll在Linux2.6内核正式提出,是基于事件驱动的IO方式,相对于Select来说,epoll没有描述符个数限制,使用一个文件描述符管理多个描述符,将用户关心的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。 + +epoll是Linux内核为大批量文件描述符而做了改进的poll,是Linux下多路复用IO接口select、poll的增强版本,它能显著的提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。原因就是获取事件的时候,它无需遍历整个被监听的描述符集,只需要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了 + +- 水平触发:默认工作模式,即当epoll_wait检测到某描述符事件就绪并通知应用程序时,应用程序可以不立即处理该事件,下次调用epoll_wait时,会再次通知此事件 +- 边缘触发:当epoll_wait检测到某描述符事件就绪并通知应用程序时,应用程序必须立即处理该事件,如果不处理,下次调用epoll_wait时,不会再次通知此事件。(直到你做了某些操作导致该描述符变成未就绪状态,也就是说边缘触发只在状态由未就绪变成就绪时只通知一次) + +## 总结 + +一个epoll场景:一个酒吧服务员(一个线程),前面趴了一群醉汉,突然一个吼一声“倒酒”(事件),你小跑过去给他倒一杯,然后随他去吧,突然又一个要倒酒,你又过去倒上,就这样一个服务员服务好多人,有时没人喝酒,服务员处于空闲状态,可以干点别的玩玩手机。 + +至于epoll与select,poll的区别在于后两者的场景中醉汉不说话,你要挨个问要不要酒,没时间玩手机了。io多路复用大概就是指这几个醉汉共用一个服务员。 + +我们使用一张图来总结select、poll、epoll的区别 + +| | select | poll | epoll | +| ---------- | -------------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------ | +| 操作方式 | 遍历 | 遍历 | 回调 | +| 底层实现 | 数组 | 链表 | 哈希表 | +| IO效率 | 每次调用都进行线性遍历,时间复杂度为O(n) | 每次调用都进行线性遍历,时间复杂度为O(n) | 事件通知方式,每当fd就绪,系统注册的回调函数就会被调用,将就绪fd放到readyList里面,时间复杂度为O(1) | +| 最大连接数 | 1024或2048 | 无上限 | 无上限 | +| fd拷贝 | 每次调用select,都需要把fd集合从用户态拷贝到内核态 | 每次调用poll,都需要把fd集合从用户态拷贝到内核态 | 调用epoll_ctl时,拷贝进内核并保存,之后每次epoll_wait不拷贝 | + +select和poll即使只有一个描述符就绪,也要遍历整个集合。如果集合中活跃的描述符很少,遍历过程的开销就会变得很大,而如果集合中大部分的描述符都是活跃的,遍历过程的开销又可以忽略。 + +epoll的实现每次只遍历活跃的描述符(如果是水平触发,也会遍历先前活跃的描述符),在活跃描述符较少的情况下,就会很有优势,在代码的分析过程中,可以看到epoll的实现过于复杂并且实现过程中需要同步处理(锁),如果大部分描述符都是活跃的,epoll的效率可能不如select 或者 poll + +内核将就绪的文件描述符放在传入的就绪队列中,所以只用遍历依次处理即可。这里返回的文件描述符是通过mmap让内核和用户空间共享同一块内存实现传递的,减少了不必要的拷贝。 + +epoll是Linux目前大规模网络并发程序开发的首选模型,在绝大数情况下,性能远远超过select 和 poll。目前流行的高性能web服务器Nginx 正式依赖于epoll提供的高效网络套接字轮询服务,但是在并发连接不高的情况下,多线程 + 阻塞IO的方式可能会更好。 \ No newline at end of file diff --git "a/Redis/\345\244\247\347\231\275\350\257\235\350\260\210IO\346\250\241\345\236\213/images/11319096-c3fd7c0bf3904dfa.webp" "b/Redis/\345\244\247\347\231\275\350\257\235\350\260\210IO\346\250\241\345\236\213/images/11319096-c3fd7c0bf3904dfa.webp" new file mode 100644 index 0000000000000000000000000000000000000000..9c297907e68a0d208d93953c7d430d62c5af2cb3 Binary files /dev/null and "b/Redis/\345\244\247\347\231\275\350\257\235\350\260\210IO\346\250\241\345\236\213/images/11319096-c3fd7c0bf3904dfa.webp" differ diff --git "a/SpringBoot/Bean\347\232\204\347\224\237\345\221\275\345\221\250\346\234\237/README.md" "b/SpringBoot/Bean\347\232\204\347\224\237\345\221\275\345\221\250\346\234\237/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..84c8e3fa97d8f018c8e45cf56e0191bb5ab63217 --- /dev/null +++ "b/SpringBoot/Bean\347\232\204\347\224\237\345\221\275\345\221\250\346\234\237/README.md" @@ -0,0 +1,247 @@ +# Bean的生命周期 + +## 前言 + +在我们没有使用Spring框架之前,创建对象一般都是使用new关键字进行创建,当然除了new关键字外,还有 + +- 运用反射手段,使用Class类的newInstance方法 或者 Constructor类中的newInstance方法 +- 使用clone方法 +- 使用反序列化(ObjectInputStream) + +一旦对象不再被使用的时候,将有可能被JVM垃圾回收器进行回收。 + +但是在Spring通过IOC容器进行管理之后,Bean 的生命周期就变得更加复杂了,下图展示了Bean的构造过程 + +![image-20200614155732584](images/image-20200614155732584.png) + +## Bean的生命周期 + +我们对上图的每个步骤进行文字说明 + +- Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化 +- Bean实例化后对将Bean的引入和值注入到Bean的属性中 +- 如果Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法 +- 如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入 +- 如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。 +- 如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。 +- 如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用 +- 如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法。 +- 此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁。 +- 如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用。 + +## 接口方法的分类 + + Bean的完整生命周期经历了各种方法的调用,这些方法可以分类一下三类 + +### Bean自身的方法: + +这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法 + +### Bean级生命周期的方法 + +这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法 + +### 容器级生命周期的方法 + +这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。 + +### 工程后处理器接口方法 + +这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器  接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。 + +## DEMO举例 + +我们用一个简单的Spring Bean来演示一下Spring Bean的生命周期。 + +首先是一个简单的Spring Bean,调用Bean自身的方法和Bean级生命周期接口方法,为了方便演示,它实现了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这4个接口,同时有2个方法,对应配置文件中的init-method和destroy-method。如下: + +``` +package springBeanTest; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; + +public class Person implements BeanFactoryAware, BeanNameAware, + InitializingBean, DisposableBean { + + private String name; + private String address; + private int phone; + + private BeanFactory beanFactory; + private String beanName; + + public Person() { + System.out.println("【构造器】调用Person的构造器实例化"); + } + + public String getName() { + return name; + } + + public void setName(String name) { + System.out.println("【注入属性】注入属性name"); + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + System.out.println("【注入属性】注入属性address"); + this.address = address; + } + + public int getPhone() { + return phone; + } + + public void setPhone(int phone) { + System.out.println("【注入属性】注入属性phone"); + this.phone = phone; + } + + @Override + public String toString() { + return "Person [address=" + address + ", name=" + name + ", phone=" + + phone + "]"; + } + + // 这是BeanFactoryAware接口方法 + @Override + public void setBeanFactory(BeanFactory arg0) throws BeansException { + System.out + .println("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()"); + this.beanFactory = arg0; + } + + // 这是BeanNameAware接口方法 + @Override + public void setBeanName(String arg0) { + System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()"); + this.beanName = arg0; + } + + // 这是InitializingBean接口方法 + @Override + public void afterPropertiesSet() throws Exception { + System.out + .println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()"); + } + + // 这是DiposibleBean接口方法 + @Override + public void destroy() throws Exception { + System.out.println("【DiposibleBean接口】调用DiposibleBean.destory()"); + } + + // 通过的init-method属性指定的初始化方法 + public void myInit() { + System.out.println("【init-method】调用的init-method属性指定的初始化方法"); + } + + // 通过的destroy-method属性指定的初始化方法 + public void myDestory() { + System.out.println("【destroy-method】调用的destroy-method属性指定的初始化方法"); + } +} +``` + +接下来是演示BeanPostProcessor接口的方法,如下: + +``` +package springBeanTest; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; + +public class MyBeanPostProcessor implements BeanPostProcessor { + + public MyBeanPostProcessor() { + super(); + System.out.println("这是BeanPostProcessor实现类构造器!!"); + // TODO Auto-generated constructor stub + } + + @Override + public Object postProcessAfterInitialization(Object arg0, String arg1) + throws BeansException { + System.out + .println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!"); + return arg0; + } + + @Override + public Object postProcessBeforeInitialization(Object arg0, String arg1) + throws BeansException { + System.out + .println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!"); + return arg0; + } +} +``` + +如上,BeanPostProcessor接口包括2个方法postProcessAfterInitialization和postProcessBeforeInitialization,这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。返回值也都是要处理的Bean对象。这里要注意。 + +InstantiationAwareBeanPostProcessor 接口本质是BeanPostProcessor的子接口,一般我们继承Spring为其提供的适配器类InstantiationAwareBeanPostProcessor Adapter来使用它,如下: + +``` +package springBeanTest; + +import java.beans.PropertyDescriptor; + +import org.springframework.beans.BeansException; +import org.springframework.beans.PropertyValues; +import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; + +public class MyInstantiationAwareBeanPostProcessor extends + InstantiationAwareBeanPostProcessorAdapter { + + public MyInstantiationAwareBeanPostProcessor() { + super(); + System.out + .println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!"); + } + + // 接口方法、实例化Bean之前调用 + @Override + public Object postProcessBeforeInstantiation(Class beanClass, + String beanName) throws BeansException { + System.out + .println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法"); + return null; + } + + // 接口方法、实例化Bean之后调用 + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + System.out + .println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法"); + return bean; + } + + // 接口方法、设置某个属性时调用 + @Override + public PropertyValues postProcessPropertyValues(PropertyValues pvs, + PropertyDescriptor[] pds, Object bean, String beanName) + throws BeansException { + System.out + .println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法"); + return pvs; + } +} +``` + + + +## 参考 + +https://www.cnblogs.com/zrtqsk/p/3735273.html + +https://www.cnblogs.com/javazhiyin/p/10905294.html \ No newline at end of file diff --git "a/SpringBoot/Bean\347\232\204\347\224\237\345\221\275\345\221\250\346\234\237/images/image-20200614155732584.png" "b/SpringBoot/Bean\347\232\204\347\224\237\345\221\275\345\221\250\346\234\237/images/image-20200614155732584.png" new file mode 100644 index 0000000000000000000000000000000000000000..81b5e1d2247d05f7fa72074603df1ff161ec5f55 Binary files /dev/null and "b/SpringBoot/Bean\347\232\204\347\224\237\345\221\275\345\221\250\346\234\237/images/image-20200614155732584.png" differ diff --git "a/SpringBoot/SpringBoot\346\213\246\346\210\252\345\231\250\346\227\240\346\263\225\346\263\250\345\205\245Bean/README.md" "b/SpringBoot/SpringBoot\346\213\246\346\210\252\345\231\250\346\227\240\346\263\225\346\263\250\345\205\245Bean/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..3d19d3b47d2c9a372b1b1acf9f45dec58daaade6 --- /dev/null +++ "b/SpringBoot/SpringBoot\346\213\246\346\210\252\345\231\250\346\227\240\346\263\225\346\263\250\345\205\245Bean/README.md" @@ -0,0 +1,100 @@ +# SpringBoot拦截器无法注入Bean + +## 前言 + +今天在给mogu_picture模块添加拦截器,用于拦截用户传递过来的token,并获取到用户信息,这里需要注入RedisUtil工具类 + +```java +@Autowrite +RedisUtil redisUtil; +``` + +但是我在使用的时候,一直报空指针异常,开始以为是代码有问题,后面经过排查是因为没有注入RedisUtil。 + +首先我们先了解 @Autowired的原理,.当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor (继承InstantiationAwareBeanPostProcessorAdapter)将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有@Autowired 注解时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。那为什么这里的注解没有生效呢? + +注册拦截器时直接通过new LoggerInterceptor(),并没有触发Spring去管理bean,所以@Autowired没有生效,如下所示,我们的拦截器是通过new TokenInterceptor(),进行创建的,并没有触发Spring去管理Bean + +``` +/** + * @author: 陌溪 + * @create: 2020-06-14-21:55 + */ +@Configuration +public class InterceptorConfig implements WebMvcConfigurer { + + /** + * 注册自定义拦截器 + */ + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new TokenInterceptor()).addPathPatterns("/**"); + } +} +``` + +## 解决办法 + +我们可以通过ApplicationContent容器去获取到我们需要的bean,这里提供一个Spring工具类 + +``` +package com.moxi.mogublog.utils; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.servlet.LocaleResolver; + +import javax.servlet.http.HttpServletRequest; +import java.util.Locale; + +/** + * SpringUtils + * + * @author: 陌溪 + * @create: 2020-03-05-9:30 + */ +@Component +public class SpringUtils implements ApplicationContextAware { + private static ApplicationContext applicationContext; + + public static T getBean(Class tClass) { + return applicationContext.getBean(tClass); + } + + public static T getBean(String name, Class type) { + return applicationContext.getBean(name, type); + } + + public static HttpServletRequest getCurrentReq() { + ServletRequestAttributes requestAttrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (requestAttrs == null) { + return null; + } + return requestAttrs.getRequest(); + } + + public static String getMessage(String code, Object... args) { + LocaleResolver localeResolver = getBean(LocaleResolver.class); + Locale locale = localeResolver.resolveLocale(getCurrentReq()); + return applicationContext.getMessage(code, args, locale); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringUtils.applicationContext = applicationContext; + } +} +``` + +然后在具体的拦截器中,我们就可以直接获取到我们之前想要注入的bean,例如我这里获取RedisUtil + +``` +RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class); +``` + + + diff --git "a/SpringBoot/SpringBoot\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250\345\255\227\347\254\246\344\270\262\345\215\240\344\275\215\347\254\246/README.md" "b/SpringBoot/SpringBoot\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250\345\255\227\347\254\246\344\270\262\345\215\240\344\275\215\347\254\246/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..925106780482ff7f138087e9a1633af3ca29a7f5 --- /dev/null +++ "b/SpringBoot/SpringBoot\351\241\271\347\233\256\344\270\255\344\275\277\347\224\250\345\255\227\347\254\246\344\270\262\345\215\240\344\275\215\347\254\246/README.md" @@ -0,0 +1,29 @@ +前言 +-- + +前阵子群里很多小伙伴在咨询,怎么更改蘑菇博客项目的版权这部分代码 + +![](http://image.moguit.cn/822593737ee24ab497e5b911bd0241bd) + +因为最开始为了偷懒,就直接写死在了代码里面,后面发现如果要更改的话,得找到对应的代码,一般在找对应的接口的时候,还是比较麻烦的 + +因此就想着将它单独写在application.yml的配置文件中,然后使用java占位符的方式填充我们需要的更改的地方 + + #博客相关配置 + BLOG: + + # 原创模板 + ORIGINAL_TEMPLATE: 本文为蘑菇博客原创文章,转载无需和我联系,但请注明来自蘑菇博客 http://www.moguit.cn + # 转载模板 + REPRINTED_TEMPLATE: 本着开源共享、共同学习的精神,本文转载自 %S ,版权归 %S 所有,如果侵权之处,请联系博主进行删除,谢谢~ + +然后到后端,我们就需要进行替换了 + + String reprintedTemplate = REPRINTED_TEMPLATE; + String [] variable = {blog.getArticlesPart(), blog.getAuthor()}; + String str = String.format(reprintedTemplate, variable); + blog.setCopyright(str); + +这里使用了String.format,里面有两个参数,一个是给定的模板,另一个参数就是我们需要替换的列表 + +他会找到对应的占位符,然后将数组中的变量进行逐个替换我们之前模板中的占位符%s \ No newline at end of file diff --git "a/SpringBoot/Spring Security\351\200\240\346\210\220\346\227\240\346\263\225\344\275\277\347\224\250iframe\347\232\204\345\206\205\345\265\214\351\241\265\351\235\242\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/README.md" "b/SpringBoot/SpringSecurity\351\200\240\346\210\220\346\227\240\346\263\225\344\275\277\347\224\250iframe\347\232\204\345\206\205\345\265\214\351\241\265\351\235\242\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/README.md" similarity index 100% rename from "SpringBoot/Spring Security\351\200\240\346\210\220\346\227\240\346\263\225\344\275\277\347\224\250iframe\347\232\204\345\206\205\345\265\214\351\241\265\351\235\242\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/README.md" rename to "SpringBoot/SpringSecurity\351\200\240\346\210\220\346\227\240\346\263\225\344\275\277\347\224\250iframe\347\232\204\345\206\205\345\265\214\351\241\265\351\235\242\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/README.md" diff --git "a/SpringBoot/Spring Security\351\200\240\346\210\220\346\227\240\346\263\225\344\275\277\347\224\250iframe\347\232\204\345\206\205\345\265\214\351\241\265\351\235\242\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/images/image-20200106095854704.png" "b/SpringBoot/SpringSecurity\351\200\240\346\210\220\346\227\240\346\263\225\344\275\277\347\224\250iframe\347\232\204\345\206\205\345\265\214\351\241\265\351\235\242\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/images/image-20200106095854704.png" similarity index 100% rename from "SpringBoot/Spring Security\351\200\240\346\210\220\346\227\240\346\263\225\344\275\277\347\224\250iframe\347\232\204\345\206\205\345\265\214\351\241\265\351\235\242\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/images/image-20200106095854704.png" rename to "SpringBoot/SpringSecurity\351\200\240\346\210\220\346\227\240\346\263\225\344\275\277\347\224\250iframe\347\232\204\345\206\205\345\265\214\351\241\265\351\235\242\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/images/image-20200106095854704.png" diff --git "a/SpringBoot/Spring Security\351\200\240\346\210\220\346\227\240\346\263\225\344\275\277\347\224\250iframe\347\232\204\345\206\205\345\265\214\351\241\265\351\235\242\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/images/image-20200106101231543.png" "b/SpringBoot/SpringSecurity\351\200\240\346\210\220\346\227\240\346\263\225\344\275\277\347\224\250iframe\347\232\204\345\206\205\345\265\214\351\241\265\351\235\242\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/images/image-20200106101231543.png" similarity index 100% rename from "SpringBoot/Spring Security\351\200\240\346\210\220\346\227\240\346\263\225\344\275\277\347\224\250iframe\347\232\204\345\206\205\345\265\214\351\241\265\351\235\242\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/images/image-20200106101231543.png" rename to "SpringBoot/SpringSecurity\351\200\240\346\210\220\346\227\240\346\263\225\344\275\277\347\224\250iframe\347\232\204\345\206\205\345\265\214\351\241\265\351\235\242\347\232\204\350\247\243\345\206\263\346\226\271\346\263\225/images/image-20200106101231543.png" diff --git "a/SpringBoot/Swagger-ui.html\351\241\265\351\235\242\345\207\272\347\216\260404/README.md" "b/SpringBoot/Swagger-ui.html\351\241\265\351\235\242\345\207\272\347\216\260404/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..035ffe74de9d75d2ee57080b66ff9c6a0c8a33a0 --- /dev/null +++ "b/SpringBoot/Swagger-ui.html\351\241\265\351\235\242\345\207\272\347\216\260404/README.md" @@ -0,0 +1,86 @@ +# Swagger-ui.html页面出现404 + +## 前言 + +首先感谢群里小伙伴@Major_Tom的反馈,今天排查了一下mogu_picture的 swagger-ui.html页面打不开了,显示的是404。因为 swagger-ui的引入比较简单,所以我先排查了一下依赖和配置,以及对应方法上的注解,都是正常的,并且同样的配置在mogu_web和mogu_admin项目是正常的,所以非常好奇问题出来哪里? + +## 排查过程 + +首先排除的是配置的问题,因为原来mogu_picture是能够正常使用的,但是这阵子因为加了一些新功能,所以引入了拦截器。 + +我们通过查看mogu_picture的日志记录,能够看到下面的信息 + +```bash +No mapping found for HTTP request with URI [/swagger-ui.html] in DispatcherServlet with name 'dispatcherServlet' +``` + +这个错误其实很明显,就是没有 /swagger-ui.html 的映射 + +对于一个正常的接口类来说,例如我们在Controller类中,只需要配置了RequestMapper("/user/getInfo"),那么我们请求 /user/info 就能够直接调用,而上面这段信息告诉我们,就是没有RequestMapper这个东西,但是因为Swagger-ui是属于静态资源,那么原本也会有对应的静态资源映射的处理机制。 + +突然想起来,之前引入了拦截器,主要就是为了登录拦截的功能 + +```java +/** + * @author: 陌溪 + * @create: 2020-06-14-21:55 + */ +@Configuration +public class InterceptorConfig implements WebMvcConfigurer { + + /** + * 注册自定义拦截器 + */ + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new TokenInterceptor()).addPathPatterns("/**"); + } +} + +``` + +会不会是因为上面的代码把我们的静态资源给拦截了呢? + +首先我们可以知道的是,注册的动作最终还是由实现了`WebMvcConfigurer`接口的实例来实现的,这些实例当中肯定有注册资源处理器的,现在的项目中肯定就是缺少这个实例。 + +通过查看 `WebMvcConfigurer` 的实现,发现了`WebMvcAutoConfigurationAdapter`,这是springboot里的自动装配,而且它有`addResourceHandlers`的实现,可能需要它,那接下来就要看这个自动装配为啥没有生效了 + +来看看生效的条件,因为WebMvcAutoConfigurationAdapter是一个嵌套的配置,所以看它的依附类WebMvcAutoConfiguration的一个条件:@ConditionalOnMissingBean(WebMvcConfigurationSupport.class),可能就是WebMvcConfigurationSupport的实例存在,才导致自动装配失效。 + +也就是说,因为通过引入了 `WebMvcConfigurer` 可能就造成了原来SpringBoot中无法自动装配静态资源映射了,那么就需要我们在原来的基础上,手动进行添加 + +```java +/** + * @author: 陌溪 + * @create: 2020-06-14-21:55 + */ +@Configuration +public class InterceptorConfig implements WebMvcConfigurer { + + /** + * 注册自定义拦截器 + */ + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new TokenInterceptor()).addPathPatterns("/**"); + } + + /** + * 注册资源映射 + * @param registry + */ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/**").addResourceLocations( + "classpath:/static/"); + registry.addResourceHandler("swagger-ui.html").addResourceLocations( + "classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**").addResourceLocations( + "classpath:/META-INF/resources/webjars/"); + } +} +``` + +我们在原来的配置类中,重写静态资源映射的代码,然后重启项目,发现Swagger-ui项目能够正常访问了~ + +![image-20200704092918177](images/image-20200704092918177.png) \ No newline at end of file diff --git "a/SpringBoot/Swagger-ui.html\351\241\265\351\235\242\345\207\272\347\216\260404/images/image-20200704092918177.png" "b/SpringBoot/Swagger-ui.html\351\241\265\351\235\242\345\207\272\347\216\260404/images/image-20200704092918177.png" new file mode 100644 index 0000000000000000000000000000000000000000..a6986ad5d5d43e7e69ca1a5c38c9cb6692cf1660 Binary files /dev/null and "b/SpringBoot/Swagger-ui.html\351\241\265\351\235\242\345\207\272\347\216\260404/images/image-20200704092918177.png" differ diff --git "a/SpringBoot/\344\275\277\347\224\250\350\207\252\345\256\232\344\271\211\346\227\245\345\277\227\346\216\245\345\217\243\346\224\266\351\233\206\347\224\250\346\210\267\350\256\277\351\227\256\346\227\245\345\277\227/README.md" "b/SpringBoot/\344\275\277\347\224\250\350\207\252\345\256\232\344\271\211\346\227\245\345\277\227\346\216\245\345\217\243\346\224\266\351\233\206\347\224\250\346\210\267\350\256\277\351\227\256\346\227\245\345\277\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..d71a070fd1c140229135cc811738cc197a91d94f --- /dev/null +++ "b/SpringBoot/\344\275\277\347\224\250\350\207\252\345\256\232\344\271\211\346\227\245\345\277\227\346\216\245\345\217\243\346\224\266\351\233\206\347\224\250\346\210\267\350\256\277\351\227\256\346\227\245\345\277\227/README.md" @@ -0,0 +1,533 @@ +前言 +-- + +最开始蘑菇博客收集用户访问日志,是直接在请求接口里面进行编写的,比如像下面这样 + +![](http://image.moguit.cn/f3b9e96ea8334a9ea534c9b61aa7bee8) + +很显然这种方法是非常笨的一种方法,因为它直接侵入了我们的业务代码,引入无关的操作,因此这次主要就是通过spring aop + 自定义接口,来收集用户的访问日志 + +编写自定义接口 +------- + +首先我们需要创建一个自定义接口 + + package com.moxi.mogublog.web.log; + + import com.moxi.mougblog.base.enums.EBehavior; + import com.moxi.mougblog.base.enums.PlatformEnum; + + import java.lang.annotation.ElementType; + import java.lang.annotation.Retention; + import java.lang.annotation.RetentionPolicy; + import java.lang.annotation.Target; + + /** + * 日志记录、自定义注解 + * + * @author 陌溪 + * @date 2020年2月27日08:55:02 + */ + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface BussinessLog { + + /** + * 业务名称 + * + * @return + */ + String value() default ""; + + /** + * 用户行为 + * + * @return + */ + EBehavior behavior(); + + /** + * 平台,默认为WEB端 + */ + PlatformEnum platform() default PlatformEnum.WEB; + + /** + * 是否将当前日志记录到数据库中 + */ + boolean save() default true; + } + +这里的用户行为使用了枚举类,方便扩展,目前共有15中行为 + + package com.moxi.mougblog.base.enums; + + import com.moxi.mogublog.utils.JsonUtils; + import com.moxi.mougblog.base.global.BaseSysConf; + + import java.util.HashMap; + import java.util.Map; + + public enum EBehavior { + + BLOG_TAG("点击标签", "blog_tag"), + BLOG_SORT("点击博客分类", "blog_sort"), + BLOG_CONTNET("点击博客", "blog_content"), + BLOG_PRAISE("点赞", "blog_praise"), + FRIENDSHIP_LINK("点击友情链接", "friendship_link"), + BLOG_SEARCH("点击搜索", "blog_search"), + STUDY_VIDEO("点击学习视频", "study_video"), + VISIT_PAGE("访问页面", "visit_page"), + VISIT_SORT("点击归档", "visit_sort"), + BLOG_AUTHOR("点击作者", "blog_author"), + PUBLISH_COMMENT("发表评论", "publish_comment"), + DELETE_COMMENT("删除评论", "delete_comment"), + REPORT_COMMENT("举报评论", "report_comment"), + VISIT_CLASSIFY("点击分类", "visit_classify"); + + + private String content; + private String behavior; + + private EBehavior(String content, String behavior) { + this.content = content; + this.behavior = behavior; + } + + /** + * 根据value返回枚举类型,主要在switch中使用 + * @param value + * @return + */ + public static EBehavior getByValue(String value) { + for(EBehavior behavior: values()) { + if(behavior.getBehavior() == value) { + return behavior; + } + } + return null; + } + + public static Map getModuleAndOtherData(EBehavior behavior, Map nameAndArgsMap, String bussinessName) { + String otherData = ""; + String moduleUid = ""; + switch (behavior) { + case BLOG_AUTHOR: { + // 判断是否是点击作者 + if(nameAndArgsMap.get(BaseSysConf.AUTHOR) != null) { + otherData = nameAndArgsMap.get(BaseSysConf.AUTHOR).toString(); + } + };break; + case BLOG_SORT: { + // 判断是否点击博客分类 + if(nameAndArgsMap.get(BaseSysConf.BLOG_SORT_UID) != null) { + moduleUid = nameAndArgsMap.get(BaseSysConf.BLOG_SORT_UID).toString(); + } + };break; + case BLOG_TAG: { + // 判断是否点击博客标签 + if(nameAndArgsMap.get(BaseSysConf.TAG_UID) != null) { + moduleUid = nameAndArgsMap.get(BaseSysConf.TAG_UID).toString(); + } + };break; + case BLOG_SEARCH: { + // 判断是否进行搜索 + if(nameAndArgsMap.get(BaseSysConf.KEYWORDS) != null) { + otherData = nameAndArgsMap.get(BaseSysConf.KEYWORDS).toString(); + } + };break; + case VISIT_CLASSIFY: { + // 判断是否点击分类 + if(nameAndArgsMap.get(BaseSysConf.BLOG_SORT_UID) != null) { + moduleUid = nameAndArgsMap.get(BaseSysConf.BLOG_SORT_UID).toString(); + } + };break; + case VISIT_SORT: { + // 判断是否点击归档 + if(nameAndArgsMap.get(BaseSysConf.MONTH_DATE) != null) { + otherData = nameAndArgsMap.get(BaseSysConf.MONTH_DATE).toString(); + } + };break; + case BLOG_CONTNET: { + // 判断是否博客详情 + if(nameAndArgsMap.get(BaseSysConf.UID) != null) { + moduleUid = nameAndArgsMap.get(BaseSysConf.UID).toString(); + } + };break; + case BLOG_PRAISE: { + // 判断是否给博客点赞 + if(nameAndArgsMap.get(BaseSysConf.UID) != null) { + moduleUid = nameAndArgsMap.get(BaseSysConf.UID).toString(); + } + };break; + case VISIT_PAGE: { + // 访问页面 + otherData = bussinessName; + };break; + case PUBLISH_COMMENT: { + Object object = nameAndArgsMap.get(BaseSysConf.COMMENT_VO); + Map map = JsonUtils.objectToMap(object); + if(map.get(BaseSysConf.CONTENT) != null) { + otherData = map.get(BaseSysConf.CONTENT).toString(); + } + };break; + case REPORT_COMMENT: { + // 举报评论 + Object object = nameAndArgsMap.get(BaseSysConf.COMMENT_VO); + Map map = JsonUtils.objectToMap(object); + if(map.get(BaseSysConf.CONTENT) != null) { + otherData = map.get(BaseSysConf.CONTENT).toString(); + } + };break; + case DELETE_COMMENT: { + // 删除评论 + Object object = nameAndArgsMap.get(BaseSysConf.COMMENT_VO); + Map map = JsonUtils.objectToMap(object); + if(map.get(BaseSysConf.CONTENT) != null) { + otherData = map.get(BaseSysConf.CONTENT).toString(); + } + };break; + } + Map result = new HashMap<>(); + result.put(BaseSysConf.MODULE_UID, moduleUid); + result.put(BaseSysConf.OTHER_DATA, otherData); + return result; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getBehavior() { + return behavior; + } + + public void setBehavior(String behavior) { + this.behavior = behavior; + } + + + } + +编写AOP代码 +------- + +在AOP中,我们使用环绕通知的方式,来收集用户的访问日志 + + package com.moxi.mogublog.web.log; + + import com.moxi.mogublog.utils.AopUtils; + import com.moxi.mogublog.utils.AspectUtil; + import com.moxi.mogublog.utils.IpUtils; + import com.moxi.mogublog.web.global.SysConf; + import com.moxi.mogublog.xo.entity.ExceptionLog; + import com.moxi.mogublog.xo.entity.SysLog; + import com.moxi.mogublog.xo.service.WebVisitService; + import com.moxi.mougblog.base.enums.EBehavior; + import com.moxi.mougblog.base.holder.RequestHolder; + import com.moxi.mougblog.base.util.RequestUtil; + import lombok.extern.slf4j.Slf4j; + import org.aspectj.lang.ProceedingJoinPoint; + import org.aspectj.lang.annotation.Around; + import org.aspectj.lang.annotation.Aspect; + import org.aspectj.lang.annotation.Pointcut; + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.stereotype.Component; + + import javax.servlet.http.HttpServletRequest; + import java.lang.reflect.Method; + import java.util.Map; + + /** + * 日志切面 + */ + @Aspect + @Component + @Slf4j + public class LoggerAspect { + + private SysLog sysLog; + + private ExceptionLog exceptionLog; + + @Autowired + private WebVisitService webVisitService; + + + @Pointcut(value = "@annotation(bussinessLog)") + public void pointcut(BussinessLog bussinessLog) { + + } + + @Around(value = "pointcut(bussinessLog)") + public Object doAround(ProceedingJoinPoint joinPoint, BussinessLog bussinessLog) throws Throwable { + + //先执行业务 + Object result = joinPoint.proceed(); + + try { + // 日志收集 + handle(joinPoint); + } catch (Exception e) { + log.error("日志记录出错!", e); + } + + return result; + } + + private void handle(ProceedingJoinPoint point) throws Exception { + + HttpServletRequest request = RequestHolder.getRequest(); + + Method currentMethod = AspectUtil.INSTANCE.getMethod(point); + //获取操作名称 + BussinessLog annotation = currentMethod.getAnnotation(BussinessLog.class); + + boolean save = annotation.save(); + + EBehavior behavior = annotation.behavior(); + + String bussinessName = AspectUtil.INSTANCE.parseParams(point.getArgs(), annotation.value()); + + String ua = RequestUtil.getUa(); + + log.info("{} | {} - {} {} - {}", bussinessName, IpUtils.getIpAddr(request), RequestUtil.getMethod(), RequestUtil.getRequestUrl(), ua); + if (!save) { + return; + } + + // 获取参数名称和值 + Map nameAndArgsMap = AopUtils.getFieldsName(point); + + Map result = EBehavior.getModuleAndOtherData(behavior, nameAndArgsMap, bussinessName); + + AopUtils.getFieldsName(point); + + if (result != null) { + String userUid = ""; + if (request.getAttribute(SysConf.USER_UID) != null) { + userUid = request.getAttribute(SysConf.USER_UID).toString(); + } + webVisitService.addWebVisit(userUid, request, behavior.getBehavior(), result.get(SysConf.MODULE_UID), result.get(SysConf.OTHER_DATA)); + } + } + } + + +这里使用了一个AspectUtils工具类 + + package com.moxi.mogublog.utils; + + import com.alibaba.fastjson.JSON; + import org.aspectj.lang.JoinPoint; + import org.aspectj.lang.Signature; + import org.aspectj.lang.reflect.MethodSignature; + import org.springframework.util.StringUtils; + + import java.lang.reflect.Method; + import java.util.List; + + /** + * AOP相关的工具 + * @author 陌溪 + * @date 2020年2月27日08:44:28 + */ + public enum AspectUtil { + + INSTANCE; + + /** + * 获取以类路径为前缀的键 + * + * @param point 当前切面执行的方法 + */ + public String getKey(JoinPoint point, String prefix) { + String keyPrefix = ""; + if (!StringUtils.isEmpty(prefix)) { + keyPrefix += prefix; + } + keyPrefix += getClassName(point); + return keyPrefix; + } + + /** + * 获取当前切面执行的方法所在的class + * + * @param point 当前切面执行的方法 + */ + public String getClassName(JoinPoint point) { + return point.getTarget().getClass().getName().replaceAll("\\.", "_"); + } + + /** + * 获取当前切面执行的方法的方法名 + * + * @param point 当前切面执行的方法 + */ + public Method getMethod(JoinPoint point) throws NoSuchMethodException { + Signature sig = point.getSignature(); + MethodSignature msig = (MethodSignature) sig; + Object target = point.getTarget(); + return target.getClass().getMethod(msig.getName(), msig.getParameterTypes()); + } + + public String parseParams(Object[] params, String bussinessName) { + if (bussinessName.contains("{") && bussinessName.contains("}")) { + List result = RegexUtils.match(bussinessName, "(?<=\\{)(\\d+)"); + for (String s : result) { + int index = Integer.parseInt(s); + bussinessName = bussinessName.replaceAll("\\{" + index + "}", JSON.toJSONString(params[index - 1])); + } + } + return bussinessName; + } + } + + +以及AOPUtils + + package com.moxi.mogublog.utils; + + import com.alibaba.fastjson.JSON; + import lombok.extern.slf4j.Slf4j; + import org.apache.ibatis.javassist.*; + import org.apache.ibatis.javassist.bytecode.CodeAttribute; + import org.apache.ibatis.javassist.bytecode.LocalVariableAttribute; + import org.apache.ibatis.javassist.bytecode.MethodInfo; + import org.aspectj.lang.JoinPoint; + import org.aspectj.lang.ProceedingJoinPoint; + import org.aspectj.lang.Signature; + import org.aspectj.lang.reflect.MethodSignature; + import org.springframework.core.DefaultParameterNameDiscoverer; + import org.springframework.core.ParameterNameDiscoverer; + import org.springframework.web.multipart.MultipartFile; + + import javax.servlet.ServletRequest; + import javax.servlet.ServletResponse; + import java.lang.reflect.Method; + import java.util.HashMap; + import java.util.Map; + + /** + * 切面相关工具类 + * + * @author: 陌溪 + * @create: 2020-01-21-12:34 + */ + @Slf4j + public class AopUtils { + + /** + * 获取参数名和值 + * @param joinPoint + * @return + */ + public static Map getFieldsName(ProceedingJoinPoint joinPoint) throws ClassNotFoundException, NoSuchMethodException { + // 参数值 + Object[] args = joinPoint.getArgs(); + + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + String[] parameterNames = methodSignature.getParameterNames(); + + // 通过map封装参数和参数值 + HashMap paramMap = new HashMap(); + for (int i = 0; i < parameterNames.length; i++) { + paramMap.put(parameterNames[i], args[i]); + } + return paramMap; + } + } + + +需要注意的是,我们在进行日志收集的时候,采用的是@Async注解修饰,也就是异步调用 + +>  在Spring中,基于@Async标注的方法,称之为异步方法;这些方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。 + + @Async + @Override + public void addWebVisit(String userUid, HttpServletRequest request, String behavior, String moduleUid, String otherData) { + + //增加记录(可以考虑使用AOP) + Map map = IpUtils.getOsAndBrowserInfo(request); + String os = map.get("OS"); + String browser = map.get("BROWSER"); + WebVisit webVisit = new WebVisit(); + String ip = IpUtils.getIpAddr(request); + webVisit.setIp(ip); + + //从Redis中获取IP来源 + String jsonResult = stringRedisTemplate.opsForValue().get("IP_SOURCE:" + ip); + if (StringUtils.isEmpty(jsonResult)) { + String addresses = IpUtils.getAddresses("ip=" + ip, "utf-8"); + if (StringUtils.isNotEmpty(addresses)) { + webVisit.setIpSource(addresses); + stringRedisTemplate.opsForValue().set("IP_SOURCE" + BaseSysConf.REDIS_SEGMENTATION + ip, addresses, 24, TimeUnit.HOURS); + } + } else { + webVisit.setIpSource(jsonResult); + } + webVisit.setOs(os); + webVisit.setBrowser(browser); + webVisit.setUserUid(userUid); + webVisit.setBehavior(behavior); + webVisit.setModuleUid(moduleUid); + webVisit.setOtherData(otherData); + webVisit.insert(); + } + +tip:在使用@Async注解时候,需要在启动类中加入  @EnableAsync  才能够开启异步功能 + +指定接口进行收集 +-------- + +最后我们使用  @BussinessLog 在我们需要收集的日志出进行标记,标记后AOP的环绕通知 就会获取该接口的相关参数,将其实例化到数据库中 + +  示例代码如下: + + @BussinessLog(value = "发表评论", behavior = EBehavior.PUBLISH_COMMENT) + @ApiOperation(value = "增加评论", notes = "增加评论") + @PostMapping("/add") + public String add(@Validated({Insert.class}) @RequestBody CommentVO commentVO, BindingResult result) { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(SysConf.STATUS, EStatus.ENABLE); + WebConfig webConfig = webConfigService.getOne(queryWrapper); + if (SysConf.CAN_NOT_COMMENT.equals(webConfig.getStartComment())) { + return ResultUtil.result(SysConf.ERROR, MessageConf.NO_COMMENTS_OPEN); + } + ThrowableUtils.checkParamArgument(result); + + if (commentVO.getContent().length() > SysConf.TWO_TWO_FIVE) { + return ResultUtil.result(SysConf.ERROR, MessageConf.COMMENT_CAN_NOT_MORE_THAN_225); + } + Comment comment = new Comment(); + comment.setSource(commentVO.getSource()); + comment.setBlogUid(commentVO.getBlogUid()); + comment.setContent(commentVO.getContent()); + comment.setUserUid(commentVO.getUserUid()); + comment.setToUid(commentVO.getToUid()); + comment.setToUserUid(commentVO.getToUserUid()); + comment.setStatus(EStatus.ENABLE); + comment.insert(); + + User user = userService.getById(commentVO.getUserUid()); + + //获取图片 + if (StringUtils.isNotEmpty(user.getAvatar())) { + String pictureList = this.pictureFeignClient.getPicture(user.getAvatar(), SysConf.FILE_SEGMENTATION); + if (webUtils.getPicture(pictureList).size() > 0) { + user.setPhotoUrl(webUtils.getPicture(pictureList).get(0)); + } + } + comment.setUser(user); + + return ResultUtil.result(SysConf.SUCCESS, comment); + } + +最后用户的日志记录也能够成功记录下来了 + +![](http://image.moguit.cn/6211208ae36e4523ae620cd9cf0e180d) \ No newline at end of file diff --git "a/SpringBoot/\345\260\206Swagger\345\215\207\347\272\2473.0/README.md" "b/SpringBoot/\345\260\206Swagger\345\215\207\347\272\2473.0/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..3894e16ad69a9e706d2505fc5c9fa127c5303ada --- /dev/null +++ "b/SpringBoot/\345\260\206Swagger\345\215\207\347\272\2473.0/README.md" @@ -0,0 +1,149 @@ +# SpringBoot项目将Swagger升级3.0 + +## 前言 + +这阵子观察到Swagger官方已经升级到了3.0的版本,想着升级体验一下最新的版本 + +## 新特性 + +- 移除了2.x版本的冲突版本,移除了guava等 +- 移除了@EnableSwagger2 +- 新增了springfox-boot-starter +- ..... + +## 引入依赖 + +新版本中,将改成starter的方式,所以我们一来是这样引入的 + +```pom + + io.springfox + springfox-boot-starter + 3.0.0 + +``` + +同时引用主类的注解已经修改了 + +```bash +# 原来注解 +@EnableSwagger2 + +# 修改后的注解 +@EnableOpenApi +``` + +## 修改配置文件 + +```bash +@Configuration +public class Swagger3Config { + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.OAS_30) + .apiInfo(apiInfo()) + .select() + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + .paths(PathSelectors.any()) + .build(); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("Swagger3接口文档") + .description("文档描述") + .contact(new Contact("fanl", "#", "862844083@qq.com")) + .version("1.0") + .build(); + } +} +``` + +然后在原来的SpringSecurity配置文件里面,允许对于网站静态资源的无授权访问 + +```java +.antMatchers( + "/swagger-ui.html", + "/swagger-ui/*", + "/swagger-resources/**", + "/v2/api-docs", + "/v3/api-docs", + "/webjars/**", + "/actuator/**", + "/druid/**" +).permitAll() +``` + +然后我们运行我们的项目程序,然后输入下面的网址访问swagger-ui页面 + +```bash +# 注意,新版的swagger页面和2.x版本是有区别的 +http://localhost:8601/swagger-ui/index.html +``` + +就能看到最新版的页面了 + +![image-20200907160008613](images/image-20200907160008613.png) + +但是我们有些接口还需要授权,因此我们还要配置携带token进行访问,因此我们还需要修改一下配置信息 + +```java +@Configuration +class Swagger3Config { + @Bean + public Docket createRestApi() { + + return new Docket(DocumentationType.SWAGGER_2). + useDefaultResponseMessages(false) + .apiInfo(apiInfo()) + .select() + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + .paths(PathSelectors.regex("^(?!auth).*$")) + .build() + .securitySchemes(securitySchemes()) + .securityContexts(securityContexts()); + } + + private List securitySchemes() { + return Lists.newArrayList( + new ApiKey("Authorization", "Authorization", "header")); + } + + List defaultAuth() { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + return Lists.newArrayList( + new SecurityReference("Authorization", authorizationScopes)); + } + + private List securityContexts() { + return Lists.newArrayList( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .forPaths(PathSelectors.regex("^(?!auth).*$")) + .build() + ); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("蘑菇博客Admin接口文档") + .description("简单优雅的restful风格") + .version("1.0") + .build(); + } +} +``` + +修改完成后,即可进行授权的安全验证了 + +![image-20200907164308978](images/image-20200907164308978.png) + +点击按钮,添加对应的token,然后我们在请求接口的时候,就会携带对应的请求头信息了 + +![image-20200907164332769](images/image-20200907164332769.png) + +## 参考 + +https://blog.csdn.net/qq_15973399/article/details/107436089 \ No newline at end of file diff --git "a/SpringBoot/\345\260\206Swagger\345\215\207\347\272\2473.0/images/image-20200907160008613.png" "b/SpringBoot/\345\260\206Swagger\345\215\207\347\272\2473.0/images/image-20200907160008613.png" new file mode 100644 index 0000000000000000000000000000000000000000..d992d257d6eca8a214cc0f763da845d80b873950 Binary files /dev/null and "b/SpringBoot/\345\260\206Swagger\345\215\207\347\272\2473.0/images/image-20200907160008613.png" differ diff --git "a/SpringBoot/\345\260\206Swagger\345\215\207\347\272\2473.0/images/image-20200907164308978.png" "b/SpringBoot/\345\260\206Swagger\345\215\207\347\272\2473.0/images/image-20200907164308978.png" new file mode 100644 index 0000000000000000000000000000000000000000..33700129e0f6c036583c54c3a5214004fadca995 Binary files /dev/null and "b/SpringBoot/\345\260\206Swagger\345\215\207\347\272\2473.0/images/image-20200907164308978.png" differ diff --git "a/SpringBoot/\345\260\206Swagger\345\215\207\347\272\2473.0/images/image-20200907164332769.png" "b/SpringBoot/\345\260\206Swagger\345\215\207\347\272\2473.0/images/image-20200907164332769.png" new file mode 100644 index 0000000000000000000000000000000000000000..990c150176f8c25c20d847cfb2c76d46737bd22a Binary files /dev/null and "b/SpringBoot/\345\260\206Swagger\345\215\207\347\272\2473.0/images/image-20200907164332769.png" differ diff --git "a/SpringBoot/\350\247\243\345\206\263\345\215\207\347\272\247SpringBoot2.X\345\220\216\346\227\240\346\263\225\345\220\221eureka\346\263\250\345\206\214\346\234\215\345\212\241\347\232\204\351\227\256\351\242\230/README.md" "b/SpringBoot/\350\247\243\345\206\263\345\215\207\347\272\247SpringBoot2.X\345\220\216\346\227\240\346\263\225\345\220\221eureka\346\263\250\345\206\214\346\234\215\345\212\241\347\232\204\351\227\256\351\242\230/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..47f25d36c413f85c57c550d78c3cd3acb8db255d --- /dev/null +++ "b/SpringBoot/\350\247\243\345\206\263\345\215\207\347\272\247SpringBoot2.X\345\220\216\346\227\240\346\263\225\345\220\221eureka\346\263\250\345\206\214\346\234\215\345\212\241\347\232\204\351\227\256\351\242\230/README.md" @@ -0,0 +1,86 @@ +前言 +-- + +今天对蘑菇博客的springboot和springcloud的版本进行升级,在升级后发现挺多地方需要更改的 + +首先是yml配置文件里面的security已经更改了,由之前的配置 + + security: + basic: + enabled: true + user: + name: user + password: password123 + +更改成下面这样的配置 + + spring: + security: + user: + name: user + password: password123 + +然后,我们需要引入的eureka依赖,也由原来的 + + + org.springframework.cloud + spring-cloud-starter-eureka-server + + +变成了下面的 + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-server + + +在启动eureka之前,我们还需要添加一个配置文件:WebSecurityConfig + +![](http://image.moguit.cn/1576929701250.png) + + package com.moxi.mogublog.eureka.config; + + import org.springframework.context.annotation.Configuration; + import org.springframework.security.config.annotation.web.builders.HttpSecurity; + import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; + import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + import org.springframework.security.config.http.SessionCreationPolicy; + + /** + * WebSecurityConfig + * + * @author: 陌溪 + * @create: 2019-12-21-19:20 + */ + @Configuration + @EnableWebSecurity + public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + /** + * + * @param http + * @throws Exception + */ + @Override + protected void configure(HttpSecurity http) throws Exception { + // Configure HttpSecurity as needed (e.g. enable http basic). + http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER); + http.csrf().disable(); + // 如果是form方式,不能使用url格式登录 + http.authorizeRequests().anyRequest().authenticated().and().httpBasic(); + } + + } + + +因为springboot 2.x版本,将下列的yml配置给废弃了 + + #高版本的丢弃了 + security: + basic: + enabled: true + + +所以我们需要通过配置类的方式,来启动安全验证,如果不配置的话,就会出现下面的问题 + + javax.ws.rs.WebApplicationException: com.fasterxml.jackson.databind.exc.MismatchedInputException: Root name 'timestamp' does not match expected ('instance') for type [simple type, class com.netflix.appinfo.InstanceInfo] \ No newline at end of file diff --git "a/SpringCloud/Nacos\345\205\263\351\227\255\345\277\203\350\267\263\346\227\245\345\277\227/README.md" "b/SpringCloud/Nacos\345\205\263\351\227\255\345\277\203\350\267\263\346\227\245\345\277\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..3ad58efa6d9f8f604b09bc300dfd450f9ae98b0f --- /dev/null +++ "b/SpringCloud/Nacos\345\205\263\351\227\255\345\277\203\350\267\263\346\227\245\345\277\227/README.md" @@ -0,0 +1,39 @@ +# Nacos关闭心跳日志 + +## 前言 + +这两天在使用ElasticStack收集我们的日志信息,但是Nacos在启动后,会不断的生成一些心跳日志,如下所示 + +```bash +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:14:59.112 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [] +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:15:00.114 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [] +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:15:01.115 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [] +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:15:02.117 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [] +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:15:03.118 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [] +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:15:04.120 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [] +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:15:05.121 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [] +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:15:06.122 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [][{"clusterName":"DEFAULT","enabled":true,"ephemeral":true,"healthy":true,"instanceHeartBeatInterval":5000,"instanceHeartBeatTimeOut":15000,"instanceId":"172.17.0.2#8602#DEFAULT#DEFAULT_GROUP@@mogu-picture","ip":"172.17.0.2","ipDeleteTimeout":30000,"metadata":{"preserved.register.source":"SPRING_CLOUD"},"port":8602,"serviceName":"DEFAULT_GROUP@@mogu-picture","weight":1.0}] +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:15:09.127 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [] +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:15:15.136 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [] +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:15:16.137 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [] +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:15:17.139 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [] +[mogu-admin:172.17.0.2:8601] [,] 2020-09-26 20:15:18.141 INFO 19155 [com.alibaba.nacos.client.naming.updater] com.alibaba.nacos.client.naming current ips:(0) service: DEFAULT_GROUP@@mogu-search -> [] +``` + +因为大量充斥着这样的无用数据,被我们收集上来其实没有啥作用,所以我们打算把这个关闭掉 + +## 解决方法 + +解决方法就是在yml文件中,配置一下nacos的日志级别,改成error即可 + +```yml +# 调整nacos日志级别 +logging: + level: + com: + alibaba: + nacos: + client: + naming: error +``` + diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/README.md" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a6eee5981ae9ec5895c22029b143f4290f020027 --- /dev/null +++ "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/README.md" @@ -0,0 +1,861 @@ +# SpringCloudAlibabaSentinel实现熔断和限流 + +## Sentinel + +### 官网 + +Github:https://github.com/alibaba/Sentinel + +Sentinel:分布式系统的流量防卫兵,相当于Hystrix + +Hystrix存在的问题 + +- 需要我们程序员自己手工搭建监控平台 +- 没有一套web界面可以给我们进行更加细粒度化的配置,流量控制,速率控制,服务熔断,服务降级。。 + +这个时候Sentinel运营而生 + +- 单独一个组件,可以独立出来 +- 直接界面化的细粒度统一配置 + +约定 > 配置 >编码,都可以写在代码里,但是尽量使用注解和配置代替编码 + +### 是什么 + +随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 + +Sentinel 具有以下特征: + +- **丰富的应用场景**:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。 +- **完备的实时监控**:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。 +- **广泛的开源生态**:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。 +- **完善的 SPI 扩展点**:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。 + +### 主要特征 + +![image-20200416073841558](images/image-20200416073841558.png) + +### 生态圈 + +![image-20200416073905426](images/image-20200416073905426.png) + +### 下载 + +Github:https://github.com/alibaba/Sentinel/releases + +![image-20200416074923500](images/image-20200416074923500.png) + +## 安装Sentinel控制台 + +sentinel组件由两部分组成,后台和前台8080 + +Sentinel分为两部分 + +- 核心库(Java客户端)不依赖任何框架/库,能够运行在所有Java运行时环境,同时对Dubbo、SpringCloud等框架也有较好的支持。 +- 控制台(Dashboard)基于SpringBoot开发,打包后可以直接运行,不需要额外的Tomcat等应用容器 + +使用 `java -jar` 启动,同时Sentinel默认的端口号是8080,因此不能被占用 + +注意,下载时候,由于Github经常抽风,因此可以使用Gitee进行下,首先先去Gitee下载源码 + +![image-20200416080109354](images/image-20200416080109354.png) + +然后执行`mvn package` 进行构建,本博客同级目录下了,已经有个已经下载好的,欢迎自取 + +## 初始化演示工程 + +启动Nacos8848成功 + +### 引入依赖 + +``` + + + com.alibaba.csp + sentinel-datasource-nacos + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + +``` + +### 修改YML + +``` +server: + port: 8401 + +spring: + application: + name: cloudalibaba-sentinel-service + cloud: + nacos: + discovery: + server-addr: localhost:8848 #Nacos服务注册中心地址 + sentinel: + transport: + dashboard: localhost:8080 #配置Sentinel dashboard地址 + port: 8719 +``` + +### 增加业务类 + +``` +@RestController +@Slf4j +public class FlowLimitController +{ + @GetMapping("/testA") + public String testA() + { + return "------testA"; + } + + @GetMapping("/testB") + public String testB() + { + log.info(Thread.currentThread().getName()+"\t"+"...testB"); + return "------testB"; + } +} +``` + +启动8401微服务,查看Sentinel控制台 + +我们会发现Sentinel里面空空如也,什么也没有,这是因为Sentinel采用的懒加载 + +执行一下访问即可:`http://localhost:8401/testA` `http://localhost:8401/testB` + +![image-20200416083940979](images/image-20200416083940979.png) + + + +## 流控规则 + +### 基本介绍 + +![image-20200416084144709](images/image-20200416084144709.png) + +**字段说明** + +- 资源名:唯一名称,默认请求路径 +- 针对来源:Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源) +- 阈值类型 / 单机阈值 + - QPS:(每秒钟的请求数量):但调用该API的QPS达到阈值的时候,进行限流 + - 线程数:当调用该API的线程数达到阈值的时候,进行限流 +- 是否集群:不需要集群 +- 流控模式 + - 直接:api都达到限流条件时,直接限流 + - 关联:当关联的资源达到阈值,就限流自己 + - 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【API级别的针对来源】 +- 流控效果 + - 快速失败:直接失败,抛异常 + - Warm UP:根据codeFactory(冷加载因子,默认3),从阈值/CodeFactor,经过预热时长,才达到设置的QPS阈值 + - 排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置QPS,否则无效 + +### 流控模式 + +#### 直接(默认) + +我们给testA增加流控 + +![image-20200416084934271](images/image-20200416084934271.png) + +![image-20200416085039034](images/image-20200416085039034.png) + +![image-20200416085226574](images/image-20200416085226574.png) + +然后我们请求 `http://localhost:8401/testA`,就会出现失败,被限流,快速失败 + +![image-20200416085117306](images/image-20200416085117306.png) + +思考: + +直接调用的是默认报错信息,能否有我们的后续处理,比如更加友好的提示,类似有hystrix的fallback方法 + + + +线程数 + +这里的线程数表示一次只有一个线程进行业务请求,当前出现请求无法响应的时候,会直接报错,例如,在方法的内部增加一个睡眠,那么后面来的就会失败 + +``` + @GetMapping("/testD") + public String testD() + { + try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } + return "------testD"; + } +``` + + + +#### 关联 + +当关联的资源达到阈值时,就限流自己 + +当与A关联的资源B达到阈值后,就限流A自己,B惹事,A挂了 + +场景:支付接口达到阈值后,就限流下订单的接口 + +设置: + +当关联资源 /testB的QPS达到阈值超过1时,就限流/testA的Rest访问地址,当关联资源达到阈值后,限制配置好的资源名 + +![image-20200416090827339](images/image-20200416090827339.png) + +这个使用我们利用postman模拟并发密集访问`testB` + +首先我们需要使用postman,创建一个请求 + +![image-20200416091302584](images/image-20200416091302584.png) + +同时将请求保存在 Collection中 + +然后点击箭头,选中接口,选择run + +![image-20200416091349552](images/image-20200416091349552.png) + +![image-20200416091517551](images/image-20200416091517551.png) + +点击运行,大批量线程高并发访问B,导致A失效了,同时我们点击访问 `http://localhost:8401/testA`,结果发现,我们的A已经挂了 + +![image-20200416091801271](images/image-20200416091801271.png) + +在测试A接口 + +![image-20200416091815140](images/image-20200416091815140.png) + +这就是我们的关联限流 + + + +#### 链路 + +多个请求调用了同一个微服务 + + + +### 流控效果 + +#### 直接 + +快速失败,默认的流控处理 + +- 直接失败,抛出异常:Blocked by Sentinel(Flow limiting) + +#### 预热 + +系统最怕的就是出现,平时访问是0,然后突然一瞬间来了10W的QPS + +公式:阈值 除以 clodFactor(默认值为3),经过预热时长后,才会达到阈值 + +Warm Up方式,即预热/冷启动方式,当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能会瞬间把系统压垮。通过冷启动,让通过的流量缓慢增加,在一定时间内逐渐增加到阈值,给冷系统一个预热的时间,避免冷系统被压垮。通常冷启动的过程系统允许的QPS曲线如下图所示 + +![image-20200416093702689](images/image-20200416093702689.png) + +默认clodFactor为3,即请求QPS从threshold / 3开始,经预热时长逐渐提升至设定的QPS阈值 + +![image-20200416093919458](images/image-20200416093919458.png) + +假设这个系统的QPS是10,那么最开始系统能够接受的 QPS = 10 / 3 = 3,然后从3逐渐在5秒内提升到10 + +应用场景: + +秒杀系统在开启的瞬间,会有很多流量上来,很可能把系统打死,预热的方式就是为了保护系统,可能慢慢的把流量放进来,慢慢的把阈值增长到设置的阈值。 + +![image-20200416094419813](images/image-20200416094419813.png) + +#### 排队等待 + +大家均速排队,让请求以均匀的速度通过,阈值类型必须设置成QPS,否则无效 + +均速排队方式必须严格控制请求通过的间隔时间,也即让请求以匀速的速度通过,对应的是漏桶算法。 + +![image-20200416094734543](images/image-20200416094734543.png) + +这种方式主要用于处理间隔性突发的流量,例如消息队列,想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒处于空闲状态,我们系统系统能够接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。 + +设置含义:/testA 每秒1次请求,超过的话,就排队等待,等待时间超过20000毫秒 + +![image-20200416094609143](images/image-20200416094609143.png) + + + +## 降级规则 + +### 名词介绍 + +![image-20200416095515859](images/image-20200416095515859.png) + + + +- RT(平均响应时间,秒级) + - 平均响应时间,超过阈值 且 时间窗口内通过的请求 >= 5,两个条件同时满足后出发降级 + - 窗口期过后,关闭断路器 + - RT最大4900(更大的需要通过 -Dcsp.sentinel.staticstic.max.rt=XXXXX才能生效) + +- 异常比例(秒级) + - QPA >= 5 且异常比例(秒级)超过阈值时,触发降级;时间窗口结束后,关闭降级 +- 异常数(分钟级) + - 异常数(分钟统计)超过阈值时,触发降级,时间窗口结束后,关闭降级 + + + +### 概念 + +Sentinel熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。 + +当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都进行自动熔断(默认行为是抛出DegradeException) + +Sentinel的断路器是没有半开状态 + +半开的状态,系统自动去检测是否请求有异常,没有异常就关闭断路器恢复使用,有异常则继续打开断路器不可用,具体可以参考hystrix + +![image-20200416100340083](images/image-20200416100340083.png) + +### 降级策略实战 + +#### RT + +平均响应时间 (`DEGRADE_GRADE_RT`):当 1s 内持续进入 N 个请求,对应时刻的平均响应时间(秒级)均超过阈值(`count`,以 ms 为单位),那么在接下的时间窗口(`DegradeRule` 中的 `timeWindow`,以 s 为单位)之内,对这个方法的调用都会自动地熔断(抛出 `DegradeException`)。注意 Sentinel 默认统计的 RT 上限是 4900 ms,**超出此阈值的都会算作 4900 ms**,若需要变更此上限可以通过启动配置项 `-Dcsp.sentinel.statistic.max.rt=xxx` 来配置。 + +![image-20200416102754797](images/image-20200416102754797.png) + +代码测试 + +``` + @GetMapping("/testD") + public String testD() + { + try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } + log.info("testD 异常比例"); + return "------testD"; + } +``` + +然后使用Jmeter压力测试工具进行测试 + +![image-20200416103619799](images/image-20200416103619799.png) + +按照上述操作,永远1秒种打进来10个线程,大于5个了,调用tesetD,我们希望200毫秒内处理完本次任务,如果200毫秒没有处理完,在未来的1秒的时间窗口内,断路器打开(保险丝跳闸)微服务不可用,保险丝跳闸断电 + +``` +Blocked by Sentinel (flow limiting) +``` + +![image-20200416103959047](images/image-20200416103959047.png) + +后续我们停止使用jmeter,没有那么大的访问量了,断路器关闭(保险丝恢复),微服务恢复OK + +#### 异常比例 + +异常比例 (`DEGRADE_GRADE_EXCEPTION_RATIO`):当资源的每秒请求量 >= N(可配置),并且每秒异常总数占通过量的比值超过阈值(`DegradeRule` 中的 `count`)之后,资源进入降级状态,即在接下的时间窗口(`DegradeRule` 中的 `timeWindow`,以 s 为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是 `[0.0, 1.0]`,代表 0% - 100%。 + +![image-20200416104157714](images/image-20200416104157714.png) + +单独访问一次,必然来一次报错一次,开启jmeter后,直接高并发发送请求,多次调用达到我们的配置条件了,断路器开启(保险丝跳闸),微服务不可用,不在报错,而是服务降级了 + +![image-20200416104919798](images/image-20200416104919798.png) + +设置3秒内,如果请求百分50出错,那么就会熔断 + +![image-20200416104908479](images/image-20200416104908479.png) + +我们用jmeter每秒发送10次请求,3秒后,再次调用 `localhost:8401/testD` 出现服务降级 + +![image-20200416104858019](images/image-20200416104858019.png) + +#### 异常数 + +异常数 (`DEGRADE_GRADE_EXCEPTION_COUNT`):当资源近 1 分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若 `timeWindow` 小于 60s,则结束熔断状态后仍可能再进入熔断状态 + +时间窗口一定要大于等于60秒 + +异常数是按分钟来统计的 + +![image-20200416105132256](images/image-20200416105132256.png) + +下面设置是,一分钟内出现5次,则熔断 + +![image-20200416105535535](images/image-20200416105535535.png) + +首先我们再次访问 `http://localhost:8401/testE`,第一次访问绝对报错,因为除数不能为0,我们看到error窗口,但是达到5次报错后,进入熔断后的降级 + + + +## Sentinel热点规则 + +### 什么是热点数据 + +[Github文档传送门](https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81) + +何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如: + +- 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制 +- 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制 + +热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。 + +![image-20200416121306501](images/image-20200416121306501.png) + +Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。热点参数限流支持集群模式。 + +### 兜底的方法 + +分为系统默认的和客户自定义的,两种,之前的case中,限流出现问题了,都用sentinel系统默认的提示:Blocked By Sentinel,我们能不能自定义,类似于hystrix,某个方法出现问题了,就找到对应的兜底降级方法。 + +从 `@HystrixCommand` 到 `@SentinelResource` + +### 配置 + +@SentinelResource的value,就是我们的资源名,也就是对哪个方法配置热点规则 + +``` + @GetMapping("/testHotKey") + @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey") + public String testHotKey(@RequestParam(value = "p1",required = false) String p1, + @RequestParam(value = "p2",required = false) String p2) + { + //int age = 10/0; + return "------testHotKey"; + } + + // 和上面的参数一样,不错需要加入 BlockException + public String deal_testHotKey (String p1, String p2, BlockException exception) + { + return "------deal_testHotKey,o(╥﹏╥)o"; // 兜底的方法 + } +``` + +我们对参数0,设置热点key进行限流 + +![image-20200416122406091](images/image-20200416122406091.png) + +配置完成后 + +![image-20200416122450886](images/image-20200416122450886.png) + +当我们不断的请求时候,也就是以第一个参数为目标,请求接口,我们会发现多次请求后 + +``` +http://localhost:8401/testHotKey?p1=a +``` + +就会出现以下的兜底错误 + +``` +------deal_testHotKey,o(╥﹏╥)o +``` + +这是因为我们针对第一个参数进行了限制,当我们QPS超过1的时候,就会触发兜底的错误 + +假设我们请求的接口是:`http://localhost:8401/testHotKey?p2=a` ,我们会发现他就没有进行限流 + +![image-20200416123605410](images/image-20200416123605410.png) + +### 参数例外项 + +上述案例演示了第一个参数p1,当QPS超过1秒1次点击狗,马上被限流 + +- 普通:超过一秒1个后,达到阈值1后马上被限流 +- 我们期望p1参数当它达到某个特殊值时,它的限流值和平时不一样 +- 特例:假设当p1的值等于5时,它的阈值可以达到200 +- 一句话说:当key为特殊值的时候,不被限制 + +![image-20200416123922325](images/image-20200416123922325.png) + +平时的时候,参数1的QPS是1,超过的时候被限流,但是有特殊值,比如5,那么它的阈值就是200 + +我们通过 `http://localhost:8401/testHotKey?p1=5` 一直刷新,发现不会触发兜底的方法,这就是参数例外项 + +热点参数的注意点,参数必须是基本类型或者String + +### 结语 + +`@SentinelResource` 处理的是Sentinel控制台配置的违规情况,有blockHandler方法配置的兜底处理 + +RuntimeException,如 int a = 10/0 ; 这个是java运行时抛出的异常,RuntimeException,@RentinelResource不管 + +也就是说:`@SentinelResource` 主管配置出错,运行出错不管。 + +如果想要有配置出错,和运行出错的话,那么可以设置 fallback + +``` + @GetMapping("/testHotKey") + @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey", fallback = "fallBack") + public String testHotKey(@RequestParam(value = "p1",required = false) String p1, + @RequestParam(value = "p2",required = false) String p2) + { + //int age = 10/0; + return "------testHotKey"; + } +``` + + + +## Sentinel系统配置 + +Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。 + +系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。 + +系统保护规则是应用整体维度的,而不是资源维度的,并且**仅对入口流量生效**。入口流量指的是进入应用的流量(`EntryType.IN`),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。 + +系统规则支持以下的模式: + +- **Load 自适应**(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 `maxQps * minRt` 估算得出。设定参考值一般是 `CPU cores * 2.5`。 +- **CPU usage**(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。 +- **平均 RT**:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。 +- **并发线程数**:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。 +- **入口 QPS**:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。 + +![image-20200416144836658](images/image-20200416144836658.png) + +这样相当于设置了全局的QPS过滤 + + + +## @SentinelResource注解 + +- 按资源名称限流 + 后续处理 +- 按URL地址限流 + 后续处理 + +### 问题 + +- 系统默认的,没有体现我们自己的业务要求 +- 依照现有条件,我们自定义的处理方法又和业务代码耦合在一块,不直观 +- 每个业务方法都添加一个兜底方法,那代码膨胀加剧 +- 全局统一的处理方法没有体现 +- 关闭8401,发现流控规则已经消失,说明这个是没有持久化 + +### 客户自定义限流处理逻辑 + +创建CustomerBlockHandler类用于自定义限流处理逻辑 + +``` +public class CustomerBlockHandler +{ + public static CommonResult handlerException(BlockException exception) + { + return new CommonResult(4444,"按客戶自定义,global handlerException----1"); + } + public static CommonResult handlerException2(BlockException exception) + { + return new CommonResult(4444,"按客戶自定义,global handlerException----2"); + } +} +``` + +那么我们在使用的时候,就可以首先指定是哪个类,哪个方法 + +``` + @GetMapping("/rateLimit/customerBlockHandler") + @SentinelResource(value = "customerBlockHandler", + blockHandlerClass = CustomerBlockHandler.class, + blockHandler = "handlerException2") + public CommonResult customerBlockHandler() + { + return new CommonResult(200,"按客戶自定义",new Payment(2020L,"serial003")); + } +``` + +![image-20200416150947457](images/image-20200416150947457.png) + +### 更多注解属性说明 + +所有的代码都要用try - catch - finally 进行处理 + +sentinel主要有三个核心API + +- Sphu定义资源 +- Tracer定义统计 +- ContextUtil定义了上下文 + + + +## 服务熔断 + +sentinel整合Ribbon + openFeign + fallback + +搭建 9003 和 9004 服务提供者 + +### 不设置任何参数 + +然后在使用 84作为服务消费者,当我们值使用 `@SentinelResource`注解时,不添加任何参数,那么如果出错的话,是直接返回一个error页面,对前端用户非常不友好,因此我们需要配置一个兜底的方法 + +``` + @RequestMapping("/consumer/fallback/{id}") + @SentinelResource(value = "fallback") //没有配置 + public CommonResult fallback(@PathVariable Long id) + { + CommonResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id); + + if (id == 4) { + throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常...."); + }else if (result.getData() == null) { + throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常"); + } + + return result; + } +``` + +### 设置fallback + +``` + @RequestMapping("/consumer/fallback/{id}") + @SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常 + public CommonResult fallback(@PathVariable Long id) + { + CommonResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id); + + if (id == 4) { + throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常...."); + }else if (result.getData() == null) { + throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常"); + } + + return result; + } + + //本例是fallback + public CommonResult handlerFallback(@PathVariable Long id,Throwable e) { + Payment payment = new Payment(id,"null"); + return new CommonResult<>(444,"兜底异常handlerFallback,exception内容 "+e.getMessage(),payment); + } +``` + +加入fallback后,当我们程序运行出错时,我们会有一个兜底的异常执行,但是服务限流和熔断的异常还是出现默认的 + +### 设置blockHandler + +``` + @RequestMapping("/consumer/fallback/{id}") + @SentinelResource(value = "fallback",blockHandler = "blockHandler" ,fallback = "handlerFallback") //blockHandler只负责sentinel控制台配置违规 + public CommonResult fallback(@PathVariable Long id) + { + CommonResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id); + + if (id == 4) { + throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常...."); + }else if (result.getData() == null) { + throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常"); + } + + return result; + } + + //本例是blockHandler + public CommonResult blockHandler(@PathVariable Long id,BlockException blockException) { + Payment payment = new Payment(id,"null"); + return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException "+blockException.getMessage(),payment); + } +``` + +### blockHandler和fallback一起配置 + +``` + @RequestMapping("/consumer/fallback/{id}") + @SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规 + public CommonResult fallback(@PathVariable Long id) + { + CommonResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id); + + if (id == 4) { + throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常...."); + }else if (result.getData() == null) { + throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常"); + } + return result; + } +``` + +若blockHandler 和 fallback都进行了配置,则被限流降级而抛出 BlockException时,只会进入blockHandler处理逻辑 + + + +### 异常忽略 + +![image-20200416213834495](images/image-20200416213834495.png) + + + +## Feign系列 + +#### 引入依赖 + +``` + + + org.springframework.cloud + spring-cloud-starter-openfeign + +``` + +#### 修改YML + +``` +server: + port: 84 + +spring: + application: + name: nacos-order-consumer + cloud: + nacos: + discovery: + server-addr: localhost:8848 + sentinel: + transport: + #配置Sentinel dashboard地址 + dashboard: localhost:8080 + #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口 + port: 8719 + +#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者) +service-url: + nacos-user-service: http://nacos-payment-provider + +# 激活Sentinel对Feign的支持 +feign: + sentinel: + enabled: true +``` + +#### 启动类激活Feign + +``` +@EnableDiscoveryClient +@SpringBootApplication +@EnableFeignClients +public class OrderNacosMain84 +{ + public static void main(String[] args) { + SpringApplication.run(OrderNacosMain84.class, args); + } +} +``` + +#### 引入Feign接口 + +``` +@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class) +public interface PaymentService +{ + @GetMapping(value = "/paymentSQL/{id}") + public CommonResult paymentSQL(@PathVariable("id") Long id); +} +``` + +#### 加入fallback兜底方法实现 + +``` +@Component +public class PaymentFallbackService implements PaymentService +{ + @Override + public CommonResult paymentSQL(Long id) + { + return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial")); + } +} +``` + +#### 测试 + +请求接口:`http://localhost:84/consumer/paymentSQL/1` + +测试84调用9003,此时故意关闭9003微服务提供者,看84消费侧自动降级 + +我们发现过了一段时间后,会触发服务降级,返回失败的方法 + +## 熔断框架对比 + +![image-20200416215711875](images/image-20200416215711875.png) + + + +## Sentinel规则持久化 + +### 是什么 + +一旦我们重启应用,sentinel规则将会消失,生产环境需要将规则进行持久化 + +### 怎么玩 + +将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上的流控规则持续有效 + +### 解决方法 + +使用nacos持久化保存 + +#### 引入依赖 + +``` + + + com.alibaba.csp + sentinel-datasource-nacos + +``` + +#### 修改yml + +``` +server: + port: 8401 + +spring: + application: + name: cloudalibaba-sentinel-service + cloud: + nacos: + discovery: + server-addr: localhost:8848 #Nacos服务注册中心地址 + sentinel: + transport: + dashboard: localhost:8080 #配置Sentinel dashboard地址 + port: 8719 + datasource: + ds1: + nacos: + server-addr: localhost:8848 + dataId: cloudalibaba-sentinel-service + groupId: DEFAULT_GROUP + data-type: json + rule-type: flow + +management: + endpoints: + web: + exposure: + include: '*' + +feign: + sentinel: + enabled: true # 激活Sentinel对Feign的支持 +``` + +#### 添加nacos配置 + +![image-20200416222218661](images/image-20200416222218661.png) + +内容解析 + +![image-20200416222317824](images/image-20200416222317824.png) + +- resource:资源名称 +- limitApp:来源应用 +- grade:阈值类型,0表示线程数,1表示QPS +- count:单机阈值 +- strategy:流控模式,0表示直接,1表示关联,2表示链路 +- controlBehavior:流控效果,0表示快速失败,1表示Warm,2表示排队等待 +- clusterMode:是否集群 + + + +这样启动的时候,调用一下接口,我们的限流规则就会重新出现~ \ No newline at end of file diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416073841558.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416073841558.png" new file mode 100644 index 0000000000000000000000000000000000000000..a39cffecf8f3bcd83fcbdcb671600d7f87cdb8a2 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416073841558.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416073905426.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416073905426.png" new file mode 100644 index 0000000000000000000000000000000000000000..0c0cb28af741d3567a1bc053d7ef75bd809cdfe0 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416073905426.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416074923500.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416074923500.png" new file mode 100644 index 0000000000000000000000000000000000000000..c0b87fe38cc8a47de3d203e82bc9b07a00c2ec37 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416074923500.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416080109354.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416080109354.png" new file mode 100644 index 0000000000000000000000000000000000000000..d18b1a2bf8ca1f5980f9a8d58b57a7e66c3b467e Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416080109354.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416083940979.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416083940979.png" new file mode 100644 index 0000000000000000000000000000000000000000..d37b9b7f8e5c3ec2a8978944fd351f880503a5dd Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416083940979.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416084144709.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416084144709.png" new file mode 100644 index 0000000000000000000000000000000000000000..843fd922562f684e6dca740833bd35afa11f5c27 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416084144709.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416084934271.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416084934271.png" new file mode 100644 index 0000000000000000000000000000000000000000..f43c4ffdfdcb3fd213f85fdb906d68d327f53fae Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416084934271.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416085039034.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416085039034.png" new file mode 100644 index 0000000000000000000000000000000000000000..30c4561b07871719efe16778fecad79947320c2a Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416085039034.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416085117306.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416085117306.png" new file mode 100644 index 0000000000000000000000000000000000000000..f335175cfe701468569e82780b9a2335912dc503 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416085117306.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416085226574.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416085226574.png" new file mode 100644 index 0000000000000000000000000000000000000000..56c4463fcb1bde94460b2ee163810475fe0f709e Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416085226574.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416090827339.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416090827339.png" new file mode 100644 index 0000000000000000000000000000000000000000..1ba1fbea6059414385cbd58914bc5df8b5b0f875 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416090827339.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091302584.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091302584.png" new file mode 100644 index 0000000000000000000000000000000000000000..939b73b53cfba88e12fdda5af1ae8c4cb36a28c0 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091302584.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091349552.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091349552.png" new file mode 100644 index 0000000000000000000000000000000000000000..b20c5f5b2929f1a1a9206d85416315faa711d7aa Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091349552.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091517551.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091517551.png" new file mode 100644 index 0000000000000000000000000000000000000000..8fa9150c5e882d664fff59b498996a08b4ebc721 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091517551.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091801271.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091801271.png" new file mode 100644 index 0000000000000000000000000000000000000000..cb48032c50fe9ee23af1d78b80c424d8d8b69caa Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091801271.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091815140.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091815140.png" new file mode 100644 index 0000000000000000000000000000000000000000..08da9e9dda154de1db99ecfcbadea796e6c4d759 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416091815140.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416093702689.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416093702689.png" new file mode 100644 index 0000000000000000000000000000000000000000..7fc4b0294f8545996689376a1bcdd878a6af9dd8 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416093702689.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416093919458.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416093919458.png" new file mode 100644 index 0000000000000000000000000000000000000000..72df1d19db0a6bdb20a190e497c2ef27f168c447 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416093919458.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416094419813.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416094419813.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a8693d0ff751165939466ae268d6a63b2c2de9e Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416094419813.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416094609143.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416094609143.png" new file mode 100644 index 0000000000000000000000000000000000000000..de771cf17a9a495ea97ab32fa02260fffc17c7a1 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416094609143.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416094734543.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416094734543.png" new file mode 100644 index 0000000000000000000000000000000000000000..765ec84a3087fa74b7754063037404ae5d4a84bf Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416094734543.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416095515859.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416095515859.png" new file mode 100644 index 0000000000000000000000000000000000000000..2fdb2593ddba0651d52161a25f9197e4269d3054 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416095515859.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416100340083.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416100340083.png" new file mode 100644 index 0000000000000000000000000000000000000000..d9cbfdbe5efb67ef1517380d702112fe14de720b Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416100340083.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416102754797.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416102754797.png" new file mode 100644 index 0000000000000000000000000000000000000000..82a4f695a703a63a0ad70589ff8b6eb520560961 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416102754797.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416103619799.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416103619799.png" new file mode 100644 index 0000000000000000000000000000000000000000..129010dcb7df01e9f582199c020668c4526ad700 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416103619799.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416103959047.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416103959047.png" new file mode 100644 index 0000000000000000000000000000000000000000..bc70fd9fd6ea87a96c86dca653eaf66dad7646a6 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416103959047.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416104157714.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416104157714.png" new file mode 100644 index 0000000000000000000000000000000000000000..8ed24a46a6efbcbf5494639ae81d27b58b3a36f7 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416104157714.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416104858019.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416104858019.png" new file mode 100644 index 0000000000000000000000000000000000000000..905cdd4f0dcbf9bd05ba61a4f993835d95f197f7 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416104858019.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416104908479.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416104908479.png" new file mode 100644 index 0000000000000000000000000000000000000000..f7ea4c3c49a4857653ee489ac28edc7d9e9fbc6a Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416104908479.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416104919798.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416104919798.png" new file mode 100644 index 0000000000000000000000000000000000000000..f46ce77c89e24c4436a8d1bc2b1ee2ead43a8b04 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416104919798.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416105132256.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416105132256.png" new file mode 100644 index 0000000000000000000000000000000000000000..1bf187709dd9c034a1659c9a27656634539b949a Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416105132256.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416105535535.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416105535535.png" new file mode 100644 index 0000000000000000000000000000000000000000..cfa75d4386f49afb7e8efd7d9b29564023f810bf Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416105535535.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416121306501.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416121306501.png" new file mode 100644 index 0000000000000000000000000000000000000000..01fa4af7d8f33af37a2b7008993768bd0db4519b Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416121306501.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416122406091.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416122406091.png" new file mode 100644 index 0000000000000000000000000000000000000000..1a20715de69e97a1904c7c4799e90b777632d581 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416122406091.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416122450886.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416122450886.png" new file mode 100644 index 0000000000000000000000000000000000000000..ac1ab89c7945bcfac18c562e9b8e69f753027ee1 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416122450886.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416123605410.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416123605410.png" new file mode 100644 index 0000000000000000000000000000000000000000..410c3ba8c41aa424a9d9b6f3504ff48c0d4bcfd1 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416123605410.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416123922325.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416123922325.png" new file mode 100644 index 0000000000000000000000000000000000000000..9d4cb568a5adea481f0d0380e36108bd9e6cb697 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416123922325.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416144836658.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416144836658.png" new file mode 100644 index 0000000000000000000000000000000000000000..604e02c7d6214b666f0cebf3b2d574e81fea0ae3 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416144836658.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416150947457.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416150947457.png" new file mode 100644 index 0000000000000000000000000000000000000000..a7b6a52c3d4919117aa1b2fd014b23e36de2ab3d Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416150947457.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416213834495.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416213834495.png" new file mode 100644 index 0000000000000000000000000000000000000000..357260e12f67f7561513da6a1d68ca4f30509b71 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416213834495.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416215711875.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416215711875.png" new file mode 100644 index 0000000000000000000000000000000000000000..37bce8cae53bceaf51065cbb9447003f47692b2e Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416215711875.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416222218661.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416222218661.png" new file mode 100644 index 0000000000000000000000000000000000000000..24b740c5efbb5c2f9368c6fba1c62971d644b9e2 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416222218661.png" differ diff --git "a/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416222317824.png" "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416222317824.png" new file mode 100644 index 0000000000000000000000000000000000000000..b232930348368f6070703f6f6d6e70ce8b515c80 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel\345\256\236\347\216\260\347\206\224\346\226\255\345\222\214\351\231\220\346\265\201/images/image-20200416222317824.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/README.md" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..008b40752ab87bdc91592fcc66c1b62a4853994a --- /dev/null +++ "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/README.md" @@ -0,0 +1,864 @@ +# SpringCloudAlibabaSeata处理分布式事务 + +基于分布式的事务管理 + +## 分布式事务 + +分布式之前,单机单库没有这个问题,从 1:1 -> 1:N -> N:N + +![image-20200417081113603](images/image-20200417081113603.png) + +跨数据库,多数据源的统一调度,就会遇到分布式事务问题 + +如下图,单体应用被拆分成微服务应用,原来的三个模板被拆分成三个独立的应用,分别使用三个独立的数据源,业务操作需要调用三个服务来完成。此时每个服务内部的数据一致性由本地事务来保证,但是全局的数据一致性问题没法保证。 + +![image-20200417081239933](images/image-20200417081239933.png) + + + +## Seata简介 + +官方文档:[点我传送](https://seata.io/zh-cn/docs/overview/what-is-seata.html) + +Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。 + +分布式事务处理过程的一致性ID + 三组件模型 + +- Transaction ID XID:全局唯一的事务ID +- 三组件的概念 + - Transaction Coordinator(TC):事务协调器,维护全局事务,驱动全局事务提交或者回滚 + - Transaction Manager(TM):事务管理器,控制全局事务的范围,开始全局事务提交或回滚全局事务 + - Resource Manager(RM):资源管理器,控制分支事务,负责分支注册分支事务和报告 + +### 处理过程 + +![image-20200417121037783](images/image-20200417121037783.png) + +- TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID +- XID在微服务调用链路的上下文中传播 +- RM向TC注册分支事务,将其纳入XID对应全局事务的管辖 +- TM向TC发起针对XID的全局提交或回滚决议 +- TM调度XID下管辖的全部分支事务完成提交或回滚请求 + +### 下载 + +地址:https://github.com/seata/seata/releases + +下载 1.1版本完成后,修改conf目录下的file.conf配置文件 + +#### 修改file.conf + +首先我们需要备份原始的file.conf文件 + +主要修改,自定义事务组名称 + 事务日志存储模式为db + 数据库连接信息,也就是修改存储的数据库 + +#### 修改service模块 + +修改服务模块中的分组 + +![image-20200417133537054](images/image-20200417133537054.png) + +#### 修改store模块 + +修改存储模块 + +![image-20200417134353031](images/image-20200417134353031.png) + +![image-20200417133715606](images/image-20200417133715606.png) + +#### 创建一个seata数据库 + +在seata数据库中建表,建表语句在 seata/conf目录下的 db_store.sql + +#### 修改seata-server的registry.conf配置文件 + +![image-20200417134800315](images/image-20200417134800315.png) + +目的是:指明注册中心为nacos,及修改nacos连接信息 + +然后启动nacos 和 seata-server + +### 怎么玩 + +- 本地:@Transaction +- 全局:@GlobalTransaction + +Spring自带的是 @Transaction 控制本地事务 + +而 @GlobalTransaction控制的是全局事务 + +![image-20200417133041311](images/image-20200417133041311.png) + +我们只需要在需要支持分布式事务的业务类上,使用该注解即可 + + + +## 订单/库存/账户业务微服务准备 + +在这之前首先需要先启动Nacos,然后启动Seata,保证两个都OK + +### 分布式事务的业务说明 + +这里我们会创建三个微服务,一个订单服务,一个库存服务,一个账户服务。 + +当用户下单时,会在订单服务中创建一个订单,然后通过远程调用库存服务来扣减下单商品的库存,在通过远程调用账户服务来扣减用户账户里面的金额,最后在订单服务修改订单状态为已完成 + +该操作跨越了三个数据库,有两次远程调用,很明显会有分布式事务的问题。 + +一句话:下订单 -> 扣库存 -> 减余额 + +### 创建数据库 + +- seata_order:存储订单的数据库 +- seata_storage:存储库存的数据库 +- seata_account:存储账户信息的数据库 + +建库SQL + +``` +create database seata_order; +create database seata_storage; +create database seata_account; +``` + +### 建立业务表 + +- seata_order库下建立t_order表 +- seata_storage库下建t_storage表 +- seata_account库下建t_account表 + +``` +DROP TABLE IF EXISTS `t_order`; +CREATE TABLE `t_order` ( + `int` bigint(11) NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) DEFAULT NULL COMMENT '用户id', + `product_id` bigint(11) DEFAULT NULL COMMENT '产品id', + `count` int(11) DEFAULT NULL COMMENT '数量', + `money` decimal(11, 0) DEFAULT NULL COMMENT '金额', + `status` int(1) DEFAULT NULL COMMENT '订单状态: 0:创建中 1:已完结', + PRIMARY KEY (`int`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '订单表' ROW_FORMAT = Dynamic; + +DROP TABLE IF EXISTS `t_storage`; +CREATE TABLE `t_storage` ( + `int` bigint(11) NOT NULL AUTO_INCREMENT, + `product_id` bigint(11) DEFAULT NULL COMMENT '产品id', + `total` int(11) DEFAULT NULL COMMENT '总库存', + `used` int(11) DEFAULT NULL COMMENT '已用库存', + `residue` int(11) DEFAULT NULL COMMENT '剩余库存', + PRIMARY KEY (`int`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '库存' ROW_FORMAT = Dynamic; +INSERT INTO `t_storage` VALUES (1, 1, 100, 0, 100); + +CREATE TABLE `t_account` ( + `id` bigint(11) NOT NULL COMMENT 'id', + `user_id` bigint(11) DEFAULT NULL COMMENT '用户id', + `total` decimal(10, 0) DEFAULT NULL COMMENT '总额度', + `used` decimal(10, 0) DEFAULT NULL COMMENT '已用余额', + `residue` decimal(10, 0) DEFAULT NULL COMMENT '剩余可用额度', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '账户表' ROW_FORMAT = Dynamic; + +INSERT INTO `t_account` VALUES (1, 1, 1000, 0, 1000); +``` + +### 创建回滚日志表 + +订单 - 库存 - 账户 3个库都需要建各自的回滚日志表,目录在 db_undo_log.sql + +``` +-- the table to store seata xid data +-- 0.7.0+ add context +-- you must to init this sql for you business databese. the seata server not need it. +-- 此脚本必须初始化在你当前的业务数据库中,用于AT 模式XID记录。与server端无关(注:业务数据库) +-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log +DROP TABLE `undo_log`; +CREATE TABLE `undo_log` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `branch_id` BIGINT(20) NOT NULL, + `xid` VARCHAR(100) NOT NULL, + `context` VARCHAR(128) NOT NULL, + `rollback_info` LONGBLOB NOT NULL, + `log_status` INT(11) NOT NULL, + `log_created` DATETIME NOT NULL, + `log_modified` DATETIME NOT NULL, + `ext` VARCHAR(100) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) +) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; +``` + + + +## 订单/库存/账户业务微服务准备 + +### 业务需求 + +下订单 -> 减库存 -> 扣余额 -> 改(订单)状态 + +### 新建Order-Module表 + +#### 约定 + +entity,domain:相当于实体类层 + +vo:view object,value object + +dto:前台传到后台的数据传输类 + +#### 新建module2001 + +#### 引入POM + +``` + + + com.alibaba.cloud + spring-cloud-starter-alibaba-seata + + + seata-all + io.seata + + + + + io.seata + seata-all + 0.9.0 + +``` + +#### 修改yml + +``` +server: + port: 2001 + +spring: + application: + name: seata-order-service + cloud: + alibaba: + seata: + #自定义事务组名称需要与seata-server中的对应 + tx-service-group: fsp_tx_group + nacos: + discovery: + server-addr: localhost:8848 + datasource: + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://localhost:3306/seata_order + username: root + password: 123456 + +feign: + hystrix: + enabled: false + +logging: + level: + io: + seata: info + +mybatis: + mapperLocations: classpath:mapper/*.xml +``` + +#### 增加file.conf + +在resources目录下,创建file.conf文件 + +``` +transport { + # tcp udt unix-domain-socket + type = "TCP" + #NIO NATIVE + server = "NIO" + #enable heartbeat + heartbeat = true + #thread factory for netty + thread-factory { + boss-thread-prefix = "NettyBoss" + worker-thread-prefix = "NettyServerNIOWorker" + server-executor-thread-prefix = "NettyServerBizHandler" + share-boss-worker = false + client-selector-thread-prefix = "NettyClientSelector" + client-selector-thread-size = 1 + client-worker-thread-prefix = "NettyClientWorkerThread" + # netty boss thread size,will not be used for UDT + boss-thread-size = 1 + #auto default pin or 8 + worker-thread-size = 8 + } + shutdown { + # when destroy server, wait seconds + wait = 3 + } + serialization = "seata" + compressor = "none" +} + +service { + + vgroup_mapping.fsp_tx_group = "default" #修改自定义事务组名称 + + default.grouplist = "127.0.0.1:8091" + enableDegrade = false + disable = false + max.commit.retry.timeout = "-1" + max.rollback.retry.timeout = "-1" + disableGlobalTransaction = false +} + + +client { + async.commit.buffer.limit = 10000 + lock { + retry.internal = 10 + retry.times = 30 + } + report.retry.count = 5 + tm.commit.retry.count = 1 + tm.rollback.retry.count = 1 +} + +## transaction log store +store { + ## store mode: file、db + mode = "db" + + ## file store + file { + dir = "sessionStore" + + # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions + max-branch-session-size = 16384 + # globe session size , if exceeded throws exceptions + max-global-session-size = 512 + # file buffer size , if exceeded allocate new buffer + file-write-buffer-cache-size = 16384 + # when recover batch read size + session.reload.read_size = 100 + # async, sync + flush-disk-mode = async + } + + ## database store + db { + ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc. + datasource = "dbcp" + ## mysql/oracle/h2/oceanbase etc. + db-type = "mysql" + driver-class-name = "com.mysql.jdbc.Driver" + url = "jdbc:mysql://127.0.0.1:3306/seata" + user = "root" + password = "123456" + min-conn = 1 + max-conn = 3 + global.table = "global_table" + branch.table = "branch_table" + lock-table = "lock_table" + query-limit = 100 + } +} +lock { + ## the lock store mode: local、remote + mode = "remote" + + local { + ## store locks in user's database + } + + remote { + ## store locks in the seata's server + } +} +recovery { + #schedule committing retry period in milliseconds + committing-retry-period = 1000 + #schedule asyn committing retry period in milliseconds + asyn-committing-retry-period = 1000 + #schedule rollbacking retry period in milliseconds + rollbacking-retry-period = 1000 + #schedule timeout retry period in milliseconds + timeout-retry-period = 1000 +} + +transaction { + undo.data.validation = true + undo.log.serialization = "jackson" + undo.log.save.days = 7 + #schedule delete expired undo_log in milliseconds + undo.log.delete.period = 86400000 + undo.log.table = "undo_log" +} + +## metrics settings +metrics { + enabled = false + registry-type = "compact" + # multi exporters use comma divided + exporter-list = "prometheus" + exporter-prometheus-port = 9898 +} + +support { + ## spring + spring { + # auto proxy the DataSource bean + datasource.autoproxy = false + } +} +``` + +#### registry.conf 注册器 + +``` +registry { + # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa + type = "nacos" + + nacos { + serverAddr = "localhost:8848" + namespace = "" + cluster = "default" + } + eureka { + serviceUrl = "http://localhost:8761/eureka" + application = "default" + weight = "1" + } + redis { + serverAddr = "localhost:6379" + db = "0" + } + zk { + cluster = "default" + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + consul { + cluster = "default" + serverAddr = "127.0.0.1:8500" + } + etcd3 { + cluster = "default" + serverAddr = "http://localhost:2379" + } + sofa { + serverAddr = "127.0.0.1:9603" + application = "default" + region = "DEFAULT_ZONE" + datacenter = "DefaultDataCenter" + cluster = "default" + group = "SEATA_GROUP" + addressWaitTime = "3000" + } + file { + name = "file.conf" + } +} + +config { + # file、nacos 、apollo、zk、consul、etcd3 + type = "file" + + nacos { + serverAddr = "localhost" + namespace = "" + } + consul { + serverAddr = "127.0.0.1:8500" + } + apollo { + app.id = "seata-server" + apollo.meta = "http://192.168.1.204:8801" + } + zk { + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + etcd3 { + serverAddr = "http://localhost:2379" + } + file { + name = "file.conf" + } +} +``` + +#### domain + +``` +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CommonResult +{ + private Integer code; + private String message; + private T data; + + public CommonResult(Integer code, String message) + { + this(code,message,null); + } +} + + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Order +{ + private Long id; + + private Long userId; + + private Long productId; + + private Integer count; + + private BigDecimal money; + + private Integer status; //订单状态:0:创建中;1:已完结 +} +``` + +#### Dao接口及实现 + +``` +@Mapper +public interface OrderDao +{ + //1 新建订单 + void create(Order order); + + //2 修改订单状态,从零改为1 + void update(@Param("userId") Long userId,@Param("status") Integer status); +} +``` + +``` + + + + + + + + + + + + + + + + insert into t_order (id,user_id,product_id,count,money,status) + values (null,#{userId},#{productId},#{count},#{money},0); + + + + update t_order set status = 1 + where user_id=#{userId} and status = #{status}; + + + +``` + +#### Service实现类 + +OrderService接口 + +``` +public interface OrderService +{ + void create(Order order); +} +``` + +StorageService的Feign接口, + +``` +@FeignClient(value = "seata-storage-service") +public interface StorageService +{ + @PostMapping(value = "/storage/decrease") + CommonResult decrease(@RequestParam("productId") Long productId, @RequestParam("count") Integer count); +} +``` + +AccountService的Feign接口,账户接口 + +``` +@FeignClient(value = "seata-account-service") +public interface AccountService +{ + @PostMapping(value = "/account/decrease") + CommonResult decrease(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money); +} +``` + + + +OrderServiceImpl实现类 + +``` +@Service +@Slf4j +public class OrderServiceImpl implements OrderService +{ + @Resource + private OrderDao orderDao; + @Resource + private StorageService storageService; + @Resource + private AccountService accountService; + + /** + * 创建订单->调用库存服务扣减库存->调用账户服务扣减账户余额->修改订单状态 + * 简单说:下订单->扣库存->减余额->改状态 + */ + @Override + @GlobalTransactional(name = "fsp-create-order",rollbackFor = Exception.class) + public void create(Order order) + { + log.info("----->开始新建订单"); + //1 新建订单 + orderDao.create(order); + + //2 扣减库存 + log.info("----->订单微服务开始调用库存,做扣减Count"); + storageService.decrease(order.getProductId(),order.getCount()); + log.info("----->订单微服务开始调用库存,做扣减end"); + + //3 扣减账户 + log.info("----->订单微服务开始调用账户,做扣减Money"); + accountService.decrease(order.getUserId(),order.getMoney()); + log.info("----->订单微服务开始调用账户,做扣减end"); + + //4 修改订单状态,从零到1,1代表已经完成 + log.info("----->修改订单状态开始"); + orderDao.update(order.getUserId(),0); + log.info("----->修改订单状态结束"); + + log.info("----->下订单结束了,O(∩_∩)O哈哈~"); + + } +} +``` + +#### 业务类 + +``` +@RestController +public class OrderController +{ + @Resource + private OrderService orderService; + + + @GetMapping("/order/create") + public CommonResult create(Order order) + { + orderService.create(order); + return new CommonResult(200,"订单创建成功"); + } +} +``` + +#### Config配置 + +Mybatis DataSourceProxyConfig配置,这里是使用Seata对数据源进行代理 + +``` +@Configuration +public class DataSourceProxyConfig { + + @Value("${mybatis.mapperLocations}") + private String mapperLocations; + + @Bean + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource druidDataSource(){ + return new DruidDataSource(); + } + + @Bean + public DataSourceProxy dataSourceProxy(DataSource dataSource) { + return new DataSourceProxy(dataSource); + } + + @Bean + public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception { + SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); + sqlSessionFactoryBean.setDataSource(dataSourceProxy); + sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations)); + sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory()); + return sqlSessionFactoryBean.getObject(); + } + +} +``` + +Mybatis配置 + +``` +@Configuration +@MapperScan({"com.atguigu.springcloud.alibaba.dao"}) +public class MyBatisConfig { +} +``` + +#### 启动类 + +``` +@EnableDiscoveryClient +@EnableFeignClients +@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//取消数据源的自动创建 +public class SeataOrderMainApp2001 +{ + + public static void main(String[] args) + { + SpringApplication.run(SeataOrderMainApp2001.class, args); + } +} +``` + +### 新建Storage-Module + +参考项目:seata-storage-service2002 + +### 新建账户Account-Module + +参考项目:seata-account-service2003 + +### 测试 + +#### 数据库初始情况 + +![image-20200417225230939](images/image-20200417225230939.png) + +#### 正常下单 + +访问 + +``` +http://localhost:2001/order/create?userId=1&productId=1&count=10&money=100 +``` + +![image-20200417225932063](images/image-20200417225932063.png) + + + +#### 超时异常,没加@GlobalTransaction + +我们在account-module模块,添加睡眠时间20秒,因为openFeign默认时间是1秒 + +![image-20200417230124982](images/image-20200417230124982.png) + +出现了数据不一致的问题 + +故障情况 + +- 当库存和账户金额扣减后,订单状态并没有设置成已经完成,没有从零改成1 +- 而且由于Feign的重试机制,账户余额还有可能被多次扣除 + +#### 超时异常,添加@GlobalTransaction + +``` +@GlobalTransactional(name = "fsp-create-order",rollbackFor = Exception.class) +``` + +rollbackFor表示,什么什么错误就会回滚 + +添加这个后,发现下单后的数据库并没有改变,记录都添加不进来 + + + +## 一部分补充 + +### Seata + +2019年1月份,蚂蚁金服和阿里巴巴共同开源的分布式事务解决方案 + +Seata:Simple Extensible Autonomous Transaction Architecture,简单可扩展自治事务框架 + +2020起始,参加工作以后用1.0以后的版本。 + +### 再看TC/TM/RM三大组件 + +![image-20200417231145550](images/image-20200417231145550.png) + +什么是TC,TM,RM + +TC:seata服务器 + +TM:带有@GlobalTransaction注解的方法 + +RM:数据库,也就是事务参与方 + +![image-20200417231314748](images/image-20200417231314748.png) + +### 分布式事务的执行流程 + +- TM开启分布式事务(TM向TC注册全局事务记录),相当于注解 `@GlobelTransaction`注解 +- 按业务场景,编排数据库,服务等事务内部资源(RM向TC汇报资源准备状态) +- TM结束分布式事务,事务一阶段结束(TM通知TC提交、回滚分布式事务) +- TC汇总事务信息,决定分布式事务是提交还是回滚 +- TC通知所有RM提交、回滚资源,事务二阶段结束 + +### AT模式如何做到对业务的无侵入 + +默认AT模式,阿里云GTS + +### AT模式 + +#### 前提 + +- 基于支持本地ACID事务的关系型数据库 +- Java应用,通过JDBC访问数据库 + +#### 整体机制 + +两阶段提交协议的演变 + +- 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源 +- 二阶段 + - 提交异步化,非常快速的完成 + - 回滚通过一阶段的回滚日志进行反向补偿 + +#### 一阶段加载 + +在一阶段,Seata会拦截 业务SQL + +- 解析SQL语义,找到业务SQL,要更新的业务数据,在业务数据被更新前,将其保存成 `before image(前置镜像)` +- 执行业务SQL更新业务数据,在业务数据更新之后 +- 将其保存成 after image,最后生成行锁 + +以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性 + +![image-20200417232316157](images/image-20200417232316157.png) + +#### 二阶段提交 + +二阶段如果顺利提交的话,因为业务SQL在一阶段已经提交至数据库,所以Seata框架只需将一阶段保存的快照和行锁删除掉,完成数据清理即可 + +![image-20200417232502282](images/image-20200417232502282.png) + +#### 二阶段回滚 + +二阶段如果回滚的话,Seata就需要回滚到一阶段已经执行的 业务SQL,还原业务数据 + +回滚方式便是用 before image 还原业务数据,但是在还原前要首先校验脏写,对比数据库当前业务数据 和after image,如果两份数据完全一致,没有脏写,可以还原业务数据,如果不一致说明有脏读,出现脏读就需要转人工处理 + +![image-20200417232859708](images/image-20200417232859708.png) + +#### 总结 + +![image-20200417233926182](images/image-20200417233926182.png) \ No newline at end of file diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417081113603.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417081113603.png" new file mode 100644 index 0000000000000000000000000000000000000000..5560db7479806c496cf0f42ad4b88c65687a3751 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417081113603.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417081239933.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417081239933.png" new file mode 100644 index 0000000000000000000000000000000000000000..e66d3272639c253e87af4a640486525890387cd5 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417081239933.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417121037783.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417121037783.png" new file mode 100644 index 0000000000000000000000000000000000000000..a6f6cb6bfef5d6ef4b1a2dda30ac45e080148e9a Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417121037783.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417133041311.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417133041311.png" new file mode 100644 index 0000000000000000000000000000000000000000..fac280c6eb41e7948462fd8a30c8673859d671bb Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417133041311.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417133537054.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417133537054.png" new file mode 100644 index 0000000000000000000000000000000000000000..eef711ee8a4780f40bab45b95a15940223bba205 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417133537054.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417133715606.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417133715606.png" new file mode 100644 index 0000000000000000000000000000000000000000..1dc1714dbc5b475aef98aea5ec59111b6ce9233f Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417133715606.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417134353031.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417134353031.png" new file mode 100644 index 0000000000000000000000000000000000000000..3508a1f1528cef13bfa42629ff45d704e82a9f90 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417134353031.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417134800315.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417134800315.png" new file mode 100644 index 0000000000000000000000000000000000000000..4cd1a4cf4d60477103cef68df41999175baf35d3 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417134800315.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417225230939.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417225230939.png" new file mode 100644 index 0000000000000000000000000000000000000000..80c97822f55386ff44c52a0e586b506d2891761d Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417225230939.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417225932063.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417225932063.png" new file mode 100644 index 0000000000000000000000000000000000000000..92aec99961cc9eb1e275ed3e5c7907f1afe9efea Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417225932063.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417230124982.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417230124982.png" new file mode 100644 index 0000000000000000000000000000000000000000..33b54169b16e8861041480ce43c89327c7f1cc4e Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417230124982.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417231145550.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417231145550.png" new file mode 100644 index 0000000000000000000000000000000000000000..80e1b2e24d923a662edf143bac6444d0940eb4e7 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417231145550.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417231314748.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417231314748.png" new file mode 100644 index 0000000000000000000000000000000000000000..b2656d04b47571b7414e855feb236660d77abfa5 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417231314748.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417232316157.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417232316157.png" new file mode 100644 index 0000000000000000000000000000000000000000..a584b4436bbee1adc69dec4534d2d8f2bb446c9f Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417232316157.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417232502282.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417232502282.png" new file mode 100644 index 0000000000000000000000000000000000000000..94067d953ad628b7d9a33658ecb2537935358b1c Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417232502282.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417232859708.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417232859708.png" new file mode 100644 index 0000000000000000000000000000000000000000..95094d90d5679b9c136c8079159e012a0b98bffa Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417232859708.png" differ diff --git "a/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417233926182.png" "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417233926182.png" new file mode 100644 index 0000000000000000000000000000000000000000..02cb7df82c633dafa08051a4e6815c99f5f63d38 Binary files /dev/null and "b/SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata\345\244\204\347\220\206\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241/images/image-20200417233926182.png" differ diff --git "a/SpringCloud/SpringCloud2020/3_\346\220\255\345\273\272Eureka\351\233\206\347\276\244/README.md" "b/SpringCloud/SpringCloud2020/3_\346\220\255\345\273\272Eureka\351\233\206\347\276\244/README.md" index 5cea0af4b90ad756ad339cfba3eccff086bf9202..123d9a9e427460fcaade518ea7ecd74c7e57da69 100644 --- "a/SpringCloud/SpringCloud2020/3_\346\220\255\345\273\272Eureka\351\233\206\347\276\244/README.md" +++ "b/SpringCloud/SpringCloud2020/3_\346\220\255\345\273\272Eureka\351\233\206\347\276\244/README.md" @@ -8,8 +8,6 @@ - 服务发现:从注册中心上获取服务信息 - 实质:存key服务命名,取value调用地址 - - 1. 先启动eureka注册中心 2. 启动服务提供者payment支付服务 3. 支付服务启动后,会把自身信息(比如 服务地址以别名方式注册进eureka) @@ -369,8 +367,6 @@ eureka: 设置完成后,只要服务宕机,会马上从服务注册列表中清除 - - ## 关于Eureka停更 Eureka停更后,出现了其它的替代者 diff --git a/SpringCloud/SpringCloud2020/README.md b/SpringCloud/SpringCloud2020/README.md new file mode 100644 index 0000000000000000000000000000000000000000..625fa3638b617005bf8ae8120323623a3c37c0a0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/README.md @@ -0,0 +1,19 @@ +## SpringCloud + +> 来源Bilibili尚硅谷周阳老师学习视频:[尚硅谷2020最新版SpringCloud(H版&alibaba)框架](https://www.bilibili.com/video/BV18E411x7eT) + +- [SpringCloud是什么](./1_SpringCloud是什么) +- [搭建Eureka集群](./3_搭建Eureka集群)  [传送门](http://www.moguit.cn/#/info?blogUid=bcbe47eb92aa3ca50fe57f0154a0d03c) +- [Eureka停更后的替换](./4_Eureka停更后的替换)  [传送门](http://www.moguit.cn/#/info?blogUid=d60f64857d0d4c01e99de1f8715db75d) +- [Ribbon负载均衡](./5_Ribbon负载均衡)   [传送门](http://www.moguit.cn/#/info?blogUid=ada9f522a377c5b3a2a323cabd376637) +- [OpenFeign实现服务调用](./6_OpenFeign实现服务调用)   [传送门](http://www.moguit.cn/#/info?blogUid=32fcba6449f1caac0a7ecb2fef323158) +- [Hystrix中的服务降级和熔断](./7_Hystrix中的服务降级和熔断)   [传送门](http://www.moguit.cn/#/info?blogUid=030a46c4ac414860135f6500ba7683af) +- [服务网关Gateway](./8_服务网关Gateway)  [传送门](http://www.moguit.cn/#/info?blogUid=d0fbc44ce9abb852f095ba3293bc8f5e) +- [分布式配置中心SpringCloudConfig](./9_分布式配置中心SpringCloudConfig)  [传送门](http://www.moguit.cn/#/info?blogUid=abea85566c6ce7a7bbd7a290ff40be59) +- [消息总线Bus](./10_消息总线Bus)  [传送门](http://www.moguit.cn/#/info?blogUid=3c228ae1db6a9313ab4068ccdd9921ff) +- [消息驱动SpringCloudStream](./11_消息驱动SpringCloudStream)  [传送门](http://www.moguit.cn/#/info?blogUid=a4ac92b0bafc804629a9aa0309dc36e6) +- [SpringCloudSleuth分布式请求链路跟踪](./12_SpringCloudSleuth分布式请求链路跟踪)  [传送门](http://www.moguit.cn/#/info?blogUid=7e4fd64914beae0ffc521bff1541cacc) +- [使用Nacos实现服务注册发现以及服务配置等功能](./13_Nacos是什么)  [传送门](http://www.moguit.cn/#/info?blogUid=e6e619349d31dded928c9265c5a9c672) +- [SpringCloudAlibabaSentinel实现熔断和限流](./14_SpringCloudAlibabaSentinel实现熔断和限流)  [传送门](http://www.moguit.cn/#/info?blogUid=408e9c889ebf96a66af2adfdc258ba5f) +- [SpringCloudAlibabaSeata处理分布式事务](./15_SpringCloudAlibabaSeata处理分布式事务)  [传送门](http://www.moguit.cn/#/info?blogUid=5f17644d6db710c60fc42fad561000bd) +- [源码](SpringCloud2020) \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/.gitignore b/SpringCloud/SpringCloud2020/cloud2020/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..5c98b428844d9f7d529e2b6fb918d15bf072f3df --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/cloud2020.iml b/SpringCloud/SpringCloud2020/cloud2020/.idea/cloud2020.iml new file mode 100644 index 0000000000000000000000000000000000000000..f409c0ea8d8352a600994b03eff71bf727df5857 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/cloud2020.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/compiler.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/compiler.xml new file mode 100644 index 0000000000000000000000000000000000000000..d3cd4623a5cfe337de1219b67e256c269e5b786a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/compiler.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/encodings.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/encodings.xml new file mode 100644 index 0000000000000000000000000000000000000000..58184291fb71c8a4fafbb32afa372004c335b9e5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/encodings.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/inspectionProfiles/Project_Default.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000000000000000000000000000000000000..e9844ba05b4c5809f12af8e912faa69b718124f9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__antlr_antlr_2_7_7.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__antlr_antlr_2_7_7.xml new file mode 100644 index 0000000000000000000000000000000000000000..b8d93d8e01dadbfcc25cc9e16e8b69b5dfdefcb2 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__antlr_antlr_2_7_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..30ff5cb79106a1706b39c305da86ff96a2d96118 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__cglib_cglib_3_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__cglib_cglib_3_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..bd3cddd6ba0ac1a7aed8c50b8c5f30cb6945aa20 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__cglib_cglib_3_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..6fec8f4346ac31350b855bd6cd3886f1d15e3f79 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..9eb8596a33a55f6e2480baf37393b24b7ae8da60 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__cn_hutool_hutool_all_4_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__cn_hutool_hutool_all_4_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..2decf29c24ef7c5d85cb06eb78613c77fca345a0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__cn_hutool_hutool_all_4_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__cn_hutool_hutool_all_5_1_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__cn_hutool_hutool_all_5_1_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..0dbafef857fafa10ff8f3df96a624455cfc23294 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__cn_hutool_hutool_all_5_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__cn_hutool_hutool_all_5_3_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__cn_hutool_hutool_all_5_3_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..20eb9aafcc9f9e7ab61149cec35a82e9997be53d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__cn_hutool_hutool_all_5_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_nacos_config_2_1_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_nacos_config_2_1_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..e3970783c9b203108a32ac8958a8dd15eda68aa5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_nacos_config_2_1_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_nacos_discovery_2_1_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_nacos_discovery_2_1_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..771267348e7afd381aa77eedb9e642b96e5ef73a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_nacos_discovery_2_1_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_seata_2_1_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_seata_2_1_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..cd1d1f556d85fdab965e2f0c65f25434a4bc9a4d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_seata_2_1_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_sentinel_2_1_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_sentinel_2_1_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..22e6aeb85ddbe9c2a7ef3fc26ee81dda1b428c8d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_sentinel_2_1_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_sentinel_datasource_2_1_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_sentinel_datasource_2_1_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..0505068d4c2b849eb7dec622cfa9c900c21af93a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_alibaba_sentinel_datasource_2_1_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_starter_alibaba_nacos_config_2_1_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_starter_alibaba_nacos_config_2_1_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..91cbd4028f2c1026189ed753b2cee75588bedd06 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_starter_alibaba_nacos_config_2_1_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_starter_alibaba_nacos_discovery_2_1_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_starter_alibaba_nacos_discovery_2_1_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..ca9616fb3ea8b775a974c5153cc76acf344e60b6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_starter_alibaba_nacos_discovery_2_1_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_starter_alibaba_seata_2_1_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_starter_alibaba_seata_2_1_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..6c9d74d7216014e87eaaf4a8b0d6106893b065d5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_starter_alibaba_seata_2_1_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_starter_alibaba_sentinel_2_1_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_starter_alibaba_sentinel_2_1_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..5292d470bfbaa1515661443d9d325ee6281ae2eb --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_cloud_spring_cloud_starter_alibaba_sentinel_2_1_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_annotation_aspectj_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_annotation_aspectj_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..15e31414a183f36c883093a8331bba2d3a9fdd23 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_annotation_aspectj_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_cluster_client_default_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_cluster_client_default_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..db821b4a5e60c2a963efbd5b9150facebf3f46b8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_cluster_client_default_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_cluster_common_default_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_cluster_common_default_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..eec51f5e77abc3ffffc2364bb9481f340a9a2bbc --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_cluster_common_default_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_cluster_server_default_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_cluster_server_default_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..2eab4fee87c3c820c453dba08752728db44bd776 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_cluster_server_default_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_core_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_core_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..b71062ed3cab72cae49b8f9b175f3d59cb07a691 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_core_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_datasource_extension_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_datasource_extension_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..20ecffe4164b7c4ab34f9759b2f803dc76ec4b5f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_datasource_extension_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_datasource_nacos_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_datasource_nacos_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..8985ebcebad905f60de242f3cc77c7d215b7f4b1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_datasource_nacos_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_parameter_flow_control_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_parameter_flow_control_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..876e2573aba3dedbc239404ed3e07a7e7518f263 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_parameter_flow_control_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_reactor_adapter_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_reactor_adapter_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..896c5ea3f2cdbd0f62337b55970fba6a59ab0107 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_reactor_adapter_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_spring_webflux_adapter_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_spring_webflux_adapter_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..9d25a2f124e5edfbaedc865d78928ee0707824ad --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_spring_webflux_adapter_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_transport_common_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_transport_common_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..eb823e421aa711a51eae78d5fbc5076545c374fe --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_transport_common_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_transport_simple_http_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_transport_simple_http_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..928b48c569fda04550e4dce9e7f974ca476bf6e8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_transport_simple_http_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_web_servlet_1_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_web_servlet_1_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..fcdcd2446262abcb379a38d1c80ca04d13d62776 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_csp_sentinel_web_servlet_1_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_druid_1_1_16.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_druid_1_1_16.xml new file mode 100644 index 0000000000000000000000000000000000000000..0aedc628c922faeb37b864dd9259c938161f74ac --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_druid_1_1_16.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_druid_spring_boot_starter_1_1_10.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_druid_spring_boot_starter_1_1_10.xml new file mode 100644 index 0000000000000000000000000000000000000000..74fcd43e41862c8d4c946a8a510b60c96de7dad6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_druid_spring_boot_starter_1_1_10.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_fastjson_1_2_47.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_fastjson_1_2_47.xml new file mode 100644 index 0000000000000000000000000000000000000000..dcd6ee594b31b9c7765dc7dbdc46f68986c06bd5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_fastjson_1_2_47.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_fastjson_1_2_60.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_fastjson_1_2_60.xml new file mode 100644 index 0000000000000000000000000000000000000000..567a6430185663c525d4c649eb1924087b44c1c4 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_fastjson_1_2_60.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_nacos_nacos_api_1_1_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_nacos_nacos_api_1_1_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..1de6629829003e36ee24ab6fa557de0d734c5962 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_nacos_nacos_api_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_nacos_nacos_client_1_1_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_nacos_nacos_client_1_1_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..2b7a2dfd2c44f5a9d6d30d5354f04859a86254da --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_nacos_nacos_client_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_nacos_nacos_common_1_1_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_nacos_nacos_common_1_1_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..3c64a640f436260be3fd3f1ac6bad341c0704fef --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_alibaba_nacos_nacos_common_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_ecwid_consul_consul_api_1_4_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_ecwid_consul_consul_api_1_4_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..30b747b8ba2eec9ee1b7a72ef5dbf55032bf726e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_ecwid_consul_consul_api_1_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_classmate_1_5_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_classmate_1_5_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..bc7d7fd869dadc58b6b2b17fd7852efe43e1671f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_classmate_1_5_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_10_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_10_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..81b7257fdbb0d42b29eb7fd5087b55e519282c29 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_10_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_10_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_10_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..f1b25f9c4851ca85a87941059531d959c3fd927e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_10_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_10_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_10_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..bdf5b51f80e05a1b5659840cda7ab1404b2797b3 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_10_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_xml_2_10_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_xml_2_10_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..150cb403c5f684169f2f1a879ee582b7a7f003b5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_xml_2_10_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_yaml_2_10_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_yaml_2_10_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..b151c8e1555b0681e1853cd9abe2079623d60a75 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_dataformat_jackson_dataformat_yaml_2_10_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_10_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_10_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..c142edba8ea72d4fb5eff5262cba7571e84ecbfa --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_10_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_10_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_10_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..07259bef50c917b7a11ade6c1f41b8820a758c09 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_10_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_afterburner_2_10_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_afterburner_2_10_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..9182d62e1be3a3a810dc88b31c2a4e93fea64569 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_afterburner_2_10_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_jaxb_annotations_2_10_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_jaxb_annotations_2_10_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..606e3b3746137c071ba5be2770a009e56ca71c60 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_jaxb_annotations_2_10_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_10_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_10_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..8f08fe18d2faaf6dedce09544f1061e1c868902d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_10_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_woodstox_woodstox_core_5_2_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_woodstox_woodstox_core_5_2_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..0cf8aa1319098c7e312b238aae3e864b717b1d9e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_fasterxml_woodstox_woodstox_core_5_2_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_github_ben_manes_caffeine_caffeine_2_8_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_github_ben_manes_caffeine_caffeine_2_8_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..8f636b518e4156e9ef33a94cfa3fad5060ffa812 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_github_ben_manes_caffeine_caffeine_2_8_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_code_findbugs_jsr305_3_0_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_code_findbugs_jsr305_3_0_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..09453c91f2219c770b1ac5a50b8f66adbdff9e69 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_code_findbugs_jsr305_3_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_code_gson_gson_2_8_6.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_code_gson_gson_2_8_6.xml new file mode 100644 index 0000000000000000000000000000000000000000..82a9f20a6bba1fa25f7a2732601572f94b1dc77e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_code_gson_gson_2_8_6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_errorprone_error_prone_annotations_2_3_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_errorprone_error_prone_annotations_2_3_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..1c81eb05d86c58ec28a20698a708108aa31d1dc5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_errorprone_error_prone_annotations_2_3_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_guava_guava_15_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_guava_guava_15_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..8ae2de1289a449c0fe7cdcf49141fba056823954 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_guava_guava_15_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_guava_guava_16_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_guava_guava_16_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..91cff2f5a6d8fa4c99903044284eded78c9b7ba3 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_guava_guava_16_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_guava_guava_16_0_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_guava_guava_16_0_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..b7c7684574d21ff2adc6926ab569d20303fee896 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_guava_guava_16_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_guava_guava_19_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_guava_guava_19_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..68e23ccd00646751958b22e63211a5da6e79bdbc --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_guava_guava_19_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_inject_guice_4_1_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_inject_guice_4_1_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..e956197de3e0960e9eb90e621bc2b8b19982bb6e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_inject_guice_4_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_protobuf_protobuf_java_3_7_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_protobuf_protobuf_java_3_7_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..06e923041e76ff744219c26bf1a286f5392351d6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_google_protobuf_protobuf_java_3_7_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_googlecode_concurrentlinkedhashmap_concurrentlinkedhashmap_lru_1_4_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_googlecode_concurrentlinkedhashmap_concurrentlinkedhashmap_lru_1_4_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..e497bcba5b5b4be80c2b0956f9d26e90bfdbcf7e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_googlecode_concurrentlinkedhashmap_concurrentlinkedhashmap_lru_1_4_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_googlecode_javaewah_JavaEWAH_1_1_6.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_googlecode_javaewah_JavaEWAH_1_1_6.xml new file mode 100644 index 0000000000000000000000000000000000000000..9ee346c5030d8c32f9872837795b33fbf34f8e9c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_googlecode_javaewah_JavaEWAH_1_1_6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_jayway_jsonpath_json_path_2_4_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_jayway_jsonpath_json_path_2_4_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..f19f6eb36d90a68eaceb438559d62b3054eaef31 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_jayway_jsonpath_json_path_2_4_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_jcraft_jsch_0_1_54.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_jcraft_jsch_0_1_54.xml new file mode 100644 index 0000000000000000000000000000000000000000..2a43ce7570aa3cee5e24698900769346280aa8b1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_jcraft_jsch_0_1_54.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_jcraft_jzlib_1_1_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_jcraft_jzlib_1_1_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..3795be8a02d6658f0d5e27744e52ac2a4a070a5d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_jcraft_jzlib_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_archaius_archaius_core_0_7_6.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_archaius_archaius_core_0_7_6.xml new file mode 100644 index 0000000000000000000000000000000000000000..bd9061c2646932de076caa04eb60b2e0d8ec8b83 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_archaius_archaius_core_0_7_6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_eureka_eureka_client_1_9_13.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_eureka_eureka_client_1_9_13.xml new file mode 100644 index 0000000000000000000000000000000000000000..0232f885f9a34d5e15130635afc2622ca72d214c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_eureka_eureka_client_1_9_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_eureka_eureka_core_1_9_13.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_eureka_eureka_core_1_9_13.xml new file mode 100644 index 0000000000000000000000000000000000000000..2cc53836910dbf52df5a8837a2201c9e76973f67 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_eureka_eureka_core_1_9_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_hystrix_hystrix_core_1_5_18.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_hystrix_hystrix_core_1_5_18.xml new file mode 100644 index 0000000000000000000000000000000000000000..588dca0fcf116bd100ecda0a75dc805c8cfe01d2 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_hystrix_hystrix_core_1_5_18.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_hystrix_hystrix_javanica_1_5_18.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_hystrix_hystrix_javanica_1_5_18.xml new file mode 100644 index 0000000000000000000000000000000000000000..4abf577035009375c3a7a0dc61a5e8a1cb7339c7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_hystrix_hystrix_javanica_1_5_18.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_hystrix_hystrix_metrics_event_stream_1_5_18.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_hystrix_hystrix_metrics_event_stream_1_5_18.xml new file mode 100644 index 0000000000000000000000000000000000000000..eb0c81dd457087b823a38dc0aec8e55a4338e1f1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_hystrix_hystrix_metrics_event_stream_1_5_18.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_hystrix_hystrix_serialization_1_5_18.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_hystrix_hystrix_serialization_1_5_18.xml new file mode 100644 index 0000000000000000000000000000000000000000..0c801493b536e249da8443f9e106eca15361cbd1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_hystrix_hystrix_serialization_1_5_18.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_netflix_commons_netflix_commons_util_0_3_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_netflix_commons_netflix_commons_util_0_3_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..a1a320cd68fc30976383ba104e07d0f361cb4cad --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_netflix_commons_netflix_commons_util_0_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_netflix_commons_netflix_eventbus_0_3_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_netflix_commons_netflix_eventbus_0_3_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..85ba8c99e8a54e84b46f582c921e6bc4dc91ac7a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_netflix_commons_netflix_eventbus_0_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_netflix_commons_netflix_infix_0_3_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_netflix_commons_netflix_infix_0_3_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..c8b512e3a8395746382d75bc1f357a25669a942c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_netflix_commons_netflix_infix_0_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_netflix_commons_netflix_statistics_0_1_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_netflix_commons_netflix_statistics_0_1_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..09c6f6e0babe58aa906e623c337c3662a3320a5a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_netflix_commons_netflix_statistics_0_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_2_3_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_2_3_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..28cf88000c74f0c4acb7753f87dad171ee76818f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_2_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_core_2_3_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_core_2_3_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..eff738de4350eac721e2e4260c898dcc2de52020 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_core_2_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_eureka_2_3_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_eureka_2_3_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..4b0af0d637009bb1bb33aadc7a8cd2c21032dba9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_eureka_2_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_httpclient_2_3_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_httpclient_2_3_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..13122699c562eb1580dc820f78de0bf8e638b832 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_httpclient_2_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_loadbalancer_2_3_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_loadbalancer_2_3_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..a1ff3f02abf246939614adfeb4c5bd3d938cbcc3 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_loadbalancer_2_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_transport_2_3_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_transport_2_3_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..658fe0c29566b3b9cb3aa9be2a5ebcba705e3aca --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_ribbon_ribbon_transport_2_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_servo_servo_core_0_12_21.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_servo_servo_core_0_12_21.xml new file mode 100644 index 0000000000000000000000000000000000000000..837985aac416556859b7a06652c6ab2c58780d2d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_netflix_servo_servo_core_0_12_21.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_rabbitmq_amqp_client_5_7_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_rabbitmq_amqp_client_5_7_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..373e329d96f59ba520b23cbc4f706a20c70bbace --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_rabbitmq_amqp_client_5_7_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_rabbitmq_http_client_2_1_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_rabbitmq_http_client_2_1_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..cf6e5e0c9dce242b3aa60191c823adf4c3bbf64c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_rabbitmq_http_client_2_1_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_stoyanr_evictor_1_0_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_stoyanr_evictor_1_0_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..4f6676e4410e1caebc47bc93db0e4b30ccb86985 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_stoyanr_evictor_1_0_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_istack_istack_commons_runtime_3_0_8.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_istack_istack_commons_runtime_3_0_8.xml new file mode 100644 index 0000000000000000000000000000000000000000..bea8d79f9132d5743f7aeaebbd0983824ac11489 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_istack_istack_commons_runtime_3_0_8.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_contribs_jersey_apache_client4_1_19_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_contribs_jersey_apache_client4_1_19_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..2061d8cf5ea09b327c266cfffe21934e79a024b8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_contribs_jersey_apache_client4_1_19_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_jersey_client_1_19_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_jersey_client_1_19_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..2b077bc222e72315623310d60ac9b32e44cb9ffb --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_jersey_client_1_19_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_jersey_core_1_19_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_jersey_core_1_19_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..91d65b20118795164166fc123f32d23dc669998a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_jersey_core_1_19_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_jersey_server_1_19_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_jersey_server_1_19_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..b4ad3ded6f0d2d3d3c839585557cd7e74dc4db7b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_jersey_server_1_19_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_jersey_servlet_1_19_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_jersey_servlet_1_19_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..943df5a5118143f9c9c3012f1b7cdad3c801762e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_jersey_jersey_servlet_1_19_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_xml_fastinfoset_FastInfoset_1_2_16.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_xml_fastinfoset_FastInfoset_1_2_16.xml new file mode 100644 index 0000000000000000000000000000000000000000..aa1516a06ed700e32aa7dcf5bea7c0d2f38bb25e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_sun_xml_fastinfoset_FastInfoset_1_2_16.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_thoughtworks_xstream_xstream_1_4_11_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_thoughtworks_xstream_xstream_1_4_11_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..ba904efb0564d2a239f1d2f26e64e30423823765 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_thoughtworks_xstream_xstream_1_4_11_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_typesafe_config_1_2_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_typesafe_config_1_2_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..cc787214989ccb7e835be7612fcf2cb39279d093 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_typesafe_config_1_2_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml new file mode 100644 index 0000000000000000000000000000000000000000..b8581a6f5eef96c4979f258063e7c7c8d633f024 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_zaxxer_HikariCP_3_4_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_zaxxer_HikariCP_3_4_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..8902ae527a8d1ca310584c835447ce483d7d43df --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__com_zaxxer_HikariCP_3_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_codec_commons_codec_1_13.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_codec_commons_codec_1_13.xml new file mode 100644 index 0000000000000000000000000000000000000000..5384f7ab5d5e63133c525a595ddf17b35a92e165 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_codec_commons_codec_1_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_collections_commons_collections_3_2_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_collections_commons_collections_3_2_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..13afda2962f972e7f2e35e97e6a0dc52d8e90bbb --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_collections_commons_collections_3_2_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_configuration_commons_configuration_1_8.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_configuration_commons_configuration_1_8.xml new file mode 100644 index 0000000000000000000000000000000000000000..772d6fed2b029dda09f880f08ee03d6295875ebe --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_configuration_commons_configuration_1_8.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_fileupload_commons_fileupload_1_4.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_fileupload_commons_fileupload_1_4.xml new file mode 100644 index 0000000000000000000000000000000000000000..3b9dcc07e76cb11ea1932a8ade1ea970da60aee1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_fileupload_commons_fileupload_1_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_io_commons_io_2_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_io_commons_io_2_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..f8084ec2882480e132da7ce7f7341a8a8f498307 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_io_commons_io_2_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_jxpath_commons_jxpath_1_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_jxpath_commons_jxpath_1_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..1816895793087fffa8497e12d67048e2d60a4fcb --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_jxpath_commons_jxpath_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_lang_commons_lang_2_6.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_lang_commons_lang_2_6.xml new file mode 100644 index 0000000000000000000000000000000000000000..2ec837671d1d569002bd379eaa8e1c32929c626e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_lang_commons_lang_2_6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_pool_commons_pool_1_6.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_pool_commons_pool_1_6.xml new file mode 100644 index 0000000000000000000000000000000000000000..83936486814b86d79831e468dfb047b15d0314a3 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__commons_pool_commons_pool_1_6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_feign_core_10_4_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_feign_core_10_4_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..639427fb6a597142cb4a93febfbb4535145d2e17 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_feign_core_10_4_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_feign_hystrix_10_4_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_feign_hystrix_10_4_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..91c675e581557f09b31b1157d4ce297ff12983ee --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_feign_hystrix_10_4_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_feign_slf4j_10_4_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_feign_slf4j_10_4_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..b604121746289d5b087b2c77aae7a5a1f54f8333 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_feign_slf4j_10_4_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_form_feign_form_3_8_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_form_feign_form_3_8_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..05344763191b3da6d310dcd29049521bcf1335f1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_form_feign_form_3_8_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_form_feign_form_spring_3_8_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_form_feign_form_spring_3_8_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..47e101ee2f3f7f97c36c70bdc58159c09786269b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_github_openfeign_form_feign_form_spring_3_8_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_micrometer_micrometer_core_1_3_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_micrometer_micrometer_core_1_3_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..37b4f0efee1bf6d7e0ee4c82d10b66950810afce --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_micrometer_micrometer_core_1_3_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_3_10_5_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_3_10_5_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..d1cfe8029db87f7f758e44ddddd19a1b80393762 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_3_10_5_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_all_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_all_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..ae34c58aaf82c859d1c94be65a0bce6d52adec44 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_all_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_buffer_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_buffer_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..a42dce8dca0d3c28b4d5fa855a6428f920227c6b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_buffer_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_codec_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_codec_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..595a17c1127d17ec50ecb9cde1c420485963430b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_codec_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_codec_http2_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_codec_http2_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..08d41c893f837e74ad4ecdfcde7451d5420f72ee --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_codec_http2_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_codec_http_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_codec_http_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..f7e78387ebcd0c7f73dbba75ff9055bfbb6d98dc --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_codec_http_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_codec_socks_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_codec_socks_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..4864c8f4b5c139386d3269cae5c964de3a9adb8c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_codec_socks_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_common_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_common_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..fd4c34961f0a68054a73652758f48b80ccd02a7e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_common_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_handler_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_handler_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..bfcd64b4af92e06d69a678bba0052e992f9d8a83 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_handler_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_handler_proxy_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_handler_proxy_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..2e8a186fb11b20e83ad3bed4a4cf2e8cca03c59a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_handler_proxy_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_resolver_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_resolver_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..d9b941eac9ff1e1dc119bb96eaca051aee231c74 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_resolver_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_transport_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_transport_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..382980157b79614927a0df7d70e7e804ed6a5465 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_transport_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_transport_native_epoll_linux_x86_64_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_transport_native_epoll_linux_x86_64_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..204dc7109c0a0d0aba8ba5c8b62ce1bc3afeb15a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_transport_native_epoll_linux_x86_64_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_transport_native_unix_common_4_1_43_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_transport_native_unix_common_4_1_43_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..8856063c5bd422f1946e2dd84a6f7460b660b57a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_netty_netty_transport_native_unix_common_4_1_43_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_projectreactor_addons_reactor_extra_3_3_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_projectreactor_addons_reactor_extra_3_3_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..bb93f7b64f7d0d4747a20e07a499960c59c7e0a7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_projectreactor_addons_reactor_extra_3_3_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_projectreactor_netty_reactor_netty_0_9_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_projectreactor_netty_reactor_netty_0_9_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..3c8692744966e3702cda27acf0ee649bf48bf797 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_projectreactor_netty_reactor_netty_0_9_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_projectreactor_reactor_core_3_3_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_projectreactor_reactor_core_3_3_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..408e1474a4be9f71f6217977b990b5fcf570ad64 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_projectreactor_reactor_core_3_3_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_prometheus_simpleclient_0_5_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_prometheus_simpleclient_0_5_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..555759b49c53c017bc0489262ab12f67aa464ed7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_prometheus_simpleclient_0_5_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxjava_1_3_8.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxjava_1_3_8.xml new file mode 100644 index 0000000000000000000000000000000000000000..cda742bac2bf41157e23f6619b55ed7fe3bdab86 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxjava_1_3_8.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxjava_reactive_streams_1_2_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxjava_reactive_streams_1_2_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..c77c4af8f66ac3f7f259dd0af1eed47f29e63f53 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxjava_reactive_streams_1_2_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxnetty_0_4_9.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxnetty_0_4_9.xml new file mode 100644 index 0000000000000000000000000000000000000000..82613f4c92e2eb70303be2c5e5c3772beb9d5cc6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxnetty_0_4_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxnetty_contexts_0_4_9.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxnetty_contexts_0_4_9.xml new file mode 100644 index 0000000000000000000000000000000000000000..1ce62ff2c159a274020f5fb1154afc9eb7109845 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxnetty_contexts_0_4_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxnetty_servo_0_4_9.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxnetty_servo_0_4_9.xml new file mode 100644 index 0000000000000000000000000000000000000000..f9da5f7533764ef06d42996160f1e1ef1c9f6f62 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_reactivex_rxnetty_servo_0_4_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_seata_seata_all_0_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_seata_seata_all_0_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..58b9e7d42baa0789a0ef11d27cba3da064a49da3 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_seata_seata_all_0_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..5b473bf58d171c127d23335be02781b234a92abc --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_context_log4j2_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_context_log4j2_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..01a500907e998c65154ba905024eede6c05f19f9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_context_log4j2_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_http_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_http_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..f3a8dbd8cfe9f726441aaf0865390106c4c53f0c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_http_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_httpasyncclient_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_httpasyncclient_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..349b8e129a94786ab6699cabc113830402f16000 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_httpasyncclient_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_httpclient_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_httpclient_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..847a5888a08038bbecc1483d36f9b6f8fe36ec00 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_httpclient_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_jms_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_jms_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..cbc8e23baa8d183e3b62663ac205520a915b5620 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_jms_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_kafka_clients_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_kafka_clients_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..375d92db4b5a55f04c40792fe400924479e9f650 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_kafka_clients_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_kafka_streams_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_kafka_streams_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..f127724aa60030c2debe20562171bafa04592989 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_kafka_streams_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_messaging_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_messaging_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..3ed0fd3d65b722a4831be2103959d934670b6280 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_messaging_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_rpc_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_rpc_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..e10a47e03b998e12124160d7f86da667ed677daf --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_rpc_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_servlet_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_servlet_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..93db81428e6a16be9a53e1cba189a8736617ce8b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_servlet_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_spring_rabbit_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_spring_rabbit_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..3a2468a6394733372176d33be18cbdc5f157203b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_spring_rabbit_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_spring_web_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_spring_web_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..0626f22824452e958c784bae05a84713cecc778e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_spring_web_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_spring_webmvc_5_9_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_spring_webmvc_5_9_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..f1b9570fc61ba3f51d7ac0a024e7de5342750196 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_brave_brave_instrumentation_spring_webmvc_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_reporter_2_11_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_reporter_2_11_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..1df62792830266fada314421accfab5723d32f2a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_reporter_2_11_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_reporter_metrics_micrometer_2_11_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_reporter_metrics_micrometer_2_11_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..42bc7f20b3d82e0a130ca7ddac78d44bbf180073 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_reporter_metrics_micrometer_2_11_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_sender_activemq_client_2_11_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_sender_activemq_client_2_11_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..7705015c6e3b446a30e1047d3a503f5c6d2d9b64 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_sender_activemq_client_2_11_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_sender_amqp_client_2_11_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_sender_amqp_client_2_11_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..87d8b2ffe82a87bc6e8af671bee519338c786937 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_sender_amqp_client_2_11_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_sender_kafka_2_11_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_sender_kafka_2_11_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..53dad4cf237d8208e276ae457a3f3129230f3f43 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_reporter2_zipkin_sender_kafka_2_11_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_zipkin2_zipkin_2_19_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_zipkin2_zipkin_2_19_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..f21a239443b216e4559689755d11daf18c79644e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__io_zipkin_zipkin2_zipkin_2_19_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jakarta_activation_jakarta_activation_api_1_2_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jakarta_activation_jakarta_activation_api_1_2_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..a96bbdc69697d90b75800cc15b773f3b89d11b2b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jakarta_activation_jakarta_activation_api_1_2_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jakarta_annotation_jakarta_annotation_api_1_3_5.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jakarta_annotation_jakarta_annotation_api_1_3_5.xml new file mode 100644 index 0000000000000000000000000000000000000000..cba9dd244f222ce7ecbdcab4c7f9621a57fe1a67 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jakarta_annotation_jakarta_annotation_api_1_3_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jakarta_validation_jakarta_validation_api_2_0_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jakarta_validation_jakarta_validation_api_2_0_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..b60c21cb2a99556a5df0e312196161c4d926677f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jakarta_validation_jakarta_validation_api_2_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jakarta_xml_bind_jakarta_xml_bind_api_2_3_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jakarta_xml_bind_jakarta_xml_bind_api_2_3_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..bdf217a0c258ed07bb96036043bf50b69bc534f0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jakarta_xml_bind_jakarta_xml_bind_api_2_3_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__javax_annotation_javax_annotation_api_1_3_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__javax_annotation_javax_annotation_api_1_3_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..e74f3ab28b28ba4a1bfd7d0a218614887cb496fc --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__javax_annotation_javax_annotation_api_1_3_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__javax_inject_javax_inject_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__javax_inject_javax_inject_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..93cf65aba0780739b44f7a15b5fc6288feadf8b9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__javax_inject_javax_inject_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__javax_ws_rs_jsr311_api_1_1_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__javax_ws_rs_jsr311_api_1_1_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..a0c4d7663d7066654fd65aa002f42b119e70749c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__javax_ws_rs_jsr311_api_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jline_jline_0_9_94.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jline_jline_0_9_94.xml new file mode 100644 index 0000000000000000000000000000000000000000..903c33979bbf5257be5faaec5ae24aec10071dcf --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__jline_jline_0_9_94.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__joda_time_joda_time_2_10_5.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__joda_time_joda_time_2_10_5.xml new file mode 100644 index 0000000000000000000000000000000000000000..cbed35c2184318275b3a8fbf7c8c2f8e63dd3b71 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__joda_time_joda_time_2_10_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__junit_junit_4_12.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__junit_junit_4_12.xml new file mode 100644 index 0000000000000000000000000000000000000000..d411041745b6e44356035cdd44538daca09388f6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__junit_junit_4_12.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__log4j_log4j_1_2_17.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__log4j_log4j_1_2_17.xml new file mode 100644 index 0000000000000000000000000000000000000000..e383c1bf1e55f2de28db071054723041d116b00c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__log4j_log4j_1_2_17.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__mysql_mysql_connector_java_5_1_37.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__mysql_mysql_connector_java_5_1_37.xml new file mode 100644 index 0000000000000000000000000000000000000000..6c3a8221866f0c019cbe06c167fec5c84018e97b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__mysql_mysql_connector_java_5_1_37.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__mysql_mysql_connector_java_5_1_47.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__mysql_mysql_connector_java_5_1_47.xml new file mode 100644 index 0000000000000000000000000000000000000000..8ed561b0d5e44fe1d2e7c36682ce32c97ee1e7de --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__mysql_mysql_connector_java_5_1_47.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_10_4.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_10_4.xml new file mode 100644 index 0000000000000000000000000000000000000000..1ae7060801425522028586c399c80203e2fa095c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_10_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_10_4.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_10_4.xml new file mode 100644 index 0000000000000000000000000000000000000000..f4ad5290df2b55806e4e1860b07f004ee0c7fa4f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_10_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__net_minidev_accessors_smart_1_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__net_minidev_accessors_smart_1_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..b3d38583846d5aa1772f53caeccc169761a55a6f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__net_minidev_accessors_smart_1_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__net_minidev_json_smart_2_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__net_minidev_json_smart_2_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..108302355fbaaf40e819f97756e3ed357517a466 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__net_minidev_json_smart_2_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_antlr_antlr_runtime_3_4.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_antlr_antlr_runtime_3_4.xml new file mode 100644 index 0000000000000000000000000000000000000000..fd0779a3ff36886a317a6a8f90d7bd6417a0114a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_antlr_antlr_runtime_3_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_antlr_stringtemplate_3_2_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_antlr_stringtemplate_3_2_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..6998bac10b9a8c9ef65cf545f5dd6cfe5ae7e2e1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_antlr_stringtemplate_3_2_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_9.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_9.xml new file mode 100644 index 0000000000000000000000000000000000000000..9050e004ee154ca8d2c3a62c23a7dd9493252e85 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_commons_commons_math_2_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_commons_commons_math_2_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..8f3e3159f1ca74019c0330df89ece45fe308f323 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_commons_commons_math_2_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_commons_commons_pool2_2_7_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_commons_commons_pool2_2_7_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..dbf3aa43f9d4d9ae5d742a41f1e14dc4d150515f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_commons_commons_pool2_2_7_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_curator_curator_client_4_0_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_curator_curator_client_4_0_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..dd8b5dfb91b046a6705a7fdcbe4d6ebc27310ef3 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_curator_curator_client_4_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_curator_curator_framework_4_0_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_curator_curator_framework_4_0_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..6c7a21117c394eebba940d044ea6513540092495 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_curator_curator_framework_4_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_curator_curator_recipes_4_0_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_curator_curator_recipes_4_0_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..22c7320a26864ee9f3b25d9440c1b12a250ae63e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_curator_curator_recipes_4_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_curator_curator_x_discovery_4_0_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_curator_curator_x_discovery_4_0_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..58b14b2fa86627594422a6b21bbe729ddcafb661 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_curator_curator_x_discovery_4_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5_10.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5_10.xml new file mode 100644 index 0000000000000000000000000000000000000000..32ad6d3d68cc1fa4324c34fda3b5b946c8ee2b79 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5_10.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_12.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_12.xml new file mode 100644 index 0000000000000000000000000000000000000000..e95289eaab68920e8789629c1f297f5a9009798e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_12.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_12_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_12_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..ad03854608be6128520abc3cbdcded0ecaf54a77 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_12_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_12_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_12_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..b4b1b1b6b7ea6ce1420fb5a9e42954ef96d63e43 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_12_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_29.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_29.xml new file mode 100644 index 0000000000000000000000000000000000000000..1fe40ff42baa5f766434a1da17a543c9239e2d0d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_29.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_29.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_29.xml new file mode 100644 index 0000000000000000000000000000000000000000..0a0c714bcade3a5ead9e86c51a05eba2ebfcdad3 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_29.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_29.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_29.xml new file mode 100644 index 0000000000000000000000000000000000000000..8733fa7fd0d43f5cad8b0aa7395e90aa2bf3e701 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_29.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_zookeeper_zookeeper_3_4_9.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_zookeeper_zookeeper_3_4_9.xml new file mode 100644 index 0000000000000000000000000000000000000000..24de43f54dbacf4cbb173e86db030ef876474f6e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apache_zookeeper_zookeeper_3_4_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..f854ab00fdbf2e7209bbdf678f7c45f3bb209378 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_aspectj_aspectjrt_1_9_5.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_aspectj_aspectjrt_1_9_5.xml new file mode 100644 index 0000000000000000000000000000000000000000..649cc0eeca742179f2c396aff653566974ccfd59 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_aspectj_aspectjrt_1_9_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_aspectj_aspectjweaver_1_9_5.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_aspectj_aspectjweaver_1_9_5.xml new file mode 100644 index 0000000000000000000000000000000000000000..1a387a4d35109037cd10a698fe55b6e9eb0ebaff --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_aspectj_aspectjweaver_1_9_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_assertj_assertj_core_3_13_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_assertj_assertj_core_3_13_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..6222cc8995af49f593ecee44e582a33b34bd7954 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_assertj_assertj_core_3_13_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_bouncycastle_bcpkix_jdk15on_1_64.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_bouncycastle_bcpkix_jdk15on_1_64.xml new file mode 100644 index 0000000000000000000000000000000000000000..56cfc40f4a9647318d33555ecb52e6f93230dc01 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_bouncycastle_bcpkix_jdk15on_1_64.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_bouncycastle_bcprov_jdk15on_1_64.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_bouncycastle_bcprov_jdk15on_1_64.xml new file mode 100644 index 0000000000000000000000000000000000000000..861cb28259605f5dcd793a41e6d4353932fdac51 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_bouncycastle_bcprov_jdk15on_1_64.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_checkerframework_checker_qual_2_10_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_checkerframework_checker_qual_2_10_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..2301054201b1b4c71778c6447cf3e720e9b9631f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_checkerframework_checker_qual_2_10_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_9_13.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_9_13.xml new file mode 100644 index 0000000000000000000000000000000000000000..98eb5499988ed0465e9010cd5fe5bd624b64516b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_9_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_9_13.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_9_13.xml new file mode 100644 index 0000000000000000000000000000000000000000..77f3bad57a88c598ebd985a40a1b8772f51ab29e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_9_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_codehaus_jettison_jettison_1_3_7.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_codehaus_jettison_jettison_1_3_7.xml new file mode 100644 index 0000000000000000000000000000000000000000..ca43e29ae47e2e92fd357cc677d6c6bace80a982 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_codehaus_jettison_jettison_1_3_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_codehaus_woodstox_stax2_api_4_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_codehaus_woodstox_stax2_api_4_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..30ed863ca83077499c83c30d59f494df17e972be --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_codehaus_woodstox_stax2_api_4_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_eclipse_jgit_org_eclipse_jgit_5_1_3_201810200350_r.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_eclipse_jgit_org_eclipse_jgit_5_1_3_201810200350_r.xml new file mode 100644 index 0000000000000000000000000000000000000000..93b510349d3e9ff90dedbe4f9533648c9729add8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_eclipse_jgit_org_eclipse_jgit_5_1_3_201810200350_r.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_eclipse_jgit_org_eclipse_jgit_http_apache_5_1_3_201810200350_r.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_eclipse_jgit_org_eclipse_jgit_http_apache_5_1_3_201810200350_r.xml new file mode 100644 index 0000000000000000000000000000000000000000..f4073f315e8982f8d208fec5aaa05e0d03ad3ad6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_eclipse_jgit_org_eclipse_jgit_http_apache_5_1_3_201810200350_r.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_freemarker_freemarker_2_3_29.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_freemarker_freemarker_2_3_29.xml new file mode 100644 index 0000000000000000000000000000000000000000..a2d193b7ca6f40c5fa8610bcbe1acef84c8fd878 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_freemarker_freemarker_2_3_29.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_glassfish_jakarta_el_3_0_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_glassfish_jakarta_el_3_0_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..ae5020d69f0e700c9eca359ae07f33d714285800 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_glassfish_jakarta_el_3_0_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_glassfish_jaxb_jaxb_runtime_2_3_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_glassfish_jaxb_jaxb_runtime_2_3_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..dd040299762c1eb9c04be14a250c7f4c8074b8ab --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_glassfish_jaxb_jaxb_runtime_2_3_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_glassfish_jaxb_txw2_2_3_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_glassfish_jaxb_txw2_2_3_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..a0481f2198b1d20316fe2dc12a4d9eab4e9d68a0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_glassfish_jaxb_txw2_2_3_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hamcrest_hamcrest_2_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hamcrest_hamcrest_2_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..b17029340000123e7cd745a95b87abb215ea5c70 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hamcrest_hamcrest_2_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hamcrest_hamcrest_core_2_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hamcrest_hamcrest_core_2_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..2456ee8dbb12330255d6b1f0fd3cbff4cd421852 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hamcrest_hamcrest_core_2_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hdrhistogram_HdrHistogram_2_1_11.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hdrhistogram_HdrHistogram_2_1_11.xml new file mode 100644 index 0000000000000000000000000000000000000000..a1be1377a3d2be826073604b5e9d8311b7bc7d08 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hdrhistogram_HdrHistogram_2_1_11.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hdrhistogram_HdrHistogram_2_1_9.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hdrhistogram_HdrHistogram_2_1_9.xml new file mode 100644 index 0000000000000000000000000000000000000000..04cc804018ab8cf7e2a2997a090470b02e9deabf --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hdrhistogram_HdrHistogram_2_1_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_0_18_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_0_18_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..d035d9cd1c47210059ac6ee3dfa99fcb929504f4 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_0_18_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_4_1_Final.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_4_1_Final.xml new file mode 100644 index 0000000000000000000000000000000000000000..0b76247c260edd8b200bab436af4774091fd48b2 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_4_1_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_5_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_5_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..5db074039e9c200237261cb9c72da0a35f6f4017 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_5_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_5_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_5_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..8fbc8ce2b372f831ed1c244d43b7d0a6548ba04b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_5_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_5_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_5_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..cca5485d8d5e4788954bcbef0d46a24c2c5f7cf4 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_5_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_5_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_5_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..e2713d088da5600c73ec81311b63a3f215b446d8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_5_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_5_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_5_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..4192cdcdac43b1b3697281d8a06d85cd742b722f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_5_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_5_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_5_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..cbbd9b77d839f4e87e42241e3ce40f0e0e8ef038 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_5_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_vintage_junit_vintage_engine_5_5_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_vintage_junit_vintage_engine_5_5_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..824481fab02df606ed89b8cefb122b1ea3e31488 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_junit_vintage_junit_vintage_engine_5_5_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_jvnet_staxex_stax_ex_1_8_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_jvnet_staxex_stax_ex_1_8_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..38f7e124e2d01b867eab78351f533467aa2359d0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_jvnet_staxex_stax_ex_1_8_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_latencyutils_LatencyUtils_2_0_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_latencyutils_LatencyUtils_2_0_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..bf6816984376efd802c127a65673103a742d6b10 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_latencyutils_LatencyUtils_2_0_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mockito_mockito_core_3_1_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mockito_mockito_core_3_1_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..c18526d0b64cd3614ee70285a3401d82acceba48 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mockito_mockito_core_3_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mockito_mockito_junit_jupiter_3_1_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mockito_mockito_junit_jupiter_3_1_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..d4e664310927c5a715047f1a92ec76c193461394 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mockito_mockito_junit_jupiter_3_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_mybatis_3_4_4.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_mybatis_3_4_4.xml new file mode 100644 index 0000000000000000000000000000000000000000..dc8a00a92f5e0328aed655c837cd8b12c04af111 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_mybatis_3_4_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_mybatis_3_5_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_mybatis_3_5_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..9cb741b9574bdb77db289777417df02bc187d04e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_mybatis_3_5_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_mybatis_spring_1_3_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_mybatis_spring_1_3_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..774f47cdb68d013c4418f575f6bdb6c52c0921b1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_mybatis_spring_1_3_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_mybatis_spring_2_0_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_mybatis_spring_2_0_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..9b048c420a56bc7f7c95c758b1ecb3013f27c760 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_mybatis_spring_2_0_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_autoconfigure_1_3_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_autoconfigure_1_3_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..2dab29d3ca33d589c98c31bcd55c475855acf821 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_autoconfigure_1_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_autoconfigure_2_0_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_autoconfigure_2_0_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..a9a5f32870dd032a89a91328fc1e9c86ce3c6a8d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_autoconfigure_2_0_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_starter_1_3_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_starter_1_3_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..40d34817a6cbda21ae93dfef56b6ea5ab8cb72a0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_starter_1_3_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_starter_2_0_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_starter_2_0_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..dffb199ee2aea608f7b94132008f30129b5a43a8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_mybatis_spring_boot_mybatis_spring_boot_starter_2_0_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_objenesis_objenesis_2_6.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_objenesis_objenesis_2_6.xml new file mode 100644 index 0000000000000000000000000000000000000000..af41e3b6171208cedd29faa1922420ed916cc5b7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_objenesis_objenesis_2_6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..fbc1b1635a2c69174f8bea7d6306f5175015adc0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_ow2_asm_asm_4_2.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_ow2_asm_asm_4_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..b5e3748970269b38172982ebe83498489f7222a0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_ow2_asm_asm_4_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_ow2_asm_asm_5_0_4.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_ow2_asm_asm_5_0_4.xml new file mode 100644 index 0000000000000000000000000000000000000000..0bf8cf2b279adf5dbfdb0ad574f87390f1e4b072 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_ow2_asm_asm_5_0_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_projectlombok_lombok_1_16_18.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_projectlombok_lombok_1_16_18.xml new file mode 100644 index 0000000000000000000000000000000000000000..8503cb411bd6012641fbb6998922c94a68b9afe8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_projectlombok_lombok_1_16_18.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_reactivestreams_reactive_streams_1_0_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_reactivestreams_reactive_streams_1_0_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..f17253bf81c48360905fb478f634536f0202bf5f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_reactivestreams_reactive_streams_1_0_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_skyscreamer_jsonassert_1_5_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_skyscreamer_jsonassert_1_5_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..c4c54d6d5452b5e2f25085adb2d2b98c38ae4731 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_skyscreamer_jsonassert_1_5_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_29.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_29.xml new file mode 100644 index 0000000000000000000000000000000000000000..7981b9e1d956638e88553c7083e0e7279a6c9ace --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_29.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_29.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_29.xml new file mode 100644 index 0000000000000000000000000000000000000000..53615b0dba9745f01fedb5fb7899a420c6f0fb12 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_29.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_7_29.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_7_29.xml new file mode 100644 index 0000000000000000000000000000000000000000..f1df5a2890d09ed9b5ff315ff0d9f6de67a5e3d0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_7_29.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_amqp_spring_amqp_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_amqp_spring_amqp_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..fe10255067ee8068d6a2d2ccc5eccc64d58202b7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_amqp_spring_amqp_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_amqp_spring_rabbit_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_amqp_spring_rabbit_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..c2edc4c9ef1b90117c28b4235ed46fc613fc1abc --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_amqp_spring_rabbit_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..7cd7f4fa96fe00a8c90670541fbb6544b8b4890e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_actuator_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_actuator_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..beaf3ac39fe325baec5f51766e5229e02a7fc2de --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_actuator_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_actuator_autoconfigure_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_actuator_autoconfigure_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..2202259008ae0d6d22585d51cc6492733bbbd9e8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_actuator_autoconfigure_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..18be82335e154d5804a8f558a1700330322dfb77 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_devtools_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_devtools_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..ea696d5e5fbab052a636cf0ed1248c8275d118cd --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_devtools_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..7bdffb8150daf83c5bd485f9bd1951a52ac9f9b9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_actuator_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_actuator_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..a46f195b527919f06b37acfd5fe3828d10599700 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_actuator_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_amqp_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_amqp_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..6f40e098e71b1021eeaaa49f7f3b8c9bbdd14a1e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_amqp_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..5a624c190f162f09f68a8c8f0b4c8f06e9642baf --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_cache_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_cache_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..e87c52e00c6b554b2bea40296e3acb1e46af62e7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_cache_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_freemarker_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_freemarker_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..16ab80a0df1753f117b960407da05134fd11497f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_freemarker_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..44e3ac83b29b78bb6bf82215f6476ee838425b10 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..c43117fcd5379c0eeea41683eb7d60a503267737 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..a6b60e3d198af5a81a2508556d96f851fb5d2255 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_reactor_netty_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_reactor_netty_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..2bfc26d1a1a5738ef0087f5ea468717c921906fa --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_reactor_netty_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..e6bd8c46dafc1bad4f8fb113cadddcc5cd1026c4 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..ff410afeeac28b6554912b38b0eb78f396133e87 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_validation_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_validation_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..3eebbd13f80e639a72c184d063b9017420569e5c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_validation_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..fac035bb20af6737cd22524e00742cf2af06772a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_webflux_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_webflux_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..a815c9bcb284b32ea94b500bc36bd7b61f733c70 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_webflux_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..c2f4fb6df37cf3b93fc380b77288652553ebf625 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..d239a446567c60bc0b2eb882c6288a53cc147dc2 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_bus_2_2_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_bus_2_2_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..f311febd4c456849274ad79ccbf0a9b7d2d1c7e8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_bus_2_2_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_commons_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_commons_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..72cf194076cd014b23db874093ff04c22a069d41 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_commons_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_config_client_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_config_client_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..6ddb706908a620738831497c089249e7a633a3aa --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_config_client_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_config_server_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_config_server_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..95400863e60870bf01f20770ed072f9b493d6246 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_config_server_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_consul_core_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_consul_core_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..f36aec38e6db0f5a7d886abf0b8e491ac260028a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_consul_core_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_consul_discovery_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_consul_discovery_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..186ff385a870f7fe6137b7d8e098027a403e445b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_consul_discovery_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_context_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_context_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..4d04b0ae8ed02be36e4c41e0a5d48d5f2b01fed2 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_context_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_function_context_3_0_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_function_context_3_0_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..f52f8c3132ed245149d2fc3501571ded51025905 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_function_context_3_0_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_function_core_3_0_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_function_core_3_0_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..5044b21c14a7ac4fdfb83bdd2a3f9c2d7fa3ff36 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_function_core_3_0_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_gateway_core_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_gateway_core_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..42e507b184d8db6f8da0eb67fe266d9cf2ef4b69 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_gateway_core_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_loadbalancer_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_loadbalancer_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..b4cc2ff7b2707a334a4fc4bd1701c45dd4a2302a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_loadbalancer_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_archaius_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_archaius_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..fe692b72ac9f2be2ce05a1c1124a3be3b753cd85 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_archaius_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_eureka_client_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_eureka_client_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..99754a2b5d8dd939c971b8aeba589a25f5628056 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_eureka_client_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_eureka_server_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_eureka_server_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..1e7f2dc753e69cc78f5ea15ad399cb01d6799f00 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_eureka_server_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_hystrix_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_hystrix_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..c0eb18b7679762c493147d5962369a0710344651 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_hystrix_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_hystrix_dashboard_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_hystrix_dashboard_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..14fd9ee798e67fa5b486540865a2acd8c7837907 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_hystrix_dashboard_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_ribbon_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_ribbon_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..1be1276120f8a59305dcc3f53a7bd28eece84c09 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_netflix_ribbon_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_openfeign_core_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_openfeign_core_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..87bf843cb55cdaa9072a2c6988568f7a3d1d5069 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_openfeign_core_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_sleuth_core_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_sleuth_core_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..8865cda96362a8a4ba5be4b42460e572295be873 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_sleuth_core_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_sleuth_zipkin_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_sleuth_zipkin_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..f4f9216956e2cbad2a94f1e1378f594f37fe1ac6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_sleuth_zipkin_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..979e436f41f2cdd1f5ab14b251994971352c77c9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_bus_amqp_2_2_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_bus_amqp_2_2_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..4a3ba79fb223760deb7a464552279c9d5149f10b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_bus_amqp_2_2_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_config_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_config_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..b2a576a7ee43bcfe0cef640c8a25a951dc1d583b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_config_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_consul_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_consul_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..2344ec1721328fc9e8e75eb29ae7c270e4f289ac --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_consul_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_consul_discovery_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_consul_discovery_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..0731f4255255a751f0ad13c8f74528f2e2136edb --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_consul_discovery_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_gateway_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_gateway_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..997bde85502bea4423005f60074b25e5fdc99ec0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_gateway_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_loadbalancer_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_loadbalancer_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..d0bd9b8747dc94a934866865c165d81efe9d7a64 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_loadbalancer_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_archaius_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_archaius_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..7c537616be1bda2da142c2762177f9341f3f4dac --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_archaius_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_eureka_client_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_eureka_client_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..750595461142a25f4ffe78d62ee429bed700bd98 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_eureka_client_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_eureka_server_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_eureka_server_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..2eefc4d365c1ebbe5039a487066cb43f9b28d68e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_eureka_server_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_hystrix_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_hystrix_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..afa88529352258da62f6ef0e21a15c2bd5927d3a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_hystrix_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_hystrix_dashboard_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_hystrix_dashboard_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..3269c7ec3be0102e857d24a49aef16d1e38ded45 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_hystrix_dashboard_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_ribbon_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_ribbon_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..dc1dbcc27260d3b64678ce948bc26eb7c314cf6e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_netflix_ribbon_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_openfeign_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_openfeign_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..559fa0f7042e5cc7da7c873bfbd05770d98b8996 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_openfeign_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_sleuth_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_sleuth_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..d626903117f30d3eefdfcb8ec0baa3fe03cad85c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_sleuth_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_stream_rabbit_3_0_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_stream_rabbit_3_0_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..f868d74c9d4589161ccf93ad1612f22c32b739ee --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_stream_rabbit_3_0_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_zipkin_2_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_zipkin_2_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..790c2bc996e616a76b95cd88d304b9387ef9e83f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_zipkin_2_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_zookeeper_2_2_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_zookeeper_2_2_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..9892a0be87f199d69669b736fd3762d6fb01b4d2 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_zookeeper_2_2_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_zookeeper_discovery_2_2_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_zookeeper_discovery_2_2_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..a5388cf83a4c7c4c127fcd238edbcd46465984a0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_starter_zookeeper_discovery_2_2_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_stream_3_0_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_stream_3_0_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..c9bfe1156944cf905b3bc48833145569544a1788 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_stream_3_0_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_stream_binder_rabbit_3_0_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_stream_binder_rabbit_3_0_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..b412c512648159c0e9e4fd41643f3dd62cb30b7f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_stream_binder_rabbit_3_0_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_stream_binder_rabbit_core_3_0_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_stream_binder_rabbit_core_3_0_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..e46a26ba5c2b6ddc1e6847438c3a166f2e8c00ee --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_stream_binder_rabbit_core_3_0_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_zookeeper_core_2_2_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_zookeeper_core_2_2_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..52063f4bfc844ce6fdc0d462a76e3bfe80b128f7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_zookeeper_core_2_2_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_zookeeper_discovery_2_2_0_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_zookeeper_discovery_2_2_0_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..91445266d8a9b8827409b943d6f9ddceaefa225b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_cloud_spring_cloud_zookeeper_discovery_2_2_0_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_integration_spring_integration_amqp_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_integration_spring_integration_amqp_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..32529e8a053ef62d47a81904620028c5fc970387 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_integration_spring_integration_amqp_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_integration_spring_integration_core_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_integration_spring_integration_core_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..24c666af092780ba36a7e74ca2a4cbacabc205bd --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_integration_spring_integration_core_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_integration_spring_integration_jmx_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_integration_spring_integration_jmx_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..addae76630c0cd259a08a2ceb1555e0c451ff34e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_integration_spring_integration_jmx_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_retry_spring_retry_1_2_4_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_retry_spring_retry_1_2_4_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..f831afb5397440afed25d669456baad340e2c065 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_retry_spring_retry_1_2_4_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_security_spring_security_crypto_5_2_1_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_security_spring_security_crypto_5_2_1_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..4dba8d0d6d61547192d1bc662c65a0d83ef8ad79 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_security_spring_security_crypto_5_2_1_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_security_spring_security_rsa_1_0_9_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_security_spring_security_rsa_1_0_9_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..60972566c0aa3d703d0e7d2a0dcce28c19ecb7af --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_security_spring_security_rsa_1_0_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_aop_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_aop_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..b73f7874ecdbb321120f47d4eb4c422dcf0dcb56 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_aop_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_beans_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_beans_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..d2a0aca065ff11c4deebe7f2d92f557fd687ca0d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_beans_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_context_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_context_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..809fb19fe44609c1e5a41264c9493cb9f67fefa5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_context_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_context_support_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_context_support_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..e32a8acfbc4b8ec9110335528598c3b04deae6b1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_context_support_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_core_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_core_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..d7eff396e47b59edfda1da178ab4ccd4e1749469 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_core_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_expression_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_expression_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..06f29511f2a8773a49e36a832229df2b9acd08b1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_expression_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_jcl_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_jcl_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..18fdc29d745c9d179a2c1792afa2d9555f8242a6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_jcl_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_jdbc_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_jdbc_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..2215b10f6da441194d4d184536a962a6d18a948e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_jdbc_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_messaging_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_messaging_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..f59f4afcf4076a1590f37cb69eafa7952aa9b71a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_messaging_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_test_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_test_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..6ad876734d036c682793566b37dfe46b7e252085 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_test_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_tx_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_tx_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..3bdad9385d4b7af59c207892cbd6431011de9fcc --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_tx_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_web_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_web_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..7a381f8ca6b7daa2594d70042a8303f95f60c82d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_web_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_webflux_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_webflux_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..d5c867429a8056c105b42f4a8279eb01517fb3e8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_webflux_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_webmvc_5_2_2_RELEASE.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_webmvc_5_2_2_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..a6674549680c168abeac93006062028cdd60de80 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_springframework_spring_webmvc_5_2_2_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_synchronoss_cloud_nio_multipart_parser_1_1_0.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_synchronoss_cloud_nio_multipart_parser_1_1_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..1a8ebe7daf34d271dbb64b29520f1d9012f545b4 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_synchronoss_cloud_nio_multipart_parser_1_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_synchronoss_cloud_nio_stream_storage_1_1_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_synchronoss_cloud_nio_stream_storage_1_1_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..3897687eb05dede96101965875a16f7a56515587 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_synchronoss_cloud_nio_stream_storage_1_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_webjars_d3js_3_4_11.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_webjars_d3js_3_4_11.xml new file mode 100644 index 0000000000000000000000000000000000000000..8782b0929dbad219220ea300f6acef34f5ed7bab --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_webjars_d3js_3_4_11.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_webjars_jquery_2_1_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_webjars_jquery_2_1_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..643a4217e8cfe69d948bd5e7a8a67f1752a4048c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_webjars_jquery_2_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_6_3.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_6_3.xml new file mode 100644 index 0000000000000000000000000000000000000000..aed7fe22432e7a46f63d2d8b67a6926046fdb830 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_6_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_yaml_snakeyaml_1_25.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_yaml_snakeyaml_1_25.xml new file mode 100644 index 0000000000000000000000000000000000000000..495fc06fa070913239519ff3382b5487b2d37c7d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__org_yaml_snakeyaml_1_25.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__stax_stax_api_1_0_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__stax_stax_api_1_0_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..0b13335ee1567f514d4110b68a207cb48a3ae68b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__stax_stax_api_1_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__xmlpull_xmlpull_1_1_3_1.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__xmlpull_xmlpull_1_1_3_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..0f2d9ef4a8a1f0c4bde3c72fe52083b7eeb5cd65 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__xmlpull_xmlpull_1_1_3_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__xpp3_xpp3_min_1_1_4c.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__xpp3_xpp3_min_1_1_4c.xml new file mode 100644 index 0000000000000000000000000000000000000000..6726a2d68f780079e4a666abf7400c2c9af48faa --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/libraries/Maven__xpp3_xpp3_min_1_1_4c.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/misc.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/misc.xml new file mode 100644 index 0000000000000000000000000000000000000000..293797e6829e073fa5f77948164b541dd7dd0d78 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/misc.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/modules.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/modules.xml new file mode 100644 index 0000000000000000000000000000000000000000..a15b234d72295c98abcaadf2c616021649e0a32a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/modules.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/uiDesigner.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/uiDesigner.xml new file mode 100644 index 0000000000000000000000000000000000000000..e96534fb27b68192f27f985d3879e173ec77adb8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/.idea/vcs.xml b/SpringCloud/SpringCloud2020/cloud2020/.idea/vcs.xml new file mode 100644 index 0000000000000000000000000000000000000000..c2365ab11f9ba6b763735c8fd976420234bb3521 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/cloud-api-commons.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/cloud-api-commons.iml new file mode 100644 index 0000000000000000000000000000000000000000..1451244edda5a6ad2ca0d024597fb3c9dfd67f4a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/cloud-api-commons.iml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..bb4f1cd346acba2dff114e8846aea31c1c721ce6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/pom.xml @@ -0,0 +1,34 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-api-commons + + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + cn.hutool + hutool-all + 5.1.0 + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/src/main/java/com/atguigu/springcloud/entities/CommonResult.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/src/main/java/com/atguigu/springcloud/entities/CommonResult.java new file mode 100644 index 0000000000000000000000000000000000000000..e3437f834f0bf1a045544e8b947af19be5028203 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/src/main/java/com/atguigu/springcloud/entities/CommonResult.java @@ -0,0 +1,24 @@ +package com.atguigu.springcloud.entities; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @auther zzyy + * @create 2020-02-18 17:23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CommonResult +{ + private Integer code; + private String message; + private T data; + + public CommonResult(Integer code,String message) + { + this(code,message,null); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/src/main/java/com/atguigu/springcloud/entities/Payment.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/src/main/java/com/atguigu/springcloud/entities/Payment.java new file mode 100644 index 0000000000000000000000000000000000000000..0206ca4be46345ab2d264cf57d9308a82840ab43 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/src/main/java/com/atguigu/springcloud/entities/Payment.java @@ -0,0 +1,20 @@ +package com.atguigu.springcloud.entities; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @auther zzyy + * @create 2020-02-18 17:22 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Payment implements Serializable +{ + private Long id; + private String serial; +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/classes/com/atguigu/springcloud/entities/CommonResult.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/classes/com/atguigu/springcloud/entities/CommonResult.class new file mode 100644 index 0000000000000000000000000000000000000000..ea891e562563b8416731f077f13cd4eed28a1465 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/classes/com/atguigu/springcloud/entities/CommonResult.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/classes/com/atguigu/springcloud/entities/Payment.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/classes/com/atguigu/springcloud/entities/Payment.class new file mode 100644 index 0000000000000000000000000000000000000000..654ce8e983ffad292ab264eba429d7e1575eeca7 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/classes/com/atguigu/springcloud/entities/Payment.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/cloud-api-commons-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/cloud-api-commons-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..7f52ebc3ac61c8f50d28e5e30764b99e348bdc44 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/cloud-api-commons-1.0-SNAPSHOT.jar differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/maven-archiver/pom.properties" b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/maven-archiver/pom.properties similarity index 31% rename from "\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/maven-archiver/pom.properties" rename to SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/maven-archiver/pom.properties index f60f114c940fc0d31a3a091ccc5d938f4f39f76d..0b7edba24b282e697a5f3a8e9bc81d9d2f74ac8b 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/maven-archiver/pom.properties" +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/maven-archiver/pom.properties @@ -1,5 +1,5 @@ #Generated by Maven -#Tue Mar 17 10:22:18 CST 2020 +#Thu Apr 16 08:29:20 CST 2020 version=1.0-SNAPSHOT -groupId=org.example -artifactId=SchoolInterview +groupId=com.atguigu.springcloud +artifactId=cloud-api-commons diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..a52fcc7389ddeea49d0f5c0997a3337596b618a0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\atguigu\springcloud\entities\Payment.class +com\atguigu\springcloud\entities\CommonResult.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..96cb267cffba6d119c50e5971010f5628b3f44fd --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-api-commons\src\main\java\com\atguigu\springcloud\entities\Payment.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-api-commons\src\main\java\com\atguigu\springcloud\entities\CommonResult.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-api-commons/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/cloud-config-center-3344.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/cloud-config-center-3344.iml new file mode 100644 index 0000000000000000000000000000000000000000..1c19a5d4d184c835b81547391e8626fdc57a4dc2 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/cloud-config-center-3344.iml @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..9582cf8f37f0ed105f46a3c31286108ed1a5013e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/pom.xml @@ -0,0 +1,57 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-config-center-3344 + + + + + + org.springframework.cloud + spring-cloud-starter-bus-amqp + + + org.springframework.cloud + spring-cloud-config-server + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/src/main/java/com/atguigu/springcloud/ConfigCenterMain3344.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/src/main/java/com/atguigu/springcloud/ConfigCenterMain3344.java new file mode 100644 index 0000000000000000000000000000000000000000..5a68ec148b8dc0c240fc7b3beab1198bffc8852e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/src/main/java/com/atguigu/springcloud/ConfigCenterMain3344.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; + +/** + * @auther zzyy + * @create 2020-02-21 17:47 + */ +@SpringBootApplication +@EnableConfigServer +public class ConfigCenterMain3344 +{ + public static void main(String[] args) { + SpringApplication.run(ConfigCenterMain3344.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..c68afaa881c798bd667c01c6f8215303ac350f85 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/src/main/resources/application.yml @@ -0,0 +1,37 @@ +server: + port: 3344 + +spring: + application: + name: cloud-config-center #注册进Eureka服务器的微服务名 + cloud: + config: + server: + git: + uri: git@github.com:zzyybs/springcloud-config.git #GitHub上面的git仓库名字 + ####搜索目录 + search-paths: + - springcloud-config + ####读取分支 + label: master +#rabbitmq相关配置 +rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + +#服务注册到eureka地址 +eureka: + client: + service-url: + defaultZone: http://localhost:7001/eureka + +##rabbitmq相关配置,暴露bus刷新配置的端点 +management: + endpoints: #暴露bus刷新配置的端点 + web: + exposure: + include: 'bus-refresh' + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..c68afaa881c798bd667c01c6f8215303ac350f85 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/classes/application.yml @@ -0,0 +1,37 @@ +server: + port: 3344 + +spring: + application: + name: cloud-config-center #注册进Eureka服务器的微服务名 + cloud: + config: + server: + git: + uri: git@github.com:zzyybs/springcloud-config.git #GitHub上面的git仓库名字 + ####搜索目录 + search-paths: + - springcloud-config + ####读取分支 + label: master +#rabbitmq相关配置 +rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + +#服务注册到eureka地址 +eureka: + client: + service-url: + defaultZone: http://localhost:7001/eureka + +##rabbitmq相关配置,暴露bus刷新配置的端点 +management: + endpoints: #暴露bus刷新配置的端点 + web: + exposure: + include: 'bus-refresh' + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/classes/com/atguigu/springcloud/ConfigCenterMain3344.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/classes/com/atguigu/springcloud/ConfigCenterMain3344.class new file mode 100644 index 0000000000000000000000000000000000000000..1105fb5e4ee15ed1ed4f63bb5d49ec5fc7e6e4d6 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/classes/com/atguigu/springcloud/ConfigCenterMain3344.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/cloud-config-center-3344-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/cloud-config-center-3344-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..922c26b10599f59f293a0051c6fab52d2f9565b8 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/cloud-config-center-3344-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..842eddf6dd1faf8e3b3b4a9287a666a9fd7fb124 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:57 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-config-center-3344 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..8a265824193f694b2e60c6696348625975de68e9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1 @@ +com\atguigu\springcloud\ConfigCenterMain3344.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..960532e87369668b57a1a48d128bbb7f01882f6b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-config-center-3344\src\main\java\com\atguigu\springcloud\ConfigCenterMain3344.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-center-3344/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/cloud-config-client-3355.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/cloud-config-client-3355.iml new file mode 100644 index 0000000000000000000000000000000000000000..0d5f80f13e88e0643b433a7784c2bdca514a838c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/cloud-config-client-3355.iml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/bootstrap.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..bc1a04de3dbffff6129d6febba2172e7d653895b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/pom.xml @@ -0,0 +1,57 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-config-client-3355 + + + + + + org.springframework.cloud + spring-cloud-starter-bus-amqp + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/src/main/java/com/atguigu/springcloud/ConfigClientMain3355.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/src/main/java/com/atguigu/springcloud/ConfigClientMain3355.java new file mode 100644 index 0000000000000000000000000000000000000000..95451e835fa92975e57fa5b86a4212fe34379a09 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/src/main/java/com/atguigu/springcloud/ConfigClientMain3355.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; + +/** + * @auther zzyy + * @create 2020-02-21 18:07 + */ +@EnableEurekaClient +@SpringBootApplication +public class ConfigClientMain3355 +{ + public static void main(String[] args) { + SpringApplication.run(ConfigClientMain3355.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/src/main/java/com/atguigu/springcloud/controller/ConfigClientController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/src/main/java/com/atguigu/springcloud/controller/ConfigClientController.java new file mode 100644 index 0000000000000000000000000000000000000000..5812c40b3b3502c5d3f6a415ada64758c3701bb7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/src/main/java/com/atguigu/springcloud/controller/ConfigClientController.java @@ -0,0 +1,24 @@ +package com.atguigu.springcloud.controller; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @auther zzyy + * @create 2020-02-21 18:08 + */ +@RestController +@RefreshScope +public class ConfigClientController +{ + @Value("${config.info}") + private String configInfo; + + @GetMapping("/configInfo") + public String getConfigInfo() + { + return configInfo; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/src/main/resources/bootstrap.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/src/main/resources/bootstrap.yml new file mode 100644 index 0000000000000000000000000000000000000000..356529f8896335acbd36e3f2eb3b420c15ca7171 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/src/main/resources/bootstrap.yml @@ -0,0 +1,33 @@ +server: + port: 3355 + +spring: + application: + name: config-client + cloud: + #Config客户端配置 + config: + label: master #分支名称 + name: config #配置文件名称 + profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml + uri: http://localhost:3344 #配置中心地址k + +#rabbitmq相关配置 15672是Web管理界面的端口;5672是MQ访问的端口 + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + +#服务注册到eureka地址 +eureka: + client: + service-url: + defaultZone: http://localhost:7001/eureka + +# 暴露监控端点 +management: + endpoints: + web: + exposure: + include: "*" \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/classes/bootstrap.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/classes/bootstrap.yml new file mode 100644 index 0000000000000000000000000000000000000000..356529f8896335acbd36e3f2eb3b420c15ca7171 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/classes/bootstrap.yml @@ -0,0 +1,33 @@ +server: + port: 3355 + +spring: + application: + name: config-client + cloud: + #Config客户端配置 + config: + label: master #分支名称 + name: config #配置文件名称 + profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml + uri: http://localhost:3344 #配置中心地址k + +#rabbitmq相关配置 15672是Web管理界面的端口;5672是MQ访问的端口 + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + +#服务注册到eureka地址 +eureka: + client: + service-url: + defaultZone: http://localhost:7001/eureka + +# 暴露监控端点 +management: + endpoints: + web: + exposure: + include: "*" \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/classes/com/atguigu/springcloud/ConfigClientMain3355.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/classes/com/atguigu/springcloud/ConfigClientMain3355.class new file mode 100644 index 0000000000000000000000000000000000000000..838596c4f9e68eb692c79a76c38296ffd4cb99c1 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/classes/com/atguigu/springcloud/ConfigClientMain3355.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/classes/com/atguigu/springcloud/controller/ConfigClientController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/classes/com/atguigu/springcloud/controller/ConfigClientController.class new file mode 100644 index 0000000000000000000000000000000000000000..67f0a481c3e35a0818f3c9e63d10a8a2a53e63b0 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/classes/com/atguigu/springcloud/controller/ConfigClientController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/cloud-config-client-3355-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/cloud-config-client-3355-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..65d32b1c9d0ce5abe144da7c0ac42729e3a4dcbb Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/cloud-config-client-3355-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..424802819686debf44ebb5bdaaa6ca9b23219035 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:58 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-config-client-3355 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..db9dd199850d4069b66407bfb9f8c78f2e96fdae --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\atguigu\springcloud\ConfigClientMain3355.class +com\atguigu\springcloud\controller\ConfigClientController.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..104184e5d5230bf2e58f81c53c4873c8b3ad2154 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-config-client-3355\src\main\java\com\atguigu\springcloud\controller\ConfigClientController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-config-client-3355\src\main\java\com\atguigu\springcloud\ConfigClientMain3355.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3355/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/cloud-config-client-3366.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/cloud-config-client-3366.iml new file mode 100644 index 0000000000000000000000000000000000000000..a9508ea5f4e031462613a1e2fa13fa124bc4efe9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/cloud-config-client-3366.iml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..e6527e6bcceae0534772dce9a89035bb9c415f27 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/pom.xml @@ -0,0 +1,57 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-config-client-3366 + + + + + + + + org.springframework.cloud + spring-cloud-starter-bus-amqp + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/src/main/java/com/atguigu/springcloud/ConfigClientMain3366.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/src/main/java/com/atguigu/springcloud/ConfigClientMain3366.java new file mode 100644 index 0000000000000000000000000000000000000000..0aa1d5e26142906e3ac0a47a1a1627e35f7ec9a4 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/src/main/java/com/atguigu/springcloud/ConfigClientMain3366.java @@ -0,0 +1,19 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; + +/** + * @auther zzyy + * @create 2020-02-21 20:04 + */ +@EnableEurekaClient +@SpringBootApplication +public class ConfigClientMain3366 +{ + public static void main(String[] args) + { + SpringApplication.run(ConfigClientMain3366.class,args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/src/main/java/com/atguigu/springcloud/controller/ConfigClientController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/src/main/java/com/atguigu/springcloud/controller/ConfigClientController.java new file mode 100644 index 0000000000000000000000000000000000000000..6bbc64c42772a79a0b465512c459b8f2d5fe4f78 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/src/main/java/com/atguigu/springcloud/controller/ConfigClientController.java @@ -0,0 +1,28 @@ +package com.atguigu.springcloud.controller; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @auther zzyy + * @create 2020-02-21 20:04 + */ +@RestController +@RefreshScope +public class ConfigClientController +{ + @Value("${server.port}") + private String serverPort; + + @Value("${config.info}") + private String configInfo; + + @GetMapping("/configInfo") + public String configInfo() + { + return "serverPort: "+serverPort+"\t\n\n configInfo: "+configInfo; + } + +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/src/main/resources/bootstrap.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/src/main/resources/bootstrap.yml new file mode 100644 index 0000000000000000000000000000000000000000..7fc38caa3d970669eecf3c051649b48bbce6079c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/src/main/resources/bootstrap.yml @@ -0,0 +1,35 @@ +server: + port: 3366 + +spring: + application: + name: config-client + cloud: + #Config客户端配置 + config: + label: master #分支名称 + name: config #配置文件名称 + profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml + uri: http://localhost:3344 #配置中心地址 + +#rabbitmq相关配置 15672是Web管理界面的端口;5672是MQ访问的端口 + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + +#服务注册到eureka地址 +eureka: + client: + service-url: + defaultZone: http://localhost:7001/eureka + +# 暴露监控端点 +management: + endpoints: + web: + exposure: + include: "*" + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/classes/bootstrap.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/classes/bootstrap.yml new file mode 100644 index 0000000000000000000000000000000000000000..7fc38caa3d970669eecf3c051649b48bbce6079c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/classes/bootstrap.yml @@ -0,0 +1,35 @@ +server: + port: 3366 + +spring: + application: + name: config-client + cloud: + #Config客户端配置 + config: + label: master #分支名称 + name: config #配置文件名称 + profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml + uri: http://localhost:3344 #配置中心地址 + +#rabbitmq相关配置 15672是Web管理界面的端口;5672是MQ访问的端口 + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + +#服务注册到eureka地址 +eureka: + client: + service-url: + defaultZone: http://localhost:7001/eureka + +# 暴露监控端点 +management: + endpoints: + web: + exposure: + include: "*" + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/classes/com/atguigu/springcloud/ConfigClientMain3366.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/classes/com/atguigu/springcloud/ConfigClientMain3366.class new file mode 100644 index 0000000000000000000000000000000000000000..2b4627a99fc3da786962ff0272fb8fcf56601a5a Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/classes/com/atguigu/springcloud/ConfigClientMain3366.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/classes/com/atguigu/springcloud/controller/ConfigClientController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/classes/com/atguigu/springcloud/controller/ConfigClientController.class new file mode 100644 index 0000000000000000000000000000000000000000..03280ff892afc34df4f5d4cda10bb6cb85949ce9 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/classes/com/atguigu/springcloud/controller/ConfigClientController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/cloud-config-client-3366-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/cloud-config-client-3366-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..ef4877db85f807b3a9a9a61ef24b0721ada5c956 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/cloud-config-client-3366-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..3d30fe1e7faa6bb18782446ec4dcf9e3e060c7b8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:59 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-config-client-3366 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..4b1a56335c8d67ec79ee9896e0bf8e0c9730b8c8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\atguigu\springcloud\ConfigClientMain3366.class +com\atguigu\springcloud\controller\ConfigClientController.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..a3ccf9177abd25291c0000bbca09c2e1779a36ac --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-config-client-3366\src\main\java\com\atguigu\springcloud\ConfigClientMain3366.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-config-client-3366\src\main\java\com\atguigu\springcloud\controller\ConfigClientController.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-config-client-3366/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/cloud-consumer-feign-hystrix-order80.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/cloud-consumer-feign-hystrix-order80.iml new file mode 100644 index 0000000000000000000000000000000000000000..72e7917925876e218acb029518a046f5cc556e22 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/cloud-consumer-feign-hystrix-order80.iml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..ce8d194d370171555fbee9b0fba3364aee48cfc5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/pom.xml @@ -0,0 +1,68 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-consumer-feign-hystrix-order80 + + + + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + org.springframework.cloud + spring-cloud-starter-netflix-hystrix + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/java/com/atguigu/springcloud/OrderHystrixMain80.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/java/com/atguigu/springcloud/OrderHystrixMain80.java new file mode 100644 index 0000000000000000000000000000000000000000..61abf49ebfc64d118ee97dc23936d6bbf500909f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/java/com/atguigu/springcloud/OrderHystrixMain80.java @@ -0,0 +1,21 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.hystrix.EnableHystrix; +import org.springframework.cloud.openfeign.EnableFeignClients; + +/** + * @auther zzyy + * @create 2020-02-20 11:55 + */ +@SpringBootApplication +@EnableFeignClients +@EnableHystrix +public class OrderHystrixMain80 +{ + public static void main(String[] args) + { + SpringApplication.run(OrderHystrixMain80.class,args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/java/com/atguigu/springcloud/controller/OrderHystirxController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/java/com/atguigu/springcloud/controller/OrderHystirxController.java new file mode 100644 index 0000000000000000000000000000000000000000..794d2b33d5b9de879c92ceef063e83c93c67d72b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/java/com/atguigu/springcloud/controller/OrderHystirxController.java @@ -0,0 +1,54 @@ +package com.atguigu.springcloud.controller; + +import com.atguigu.springcloud.service.PaymentHystrixService; +import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties; +import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; +import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-20 11:57 + */ +@RestController +@Slf4j +@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod") +public class OrderHystirxController +{ + @Resource + private PaymentHystrixService paymentHystrixService; + + @GetMapping("/consumer/payment/hystrix/ok/{id}") + public String paymentInfo_OK(@PathVariable("id") Integer id) + { + String result = paymentHystrixService.paymentInfo_OK(id); + return result; + } + + @GetMapping("/consumer/payment/hystrix/timeout/{id}") + @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = { + @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500") + }) + //@HystrixCommand + public String paymentInfo_TimeOut(@PathVariable("id") Integer id) + { + int age = 10/0; + String result = paymentHystrixService.paymentInfo_TimeOut(id); + return result; + } + public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id) + { + return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o"; + } + + // 下面是全局fallback方法 + public String payment_Global_FallbackMethod() + { + return "Global异常处理信息,请稍后再试,/(ㄒoㄒ)/~~"; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/java/com/atguigu/springcloud/service/PaymentFallbackService.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/java/com/atguigu/springcloud/service/PaymentFallbackService.java new file mode 100644 index 0000000000000000000000000000000000000000..99229e6358fdd5cba0e8016fbaffaa8d175610ab --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/java/com/atguigu/springcloud/service/PaymentFallbackService.java @@ -0,0 +1,23 @@ +package com.atguigu.springcloud.service; + +import org.springframework.stereotype.Component; + +/** + * @auther zzyy + * @create 2020-02-20 18:22 + */ +@Component +public class PaymentFallbackService implements PaymentHystrixService +{ + @Override + public String paymentInfo_OK(Integer id) + { + return "-----PaymentFallbackService fall back-paymentInfo_OK ,o(╥﹏╥)o"; + } + + @Override + public String paymentInfo_TimeOut(Integer id) + { + return "-----PaymentFallbackService fall back-paymentInfo_TimeOut ,o(╥﹏╥)o"; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/java/com/atguigu/springcloud/service/PaymentHystrixService.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/java/com/atguigu/springcloud/service/PaymentHystrixService.java new file mode 100644 index 0000000000000000000000000000000000000000..194a78f3567dc8f969ea6c742822b7da4e90a476 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/java/com/atguigu/springcloud/service/PaymentHystrixService.java @@ -0,0 +1,21 @@ +package com.atguigu.springcloud.service; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; + +/** + * @auther zzyy + * @create 2020-02-20 11:55 + */ +@Component +@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT" ,fallback = PaymentFallbackService.class) +public interface PaymentHystrixService +{ + @GetMapping("/payment/hystrix/ok/{id}") + public String paymentInfo_OK(@PathVariable("id") Integer id); + + @GetMapping("/payment/hystrix/timeout/{id}") + public String paymentInfo_TimeOut(@PathVariable("id") Integer id); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..30e8a11535c72d9a825b9bba94f52a253716be71 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/src/main/resources/application.yml @@ -0,0 +1,12 @@ +server: + port: 80 + +eureka: + client: + register-with-eureka: false + service-url: + defaultZone: http://eureka7001.com:7001/eureka/ + +feign: + hystrix: + enabled: true \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..30e8a11535c72d9a825b9bba94f52a253716be71 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/application.yml @@ -0,0 +1,12 @@ +server: + port: 80 + +eureka: + client: + register-with-eureka: false + service-url: + defaultZone: http://eureka7001.com:7001/eureka/ + +feign: + hystrix: + enabled: true \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/com/atguigu/springcloud/OrderHystrixMain80.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/com/atguigu/springcloud/OrderHystrixMain80.class new file mode 100644 index 0000000000000000000000000000000000000000..6fdd29d0675b5d5a79e9a810e0407291233c48db Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/com/atguigu/springcloud/OrderHystrixMain80.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/com/atguigu/springcloud/controller/OrderHystirxController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/com/atguigu/springcloud/controller/OrderHystirxController.class new file mode 100644 index 0000000000000000000000000000000000000000..246c7898e3acacea8202436f166f7ed850b4e82d Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/com/atguigu/springcloud/controller/OrderHystirxController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/com/atguigu/springcloud/service/PaymentFallbackService.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/com/atguigu/springcloud/service/PaymentFallbackService.class new file mode 100644 index 0000000000000000000000000000000000000000..d0b564551ae72550d3e66948e4fb681707970938 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/com/atguigu/springcloud/service/PaymentFallbackService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/com/atguigu/springcloud/service/PaymentHystrixService.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/com/atguigu/springcloud/service/PaymentHystrixService.class new file mode 100644 index 0000000000000000000000000000000000000000..7e9568355e6b80352e3d019828205f14877a4207 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/classes/com/atguigu/springcloud/service/PaymentHystrixService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/cloud-consumer-feign-hystrix-order80-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/cloud-consumer-feign-hystrix-order80-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..08118a4658e80ac0dd057da2d6d533551980506e Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/cloud-consumer-feign-hystrix-order80-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..0eadbf71b7ace7158a175c029f5331795a83cc08 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:50 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-consumer-feign-hystrix-order80 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..2ebf2df6e1b6cc41a53da0250bad626f95380b21 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,4 @@ +com\atguigu\springcloud\service\PaymentHystrixService.class +com\atguigu\springcloud\OrderHystrixMain80.class +com\atguigu\springcloud\controller\OrderHystirxController.class +com\atguigu\springcloud\service\PaymentFallbackService.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..252321792b61760fe5f3634755606db73a17774e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,4 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-feign-hystrix-order80\src\main\java\com\atguigu\springcloud\controller\OrderHystirxController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-feign-hystrix-order80\src\main\java\com\atguigu\springcloud\service\PaymentFallbackService.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-feign-hystrix-order80\src\main\java\com\atguigu\springcloud\service\PaymentHystrixService.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-feign-hystrix-order80\src\main\java\com\atguigu\springcloud\OrderHystrixMain80.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-hystrix-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/cloud-consumer-feign-order80.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/cloud-consumer-feign-order80.iml new file mode 100644 index 0000000000000000000000000000000000000000..63dd99af134a1e600aee9a407755528f792301ba --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/cloud-consumer-feign-order80.iml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..19737175fd5436ee2386de1d1dcb2ad2aae2b7e7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/pom.xml @@ -0,0 +1,62 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-consumer-feign-order80 + + + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/java/com/atguigu/springcloud/OrderFeignMain80.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/java/com/atguigu/springcloud/OrderFeignMain80.java new file mode 100644 index 0000000000000000000000000000000000000000..1715b0af50f91364ac3663259658a3b1ee5dac7b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/java/com/atguigu/springcloud/OrderFeignMain80.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +/** + * @auther zzyy + * @create 2020-02-19 23:57 + */ +@SpringBootApplication +@EnableFeignClients +public class OrderFeignMain80 +{ + public static void main(String[] args) { + SpringApplication.run(OrderFeignMain80.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/java/com/atguigu/springcloud/config/FeignConfig.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/java/com/atguigu/springcloud/config/FeignConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..dcc128eec35e60f6291f402062b3be67e472bcc1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/java/com/atguigu/springcloud/config/FeignConfig.java @@ -0,0 +1,19 @@ +package com.atguigu.springcloud.config; + +import feign.Logger; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @auther zzyy + * @create 2020-02-20 9:40 + */ +@Configuration +public class FeignConfig +{ + @Bean + Logger.Level feignLoggerLevel() + { + return Logger.Level.FULL; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/java/com/atguigu/springcloud/controller/OrderFeignController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/java/com/atguigu/springcloud/controller/OrderFeignController.java new file mode 100644 index 0000000000000000000000000000000000000000..7e530c742e52dacabc9f88f5430077c61e48e60a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/java/com/atguigu/springcloud/controller/OrderFeignController.java @@ -0,0 +1,36 @@ +package com.atguigu.springcloud.controller; + +import com.atguigu.springcloud.entities.CommonResult; +import com.atguigu.springcloud.entities.Payment; +import com.atguigu.springcloud.service.PaymentFeignService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-20 0:05 + */ +@RestController +@Slf4j +public class OrderFeignController +{ + @Resource + private PaymentFeignService paymentFeignService; + + @GetMapping(value = "/consumer/payment/get/{id}") + public CommonResult getPaymentById(@PathVariable("id") Long id) + { + return paymentFeignService.getPaymentById(id); + } + + @GetMapping(value = "/consumer/payment/feign/timeout") + public String paymentFeignTimeout() + { + // OpenFeign客户端一般默认等待1秒钟 + return paymentFeignService.paymentFeignTimeout(); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/java/com/atguigu/springcloud/service/PaymentFeignService.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/java/com/atguigu/springcloud/service/PaymentFeignService.java new file mode 100644 index 0000000000000000000000000000000000000000..b0fdbcb5d9085852522f38fb8ec4e0c1762e92d2 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/java/com/atguigu/springcloud/service/PaymentFeignService.java @@ -0,0 +1,24 @@ +package com.atguigu.springcloud.service; + +import com.atguigu.springcloud.entities.CommonResult; +import com.atguigu.springcloud.entities.Payment; +import feign.Param; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; + +/** + * @auther zzyy + * @create 2020-02-19 23:59 + */ +@Component +@FeignClient(value = "CLOUD-PAYMENT-SERVICE") +public interface PaymentFeignService +{ + @GetMapping(value = "/payment/get/{id}") + public CommonResult getPaymentById(@PathVariable("id") Long id); + + @GetMapping(value = "/payment/feign/timeout") + public String paymentFeignTimeout(); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..b1a4ac2c173840d1794e99050836c7c924438f22 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/src/main/resources/application.yml @@ -0,0 +1,19 @@ +server: + port: 80 + +eureka: + client: + register-with-eureka: false + service-url: + defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ +#设置feign客户端超时时间(OpenFeign默认支持ribbon) +ribbon: +#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间 + ReadTimeout: 5000 +#指的是建立连接后从服务器读取到可用资源所用的时间 + ConnectTimeout: 5000 + +logging: + level: + # feign日志以什么级别监控哪个接口 + com.atguigu.springcloud.service.PaymentFeignService: debug diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..b1a4ac2c173840d1794e99050836c7c924438f22 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/application.yml @@ -0,0 +1,19 @@ +server: + port: 80 + +eureka: + client: + register-with-eureka: false + service-url: + defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ +#设置feign客户端超时时间(OpenFeign默认支持ribbon) +ribbon: +#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间 + ReadTimeout: 5000 +#指的是建立连接后从服务器读取到可用资源所用的时间 + ConnectTimeout: 5000 + +logging: + level: + # feign日志以什么级别监控哪个接口 + com.atguigu.springcloud.service.PaymentFeignService: debug diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/com/atguigu/springcloud/OrderFeignMain80.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/com/atguigu/springcloud/OrderFeignMain80.class new file mode 100644 index 0000000000000000000000000000000000000000..763b3c7b8da2b0b87d3299c76c8237e776a873bd Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/com/atguigu/springcloud/OrderFeignMain80.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/com/atguigu/springcloud/config/FeignConfig.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/com/atguigu/springcloud/config/FeignConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..4d47403c70bd0ac61944381cc74dec1b92b40a62 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/com/atguigu/springcloud/config/FeignConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/com/atguigu/springcloud/controller/OrderFeignController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/com/atguigu/springcloud/controller/OrderFeignController.class new file mode 100644 index 0000000000000000000000000000000000000000..7bd307b310e02317de8388dfb8a271170fb3f94d Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/com/atguigu/springcloud/controller/OrderFeignController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/com/atguigu/springcloud/service/PaymentFeignService.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/com/atguigu/springcloud/service/PaymentFeignService.class new file mode 100644 index 0000000000000000000000000000000000000000..97a6d1a8f14b141b943df8ef7ee85d6464ca254c Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/classes/com/atguigu/springcloud/service/PaymentFeignService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/cloud-consumer-feign-order80-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/cloud-consumer-feign-order80-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..0fe4cbedcd47acd5ade001b6b0d648c4dfb09f8a Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/cloud-consumer-feign-order80-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..607b2337d4f14cd38baba2cc978eed73932ec4d6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:46 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-consumer-feign-order80 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..91f3b98a6e35c86b8b68550a28faa1c66705432d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,4 @@ +com\atguigu\springcloud\OrderFeignMain80.class +com\atguigu\springcloud\controller\OrderFeignController.class +com\atguigu\springcloud\config\FeignConfig.class +com\atguigu\springcloud\service\PaymentFeignService.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..1704e6846651fc220b1d2d45a6e3ab10b303a595 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,4 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-feign-order80\src\main\java\com\atguigu\springcloud\config\FeignConfig.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-feign-order80\src\main\java\com\atguigu\springcloud\OrderFeignMain80.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-feign-order80\src\main\java\com\atguigu\springcloud\controller\OrderFeignController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-feign-order80\src\main\java\com\atguigu\springcloud\service\PaymentFeignService.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-feign-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/cloud-consumer-hystrix-dashboard9001.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/cloud-consumer-hystrix-dashboard9001.iml new file mode 100644 index 0000000000000000000000000000000000000000..a0c5b5a8bdc6ca824888706edfec8a26cdfd002f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/cloud-consumer-hystrix-dashboard9001.iml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..ec8b5126f2f6969d92fcc5e6bfae66e6a02d5b01 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/pom.xml @@ -0,0 +1,44 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-consumer-hystrix-dashboard9001 + + + + + org.springframework.cloud + spring-cloud-starter-netflix-hystrix-dashboard + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/src/main/java/com/atguigu/springcloud/HystrixDashboardMain9001.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/src/main/java/com/atguigu/springcloud/HystrixDashboardMain9001.java new file mode 100644 index 0000000000000000000000000000000000000000..f7c2fc3c6ea1b2758bf6c32eb1ccd457190ad07c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/src/main/java/com/atguigu/springcloud/HystrixDashboardMain9001.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; + +/** + * @auther zzyy + * @create 2020-02-20 22:02 + */ +@SpringBootApplication +@EnableHystrixDashboard +public class HystrixDashboardMain9001 +{ + public static void main(String[] args) { + SpringApplication.run(HystrixDashboardMain9001.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..3621202f14a4e0e3ac0262e7cb5d714f9c523098 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/src/main/resources/application.yml @@ -0,0 +1,2 @@ +server: + port: 9001 \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..3621202f14a4e0e3ac0262e7cb5d714f9c523098 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/classes/application.yml @@ -0,0 +1,2 @@ +server: + port: 9001 \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/classes/com/atguigu/springcloud/HystrixDashboardMain9001.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/classes/com/atguigu/springcloud/HystrixDashboardMain9001.class new file mode 100644 index 0000000000000000000000000000000000000000..1a6c516c9b599322b92651436a8bd90712369bda Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/classes/com/atguigu/springcloud/HystrixDashboardMain9001.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/cloud-consumer-hystrix-dashboard9001-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/cloud-consumer-hystrix-dashboard9001-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..6fe57eafaf1768fce74881df01b7ec8e886f93ab Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/cloud-consumer-hystrix-dashboard9001-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..1105442e234ebec9fc43bbc0a1fce6e50a0e4847 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:51 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-consumer-hystrix-dashboard9001 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..69e954f12aeb7ba31decab6f875d40af2b57533c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1 @@ +com\atguigu\springcloud\HystrixDashboardMain9001.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..b7703b1555c8abdc4a0c138771fc5ac10a58c522 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-hystrix-dashboard9001\src\main\java\com\atguigu\springcloud\HystrixDashboardMain9001.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-hystrix-dashboard9001/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/cloud-consumer-order80.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/cloud-consumer-order80.iml new file mode 100644 index 0000000000000000000000000000000000000000..530f70cadd6e32c1b5a534e136d785163fa902f7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/cloud-consumer-order80.iml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..61326398459f0a9839e47737b05b1abdd3362976 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/pom.xml @@ -0,0 +1,58 @@ + + + + com.atguigu.springcloud + cloud2020 + 1.0-SNAPSHOT + + 4.0.0 + + cloud-consumer-order80 + + + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/myrule/MySelfRule.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/myrule/MySelfRule.java new file mode 100644 index 0000000000000000000000000000000000000000..630e48213b383fd0d3466d8a289607a6f163f72c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/myrule/MySelfRule.java @@ -0,0 +1,20 @@ +package com.atguigu.myrule; + +import com.netflix.loadbalancer.IRule; +import com.netflix.loadbalancer.RandomRule; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @auther zzyy + * @create 2020-02-19 19:00 + */ +@Configuration +public class MySelfRule +{ + @Bean + public IRule myRule() + { + return new RandomRule();//定义为随机 + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/OrderMain80.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/OrderMain80.java new file mode 100644 index 0000000000000000000000000000000000000000..82afb45893e05b06bc9542b1f54a117f8d5d3d93 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/OrderMain80.java @@ -0,0 +1,22 @@ +package com.atguigu.springcloud; + +import com.atguigu.myrule.MySelfRule; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.cloud.netflix.ribbon.RibbonClient; +import org.springframework.cloud.netflix.ribbon.RibbonClients; + +/** + * @auther zzyy + * @create 2020-02-18 17:20 + */ +@SpringBootApplication +@EnableEurekaClient +//@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration=MySelfRule.class) +public class OrderMain80 +{ + public static void main(String[] args) { + SpringApplication.run(OrderMain80.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/config/ApplicationContextConfig.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/config/ApplicationContextConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..e84a3b772bf000d3094295044c959b79cd732a69 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/config/ApplicationContextConfig.java @@ -0,0 +1,22 @@ +package com.atguigu.springcloud.config; + +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * @auther zzyy + * @create 2020-02-18 17:27 + */ +@Configuration +public class ApplicationContextConfig +{ + @Bean + //@LoadBalanced + public RestTemplate getRestTemplate() + { + return new RestTemplate(); + } +} +//applicationContext.xml \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/controller/OrderController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/controller/OrderController.java new file mode 100644 index 0000000000000000000000000000000000000000..13da9b46eb56b3c4608af54bc65020cd93b7a63d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/controller/OrderController.java @@ -0,0 +1,87 @@ +package com.atguigu.springcloud.controller; + +import com.atguigu.springcloud.entities.CommonResult; +import com.atguigu.springcloud.entities.Payment; +import com.atguigu.springcloud.lb.LoadBalancer; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; +import java.net.URI; +import java.util.List; + +/** + * @auther zzyy + * @create 2020-02-18 17:23 + */ +@RestController +@Slf4j +public class OrderController +{ + //public static final String PAYMENT_URL = "http://localhost:8001"; + + public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE"; + + @Resource + private RestTemplate restTemplate; + + @Resource + private LoadBalancer loadBalancer; + @Resource + private DiscoveryClient discoveryClient; + + @GetMapping("/consumer/payment/create") + public CommonResult create(Payment payment) + { + return restTemplate.postForObject(PAYMENT_URL +"/payment/create",payment,CommonResult.class); + } + + @GetMapping("/consumer/payment/get/{id}") + public CommonResult getPayment(@PathVariable("id") Long id) + { + return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class); + } + + @GetMapping("/consumer/payment/getForEntity/{id}") + public CommonResult getPayment2(@PathVariable("id") Long id) + { + ResponseEntity entity = restTemplate.getForEntity(PAYMENT_URL+"/payment/get/"+id,CommonResult.class); + + if(entity.getStatusCode().is2xxSuccessful()){ + return entity.getBody(); + }else{ + return new CommonResult<>(444,"操作失败"); + } + } + + @GetMapping(value = "/consumer/payment/lb") + public String getPaymentLB() + { + List instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE"); + + if(instances == null || instances.size() <= 0) + { + return null; + } + + ServiceInstance serviceInstance = loadBalancer.instances(instances); + URI uri = serviceInstance.getUri(); + + return restTemplate.getForObject(uri+"/payment/lb",String.class); + + } + + // ====================> zipkin+sleuth + @GetMapping("/consumer/payment/zipkin") + public String paymentZipkin() + { + String result = restTemplate.getForObject("http://localhost:8001"+"/payment/zipkin/", String.class); + return result; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/lb/LoadBalancer.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/lb/LoadBalancer.java new file mode 100644 index 0000000000000000000000000000000000000000..57cdd6a597e88e245e7a2097eb8954aeac2b6677 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/lb/LoadBalancer.java @@ -0,0 +1,14 @@ +package com.atguigu.springcloud.lb; + +import org.springframework.cloud.client.ServiceInstance; + +import java.util.List; + +/** + * @auther zzyy + * @create 2020-02-19 20:31 + */ +public interface LoadBalancer +{ + ServiceInstance instances(List serviceInstances); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/lb/MyLB.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/lb/MyLB.java new file mode 100644 index 0000000000000000000000000000000000000000..4d273f199b032cf9d2a61d4f246c24484301e33e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/java/com/atguigu/springcloud/lb/MyLB.java @@ -0,0 +1,40 @@ +package com.atguigu.springcloud.lb; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @auther zzyy + * @create 2020-02-19 20:33 + */ +@Component +public class MyLB implements LoadBalancer +{ + + private AtomicInteger atomicInteger = new AtomicInteger(0); + + public final int getAndIncrement() + { + int current; + int next; + + do { + current = this.atomicInteger.get(); + next = current >= 2147483647 ? 0 : current + 1; + }while(!this.atomicInteger.compareAndSet(current,next)); + System.out.println("*****第几次访问,次数next: "+next); + return next; + } + + //负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标 ,每次服务重启动后rest接口计数从1开始。 + @Override + public ServiceInstance instances(List serviceInstances) + { + int index = getAndIncrement() % serviceInstances.size(); + + return serviceInstances.get(index); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..6b5373e73c5c5f5a1a7d880dc51ea5f05b66624f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/main/resources/application.yml @@ -0,0 +1,25 @@ +server: + port: 80 + +spring: + application: + name: cloud-order-service + zipkin: + base-url: http://localhost:9411 + sleuth: + sampler: + probability: 1 + +eureka: + client: + #表示是否将自己注册进EurekaServer默认为true。 + register-with-eureka: false + #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 + fetchRegistry: true + service-url: + #单机 + #defaultZone: http://localhost:7001/eureka + # 集群 + defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版 + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/test/java/T.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/test/java/T.java new file mode 100644 index 0000000000000000000000000000000000000000..14dd82729205a2d7a98600b4d79ae109ad106612 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/src/test/java/T.java @@ -0,0 +1,11 @@ +/** + * @auther zzyy + * @create 2020-02-19 20:39 + */ +public class T +{ + public static void main(String[] args) + { + System.out.println(Integer.MAX_VALUE); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..6b5373e73c5c5f5a1a7d880dc51ea5f05b66624f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/application.yml @@ -0,0 +1,25 @@ +server: + port: 80 + +spring: + application: + name: cloud-order-service + zipkin: + base-url: http://localhost:9411 + sleuth: + sampler: + probability: 1 + +eureka: + client: + #表示是否将自己注册进EurekaServer默认为true。 + register-with-eureka: false + #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 + fetchRegistry: true + service-url: + #单机 + #defaultZone: http://localhost:7001/eureka + # 集群 + defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版 + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/myrule/MySelfRule.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/myrule/MySelfRule.class new file mode 100644 index 0000000000000000000000000000000000000000..09687af6fb2ae68cb8af6d3b3b5fb7f6f1af73c4 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/myrule/MySelfRule.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/OrderMain80.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/OrderMain80.class new file mode 100644 index 0000000000000000000000000000000000000000..e7f2e5d0738554597d5721870ef084689e07761b Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/OrderMain80.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/config/ApplicationContextConfig.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/config/ApplicationContextConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..410ace2a450969f72ebbd06b5d62ecb74b4c1d94 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/config/ApplicationContextConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/controller/OrderController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/controller/OrderController.class new file mode 100644 index 0000000000000000000000000000000000000000..a7ed23f522ed3a9edc5e4f18d4209b4add6ecab4 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/controller/OrderController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/lb/LoadBalancer.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/lb/LoadBalancer.class new file mode 100644 index 0000000000000000000000000000000000000000..12c4f89c6ec5536ed6e96606731bb16ce3066906 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/lb/LoadBalancer.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/lb/MyLB.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/lb/MyLB.class new file mode 100644 index 0000000000000000000000000000000000000000..1c2090efc72256e36e68f32d242c44d03416eac6 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/classes/com/atguigu/springcloud/lb/MyLB.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/cloud-consumer-order80-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/cloud-consumer-order80-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..323546c2a18b070b95fe4ac1ca770edbda46e897 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/cloud-consumer-order80-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..256845043fc196b6ae85eb59695643a919e7b34c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:25 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-consumer-order80 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..77144f3fc60ec795beb75e6bdc5cad290dd2fb68 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,6 @@ +com\atguigu\springcloud\OrderMain80.class +com\atguigu\springcloud\controller\OrderController.class +com\atguigu\myrule\MySelfRule.class +com\atguigu\springcloud\config\ApplicationContextConfig.class +com\atguigu\springcloud\lb\MyLB.class +com\atguigu\springcloud\lb\LoadBalancer.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..5c4c165432867b1981085dc53e84d9e0bc2a6dae --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,6 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-order80\src\main\java\com\atguigu\springcloud\controller\OrderController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-order80\src\main\java\com\atguigu\springcloud\lb\MyLB.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-order80\src\main\java\com\atguigu\springcloud\config\ApplicationContextConfig.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-order80\src\main\java\com\atguigu\springcloud\OrderMain80.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-order80\src\main\java\com\atguigu\myrule\MySelfRule.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-order80\src\main\java\com\atguigu\springcloud\lb\LoadBalancer.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..10f18d72f554d7bc580992fc59642c979b080875 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst @@ -0,0 +1 @@ +T.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..4789fc6cdefb1af1f1a38869dc55a57f1e95b544 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst @@ -0,0 +1 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumer-order80\src\test\java\T.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/test-classes/T.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/test-classes/T.class new file mode 100644 index 0000000000000000000000000000000000000000..55080d80dbd578907f292b3dcba2de24cb4e814b Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumer-order80/target/test-classes/T.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/cloud-consumerconsul-order80.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/cloud-consumerconsul-order80.iml new file mode 100644 index 0000000000000000000000000000000000000000..a5ac55d839e02b0632bffd0cde571d9f87f4f80d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/cloud-consumerconsul-order80.iml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..303e52269be56401716c7ee0d3c8fed06115ce8c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/pom.xml @@ -0,0 +1,48 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-consumerconsul-order80 + + + + + + org.springframework.cloud + spring-cloud-starter-consul-discovery + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/src/main/java/com/atguigu/springcloud/OrderConsulMain80.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/src/main/java/com/atguigu/springcloud/OrderConsulMain80.java new file mode 100644 index 0000000000000000000000000000000000000000..6b8eff78f87c1a433e7329cd27bec2d4703f897b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/src/main/java/com/atguigu/springcloud/OrderConsulMain80.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @auther zzyy + * @create 2020-02-19 16:22 + */ +@SpringBootApplication +@EnableDiscoveryClient //该注解用于向使用consul或者zookeeper作为注册中心时注册服务 +public class OrderConsulMain80 +{ + public static void main(String[] args) { + SpringApplication.run(OrderConsulMain80.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/src/main/java/com/atguigu/springcloud/config/ApplicationContextConfig.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/src/main/java/com/atguigu/springcloud/config/ApplicationContextConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..50d1932233ea6d152a706e8fe99fb228795a6da6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/src/main/java/com/atguigu/springcloud/config/ApplicationContextConfig.java @@ -0,0 +1,21 @@ +package com.atguigu.springcloud.config; + +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * @auther zzyy + * @create 2020-02-19 15:20 + */ +@Configuration +public class ApplicationContextConfig +{ + @Bean + @LoadBalanced + public RestTemplate getRestTemplate() + { + return new RestTemplate(); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/src/main/java/com/atguigu/springcloud/controller/OrderConsulController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/src/main/java/com/atguigu/springcloud/controller/OrderConsulController.java new file mode 100644 index 0000000000000000000000000000000000000000..58d2c6c1470e81ae9b71c6021d8c6e41b01cf3ed --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/src/main/java/com/atguigu/springcloud/controller/OrderConsulController.java @@ -0,0 +1,29 @@ +package com.atguigu.springcloud.controller; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-19 16:24 + */ +@RestController +@Slf4j +public class OrderConsulController +{ + public static final String INVOKE_URL = "http://consul-provider-payment"; + + @Resource + private RestTemplate restTemplate; + + @GetMapping(value = "/consumer/payment/consul") + public String paymentInfo() + { + String result = restTemplate.getForObject(INVOKE_URL+"/payment/consul",String.class); + return result; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..cff3a3ea8541eb696fdd3377e8beb537887a9618 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/src/main/resources/application.yml @@ -0,0 +1,16 @@ +###consul服务端口号 +server: + port: 80 + +spring: + application: + name: cloud-consumer-order +####consul注册中心地址 + cloud: + consul: + host: localhost + port: 8500 + discovery: + #hostname: 127.0.0.1 + service-name: ${spring.application.name} + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..cff3a3ea8541eb696fdd3377e8beb537887a9618 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/classes/application.yml @@ -0,0 +1,16 @@ +###consul服务端口号 +server: + port: 80 + +spring: + application: + name: cloud-consumer-order +####consul注册中心地址 + cloud: + consul: + host: localhost + port: 8500 + discovery: + #hostname: 127.0.0.1 + service-name: ${spring.application.name} + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/classes/com/atguigu/springcloud/OrderConsulMain80.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/classes/com/atguigu/springcloud/OrderConsulMain80.class new file mode 100644 index 0000000000000000000000000000000000000000..fb89e05c7f70b0df12d95677858b61fae0665f08 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/classes/com/atguigu/springcloud/OrderConsulMain80.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/classes/com/atguigu/springcloud/config/ApplicationContextConfig.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/classes/com/atguigu/springcloud/config/ApplicationContextConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..8cd3c9395e220a79f243a3893bafbd8aab4ec943 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/classes/com/atguigu/springcloud/config/ApplicationContextConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/classes/com/atguigu/springcloud/controller/OrderConsulController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/classes/com/atguigu/springcloud/controller/OrderConsulController.class new file mode 100644 index 0000000000000000000000000000000000000000..9cb31c1726261a52661ec2bdc348fb0188b262c7 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/classes/com/atguigu/springcloud/controller/OrderConsulController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/cloud-consumerconsul-order80-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/cloud-consumerconsul-order80-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..6a68a473b6ed518109a19747ca4a3d4a319fcf04 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/cloud-consumerconsul-order80-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..b607f3ff821a39d21986a6c226a85dae748638a9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:44 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-consumerconsul-order80 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..d784e69946f736f19f7140677327d52e88d152e2 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,3 @@ +com\atguigu\springcloud\OrderConsulMain80.class +com\atguigu\springcloud\config\ApplicationContextConfig.class +com\atguigu\springcloud\controller\OrderConsulController.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..54017eace3709d4ca881e67c30d0a471f9863d14 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,3 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumerconsul-order80\src\main\java\com\atguigu\springcloud\OrderConsulMain80.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumerconsul-order80\src\main\java\com\atguigu\springcloud\controller\OrderConsulController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumerconsul-order80\src\main\java\com\atguigu\springcloud\config\ApplicationContextConfig.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerconsul-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/cloud-consumerzk-order80.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/cloud-consumerzk-order80.iml new file mode 100644 index 0000000000000000000000000000000000000000..3360e69723556fc914c70052b9eaf755a4f8853c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/cloud-consumerzk-order80.iml @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..32d46b8101c05a96266ea28355928f2a64ddb43a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/pom.xml @@ -0,0 +1,58 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-consumerzk-order80 + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.cloud + spring-cloud-starter-zookeeper-discovery + + + + org.apache.zookeeper + zookeeper + + + + + + org.apache.zookeeper + zookeeper + 3.4.9 + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/src/main/java/com/atguigu/springcloud/OrderZKMain80.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/src/main/java/com/atguigu/springcloud/OrderZKMain80.java new file mode 100644 index 0000000000000000000000000000000000000000..56a71382658c8867765ff44b9157974852f20b90 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/src/main/java/com/atguigu/springcloud/OrderZKMain80.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @auther zzyy + * @create 2020-02-19 15:19 + */ +@SpringBootApplication +@EnableDiscoveryClient +public class OrderZKMain80 +{ + public static void main(String[] args) { + SpringApplication.run(OrderZKMain80.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/src/main/java/com/atguigu/springcloud/config/ApplicationContextConfig.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/src/main/java/com/atguigu/springcloud/config/ApplicationContextConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..50d1932233ea6d152a706e8fe99fb228795a6da6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/src/main/java/com/atguigu/springcloud/config/ApplicationContextConfig.java @@ -0,0 +1,21 @@ +package com.atguigu.springcloud.config; + +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * @auther zzyy + * @create 2020-02-19 15:20 + */ +@Configuration +public class ApplicationContextConfig +{ + @Bean + @LoadBalanced + public RestTemplate getRestTemplate() + { + return new RestTemplate(); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/src/main/java/com/atguigu/springcloud/controller/OrderZKController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/src/main/java/com/atguigu/springcloud/controller/OrderZKController.java new file mode 100644 index 0000000000000000000000000000000000000000..42a9bb8f3f07593ce444d8ca832c21b24cdf06c8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/src/main/java/com/atguigu/springcloud/controller/OrderZKController.java @@ -0,0 +1,29 @@ +package com.atguigu.springcloud.controller; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-19 15:21 + */ +@RestController +@Slf4j +public class OrderZKController +{ + public static final String INVOKE_URL = "http://cloud-provider-payment"; + + @Resource + private RestTemplate restTemplate; + + @GetMapping(value = "/consumer/payment/zk") + public String paymentInfo() + { + String result = restTemplate.getForObject(INVOKE_URL+"/payment/zk",String.class); + return result; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..cdb72126fc1023c30d8dd20670eee481d44a4436 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/src/main/resources/application.yml @@ -0,0 +1,13 @@ +server: + port: 80 + +spring: + application: + name: cloud-consumer-order + cloud: + #注册到zookeeper地址 + zookeeper: + connect-string: 192.168.111.144:2181 + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..cdb72126fc1023c30d8dd20670eee481d44a4436 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/classes/application.yml @@ -0,0 +1,13 @@ +server: + port: 80 + +spring: + application: + name: cloud-consumer-order + cloud: + #注册到zookeeper地址 + zookeeper: + connect-string: 192.168.111.144:2181 + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/classes/com/atguigu/springcloud/OrderZKMain80.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/classes/com/atguigu/springcloud/OrderZKMain80.class new file mode 100644 index 0000000000000000000000000000000000000000..d82a8663ec9b821621703932c4fa07fd48f16775 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/classes/com/atguigu/springcloud/OrderZKMain80.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/classes/com/atguigu/springcloud/config/ApplicationContextConfig.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/classes/com/atguigu/springcloud/config/ApplicationContextConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..8cd3c9395e220a79f243a3893bafbd8aab4ec943 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/classes/com/atguigu/springcloud/config/ApplicationContextConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/classes/com/atguigu/springcloud/controller/OrderZKController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/classes/com/atguigu/springcloud/controller/OrderZKController.class new file mode 100644 index 0000000000000000000000000000000000000000..4b5cb5da595dc2c3489d10f8ba43962c344db7c7 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/classes/com/atguigu/springcloud/controller/OrderZKController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/cloud-consumerzk-order80-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/cloud-consumerzk-order80-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..16a59fd5c268563eb4227397114b1d4ff951e2f3 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/cloud-consumerzk-order80-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..538fb1bf7ef1b05c607c63d3969080927d79b7f8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:37 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-consumerzk-order80 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..051d4b97beae3d1702db8274ec8aa307f73f92b3 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,3 @@ +com\atguigu\springcloud\controller\OrderZKController.class +com\atguigu\springcloud\OrderZKMain80.class +com\atguigu\springcloud\config\ApplicationContextConfig.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..7659dcb04115eacf84cc50249ef1092908eec5ee --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,3 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumerzk-order80\src\main\java\com\atguigu\springcloud\OrderZKMain80.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumerzk-order80\src\main\java\com\atguigu\springcloud\config\ApplicationContextConfig.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-consumerzk-order80\src\main\java\com\atguigu\springcloud\controller\OrderZKController.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-consumerzk-order80/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/cloud-eureka-server7001.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/cloud-eureka-server7001.iml new file mode 100644 index 0000000000000000000000000000000000000000..63dc8c7fcb156fc1315978550b8b67c49f1651ce --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/cloud-eureka-server7001.iml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..e59901ad67dee51d302c3d568bff4fe25ab27a7e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/pom.xml @@ -0,0 +1,59 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-eureka-server7001 + + + + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-server + + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/src/main/java/com/atguigu/springcloud/EurekaMain7001.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/src/main/java/com/atguigu/springcloud/EurekaMain7001.java new file mode 100644 index 0000000000000000000000000000000000000000..c6a101838cbe1092b35602ed03a6e722c4313524 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/src/main/java/com/atguigu/springcloud/EurekaMain7001.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; + +/** + * @auther zzyy + * @create 2020-02-18 21:15 + */ +@SpringBootApplication +@EnableEurekaServer +public class EurekaMain7001 +{ + public static void main(String[] args) { + SpringApplication.run(EurekaMain7001.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..0380c68d6265bbcc00229ad4055fe57c36c21028 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/src/main/resources/application.yml @@ -0,0 +1,19 @@ +server: + port: 7001 + + +eureka: + instance: + hostname: eureka7001.com #eureka服务端的实例名称 + client: + register-with-eureka: false #false表示不向注册中心注册自己。 + fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 + service-url: + #集群指向其它eureka + #defaultZone: http://eureka7002.com:7002/eureka/ + #单机就是7001自己 + defaultZone: http://eureka7001.com:7001/eureka/ + #server: + #关闭自我保护机制,保证不可用服务被及时踢除 + #enable-self-preservation: false + #eviction-interval-timer-in-ms: 2000 \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..0380c68d6265bbcc00229ad4055fe57c36c21028 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/classes/application.yml @@ -0,0 +1,19 @@ +server: + port: 7001 + + +eureka: + instance: + hostname: eureka7001.com #eureka服务端的实例名称 + client: + register-with-eureka: false #false表示不向注册中心注册自己。 + fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 + service-url: + #集群指向其它eureka + #defaultZone: http://eureka7002.com:7002/eureka/ + #单机就是7001自己 + defaultZone: http://eureka7001.com:7001/eureka/ + #server: + #关闭自我保护机制,保证不可用服务被及时踢除 + #enable-self-preservation: false + #eviction-interval-timer-in-ms: 2000 \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/classes/com/atguigu/springcloud/EurekaMain7001.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/classes/com/atguigu/springcloud/EurekaMain7001.class new file mode 100644 index 0000000000000000000000000000000000000000..6c395fe3de224f09e937f182705ac38b451cc4cd Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/classes/com/atguigu/springcloud/EurekaMain7001.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/cloud-eureka-server7001-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/cloud-eureka-server7001-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..b18c8b0ae6e26bad534c6d68ee8ed63e7374291c Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/cloud-eureka-server7001-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..471fe981888674bc03bc58d42c3136e5b085fb97 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:28 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-eureka-server7001 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..aceeaccf41822b1d1274ae836ad7372d8934caf4 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1 @@ +com\atguigu\springcloud\EurekaMain7001.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..bab1212bc520a989fbced29ae2ccf0cdc0a9379e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-eureka-server7001\src\main\java\com\atguigu\springcloud\EurekaMain7001.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7001/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/cloud-eureka-server7002.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/cloud-eureka-server7002.iml new file mode 100644 index 0000000000000000000000000000000000000000..63dc8c7fcb156fc1315978550b8b67c49f1651ce --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/cloud-eureka-server7002.iml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..ede9f7c472762213129ba11bf3622b6cb4c279d2 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/pom.xml @@ -0,0 +1,60 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-eureka-server7002 + + + + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-server + + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/src/main/java/com/atguigu/springcloud/EurekaMain7002.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/src/main/java/com/atguigu/springcloud/EurekaMain7002.java new file mode 100644 index 0000000000000000000000000000000000000000..3454af634f903fbbbd825f22a0bb512f05f4da6b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/src/main/java/com/atguigu/springcloud/EurekaMain7002.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; + +/** + * @auther zzyy + * @create 2020-02-18 23:44 + */ +@SpringBootApplication +@EnableEurekaServer +public class EurekaMain7002 +{ + public static void main(String[] args) { + SpringApplication.run(EurekaMain7002.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..e714fbc66b1e93b814b44caebcb5043cf0d81245 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/src/main/resources/application.yml @@ -0,0 +1,24 @@ +server: + port: 7002 + + +eureka: + instance: + hostname: eureka7002.com #eureka服务端的实例名称 + client: + register-with-eureka: false #false表示不向注册中心注册自己。 + fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 + service-url: + #集群指向其它eureka + defaultZone: http://eureka7001.com:7001/eureka/ + #单机就是自己 + #defaultZone: http://eureka7002.com:7002/eureka/ + + + + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..e714fbc66b1e93b814b44caebcb5043cf0d81245 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/classes/application.yml @@ -0,0 +1,24 @@ +server: + port: 7002 + + +eureka: + instance: + hostname: eureka7002.com #eureka服务端的实例名称 + client: + register-with-eureka: false #false表示不向注册中心注册自己。 + fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 + service-url: + #集群指向其它eureka + defaultZone: http://eureka7001.com:7001/eureka/ + #单机就是自己 + #defaultZone: http://eureka7002.com:7002/eureka/ + + + + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/classes/com/atguigu/springcloud/EurekaMain7002.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/classes/com/atguigu/springcloud/EurekaMain7002.class new file mode 100644 index 0000000000000000000000000000000000000000..af2cdba9e9e601b4026f04a5dc3eaf78a2fe9069 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/classes/com/atguigu/springcloud/EurekaMain7002.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/cloud-eureka-server7002-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/cloud-eureka-server7002-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..5bb3fc356cb6d23be11fa98b71f84003b4672a6e Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/cloud-eureka-server7002-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..05d096b22d2af5794b28475ed562cd5a6ea99efc --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:29 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-eureka-server7002 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..11a89a1e8ec84ddb608f0fd7bb8aee7a2f2fac37 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1 @@ +com\atguigu\springcloud\EurekaMain7002.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..deb20243cca26535a3a2aab1cdd54d576f8b77c8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-eureka-server7002\src\main\java\com\atguigu\springcloud\EurekaMain7002.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-eureka-server7002/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/cloud-gateway-gateway9527.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/cloud-gateway-gateway9527.iml new file mode 100644 index 0000000000000000000000000000000000000000..5efc8ac4c73cb808fe346b7345a2c9369a8fc8c4 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/cloud-gateway-gateway9527.iml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/../cloud-consumer-hystrix-dashboard9001/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..a4d3193ffc5ae8c7e3ffbe8ae6754c31e4f95b9e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/pom.xml @@ -0,0 +1,52 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-gateway-gateway9527 + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/main/java/com/atguigu/springcloud/GateWayMain9527.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/main/java/com/atguigu/springcloud/GateWayMain9527.java new file mode 100644 index 0000000000000000000000000000000000000000..b932490fec9436a3f7d1dfb65da6cf344907ba62 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/main/java/com/atguigu/springcloud/GateWayMain9527.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; + +/** + * @auther zzyy + * @create 2020-02-21 11:02 + */ +@SpringBootApplication +@EnableEurekaClient +public class GateWayMain9527 +{ + public static void main(String[] args) { + SpringApplication.run(GateWayMain9527.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/main/java/com/atguigu/springcloud/config/GateWayConfig.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/main/java/com/atguigu/springcloud/config/GateWayConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..07c60d0d4f7a0d73f600f785b7f13459e5e355e6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/main/java/com/atguigu/springcloud/config/GateWayConfig.java @@ -0,0 +1,26 @@ +package com.atguigu.springcloud.config; + +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @auther zzyy + * @create 2020-02-21 11:42 + */ +@Configuration +public class GateWayConfig +{ + @Bean + public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) + { + RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes(); + + routes.route("path_route_atguigu", + r -> r.path("/guonei") + .uri("http://news.baidu.com/guonei")).build(); + + return routes.build(); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/main/java/com/atguigu/springcloud/filter/MyLogGateWayFilter.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/main/java/com/atguigu/springcloud/filter/MyLogGateWayFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..14fb3dde3ff043fde228add325a0c1b1a13d629d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/main/java/com/atguigu/springcloud/filter/MyLogGateWayFilter.java @@ -0,0 +1,45 @@ +package com.atguigu.springcloud.filter; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +import java.util.Date; + +/** + * @auther zzyy + * @create 2020-02-21 16:40 + */ +@Component +@Slf4j +public class MyLogGateWayFilter implements GlobalFilter,Ordered +{ + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) + { + log.info("***********come in MyLogGateWayFilter: "+new Date()); + + String uname = exchange.getRequest().getQueryParams().getFirst("uname"); + + if(uname == null) + { + log.info("*******用户名为null,非法用户,o(╥﹏╥)o"); + exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE); + return exchange.getResponse().setComplete(); + } + + return chain.filter(exchange); + } + + @Override + public int getOrder() + { + return 0; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..4c22f085e2bbb88e16b4e3807399b7ec4966b9fc --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/main/resources/application.yml @@ -0,0 +1,38 @@ + +server: + port: 9527 + +spring: + application: + name: cloud-gateway + cloud: + gateway: + discovery: + locator: + enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由 + routes: + - id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名 + #uri: http://localhost:8001 #匹配后提供服务的路由地址 + uri: lb://cloud-payment-service #匹配后提供服务的路由地址 + predicates: + - Path=/payment/get/** # 断言,路径相匹配的进行路由 + + - id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名 + #uri: http://localhost:8001 #匹配后提供服务的路由地址 + uri: lb://cloud-payment-service #匹配后提供服务的路由地址 + predicates: + - Path=/payment/lb/** # 断言,路径相匹配的进行路由 + #- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai] + #- Cookie=username,zzyy + #- Header=X-Request-Id, \d+ # 请求头要有X-Request-Id属性并且值为整数的正则表达式 + +eureka: + instance: + hostname: cloud-gateway-service + client: #服务提供者provider注册进eureka服务列表内 + service-url: + register-with-eureka: true + fetch-registry: true + defaultZone: http://eureka7001.com:7001/eureka + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/test/java/T2.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/test/java/T2.java new file mode 100644 index 0000000000000000000000000000000000000000..b89378b577851ed8b0a5e2aca7b4c1958382bb30 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/src/test/java/T2.java @@ -0,0 +1,16 @@ +import java.time.ZonedDateTime; + +/** + * @auther zzyy + * @create 2020-02-21 15:50 + */ +public class T2 +{ + public static void main(String[] args) + { + ZonedDateTime zbj = ZonedDateTime.now(); // 默认时区 + System.out.println(zbj); + + //2020-02-21T15:51:37.485+08:00[Asia/Shanghai] + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..4c22f085e2bbb88e16b4e3807399b7ec4966b9fc --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/classes/application.yml @@ -0,0 +1,38 @@ + +server: + port: 9527 + +spring: + application: + name: cloud-gateway + cloud: + gateway: + discovery: + locator: + enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由 + routes: + - id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名 + #uri: http://localhost:8001 #匹配后提供服务的路由地址 + uri: lb://cloud-payment-service #匹配后提供服务的路由地址 + predicates: + - Path=/payment/get/** # 断言,路径相匹配的进行路由 + + - id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名 + #uri: http://localhost:8001 #匹配后提供服务的路由地址 + uri: lb://cloud-payment-service #匹配后提供服务的路由地址 + predicates: + - Path=/payment/lb/** # 断言,路径相匹配的进行路由 + #- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai] + #- Cookie=username,zzyy + #- Header=X-Request-Id, \d+ # 请求头要有X-Request-Id属性并且值为整数的正则表达式 + +eureka: + instance: + hostname: cloud-gateway-service + client: #服务提供者provider注册进eureka服务列表内 + service-url: + register-with-eureka: true + fetch-registry: true + defaultZone: http://eureka7001.com:7001/eureka + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/classes/com/atguigu/springcloud/GateWayMain9527.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/classes/com/atguigu/springcloud/GateWayMain9527.class new file mode 100644 index 0000000000000000000000000000000000000000..dd653f46f6c9fe7c5af261d416abf1f695ff71a6 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/classes/com/atguigu/springcloud/GateWayMain9527.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/classes/com/atguigu/springcloud/config/GateWayConfig.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/classes/com/atguigu/springcloud/config/GateWayConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..5b9bbe5dba8f34212ec21ea1789f009e5cdd0a40 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/classes/com/atguigu/springcloud/config/GateWayConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/classes/com/atguigu/springcloud/filter/MyLogGateWayFilter.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/classes/com/atguigu/springcloud/filter/MyLogGateWayFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..d817f250c033fb488aeb030d34e4c137057c8294 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/classes/com/atguigu/springcloud/filter/MyLogGateWayFilter.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/cloud-gateway-gateway9527-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/cloud-gateway-gateway9527-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..deecdfb9453940f04ce86b3dbd85ec2122ba3f61 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/cloud-gateway-gateway9527-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..efe200c9884377520871e128e9021db5a13c2414 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:54 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-gateway-gateway9527 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..5f72b728d3be58ea41368fcb06c643c1ec69a150 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,3 @@ +com\atguigu\springcloud\GateWayMain9527.class +com\atguigu\springcloud\config\GateWayConfig.class +com\atguigu\springcloud\filter\MyLogGateWayFilter.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..6a58f38e6ff03a1ba70642281655dff4bee0c68b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,3 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-gateway-gateway9527\src\main\java\com\atguigu\springcloud\filter\MyLogGateWayFilter.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-gateway-gateway9527\src\main\java\com\atguigu\springcloud\config\GateWayConfig.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-gateway-gateway9527\src\main\java\com\atguigu\springcloud\GateWayMain9527.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..16c7120e75bd2d3213d6a11b3c4ac6e3da214daf --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst @@ -0,0 +1 @@ +T2.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..36f21e493934f99048cc80ec40cdcbf6f93c3611 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst @@ -0,0 +1 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-gateway-gateway9527\src\test\java\T2.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/test-classes/T2.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/test-classes/T2.class new file mode 100644 index 0000000000000000000000000000000000000000..13261dc1d8e5cfb40c0d046fa36f7ce1c8767b32 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-gateway-gateway9527/target/test-classes/T2.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/cloud-provider-hystrix-payment8001.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/cloud-provider-hystrix-payment8001.iml new file mode 100644 index 0000000000000000000000000000000000000000..12b54f2a30753404fffe64d83301db4e05964dcb --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/cloud-provider-hystrix-payment8001.iml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..7544ca42e5aa4be2755ef92f4e5d8ce9eb2e2262 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/pom.xml @@ -0,0 +1,58 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-provider-hystrix-payment8001 + + + + + + org.springframework.cloud + spring-cloud-starter-netflix-hystrix + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/src/main/java/com/atguigu/springcloud/PaymentHystrixMain8001.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/src/main/java/com/atguigu/springcloud/PaymentHystrixMain8001.java new file mode 100644 index 0000000000000000000000000000000000000000..e4f866c64495e8d99d1de7862e5b3ec7f917caf7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/src/main/java/com/atguigu/springcloud/PaymentHystrixMain8001.java @@ -0,0 +1,39 @@ +package com.atguigu.springcloud; + +import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.context.annotation.Bean; + +/** + * @auther zzyy + * @create 2020-02-20 11:10 + */ +@SpringBootApplication +@EnableEurekaClient +@EnableCircuitBreaker +public class PaymentHystrixMain8001 +{ + public static void main(String[] args) { + SpringApplication.run(PaymentHystrixMain8001.class, args); + } + + + /** + *此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑 + *ServletRegistrationBean因为springboot的默认路径不是"/hystrix.stream", + *只要在自己的项目里配置上下面的servlet就可以了 + */ + @Bean + public ServletRegistrationBean getServlet() { + HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); + ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); + registrationBean.setLoadOnStartup(1); + registrationBean.addUrlMappings("/hystrix.stream"); + registrationBean.setName("HystrixMetricsStreamServlet"); + return registrationBean; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/src/main/java/com/atguigu/springcloud/controller/PaymentController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/src/main/java/com/atguigu/springcloud/controller/PaymentController.java new file mode 100644 index 0000000000000000000000000000000000000000..e5c568d66d23c2e1b7b36632698f9fa2060e67ef --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/src/main/java/com/atguigu/springcloud/controller/PaymentController.java @@ -0,0 +1,50 @@ +package com.atguigu.springcloud.controller; + +import com.atguigu.springcloud.service.PaymentService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-20 11:15 + */ +@RestController +@Slf4j +public class PaymentController +{ + @Resource + private PaymentService paymentService; + + @Value("${server.port}") + private String serverPort; + + @GetMapping("/payment/hystrix/ok/{id}") + public String paymentInfo_OK(@PathVariable("id") Integer id) + { + String result = paymentService.paymentInfo_OK(id); + log.info("*****result: "+result); + return result; + } + + @GetMapping("/payment/hystrix/timeout/{id}") + public String paymentInfo_TimeOut(@PathVariable("id") Integer id) + { + String result = paymentService.paymentInfo_TimeOut(id); + log.info("*****result: "+result); + return result; + } + + //====服务熔断 + @GetMapping("/payment/circuit/{id}") + public String paymentCircuitBreaker(@PathVariable("id") Integer id) + { + String result = paymentService.paymentCircuitBreaker(id); + log.info("****result: "+result); + return result; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/src/main/java/com/atguigu/springcloud/service/PaymentService.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/src/main/java/com/atguigu/springcloud/service/PaymentService.java new file mode 100644 index 0000000000000000000000000000000000000000..ca6dfb365665481b1278fb96f4f7bef28b5ed41e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/src/main/java/com/atguigu/springcloud/service/PaymentService.java @@ -0,0 +1,65 @@ +package com.atguigu.springcloud.service; + +import cn.hutool.core.util.IdUtil; +import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; +import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.PathVariable; + +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +/** + * @auther zzyy + * @create 2020-02-20 11:11 + */ +@Service +public class PaymentService +{ + /** + * 正常访问,肯定OK + * @param id + * @return + */ + public String paymentInfo_OK(Integer id) + { + return "线程池: "+Thread.currentThread().getName()+" paymentInfo_OK,id: "+id+"\t"+"O(∩_∩)O哈哈~"; + } + + @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = { + @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="5000") + }) + public String paymentInfo_TimeOut(Integer id) + { + //int age = 10/0; + try { TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } + return "线程池: "+Thread.currentThread().getName()+" id: "+id+"\t"+"O(∩_∩)O哈哈~"+" 耗时(秒): "; + } + public String paymentInfo_TimeOutHandler(Integer id) + { + return "线程池: "+Thread.currentThread().getName()+" 8001系统繁忙或者运行报错,请稍后再试,id: "+id+"\t"+"o(╥﹏╥)o"; + } + + //=====服务熔断 + @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = { + @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),// 是否开启断路器 + @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),// 请求次数 + @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), // 时间窗口期 + @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),// 失败率达到多少后跳闸 + }) + public String paymentCircuitBreaker(@PathVariable("id") Integer id) + { + if(id < 0) + { + throw new RuntimeException("******id 不能负数"); + } + String serialNumber = IdUtil.simpleUUID(); + + return Thread.currentThread().getName()+"\t"+"调用成功,流水号: " + serialNumber; + } + public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id) + { + return "id 不能负数,请稍后再试,/(ㄒoㄒ)/~~ id: " +id; + } + +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..2f5400a692a22b7ac9b2be90d0fe844881194f89 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/src/main/resources/application.yml @@ -0,0 +1,14 @@ +server: + port: 8001 + +spring: + application: + name: cloud-provider-hystrix-payment + +eureka: + client: + register-with-eureka: true + fetch-registry: true + service-url: + #defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka + defaultZone: http://eureka7001.com:7001/eureka \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..2f5400a692a22b7ac9b2be90d0fe844881194f89 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/classes/application.yml @@ -0,0 +1,14 @@ +server: + port: 8001 + +spring: + application: + name: cloud-provider-hystrix-payment + +eureka: + client: + register-with-eureka: true + fetch-registry: true + service-url: + #defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka + defaultZone: http://eureka7001.com:7001/eureka \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/classes/com/atguigu/springcloud/PaymentHystrixMain8001.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/classes/com/atguigu/springcloud/PaymentHystrixMain8001.class new file mode 100644 index 0000000000000000000000000000000000000000..f979fbee4ccab99d46837da9a217c200d352b821 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/classes/com/atguigu/springcloud/PaymentHystrixMain8001.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/classes/com/atguigu/springcloud/controller/PaymentController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/classes/com/atguigu/springcloud/controller/PaymentController.class new file mode 100644 index 0000000000000000000000000000000000000000..4e146a2ec8de13d0e43522f4514fa9ebb2ac31ad Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/classes/com/atguigu/springcloud/controller/PaymentController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/classes/com/atguigu/springcloud/service/PaymentService.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/classes/com/atguigu/springcloud/service/PaymentService.class new file mode 100644 index 0000000000000000000000000000000000000000..4e4f3fde7c9f5f48a886bc47bdf988919fd9d518 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/classes/com/atguigu/springcloud/service/PaymentService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/cloud-provider-hystrix-payment8001-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/cloud-provider-hystrix-payment8001-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..1ac9f5eece7d30c24a7fb5e104ac02c0da39a402 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/cloud-provider-hystrix-payment8001-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..cf70941a16587c8bc6b12c2d5a76be81d8517780 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:49 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-provider-hystrix-payment8001 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..7acf60756a1d649af23f171e29e6f91405102856 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,3 @@ +com\atguigu\springcloud\PaymentHystrixMain8001.class +com\atguigu\springcloud\controller\PaymentController.class +com\atguigu\springcloud\service\PaymentService.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..dbeaa90ebb709f45a8c238e86f890d79d192f340 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,3 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-hystrix-payment8001\src\main\java\com\atguigu\springcloud\controller\PaymentController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-hystrix-payment8001\src\main\java\com\atguigu\springcloud\PaymentHystrixMain8001.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-hystrix-payment8001\src\main\java\com\atguigu\springcloud\service\PaymentService.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-hystrix-payment8001/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/cloud-provider-payment8001.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/cloud-provider-payment8001.iml new file mode 100644 index 0000000000000000000000000000000000000000..fda802c7b5edd30a4bd49ec9f01ada2a950842b7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/cloud-provider-payment8001.iml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..85e5f8296c9a63beeddb66a14e5336afca5b20ea --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/pom.xml @@ -0,0 +1,75 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-provider-payment8001 + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + + mysql + mysql-connector-java + + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/PaymentMain8001.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/PaymentMain8001.java new file mode 100644 index 0000000000000000000000000000000000000000..2bd62d68526e653d44f447fe2d31cbe7a7c46273 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/PaymentMain8001.java @@ -0,0 +1,20 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; + +/** + * @auther zzyy + * @create 2020-02-17 21:13 + */ +@SpringBootApplication +@EnableEurekaClient +@EnableDiscoveryClient +public class PaymentMain8001 +{ + public static void main(String[] args) { + SpringApplication.run(PaymentMain8001.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/controller/PaymentController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/controller/PaymentController.java new file mode 100644 index 0000000000000000000000000000000000000000..65e83325889dbfc13c054ac73a9de9a6c879325c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/controller/PaymentController.java @@ -0,0 +1,95 @@ +package com.atguigu.springcloud.controller; + +import com.atguigu.springcloud.entities.CommonResult; +import com.atguigu.springcloud.entities.Payment; +import com.atguigu.springcloud.service.PaymentService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.web.bind.annotation.*; +import org.springframework.cloud.client.discovery.DiscoveryClient; + +import javax.annotation.Resource; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @auther zzyy + * @create 2020-02-18 10:43 + */ +@RestController +@Slf4j +public class PaymentController +{ + @Resource + private PaymentService paymentService; + + @Value("${server.port}") + private String serverPort; + + @Resource + private DiscoveryClient discoveryClient; + + @PostMapping(value = "/payment/create") + public CommonResult create(@RequestBody Payment payment) + { + int result = paymentService.create(payment); + log.info("*****插入结果:"+result); + + if(result > 0) + { + return new CommonResult(200,"插入数据库成功,serverPort: "+serverPort,result); + }else{ + return new CommonResult(444,"插入数据库失败",null); + } + } + + @GetMapping(value = "/payment/get/{id}") + public CommonResult getPaymentById(@PathVariable("id") Long id) + { + Payment payment = paymentService.getPaymentById(id); + + if(payment != null) + { + return new CommonResult(200,"查询成功,serverPort: "+serverPort,payment); + }else{ + return new CommonResult(444,"没有对应记录,查询ID: "+id,null); + } + } + + @GetMapping(value = "/payment/discovery") + public Object discovery() + { + List services = discoveryClient.getServices(); + for (String element : services) { + log.info("*****element: "+element); + } + + List instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE"); + for (ServiceInstance instance : instances) { + log.info(instance.getServiceId()+"\t"+instance.getHost()+"\t"+instance.getPort()+"\t"+instance.getUri()); + } + + return this.discoveryClient; + } + + @GetMapping(value = "/payment/lb") + public String getPaymentLB() + { + return serverPort; + } + + @GetMapping(value = "/payment/feign/timeout") + public String paymentFeignTimeout() + { + // 业务逻辑处理正确,但是需要耗费3秒钟 + try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } + return serverPort; + } + + @GetMapping("/payment/zipkin") + public String paymentZipkin() + { + return "hi ,i'am paymentzipkin server fall back,welcome to atguigu,O(∩_∩)O哈哈~"; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/dao/PaymentDao.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/dao/PaymentDao.java new file mode 100644 index 0000000000000000000000000000000000000000..cd477a1ab0ac5e6aea3ab3e08f26d496d784bc52 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/dao/PaymentDao.java @@ -0,0 +1,17 @@ +package com.atguigu.springcloud.dao; + +import com.atguigu.springcloud.entities.Payment; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * @auther zzyy + * @create 2020-02-18 10:27 + */ +@Mapper +public interface PaymentDao +{ + public int create(Payment payment); + + public Payment getPaymentById(@Param("id") Long id); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/service/PaymentService.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/service/PaymentService.java new file mode 100644 index 0000000000000000000000000000000000000000..68656dcfed27de30572356ed803ac8236115ee78 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/service/PaymentService.java @@ -0,0 +1,15 @@ +package com.atguigu.springcloud.service; + +import com.atguigu.springcloud.entities.Payment; +import org.apache.ibatis.annotations.Param; + +/** + * @auther zzyy + * @create 2020-02-18 10:40 + */ +public interface PaymentService +{ + public int create(Payment payment); + + public Payment getPaymentById(@Param("id") Long id); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/service/impl/PaymentServiceImpl.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/service/impl/PaymentServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..2acb0080abdd2150d67828eb4271a1f085ae400d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/java/com/atguigu/springcloud/service/impl/PaymentServiceImpl.java @@ -0,0 +1,30 @@ +package com.atguigu.springcloud.service.impl; + +import com.atguigu.springcloud.dao.PaymentDao; +import com.atguigu.springcloud.entities.Payment; +import com.atguigu.springcloud.service.PaymentService; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-18 10:40 + */ +@Service +public class PaymentServiceImpl implements PaymentService +{ + @Resource + private PaymentDao paymentDao; + + public int create(Payment payment) + { + return paymentDao.create(payment); + } + + public Payment getPaymentById(Long id) + { + return paymentDao.getPaymentById(id); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..6ed16e41bdaf3f9b13ae2d689b4907ba4651e3fd --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/resources/application.yml @@ -0,0 +1,46 @@ +server: + port: 8001 + +spring: + application: + name: cloud-payment-service + zipkin: + base-url: http://localhost:9411 + sleuth: + sampler: + #采样率值介于 0 到 1 之间,1 则表示全部采集 + probability: 1 + datasource: + type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型 + driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包 + url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false + username: root + password: 123456 + + +eureka: + client: + #表示是否将自己注册进EurekaServer默认为true。 + register-with-eureka: true + #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 + fetchRegistry: true + service-url: + #单机版 + defaultZone: http://localhost:7001/eureka + # 集群版 + #defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka + instance: + instance-id: payment8001 + #访问路径可以显示IP地址 + prefer-ip-address: true + #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒) + #lease-renewal-interval-in-seconds: 1 + #Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务 + #lease-expiration-duration-in-seconds: 2 + + +mybatis: + mapperLocations: classpath:mapper/*.xml + type-aliases-package: com.atguigu.springcloud.entities # 所有Entity别名类所在包 + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/resources/mapper/PaymentMapper.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/resources/mapper/PaymentMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..d8231522248f959687ddb8eacbc9c7e220d6f554 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/src/main/resources/mapper/PaymentMapper.xml @@ -0,0 +1,21 @@ + + + + + + + insert into payment(serial) values(#{serial}); + + + + + + + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..6ed16e41bdaf3f9b13ae2d689b4907ba4651e3fd --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/application.yml @@ -0,0 +1,46 @@ +server: + port: 8001 + +spring: + application: + name: cloud-payment-service + zipkin: + base-url: http://localhost:9411 + sleuth: + sampler: + #采样率值介于 0 到 1 之间,1 则表示全部采集 + probability: 1 + datasource: + type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型 + driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包 + url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false + username: root + password: 123456 + + +eureka: + client: + #表示是否将自己注册进EurekaServer默认为true。 + register-with-eureka: true + #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 + fetchRegistry: true + service-url: + #单机版 + defaultZone: http://localhost:7001/eureka + # 集群版 + #defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka + instance: + instance-id: payment8001 + #访问路径可以显示IP地址 + prefer-ip-address: true + #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒) + #lease-renewal-interval-in-seconds: 1 + #Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务 + #lease-expiration-duration-in-seconds: 2 + + +mybatis: + mapperLocations: classpath:mapper/*.xml + type-aliases-package: com.atguigu.springcloud.entities # 所有Entity别名类所在包 + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/PaymentMain8001.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/PaymentMain8001.class new file mode 100644 index 0000000000000000000000000000000000000000..cca2b765b4829cc6af0866b34b054d112ee27581 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/PaymentMain8001.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/controller/PaymentController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/controller/PaymentController.class new file mode 100644 index 0000000000000000000000000000000000000000..efd0b13ceba99daeb9e14938bf6d133692f19c2d Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/controller/PaymentController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/dao/PaymentDao.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/dao/PaymentDao.class new file mode 100644 index 0000000000000000000000000000000000000000..d5b159717d7f58696c545ce6d7d5ae75eec11ae1 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/dao/PaymentDao.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/service/PaymentService.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/service/PaymentService.class new file mode 100644 index 0000000000000000000000000000000000000000..cc0b5f56d99bddca1145f17832ded7f8deb0ddff Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/service/PaymentService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/service/impl/PaymentServiceImpl.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/service/impl/PaymentServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..94498983afdc36e0fe2b79de9124cf436c78eedc Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/com/atguigu/springcloud/service/impl/PaymentServiceImpl.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/mapper/PaymentMapper.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/mapper/PaymentMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..d8231522248f959687ddb8eacbc9c7e220d6f554 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/classes/mapper/PaymentMapper.xml @@ -0,0 +1,21 @@ + + + + + + + insert into payment(serial) values(#{serial}); + + + + + + + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/cloud-provider-payment8001-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/cloud-provider-payment8001-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..11efb90ba741b8daa388cee2a9f1c9823061ccf9 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/cloud-provider-payment8001-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..65c0bb1b5327c8ce21b0430c7c7f8eb3a35e0f5d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:31 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-provider-payment8001 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..8969f704301367a06a1c46a0a9e1b5461902e9e3 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,5 @@ +com\atguigu\springcloud\controller\PaymentController.class +com\atguigu\springcloud\dao\PaymentDao.class +com\atguigu\springcloud\PaymentMain8001.class +com\atguigu\springcloud\service\impl\PaymentServiceImpl.class +com\atguigu\springcloud\service\PaymentService.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..13b234677127558f141c89b1051958f836bca5ad --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,5 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-payment8001\src\main\java\com\atguigu\springcloud\PaymentMain8001.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-payment8001\src\main\java\com\atguigu\springcloud\dao\PaymentDao.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-payment8001\src\main\java\com\atguigu\springcloud\controller\PaymentController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-payment8001\src\main\java\com\atguigu\springcloud\service\PaymentService.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-payment8001\src\main\java\com\atguigu\springcloud\service\impl\PaymentServiceImpl.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8001/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/cloud-provider-payment8002.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/cloud-provider-payment8002.iml new file mode 100644 index 0000000000000000000000000000000000000000..f44841c1bad5d57f5c2cd01065bef811596d4c1b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/cloud-provider-payment8002.iml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..071e6ae51a56a6427d8f0515ee2e556e2f211d14 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/pom.xml @@ -0,0 +1,72 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-provider-payment8002 + + + + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + + mysql + mysql-connector-java + + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/PaymentMain8002.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/PaymentMain8002.java new file mode 100644 index 0000000000000000000000000000000000000000..cc42bf284c208c0ab418dd9d875396800060f91c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/PaymentMain8002.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; + +/** + * @auther zzyy + * @create 2020-02-17 21:13 + */ +@SpringBootApplication +@EnableEurekaClient +public class PaymentMain8002 +{ + public static void main(String[] args) { + SpringApplication.run(PaymentMain8002.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/controller/PaymentController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/controller/PaymentController.java new file mode 100644 index 0000000000000000000000000000000000000000..88682c6a5e654986c5f1e41edb4706eba7edcf1c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/controller/PaymentController.java @@ -0,0 +1,57 @@ +package com.atguigu.springcloud.controller; + +import com.atguigu.springcloud.entities.CommonResult; +import com.atguigu.springcloud.entities.Payment; +import com.atguigu.springcloud.service.PaymentService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-18 10:43 + */ +@RestController +@Slf4j +public class PaymentController +{ + @Resource + private PaymentService paymentService; + @Value("${server.port}") + private String serverPort; + + @PostMapping(value = "/payment/create") + public CommonResult create(@RequestBody Payment payment) + { + int result = paymentService.create(payment); + log.info("*****插入结果:"+result); + + if(result > 0) + { + return new CommonResult(200,"插入数据库成功,serverPort: "+serverPort,result); + }else{ + return new CommonResult(444,"插入数据库失败",null); + } + } + + @GetMapping(value = "/payment/get/{id}") + public CommonResult getPaymentById(@PathVariable("id") Long id) + { + Payment payment = paymentService.getPaymentById(id); + + if(payment != null) + { + return new CommonResult(200,"查询成功,serverPort: "+serverPort,payment); + }else{ + return new CommonResult(444,"没有对应记录,查询ID: "+id,null); + } + } + + @GetMapping(value = "/payment/lb") + public String getPaymentLB() + { + return serverPort; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/dao/PaymentDao.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/dao/PaymentDao.java new file mode 100644 index 0000000000000000000000000000000000000000..cd477a1ab0ac5e6aea3ab3e08f26d496d784bc52 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/dao/PaymentDao.java @@ -0,0 +1,17 @@ +package com.atguigu.springcloud.dao; + +import com.atguigu.springcloud.entities.Payment; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * @auther zzyy + * @create 2020-02-18 10:27 + */ +@Mapper +public interface PaymentDao +{ + public int create(Payment payment); + + public Payment getPaymentById(@Param("id") Long id); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/service/PaymentService.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/service/PaymentService.java new file mode 100644 index 0000000000000000000000000000000000000000..68656dcfed27de30572356ed803ac8236115ee78 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/service/PaymentService.java @@ -0,0 +1,15 @@ +package com.atguigu.springcloud.service; + +import com.atguigu.springcloud.entities.Payment; +import org.apache.ibatis.annotations.Param; + +/** + * @auther zzyy + * @create 2020-02-18 10:40 + */ +public interface PaymentService +{ + public int create(Payment payment); + + public Payment getPaymentById(@Param("id") Long id); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/service/impl/PaymentServiceImpl.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/service/impl/PaymentServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..2acb0080abdd2150d67828eb4271a1f085ae400d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/java/com/atguigu/springcloud/service/impl/PaymentServiceImpl.java @@ -0,0 +1,30 @@ +package com.atguigu.springcloud.service.impl; + +import com.atguigu.springcloud.dao.PaymentDao; +import com.atguigu.springcloud.entities.Payment; +import com.atguigu.springcloud.service.PaymentService; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-18 10:40 + */ +@Service +public class PaymentServiceImpl implements PaymentService +{ + @Resource + private PaymentDao paymentDao; + + public int create(Payment payment) + { + return paymentDao.create(payment); + } + + public Payment getPaymentById(Long id) + { + return paymentDao.getPaymentById(id); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..502bd36dec71aada2da46565a4e2d63daba9f6bd --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/resources/application.yml @@ -0,0 +1,32 @@ +server: + port: 8002 + +spring: + application: + name: cloud-payment-service + datasource: + type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型 + driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包 + url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false + username: root + password: 123456 + + +eureka: + client: + #表示是否将自己注册进EurekaServer默认为true。 + register-with-eureka: true + #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 + fetchRegistry: true + service-url: + #defaultZone: http://localhost:7001/eureka + defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版 + instance: + instance-id: payment8002 + prefer-ip-address: true #访问路径可以显示IP地址 + +mybatis: + mapperLocations: classpath:mapper/*.xml + type-aliases-package: com.atguigu.springcloud.entities # 所有Entity别名类所在包 + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/resources/mapper/PaymentMapper.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/resources/mapper/PaymentMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..d8231522248f959687ddb8eacbc9c7e220d6f554 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/src/main/resources/mapper/PaymentMapper.xml @@ -0,0 +1,21 @@ + + + + + + + insert into payment(serial) values(#{serial}); + + + + + + + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..502bd36dec71aada2da46565a4e2d63daba9f6bd --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/application.yml @@ -0,0 +1,32 @@ +server: + port: 8002 + +spring: + application: + name: cloud-payment-service + datasource: + type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型 + driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包 + url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false + username: root + password: 123456 + + +eureka: + client: + #表示是否将自己注册进EurekaServer默认为true。 + register-with-eureka: true + #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 + fetchRegistry: true + service-url: + #defaultZone: http://localhost:7001/eureka + defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版 + instance: + instance-id: payment8002 + prefer-ip-address: true #访问路径可以显示IP地址 + +mybatis: + mapperLocations: classpath:mapper/*.xml + type-aliases-package: com.atguigu.springcloud.entities # 所有Entity别名类所在包 + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/PaymentMain8002.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/PaymentMain8002.class new file mode 100644 index 0000000000000000000000000000000000000000..cd4ad5be28b547ce869c6bae78b9b55eb14dd2d1 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/PaymentMain8002.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/controller/PaymentController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/controller/PaymentController.class new file mode 100644 index 0000000000000000000000000000000000000000..2091ac66b4a0ec9fcc02e73019e65a7fe4c72861 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/controller/PaymentController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/dao/PaymentDao.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/dao/PaymentDao.class new file mode 100644 index 0000000000000000000000000000000000000000..d5b159717d7f58696c545ce6d7d5ae75eec11ae1 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/dao/PaymentDao.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/service/PaymentService.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/service/PaymentService.class new file mode 100644 index 0000000000000000000000000000000000000000..cc0b5f56d99bddca1145f17832ded7f8deb0ddff Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/service/PaymentService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/service/impl/PaymentServiceImpl.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/service/impl/PaymentServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..94498983afdc36e0fe2b79de9124cf436c78eedc Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/com/atguigu/springcloud/service/impl/PaymentServiceImpl.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/mapper/PaymentMapper.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/mapper/PaymentMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..d8231522248f959687ddb8eacbc9c7e220d6f554 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/classes/mapper/PaymentMapper.xml @@ -0,0 +1,21 @@ + + + + + + + insert into payment(serial) values(#{serial}); + + + + + + + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/cloud-provider-payment8002-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/cloud-provider-payment8002-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..61e60596c8cea62f7727f78a8c1e945f74b27bd1 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/cloud-provider-payment8002-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..45db485c7b78908ab0a856f83943377ed22df418 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:33 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-provider-payment8002 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..24bf257a128e2057e1a74e57b87489a56508acc2 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,5 @@ +com\atguigu\springcloud\controller\PaymentController.class +com\atguigu\springcloud\dao\PaymentDao.class +com\atguigu\springcloud\service\impl\PaymentServiceImpl.class +com\atguigu\springcloud\service\PaymentService.class +com\atguigu\springcloud\PaymentMain8002.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..017c5c18f442ecdef0ac025493ebd140e7f13ca0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,5 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-payment8002\src\main\java\com\atguigu\springcloud\controller\PaymentController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-payment8002\src\main\java\com\atguigu\springcloud\service\impl\PaymentServiceImpl.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-payment8002\src\main\java\com\atguigu\springcloud\service\PaymentService.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-payment8002\src\main\java\com\atguigu\springcloud\dao\PaymentDao.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-payment8002\src\main\java\com\atguigu\springcloud\PaymentMain8002.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8002/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/cloud-provider-payment8004.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/cloud-provider-payment8004.iml new file mode 100644 index 0000000000000000000000000000000000000000..2a52680ef0734010dcd8bbc8aeb7e6e82363b9cf --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/cloud-provider-payment8004.iml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..1d6ced536320853355b0197207bc77631daa5914 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/pom.xml @@ -0,0 +1,61 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-provider-payment8004 + + + + + + org.springframework.boot + spring-boot-starter-web + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + + org.springframework.cloud + spring-cloud-starter-zookeeper-discovery + + + + org.apache.zookeeper + zookeeper + + + + + + org.apache.zookeeper + zookeeper + 3.4.9 + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/src/main/java/com/atguigu/springcloud/PaymentMain8004.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/src/main/java/com/atguigu/springcloud/PaymentMain8004.java new file mode 100644 index 0000000000000000000000000000000000000000..5f3472acd8892c44f334a297d7195a944f18a00b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/src/main/java/com/atguigu/springcloud/PaymentMain8004.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @auther zzyy + * @create 2020-02-19 14:15 + */ +@SpringBootApplication +@EnableDiscoveryClient //该注解用于向使用consul或者zookeeper作为注册中心时注册服务 +public class PaymentMain8004 +{ + public static void main(String[] args) { + SpringApplication.run(PaymentMain8004.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/src/main/java/com/atguigu/springcloud/controller/PaymentController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/src/main/java/com/atguigu/springcloud/controller/PaymentController.java new file mode 100644 index 0000000000000000000000000000000000000000..4e7086d15110ff7c881f8594fb899af5082730d8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/src/main/java/com/atguigu/springcloud/controller/PaymentController.java @@ -0,0 +1,26 @@ +package com.atguigu.springcloud.controller; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.UUID; + +/** + * @auther zzyy + * @create 2020-02-19 14:16 + */ +@RestController +@Slf4j +public class PaymentController +{ + @Value("${server.port}") + private String serverPort; + + @RequestMapping(value = "/payment/zk") + public String paymentzk() + { + return "springcloud with zookeeper: "+serverPort+"\t"+ UUID.randomUUID().toString(); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..6f078678c1e420e34441e0f3852fb487d107e3d5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/src/main/resources/application.yml @@ -0,0 +1,15 @@ +#8004表示注册到zookeeper服务器的支付服务提供者端口号 +server: + port: 8004 + + +#服务别名----注册zookeeper到注册中心名称 +spring: + application: + name: cloud-provider-payment + cloud: + zookeeper: + connect-string: 192.168.111.144:2181 + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..6f078678c1e420e34441e0f3852fb487d107e3d5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/classes/application.yml @@ -0,0 +1,15 @@ +#8004表示注册到zookeeper服务器的支付服务提供者端口号 +server: + port: 8004 + + +#服务别名----注册zookeeper到注册中心名称 +spring: + application: + name: cloud-provider-payment + cloud: + zookeeper: + connect-string: 192.168.111.144:2181 + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/classes/com/atguigu/springcloud/PaymentMain8004.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/classes/com/atguigu/springcloud/PaymentMain8004.class new file mode 100644 index 0000000000000000000000000000000000000000..1155dc3c1080d819cdc58877833ff11c05468b65 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/classes/com/atguigu/springcloud/PaymentMain8004.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/classes/com/atguigu/springcloud/controller/PaymentController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/classes/com/atguigu/springcloud/controller/PaymentController.class new file mode 100644 index 0000000000000000000000000000000000000000..08fe6039838d3364fafc3af2af7adc8dcf2e9150 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/classes/com/atguigu/springcloud/controller/PaymentController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/cloud-provider-payment8004-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/cloud-provider-payment8004-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..07c7f87e05cd34c025f936be9d977216a6540665 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/cloud-provider-payment8004-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..433e8bb849165a3b0167c7fc753ad67ad1cb0c5c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:35 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-provider-payment8004 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..3014ac62fb3ab1c333e72a90209ea630235ae385 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\atguigu\springcloud\controller\PaymentController.class +com\atguigu\springcloud\PaymentMain8004.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..87f894bac2045907f052a357122069d4c2e08c32 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-payment8004\src\main\java\com\atguigu\springcloud\PaymentMain8004.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-provider-payment8004\src\main\java\com\atguigu\springcloud\controller\PaymentController.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-provider-payment8004/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/cloud-providerconsul-payment8006.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/cloud-providerconsul-payment8006.iml new file mode 100644 index 0000000000000000000000000000000000000000..c58ec6666ccee4df19a10820193e9fdf6b29420c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/cloud-providerconsul-payment8006.iml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..9cffc994947aec57fc9fc0393942b44b8e71a57a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/pom.xml @@ -0,0 +1,68 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-providerconsul-payment8006 + + + + + + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + + org.springframework.cloud + spring-cloud-starter-consul-discovery + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + cn.hutool + hutool-all + RELEASE + test + + + cn.hutool + hutool-all + RELEASE + test + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/src/main/java/com/atguigu/springcloud/PaymentMain8006.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/src/main/java/com/atguigu/springcloud/PaymentMain8006.java new file mode 100644 index 0000000000000000000000000000000000000000..531cef6991d7563f1a0156dfa58ef88750c10e94 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/src/main/java/com/atguigu/springcloud/PaymentMain8006.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @auther zzyy + * @create 2020-02-19 16:05 + */ +@SpringBootApplication +@EnableDiscoveryClient +public class PaymentMain8006 +{ + public static void main(String[] args) { + SpringApplication.run(PaymentMain8006.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/src/main/java/com/atguigu/springcloud/controller/PaymentController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/src/main/java/com/atguigu/springcloud/controller/PaymentController.java new file mode 100644 index 0000000000000000000000000000000000000000..fcf3c9fcb02725994778405dbded759599c42c6b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/src/main/java/com/atguigu/springcloud/controller/PaymentController.java @@ -0,0 +1,26 @@ +package com.atguigu.springcloud.controller; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.UUID; + +/** + * @auther zzyy + * @create 2020-02-19 16:06 + */ +@RestController +@Slf4j +public class PaymentController +{ + @Value("${server.port}") + private String serverPort; + + @RequestMapping(value = "/payment/consul") + public String paymentConsul() + { + return "springcloud with consul: "+serverPort+"\t "+ UUID.randomUUID().toString(); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..fc2c14ecabae210de4bce953638b724993801880 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/src/main/resources/application.yml @@ -0,0 +1,18 @@ +###consul服务端口号 +server: + port: 8006 + +spring: + application: + name: consul-provider-payment +####consul注册中心地址 + cloud: + consul: + host: localhost + port: 8500 + discovery: + #hostname: 127.0.0.1 + service-name: ${spring.application.name} + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/src/test/java/T.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/src/test/java/T.java new file mode 100644 index 0000000000000000000000000000000000000000..fb4c948af8936598064759f216f52e9005d4f26b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/src/test/java/T.java @@ -0,0 +1,13 @@ +import cn.hutool.core.util.IdUtil; + +/** + * @auther zzyy + * @create 2020-02-19 19:47 + */ +public class T +{ + public static void main(String[] args) + { + System.out.println(IdUtil.simpleUUID()); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..fc2c14ecabae210de4bce953638b724993801880 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/classes/application.yml @@ -0,0 +1,18 @@ +###consul服务端口号 +server: + port: 8006 + +spring: + application: + name: consul-provider-payment +####consul注册中心地址 + cloud: + consul: + host: localhost + port: 8500 + discovery: + #hostname: 127.0.0.1 + service-name: ${spring.application.name} + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/classes/com/atguigu/springcloud/PaymentMain8006.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/classes/com/atguigu/springcloud/PaymentMain8006.class new file mode 100644 index 0000000000000000000000000000000000000000..9661a6f6432f5138f006b9eab5c22cb40dc3c388 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/classes/com/atguigu/springcloud/PaymentMain8006.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/classes/com/atguigu/springcloud/controller/PaymentController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/classes/com/atguigu/springcloud/controller/PaymentController.class new file mode 100644 index 0000000000000000000000000000000000000000..bc83c18d208e82dc7275279b4895103aa49a0696 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/classes/com/atguigu/springcloud/controller/PaymentController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/cloud-providerconsul-payment8006-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/cloud-providerconsul-payment8006-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..c8347f3da7e841d2dc4cc7cf9d498e2d5d61a76b Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/cloud-providerconsul-payment8006-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..1f1a638a1a9b15ba8b69f3358dc3504d6dec9a1a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:29:43 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-providerconsul-payment8006 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..39788e3dd0b6863f43291ad26a906283a107263d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\atguigu\springcloud\PaymentMain8006.class +com\atguigu\springcloud\controller\PaymentController.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..aa0a0854095b869130cb7956587d7f3290400c39 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-providerconsul-payment8006\src\main\java\com\atguigu\springcloud\controller\PaymentController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-providerconsul-payment8006\src\main\java\com\atguigu\springcloud\PaymentMain8006.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..10f18d72f554d7bc580992fc59642c979b080875 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst @@ -0,0 +1 @@ +T.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..60c742dc04187ad28e13c39960134c96b0261b52 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst @@ -0,0 +1 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-providerconsul-payment8006\src\test\java\T.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/test-classes/T.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/test-classes/T.class new file mode 100644 index 0000000000000000000000000000000000000000..4bb871cb469febd25c9f978623b647327f84f0cc Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-providerconsul-payment8006/target/test-classes/T.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/cloud-stream-rabbitmq-consumer8802.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/cloud-stream-rabbitmq-consumer8802.iml new file mode 100644 index 0000000000000000000000000000000000000000..04abe7ae7536d48052333c0e297e10a9dc55dd6a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/cloud-stream-rabbitmq-consumer8802.iml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..d9500669f26873200a494c5496f9ad1a81332370 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/pom.xml @@ -0,0 +1,52 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-stream-rabbitmq-consumer8802 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/src/main/java/com/atguigu/springcloud/StreamMQMain8802.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/src/main/java/com/atguigu/springcloud/StreamMQMain8802.java new file mode 100644 index 0000000000000000000000000000000000000000..5b454a6962400717441c90125e29d57dfaff9049 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/src/main/java/com/atguigu/springcloud/StreamMQMain8802.java @@ -0,0 +1,17 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @auther zzyy + * @create 2020-02-22 11:56 + */ +@SpringBootApplication +public class StreamMQMain8802 +{ + public static void main(String[] args) + { + SpringApplication.run(StreamMQMain8802.class,args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/src/main/java/com/atguigu/springcloud/controller/ReceiveMessageListenerController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/src/main/java/com/atguigu/springcloud/controller/ReceiveMessageListenerController.java new file mode 100644 index 0000000000000000000000000000000000000000..b5cb151611973592c4d95b018931cf6de16721ef --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/src/main/java/com/atguigu/springcloud/controller/ReceiveMessageListenerController.java @@ -0,0 +1,29 @@ +package com.atguigu.springcloud.controller; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.cloud.stream.messaging.Sink; +import org.springframework.messaging.Message; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-22 11:57 + */ +@Component +@EnableBinding(Sink.class) +public class ReceiveMessageListenerController +{ + @Value("${server.port}") + private String serverPort; + + + @StreamListener(Sink.INPUT) + public void input(Message message) + { + System.out.println("消费者1号,----->接受到的消息: "+message.getPayload()+"\t port: "+serverPort); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..0759c1c761a52894ca9a13df16cbb742b9798964 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/src/main/resources/application.yml @@ -0,0 +1,39 @@ +server: + port: 8802 + +spring: + application: + name: cloud-stream-consumer + cloud: + stream: + binders: # 在此处配置要绑定的rabbitmq的服务信息; + defaultRabbit: # 表示定义的名称,用于于binding整合 + type: rabbit # 消息组件类型 + environment: # 设置rabbitmq的相关的环境配置 + spring: + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + bindings: # 服务的整合处理 + input: # 这个名字是一个通道的名称 + destination: studyExchange # 表示要使用的Exchange名称定义 + content-type: application/json # 设置消息类型,本次为对象json,如果是文本则设置“text/plain” + binder: defaultRabbit # 设置要绑定的消息服务的具体设置 + + + +eureka: + client: # 客户端进行Eureka注册的配置 + service-url: + defaultZone: http://localhost:7001/eureka + instance: + lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒) + lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒) + instance-id: receive-8802.com # 在信息列表时显示主机名称 + prefer-ip-address: true # 访问的路径变为IP地址 + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..0759c1c761a52894ca9a13df16cbb742b9798964 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/classes/application.yml @@ -0,0 +1,39 @@ +server: + port: 8802 + +spring: + application: + name: cloud-stream-consumer + cloud: + stream: + binders: # 在此处配置要绑定的rabbitmq的服务信息; + defaultRabbit: # 表示定义的名称,用于于binding整合 + type: rabbit # 消息组件类型 + environment: # 设置rabbitmq的相关的环境配置 + spring: + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + bindings: # 服务的整合处理 + input: # 这个名字是一个通道的名称 + destination: studyExchange # 表示要使用的Exchange名称定义 + content-type: application/json # 设置消息类型,本次为对象json,如果是文本则设置“text/plain” + binder: defaultRabbit # 设置要绑定的消息服务的具体设置 + + + +eureka: + client: # 客户端进行Eureka注册的配置 + service-url: + defaultZone: http://localhost:7001/eureka + instance: + lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒) + lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒) + instance-id: receive-8802.com # 在信息列表时显示主机名称 + prefer-ip-address: true # 访问的路径变为IP地址 + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/classes/com/atguigu/springcloud/StreamMQMain8802.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/classes/com/atguigu/springcloud/StreamMQMain8802.class new file mode 100644 index 0000000000000000000000000000000000000000..a8a7d85986f7283c313ddf830be48db5db576e9f Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/classes/com/atguigu/springcloud/StreamMQMain8802.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/classes/com/atguigu/springcloud/controller/ReceiveMessageListenerController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/classes/com/atguigu/springcloud/controller/ReceiveMessageListenerController.class new file mode 100644 index 0000000000000000000000000000000000000000..d4186b3dfcf93eba9c52682dcfe0a91217d6e2d5 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/classes/com/atguigu/springcloud/controller/ReceiveMessageListenerController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/cloud-stream-rabbitmq-consumer8802-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/cloud-stream-rabbitmq-consumer8802-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..e56ef823f090457cfca8c308434d3ab158854c0d Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/cloud-stream-rabbitmq-consumer8802-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..58964ede88b508f520c09c6a19488804f3711bf1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:30:02 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-stream-rabbitmq-consumer8802 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..4ba7c0ca47d70cd6f6f94336dc5b7d8cf193be42 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\atguigu\springcloud\controller\ReceiveMessageListenerController.class +com\atguigu\springcloud\StreamMQMain8802.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..84ddba40facdebd70d103d4f66299baf674d5f59 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-stream-rabbitmq-consumer8802\src\main\java\com\atguigu\springcloud\controller\ReceiveMessageListenerController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-stream-rabbitmq-consumer8802\src\main\java\com\atguigu\springcloud\StreamMQMain8802.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8802/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/cloud-stream-rabbitmq-consumer8803.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/cloud-stream-rabbitmq-consumer8803.iml new file mode 100644 index 0000000000000000000000000000000000000000..04abe7ae7536d48052333c0e297e10a9dc55dd6a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/cloud-stream-rabbitmq-consumer8803.iml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..312a99143a3c8abf791544e0de9e9d19073c3125 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/pom.xml @@ -0,0 +1,53 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-stream-rabbitmq-consumer8803 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/src/main/java/com/atguigu/springcloud/StreamMQMain8803.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/src/main/java/com/atguigu/springcloud/StreamMQMain8803.java new file mode 100644 index 0000000000000000000000000000000000000000..9ccb6f2d718845ce46bddd0a9b046c48268e5dac --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/src/main/java/com/atguigu/springcloud/StreamMQMain8803.java @@ -0,0 +1,17 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @auther zzyy + * @create 2020-02-22 12:19 + */ +@SpringBootApplication +public class StreamMQMain8803 +{ + public static void main(String[] args) + { + SpringApplication.run(StreamMQMain8803.class,args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/src/main/java/com/atguigu/springcloud/controller/ReceiveMessageListenerController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/src/main/java/com/atguigu/springcloud/controller/ReceiveMessageListenerController.java new file mode 100644 index 0000000000000000000000000000000000000000..175382871922d2544c671b11e865787ab830c50b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/src/main/java/com/atguigu/springcloud/controller/ReceiveMessageListenerController.java @@ -0,0 +1,27 @@ +package com.atguigu.springcloud.controller; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.cloud.stream.messaging.Sink; +import org.springframework.messaging.Message; +import org.springframework.stereotype.Component; + +/** + * @auther zzyy + * @create 2020-02-22 12:20 + */ +@Component +@EnableBinding(Sink.class) +public class ReceiveMessageListenerController +{ + @Value("${server.port}") + private String serverPort; + + + @StreamListener(Sink.INPUT) + public void input(Message message) + { + System.out.println("消费者2号,----->接受到的消息: "+message.getPayload()+"\t port: "+serverPort); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..de0f5bbd2691319075faa2e762b2298ec295e452 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/src/main/resources/application.yml @@ -0,0 +1,36 @@ +server: + port: 8803 + +spring: + application: + name: cloud-stream-consumer + cloud: + stream: + binders: # 在此处配置要绑定的rabbitmq的服务信息; + defaultRabbit: # 表示定义的名称,用于于binding整合 + type: rabbit # 消息组件类型 + environment: # 设置rabbitmq的相关的环境配置 + spring: + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + bindings: # 服务的整合处理 + input: # 这个名字是一个通道的名称 + destination: studyExchange # 表示要使用的Exchange名称定义 + content-type: application/json # 设置消息类型,本次为对象json,如果是文本则设置“text/plain” + binder: defaultRabbit # 设置要绑定的消息服务的具体设置 + group: atguiguA + +eureka: + client: # 客户端进行Eureka注册的配置 + service-url: + defaultZone: http://localhost:7001/eureka + instance: + lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒) + lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒) + instance-id: receive-8803.com # 在信息列表时显示主机名称 + prefer-ip-address: true # 访问的路径变为IP地址 + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..de0f5bbd2691319075faa2e762b2298ec295e452 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/classes/application.yml @@ -0,0 +1,36 @@ +server: + port: 8803 + +spring: + application: + name: cloud-stream-consumer + cloud: + stream: + binders: # 在此处配置要绑定的rabbitmq的服务信息; + defaultRabbit: # 表示定义的名称,用于于binding整合 + type: rabbit # 消息组件类型 + environment: # 设置rabbitmq的相关的环境配置 + spring: + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + bindings: # 服务的整合处理 + input: # 这个名字是一个通道的名称 + destination: studyExchange # 表示要使用的Exchange名称定义 + content-type: application/json # 设置消息类型,本次为对象json,如果是文本则设置“text/plain” + binder: defaultRabbit # 设置要绑定的消息服务的具体设置 + group: atguiguA + +eureka: + client: # 客户端进行Eureka注册的配置 + service-url: + defaultZone: http://localhost:7001/eureka + instance: + lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒) + lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒) + instance-id: receive-8803.com # 在信息列表时显示主机名称 + prefer-ip-address: true # 访问的路径变为IP地址 + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/classes/com/atguigu/springcloud/StreamMQMain8803.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/classes/com/atguigu/springcloud/StreamMQMain8803.class new file mode 100644 index 0000000000000000000000000000000000000000..d6c648b276908b217f9244c71f5c2cc98b06bd1d Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/classes/com/atguigu/springcloud/StreamMQMain8803.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/classes/com/atguigu/springcloud/controller/ReceiveMessageListenerController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/classes/com/atguigu/springcloud/controller/ReceiveMessageListenerController.class new file mode 100644 index 0000000000000000000000000000000000000000..03159822c16ca9a599354faaecd2b0b379cbbf7c Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/classes/com/atguigu/springcloud/controller/ReceiveMessageListenerController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/cloud-stream-rabbitmq-consumer8803-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/cloud-stream-rabbitmq-consumer8803-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..6a7609374cc4f4f66685743687de1268f8c8c87a Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/cloud-stream-rabbitmq-consumer8803-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..5c3ac913918b4a580bb6cbcd0f347dd8ec0d1749 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:30:03 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-stream-rabbitmq-consumer8803 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..54d195001798e9c2defaef4d01e2044ea33313b1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\atguigu\springcloud\StreamMQMain8803.class +com\atguigu\springcloud\controller\ReceiveMessageListenerController.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..bcc043d2223f73324c8c4c3bee7bafbeb52be243 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-stream-rabbitmq-consumer8803\src\main\java\com\atguigu\springcloud\StreamMQMain8803.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-stream-rabbitmq-consumer8803\src\main\java\com\atguigu\springcloud\controller\ReceiveMessageListenerController.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-consumer8803/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/cloud-stream-rabbitmq-provider8801.iml b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/cloud-stream-rabbitmq-provider8801.iml new file mode 100644 index 0000000000000000000000000000000000000000..2cea97402d1f605ce07141a9cd2576eb1ff583f0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/cloud-stream-rabbitmq-provider8801.iml @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..4e2fa7f1fc9ad125a0f1b23b58750a82e8aa889a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/pom.xml @@ -0,0 +1,53 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloud-stream-rabbitmq-provider8801 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/java/com/atguigu/springcloud/StreamMQMain8801.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/java/com/atguigu/springcloud/StreamMQMain8801.java new file mode 100644 index 0000000000000000000000000000000000000000..c4cc4cd27f3d7143f8c859e3387b5c0788f56626 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/java/com/atguigu/springcloud/StreamMQMain8801.java @@ -0,0 +1,17 @@ +package com.atguigu.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @auther zzyy + * @create 2020-02-22 10:54 + */ +@SpringBootApplication +public class StreamMQMain8801 +{ + public static void main(String[] args) + { + SpringApplication.run(StreamMQMain8801.class,args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/java/com/atguigu/springcloud/controller/SendMessageController.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/java/com/atguigu/springcloud/controller/SendMessageController.java new file mode 100644 index 0000000000000000000000000000000000000000..1b4fcb211ef50083610bee76998dde20b30d2fa5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/java/com/atguigu/springcloud/controller/SendMessageController.java @@ -0,0 +1,25 @@ +package com.atguigu.springcloud.controller; + +import com.atguigu.springcloud.service.IMessageProvider; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-22 11:17 + */ +@RestController +public class SendMessageController +{ + @Resource + private IMessageProvider messageProvider; + + @GetMapping(value = "/sendMessage") + public String sendMessage() + { + return messageProvider.send(); + } + +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/java/com/atguigu/springcloud/service/IMessageProvider.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/java/com/atguigu/springcloud/service/IMessageProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..a47af2d1088cbd00312d05ff3b9130d0bd77c21b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/java/com/atguigu/springcloud/service/IMessageProvider.java @@ -0,0 +1,10 @@ +package com.atguigu.springcloud.service; + +/** + * @auther zzyy + * @create 2020-02-22 10:55 + */ +public interface IMessageProvider +{ + public String send(); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/java/com/atguigu/springcloud/service/impl/MessageProviderImpl.java b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/java/com/atguigu/springcloud/service/impl/MessageProviderImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..4d24d57484f8a61b2e4c7ecdeafee08eb67c496a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/java/com/atguigu/springcloud/service/impl/MessageProviderImpl.java @@ -0,0 +1,32 @@ +package com.atguigu.springcloud.service.impl; + +import com.atguigu.springcloud.service.IMessageProvider; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.integration.support.MessageBuilderFactory; +import org.springframework.messaging.MessageChannel; +import org.springframework.integration.support.MessageBuilder; +import javax.annotation.Resource; +import org.springframework.cloud.stream.messaging.Source; + +import javax.annotation.Resource; +import java.util.UUID; + +/** + * @auther zzyy + * @create 2020-02-22 10:56 + */ +@EnableBinding(Source.class) //定义消息的推送管道 +public class MessageProviderImpl implements IMessageProvider +{ + @Resource + private MessageChannel output; // 消息发送管道 + + @Override + public String send() + { + String serial = UUID.randomUUID().toString(); + output.send(MessageBuilder.withPayload(serial).build()); + System.out.println("*****serial: "+serial); + return null; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..39ebfcd7a9171b2b46479163a5b24c5d5d79683d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/src/main/resources/application.yml @@ -0,0 +1,40 @@ +server: + port: 8801 + +spring: + application: + name: cloud-stream-provider + cloud: + stream: + binders: # 在此处配置要绑定的rabbitmq的服务信息; + defaultRabbit: # 表示定义的名称,用于于binding整合 + type: rabbit # 消息组件类型 + environment: # 设置rabbitmq的相关的环境配置 + spring: + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + bindings: # 服务的整合处理 + output: # 这个名字是一个通道的名称 + destination: studyExchange # 表示要使用的Exchange名称定义 + content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain” + binder: defaultRabbit # 设置要绑定的消息服务的具体设置 + +eureka: + client: # 客户端进行Eureka注册的配置 + service-url: + defaultZone: http://localhost:7001/eureka + instance: + lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒) + lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒) + instance-id: send-8801.com # 在信息列表时显示主机名称 + prefer-ip-address: true # 访问的路径变为IP地址 + + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..39ebfcd7a9171b2b46479163a5b24c5d5d79683d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/application.yml @@ -0,0 +1,40 @@ +server: + port: 8801 + +spring: + application: + name: cloud-stream-provider + cloud: + stream: + binders: # 在此处配置要绑定的rabbitmq的服务信息; + defaultRabbit: # 表示定义的名称,用于于binding整合 + type: rabbit # 消息组件类型 + environment: # 设置rabbitmq的相关的环境配置 + spring: + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + bindings: # 服务的整合处理 + output: # 这个名字是一个通道的名称 + destination: studyExchange # 表示要使用的Exchange名称定义 + content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain” + binder: defaultRabbit # 设置要绑定的消息服务的具体设置 + +eureka: + client: # 客户端进行Eureka注册的配置 + service-url: + defaultZone: http://localhost:7001/eureka + instance: + lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒) + lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒) + instance-id: send-8801.com # 在信息列表时显示主机名称 + prefer-ip-address: true # 访问的路径变为IP地址 + + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/com/atguigu/springcloud/StreamMQMain8801.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/com/atguigu/springcloud/StreamMQMain8801.class new file mode 100644 index 0000000000000000000000000000000000000000..771657e70ddc62eb5cc4cfe9c3a8e99ed4fca304 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/com/atguigu/springcloud/StreamMQMain8801.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/com/atguigu/springcloud/controller/SendMessageController.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/com/atguigu/springcloud/controller/SendMessageController.class new file mode 100644 index 0000000000000000000000000000000000000000..7a6548de02155e1971a0ded45d08d70a56a37926 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/com/atguigu/springcloud/controller/SendMessageController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/com/atguigu/springcloud/service/IMessageProvider.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/com/atguigu/springcloud/service/IMessageProvider.class new file mode 100644 index 0000000000000000000000000000000000000000..2b23768b121cab301fb0bf679b049253b46ceb61 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/com/atguigu/springcloud/service/IMessageProvider.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/com/atguigu/springcloud/service/impl/MessageProviderImpl.class b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/com/atguigu/springcloud/service/impl/MessageProviderImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..e5425681eb52ed88ad891257f3df1df5e6ab6943 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/classes/com/atguigu/springcloud/service/impl/MessageProviderImpl.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/cloud-stream-rabbitmq-provider8801-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/cloud-stream-rabbitmq-provider8801-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..ce4d3eec3cda8d951a0664c1e7660bc052ffa141 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/cloud-stream-rabbitmq-provider8801-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..a4917ad02d142d247da3d2b70e1246af63c8184a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:30:01 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloud-stream-rabbitmq-provider8801 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..db5401cb0767dfac391aec7223aae00404ad9731 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,4 @@ +com\atguigu\springcloud\service\IMessageProvider.class +com\atguigu\springcloud\service\impl\MessageProviderImpl.class +com\atguigu\springcloud\controller\SendMessageController.class +com\atguigu\springcloud\StreamMQMain8801.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..374846c6a71d2a3949b9273b7def71a2dbffbab8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,4 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-stream-rabbitmq-provider8801\src\main\java\com\atguigu\springcloud\controller\SendMessageController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-stream-rabbitmq-provider8801\src\main\java\com\atguigu\springcloud\service\impl\MessageProviderImpl.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-stream-rabbitmq-provider8801\src\main\java\com\atguigu\springcloud\StreamMQMain8801.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloud-stream-rabbitmq-provider8801\src\main\java\com\atguigu\springcloud\service\IMessageProvider.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloud-stream-rabbitmq-provider8801/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/cloudalibaba-config-nacos-client3377.iml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/cloudalibaba-config-nacos-client3377.iml new file mode 100644 index 0000000000000000000000000000000000000000..ed988b4636d77aaeb483f6a50c94e41055f9cc2f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/cloudalibaba-config-nacos-client3377.iml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + file://$MODULE_DIR$/src/main/resources/bootstrap.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..d2e1425fc46b8043848af888c688644346eeadfe --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/pom.xml @@ -0,0 +1,54 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloudalibaba-config-nacos-client3377 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/src/main/java/com/atguigu/springcloud/alibaba/NacosConfigClientMain3377.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/src/main/java/com/atguigu/springcloud/alibaba/NacosConfigClientMain3377.java new file mode 100644 index 0000000000000000000000000000000000000000..8d496773613f60a6a124a4b93c074db0c7184013 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/src/main/java/com/atguigu/springcloud/alibaba/NacosConfigClientMain3377.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud.alibaba; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @auther zzyy + * @create 2020-02-23 17:01 + */ +@EnableDiscoveryClient +@SpringBootApplication +public class NacosConfigClientMain3377 +{ + public static void main(String[] args) { + SpringApplication.run(NacosConfigClientMain3377.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/src/main/java/com/atguigu/springcloud/alibaba/controller/ConfigClientController.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/src/main/java/com/atguigu/springcloud/alibaba/controller/ConfigClientController.java new file mode 100644 index 0000000000000000000000000000000000000000..e9a2e4334d2c62355b59bacce6c277ad3676d774 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/src/main/java/com/atguigu/springcloud/alibaba/controller/ConfigClientController.java @@ -0,0 +1,23 @@ +package com.atguigu.springcloud.alibaba.controller; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @auther zzyy + * @create 2020-02-23 17:02 + */ +@RestController +@RefreshScope //支持Nacos的动态刷新功能。 +public class ConfigClientController +{ + @Value("${config.info}") + private String configInfo; + + @GetMapping("/config/info") + public String getConfigInfo() { + return configInfo; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..44529cb96e3be7dd6d7f8022234272736a3b3d37 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/src/main/resources/application.yml @@ -0,0 +1,5 @@ +spring: + profiles: + active: dev # 表示开发环境 + #active: test # 表示测试环境 + #active: info \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/src/main/resources/bootstrap.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/src/main/resources/bootstrap.yml new file mode 100644 index 0000000000000000000000000000000000000000..e9dcb2d0f6d63a39fda700dc220946602723a23b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/src/main/resources/bootstrap.yml @@ -0,0 +1,22 @@ +# nacos配置 +server: + port: 3377 + +spring: + application: + name: nacos-config-client + cloud: + nacos: + discovery: + server-addr: localhost:8848 #Nacos服务注册中心地址 + config: + server-addr: localhost:8848 #Nacos作为配置中心地址 + file-extension: yaml #指定yaml格式的配置 + group: DEV_GROUP + namespace: 7d8f0f5a-6a53-4785-9686-dd460158e5d4 + + +# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension} +# nacos-config-client-dev.yaml + +# nacos-config-client-test.yaml ----> config.info \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..44529cb96e3be7dd6d7f8022234272736a3b3d37 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/classes/application.yml @@ -0,0 +1,5 @@ +spring: + profiles: + active: dev # 表示开发环境 + #active: test # 表示测试环境 + #active: info \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/classes/bootstrap.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/classes/bootstrap.yml new file mode 100644 index 0000000000000000000000000000000000000000..e9dcb2d0f6d63a39fda700dc220946602723a23b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/classes/bootstrap.yml @@ -0,0 +1,22 @@ +# nacos配置 +server: + port: 3377 + +spring: + application: + name: nacos-config-client + cloud: + nacos: + discovery: + server-addr: localhost:8848 #Nacos服务注册中心地址 + config: + server-addr: localhost:8848 #Nacos作为配置中心地址 + file-extension: yaml #指定yaml格式的配置 + group: DEV_GROUP + namespace: 7d8f0f5a-6a53-4785-9686-dd460158e5d4 + + +# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension} +# nacos-config-client-dev.yaml + +# nacos-config-client-test.yaml ----> config.info \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/classes/com/atguigu/springcloud/alibaba/NacosConfigClientMain3377.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/classes/com/atguigu/springcloud/alibaba/NacosConfigClientMain3377.class new file mode 100644 index 0000000000000000000000000000000000000000..219bf605502cf99779daa3aec1f9675bac5d0869 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/classes/com/atguigu/springcloud/alibaba/NacosConfigClientMain3377.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/classes/com/atguigu/springcloud/alibaba/controller/ConfigClientController.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/classes/com/atguigu/springcloud/alibaba/controller/ConfigClientController.class new file mode 100644 index 0000000000000000000000000000000000000000..18c26bf6851de4f55f9a638e776097dbd5199721 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/classes/com/atguigu/springcloud/alibaba/controller/ConfigClientController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/cloudalibaba-config-nacos-client3377-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/cloudalibaba-config-nacos-client3377-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..96a01dc2df1b5eb8ced24fee50c81b8fab136780 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/cloudalibaba-config-nacos-client3377-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..04e51dff4906e2222a2c2d5a465b602e7a5d5d9e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:30:24 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloudalibaba-config-nacos-client3377 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..f8ed114e1586fe72fa8947be4ec45bd03106a132 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\atguigu\springcloud\alibaba\NacosConfigClientMain3377.class +com\atguigu\springcloud\alibaba\controller\ConfigClientController.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..52db68c4fa84116360f88c04d56e3e4552ffaaff --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-config-nacos-client3377\src\main\java\com\atguigu\springcloud\alibaba\controller\ConfigClientController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-config-nacos-client3377\src\main\java\com\atguigu\springcloud\alibaba\NacosConfigClientMain3377.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-config-nacos-client3377/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/cloudalibaba-consumer-nacos-order83.iml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/cloudalibaba-consumer-nacos-order83.iml new file mode 100644 index 0000000000000000000000000000000000000000..85889cba4a416874b385f2a22afc4e96c6ddb1ad --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/cloudalibaba-consumer-nacos-order83.iml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..83b40033a9baccaac9dbcfdae5776de9f9af1e9f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/pom.xml @@ -0,0 +1,56 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloudalibaba-consumer-nacos-order83 + + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/src/main/java/com/atguigu/springcloud/alibaba/OrderNacosMain83.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/src/main/java/com/atguigu/springcloud/alibaba/OrderNacosMain83.java new file mode 100644 index 0000000000000000000000000000000000000000..ab003b5f50de49d5e6ba359e7447fe7dac9bf083 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/src/main/java/com/atguigu/springcloud/alibaba/OrderNacosMain83.java @@ -0,0 +1,19 @@ +package com.atguigu.springcloud.alibaba; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @auther zzyy + * @create 2020-02-23 14:44 + */ +@EnableDiscoveryClient +@SpringBootApplication +public class OrderNacosMain83 +{ + public static void main(String[] args) + { + SpringApplication.run(OrderNacosMain83.class,args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/src/main/java/com/atguigu/springcloud/alibaba/config/ApplicationContextConfig.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/src/main/java/com/atguigu/springcloud/alibaba/config/ApplicationContextConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..141c680c06aa36138e19410bb89c6869d9cedddb --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/src/main/java/com/atguigu/springcloud/alibaba/config/ApplicationContextConfig.java @@ -0,0 +1,21 @@ +package com.atguigu.springcloud.alibaba.config; + +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * @auther zzyy + * @create 2020-02-23 14:45 + */ +@Configuration +public class ApplicationContextConfig +{ + @Bean + @LoadBalanced + public RestTemplate getRestTemplate() + { + return new RestTemplate(); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/src/main/java/com/atguigu/springcloud/alibaba/controller/OrderNacosController.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/src/main/java/com/atguigu/springcloud/alibaba/controller/OrderNacosController.java new file mode 100644 index 0000000000000000000000000000000000000000..04d7e4bb2ae083e414362c7a53e22e94dbf137d9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/src/main/java/com/atguigu/springcloud/alibaba/controller/OrderNacosController.java @@ -0,0 +1,32 @@ +package com.atguigu.springcloud.alibaba.controller; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-23 15:01 + */ +@RestController +@Slf4j +public class OrderNacosController +{ + @Resource + private RestTemplate restTemplate; + + @Value("${service-url.nacos-user-service}") + private String serverURL; + + @GetMapping(value = "/consumer/payment/nacos/{id}") + public String paymentInfo(@PathVariable("id") Long id) + { + return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class); + } + +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..506c8930b389433b6167346eddfb0e892b208ff0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/src/main/resources/application.yml @@ -0,0 +1,18 @@ +server: + port: 83 + + +spring: + application: + name: nacos-order-consumer + cloud: + nacos: + discovery: + server-addr: localhost:8848 + + +#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者) +service-url: + nacos-user-service: http://nacos-payment-provider + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..506c8930b389433b6167346eddfb0e892b208ff0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/classes/application.yml @@ -0,0 +1,18 @@ +server: + port: 83 + + +spring: + application: + name: nacos-order-consumer + cloud: + nacos: + discovery: + server-addr: localhost:8848 + + +#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者) +service-url: + nacos-user-service: http://nacos-payment-provider + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/classes/com/atguigu/springcloud/alibaba/OrderNacosMain83.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/classes/com/atguigu/springcloud/alibaba/OrderNacosMain83.class new file mode 100644 index 0000000000000000000000000000000000000000..85eef28b648deb8a64419eba65bf829195abed7f Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/classes/com/atguigu/springcloud/alibaba/OrderNacosMain83.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/classes/com/atguigu/springcloud/alibaba/config/ApplicationContextConfig.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/classes/com/atguigu/springcloud/alibaba/config/ApplicationContextConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..fb8b2e67f9f79b9c56f03b25b9b5063d63e7cdda Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/classes/com/atguigu/springcloud/alibaba/config/ApplicationContextConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/classes/com/atguigu/springcloud/alibaba/controller/OrderNacosController.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/classes/com/atguigu/springcloud/alibaba/controller/OrderNacosController.class new file mode 100644 index 0000000000000000000000000000000000000000..a555d166c5f0d7d1d6764ae9f5751f7439433148 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/classes/com/atguigu/springcloud/alibaba/controller/OrderNacosController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/cloudalibaba-consumer-nacos-order83-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/cloudalibaba-consumer-nacos-order83-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..aca63055e3f552e408acc70843d386cba65f8cb5 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/cloudalibaba-consumer-nacos-order83-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..adee1b929293ced27a0bf837a8937fc716ce10b7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:30:21 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloudalibaba-consumer-nacos-order83 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..ab1c999eb255f34949e430c3ce50aa03ffcc12c5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,3 @@ +com\atguigu\springcloud\alibaba\config\ApplicationContextConfig.class +com\atguigu\springcloud\alibaba\controller\OrderNacosController.class +com\atguigu\springcloud\alibaba\OrderNacosMain83.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..a0ea09d04dc82e58ea9069151452b4627b618d7d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,3 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-consumer-nacos-order83\src\main\java\com\atguigu\springcloud\alibaba\config\ApplicationContextConfig.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-consumer-nacos-order83\src\main\java\com\atguigu\springcloud\alibaba\OrderNacosMain83.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-consumer-nacos-order83\src\main\java\com\atguigu\springcloud\alibaba\controller\OrderNacosController.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order83/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/cloudalibaba-consumer-nacos-order84.iml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/cloudalibaba-consumer-nacos-order84.iml new file mode 100644 index 0000000000000000000000000000000000000000..5a0f9587f5c44409b01b21021e5e5e6fca2e7da7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/cloudalibaba-consumer-nacos-order84.iml @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..6cc8c04bacad8cae35a35acf35ce95011b7417b8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/pom.xml @@ -0,0 +1,65 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloudalibaba-consumer-nacos-order84 + + + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/OrderNacosMain84.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/OrderNacosMain84.java new file mode 100644 index 0000000000000000000000000000000000000000..0acbbf1875509d5324ac6cfdf946c991411b6181 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/OrderNacosMain84.java @@ -0,0 +1,20 @@ +package com.atguigu.springcloud.alibaba; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; + +/** + * @auther zzyy + * @create 2020-02-25 16:04 + */ +@EnableDiscoveryClient +@SpringBootApplication +@EnableFeignClients +public class OrderNacosMain84 +{ + public static void main(String[] args) { + SpringApplication.run(OrderNacosMain84.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/config/ApplicationContextConfig.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/config/ApplicationContextConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..5c53741bcd300ad49ea9b4b40233003c84eab426 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/config/ApplicationContextConfig.java @@ -0,0 +1,21 @@ +package com.atguigu.springcloud.alibaba.config; + +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * @auther zzyy + * @create 2020-02-25 16:06 + */ +@Configuration +public class ApplicationContextConfig +{ + @Bean + @LoadBalanced + public RestTemplate getRestTemplate() + { + return new RestTemplate(); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/controller/CircleBreakerController.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/controller/CircleBreakerController.java new file mode 100644 index 0000000000000000000000000000000000000000..16301bfd2aa2b64c9b619c44fedb2afce2127c2c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/controller/CircleBreakerController.java @@ -0,0 +1,68 @@ +package com.atguigu.springcloud.alibaba.controller; + +import com.alibaba.csp.sentinel.annotation.SentinelResource; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.atguigu.springcloud.alibaba.service.PaymentService; +import com.atguigu.springcloud.entities.CommonResult; +import com.atguigu.springcloud.entities.Payment; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-25 16:05 + */ +@RestController +@Slf4j +public class CircleBreakerController +{ + public static final String SERVICE_URL = "http://nacos-payment-provider"; + + @Resource + private RestTemplate restTemplate; + + @RequestMapping("/consumer/fallback/{id}") + //@SentinelResource(value = "fallback") //没有配置 + //@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常 + //@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规 + @SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler", + exceptionsToIgnore = {IllegalArgumentException.class}) + public CommonResult fallback(@PathVariable Long id) + { + CommonResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id); + + if (id == 4) { + throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常...."); + }else if (result.getData() == null) { + throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常"); + } + + return result; + } + //本例是fallback + public CommonResult handlerFallback(@PathVariable Long id,Throwable e) { + Payment payment = new Payment(id,"null"); + return new CommonResult<>(444,"兜底异常handlerFallback,exception内容 "+e.getMessage(),payment); + } + //本例是blockHandler + public CommonResult blockHandler(@PathVariable Long id,BlockException blockException) { + Payment payment = new Payment(id,"null"); + return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException "+blockException.getMessage(),payment); + } + + //==================OpenFeign + @Resource + private PaymentService paymentService; + + @GetMapping(value = "/consumer/paymentSQL/{id}") + public CommonResult paymentSQL(@PathVariable("id") Long id) + { + return paymentService.paymentSQL(id); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/service/PaymentFallbackService.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/service/PaymentFallbackService.java new file mode 100644 index 0000000000000000000000000000000000000000..72efa70cad8bea7bb1e087d7826e7788ecd0df01 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/service/PaymentFallbackService.java @@ -0,0 +1,19 @@ +package com.atguigu.springcloud.alibaba.service; + +import com.atguigu.springcloud.entities.CommonResult; +import com.atguigu.springcloud.entities.Payment; +import org.springframework.stereotype.Component; + +/** + * @auther zzyy + * @create 2020-02-25 18:30 + */ +@Component +public class PaymentFallbackService implements PaymentService +{ + @Override + public CommonResult paymentSQL(Long id) + { + return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial")); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/service/PaymentService.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/service/PaymentService.java new file mode 100644 index 0000000000000000000000000000000000000000..dfc385658a1d97a6d053b97e1b8c6d64ff83ff35 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/java/com/atguigu/springcloud/alibaba/service/PaymentService.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud.alibaba.service; + +import com.atguigu.springcloud.entities.CommonResult; +import com.atguigu.springcloud.entities.Payment; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; + +/** + * @auther zzyy + * @create 2020-02-25 18:15 + */ +@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class) +public interface PaymentService +{ + @GetMapping(value = "/paymentSQL/{id}") + public CommonResult paymentSQL(@PathVariable("id") Long id); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..0d842b124798367ab83ed02dc7c15799c6ca6d7c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/src/main/resources/application.yml @@ -0,0 +1,26 @@ +server: + port: 84 + + +spring: + application: + name: nacos-order-consumer + cloud: + nacos: + discovery: + server-addr: localhost:8848 + sentinel: + transport: + #配置Sentinel dashboard地址 + dashboard: localhost:8080 + #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口 + port: 8719 + +#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者) +service-url: + nacos-user-service: http://nacos-payment-provider + +# 激活Sentinel对Feign的支持 +feign: + sentinel: + enabled: true \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..0d842b124798367ab83ed02dc7c15799c6ca6d7c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/application.yml @@ -0,0 +1,26 @@ +server: + port: 84 + + +spring: + application: + name: nacos-order-consumer + cloud: + nacos: + discovery: + server-addr: localhost:8848 + sentinel: + transport: + #配置Sentinel dashboard地址 + dashboard: localhost:8080 + #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口 + port: 8719 + +#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者) +service-url: + nacos-user-service: http://nacos-payment-provider + +# 激活Sentinel对Feign的支持 +feign: + sentinel: + enabled: true \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/OrderNacosMain84.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/OrderNacosMain84.class new file mode 100644 index 0000000000000000000000000000000000000000..a473afb8fed259fab260667b7a37ffb6c38026ef Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/OrderNacosMain84.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/config/ApplicationContextConfig.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/config/ApplicationContextConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..fb8b2e67f9f79b9c56f03b25b9b5063d63e7cdda Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/config/ApplicationContextConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/controller/CircleBreakerController.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/controller/CircleBreakerController.class new file mode 100644 index 0000000000000000000000000000000000000000..310a885a632c81c4a1b8dd28e4d2eeaae8464970 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/controller/CircleBreakerController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/service/PaymentFallbackService.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/service/PaymentFallbackService.class new file mode 100644 index 0000000000000000000000000000000000000000..23087150c07ffcd7c1fcafcbf350a9b086653a79 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/service/PaymentFallbackService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/service/PaymentService.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/service/PaymentService.class new file mode 100644 index 0000000000000000000000000000000000000000..f70e28a086c562675f49e2ce2095ef5400675031 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/classes/com/atguigu/springcloud/alibaba/service/PaymentService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/cloudalibaba-consumer-nacos-order84-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/cloudalibaba-consumer-nacos-order84-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..d34232999cb3e03da93886005cbb0cbff5b70aa5 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/cloudalibaba-consumer-nacos-order84-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..16b3459f44e449647a535dbf1478f2742ed265be --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:30:41 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloudalibaba-consumer-nacos-order84 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..07a314893530c976cf25679697df9cecbba021dc --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,5 @@ +com\atguigu\springcloud\alibaba\config\ApplicationContextConfig.class +com\atguigu\springcloud\alibaba\service\PaymentService.class +com\atguigu\springcloud\alibaba\OrderNacosMain84.class +com\atguigu\springcloud\alibaba\controller\CircleBreakerController.class +com\atguigu\springcloud\alibaba\service\PaymentFallbackService.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..d5463b517abaef66abcd00ec608d21191722b1f5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,5 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-consumer-nacos-order84\src\main\java\com\atguigu\springcloud\alibaba\OrderNacosMain84.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-consumer-nacos-order84\src\main\java\com\atguigu\springcloud\alibaba\controller\CircleBreakerController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-consumer-nacos-order84\src\main\java\com\atguigu\springcloud\alibaba\service\PaymentFallbackService.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-consumer-nacos-order84\src\main\java\com\atguigu\springcloud\alibaba\service\PaymentService.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-consumer-nacos-order84\src\main\java\com\atguigu\springcloud\alibaba\config\ApplicationContextConfig.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-consumer-nacos-order84/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/cloudalibaba-provider-payment9001.iml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/cloudalibaba-provider-payment9001.iml new file mode 100644 index 0000000000000000000000000000000000000000..2f47f9329e058696a989373af4b6be27e3f2da0b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/cloudalibaba-provider-payment9001.iml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/../cloud-stream-rabbitmq-consumer8803/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..a0696170a61dcc3b38977c89d525baddde4fce86 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/pom.xml @@ -0,0 +1,49 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloudalibaba-provider-payment9001 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/src/main/java/com/atguigu/springcloud/alibaba/PaymentMain9001.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/src/main/java/com/atguigu/springcloud/alibaba/PaymentMain9001.java new file mode 100644 index 0000000000000000000000000000000000000000..90c53687777fbfcaddf2081c0a55db1579eb7d41 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/src/main/java/com/atguigu/springcloud/alibaba/PaymentMain9001.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud.alibaba; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @auther zzyy + * @create 2020-02-23 14:12 + */ +@EnableDiscoveryClient +@SpringBootApplication +public class PaymentMain9001 +{ + public static void main(String[] args) { + SpringApplication.run(PaymentMain9001.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/src/main/java/com/atguigu/springcloud/alibaba/controller/PaymentController.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/src/main/java/com/atguigu/springcloud/alibaba/controller/PaymentController.java new file mode 100644 index 0000000000000000000000000000000000000000..119572cd2882b1efd6fb294008b8ba01412b5adf --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/src/main/java/com/atguigu/springcloud/alibaba/controller/PaymentController.java @@ -0,0 +1,23 @@ +package com.atguigu.springcloud.alibaba.controller; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +/** + * @auther zzyy + * @create 2020-02-23 14:13 + */ +@RestController +public class PaymentController +{ + @Value("${server.port}") + private String serverPort; + + @GetMapping(value = "/payment/nacos/{id}") + public String getPayment(@PathVariable("id") Integer id) + { + return "nacos registry, serverPort: "+ serverPort+"\t id"+id; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..b45bdd28f062a008af221dbb77bdb30da3699674 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/src/main/resources/application.yml @@ -0,0 +1,18 @@ +server: + port: 9001 + +spring: + application: + name: nacos-payment-provider + cloud: + nacos: + discovery: + server-addr: localhost:8848 #配置Nacos地址 + +management: + endpoints: + web: + exposure: + include: '*' + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..b45bdd28f062a008af221dbb77bdb30da3699674 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/classes/application.yml @@ -0,0 +1,18 @@ +server: + port: 9001 + +spring: + application: + name: nacos-payment-provider + cloud: + nacos: + discovery: + server-addr: localhost:8848 #配置Nacos地址 + +management: + endpoints: + web: + exposure: + include: '*' + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/classes/com/atguigu/springcloud/alibaba/PaymentMain9001.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/classes/com/atguigu/springcloud/alibaba/PaymentMain9001.class new file mode 100644 index 0000000000000000000000000000000000000000..80697ae451b4a1c225dbd298e145f276b2a308a1 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/classes/com/atguigu/springcloud/alibaba/PaymentMain9001.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/classes/com/atguigu/springcloud/alibaba/controller/PaymentController.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/classes/com/atguigu/springcloud/alibaba/controller/PaymentController.class new file mode 100644 index 0000000000000000000000000000000000000000..fffa9b5c333e40b40206d8fdfec48e1484227463 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/classes/com/atguigu/springcloud/alibaba/controller/PaymentController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/cloudalibaba-provider-payment9001-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/cloudalibaba-provider-payment9001-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..96fd51b4c79190ee15d0b00d43659bee376057fe Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/cloudalibaba-provider-payment9001-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..4c74e4f6b844f72b73e54ebcc64f7d996d85cfab --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:30:17 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloudalibaba-provider-payment9001 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..1a0edd67c4b2d453031b641e75ce6e6eeb893acf --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\atguigu\springcloud\alibaba\PaymentMain9001.class +com\atguigu\springcloud\alibaba\controller\PaymentController.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..f0ee34a144a027dbd6a721861283f0fed2e1c4d9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-provider-payment9001\src\main\java\com\atguigu\springcloud\alibaba\PaymentMain9001.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-provider-payment9001\src\main\java\com\atguigu\springcloud\alibaba\controller\PaymentController.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9001/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/cloudalibaba-provider-payment9002.iml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/cloudalibaba-provider-payment9002.iml new file mode 100644 index 0000000000000000000000000000000000000000..5560e37aa66f6f20287bc361d8aa7a9c19e5dff7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/cloudalibaba-provider-payment9002.iml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..e016c6f2e8dccea0f7d11270563570d8463c6371 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/pom.xml @@ -0,0 +1,49 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloudalibaba-provider-payment9002 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/src/main/java/com/atguigu/springcloud/alibaba/PaymentMain9002.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/src/main/java/com/atguigu/springcloud/alibaba/PaymentMain9002.java new file mode 100644 index 0000000000000000000000000000000000000000..3438f5cfa28c45389a70660bffc5618291e6f37f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/src/main/java/com/atguigu/springcloud/alibaba/PaymentMain9002.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud.alibaba; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @auther zzyy + * @create 2020-02-23 14:12 + */ +@EnableDiscoveryClient +@SpringBootApplication +public class PaymentMain9002 +{ + public static void main(String[] args) { + SpringApplication.run(PaymentMain9002.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/src/main/java/com/atguigu/springcloud/alibaba/controller/PaymentController.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/src/main/java/com/atguigu/springcloud/alibaba/controller/PaymentController.java new file mode 100644 index 0000000000000000000000000000000000000000..119572cd2882b1efd6fb294008b8ba01412b5adf --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/src/main/java/com/atguigu/springcloud/alibaba/controller/PaymentController.java @@ -0,0 +1,23 @@ +package com.atguigu.springcloud.alibaba.controller; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +/** + * @auther zzyy + * @create 2020-02-23 14:13 + */ +@RestController +public class PaymentController +{ + @Value("${server.port}") + private String serverPort; + + @GetMapping(value = "/payment/nacos/{id}") + public String getPayment(@PathVariable("id") Integer id) + { + return "nacos registry, serverPort: "+ serverPort+"\t id"+id; + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..58c4ff573c187d54b911ced51f803d04dcbe9775 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/src/main/resources/application.yml @@ -0,0 +1,20 @@ +server: + port: 9002 + +spring: + application: + name: nacos-payment-provider + cloud: + nacos: + discovery: + #server-addr: localhost:8848 #配置Nacos地址 + # 换成nginx的1111端口,做集群 + server-addr: 192.168.111.144:1111 + +management: + endpoints: + web: + exposure: + include: '*' + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..58c4ff573c187d54b911ced51f803d04dcbe9775 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/classes/application.yml @@ -0,0 +1,20 @@ +server: + port: 9002 + +spring: + application: + name: nacos-payment-provider + cloud: + nacos: + discovery: + #server-addr: localhost:8848 #配置Nacos地址 + # 换成nginx的1111端口,做集群 + server-addr: 192.168.111.144:1111 + +management: + endpoints: + web: + exposure: + include: '*' + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/classes/com/atguigu/springcloud/alibaba/PaymentMain9002.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/classes/com/atguigu/springcloud/alibaba/PaymentMain9002.class new file mode 100644 index 0000000000000000000000000000000000000000..262f618d6426f4de1e1e29a2177e141f76d98f8c Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/classes/com/atguigu/springcloud/alibaba/PaymentMain9002.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/classes/com/atguigu/springcloud/alibaba/controller/PaymentController.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/classes/com/atguigu/springcloud/alibaba/controller/PaymentController.class new file mode 100644 index 0000000000000000000000000000000000000000..fffa9b5c333e40b40206d8fdfec48e1484227463 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/classes/com/atguigu/springcloud/alibaba/controller/PaymentController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/cloudalibaba-provider-payment9002-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/cloudalibaba-provider-payment9002-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..b68967e3a07df5ed26e127ed20c3c68ba3c68bd5 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/cloudalibaba-provider-payment9002-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..77992caaa02deeb1c2345194265db17b8eea7d5e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:30:19 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloudalibaba-provider-payment9002 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e01e27e59af5d391eaaf2853f0967fd0827113fb --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\atguigu\springcloud\alibaba\controller\PaymentController.class +com\atguigu\springcloud\alibaba\PaymentMain9002.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..7a2ada15f22ab0ebe1e0f7fac61a041d7e44f785 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-provider-payment9002\src\main\java\com\atguigu\springcloud\alibaba\controller\PaymentController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-provider-payment9002\src\main\java\com\atguigu\springcloud\alibaba\PaymentMain9002.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9002/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/cloudalibaba-provider-payment9003.iml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/cloudalibaba-provider-payment9003.iml new file mode 100644 index 0000000000000000000000000000000000000000..85889cba4a416874b385f2a22afc4e96c6ddb1ad --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/cloudalibaba-provider-payment9003.iml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..beddc37afe0c1d6b51374fad40b5445910d680c5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/pom.xml @@ -0,0 +1,54 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloudalibaba-provider-payment9003 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/src/main/java/com/atguigu/springcloud/alibaba/PaymentMain9003.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/src/main/java/com/atguigu/springcloud/alibaba/PaymentMain9003.java new file mode 100644 index 0000000000000000000000000000000000000000..04aa049fd868f6f12d7de14cabb42621b8c65d6a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/src/main/java/com/atguigu/springcloud/alibaba/PaymentMain9003.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud.alibaba; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @auther zzyy + * @create 2020-02-25 16:10 + */ +@SpringBootApplication +@EnableDiscoveryClient +public class PaymentMain9003 +{ + public static void main(String[] args) { + SpringApplication.run(PaymentMain9003.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/src/main/java/com/atguigu/springcloud/alibaba/controller/PaymentController.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/src/main/java/com/atguigu/springcloud/alibaba/controller/PaymentController.java new file mode 100644 index 0000000000000000000000000000000000000000..0c3b689146d1391ed8b4c90c223fc8530fe0a770 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/src/main/java/com/atguigu/springcloud/alibaba/controller/PaymentController.java @@ -0,0 +1,40 @@ +package com.atguigu.springcloud.alibaba.controller; + +import com.atguigu.springcloud.entities.CommonResult; +import com.atguigu.springcloud.entities.Payment; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; + +/** + * @auther zzyy + * @create 2020-02-25 16:11 + */ +@RestController +public class PaymentController +{ + @Value("${server.port}") + private String serverPort; + + public static HashMap hashMap = new HashMap<>(); + static + { + hashMap.put(1L,new Payment(1L,"28a8c1e3bc2742d8848569891fb42181")); + hashMap.put(2L,new Payment(2L,"bba8c1e3bc2742d8848569891ac32182")); + hashMap.put(3L,new Payment(3L,"6ua8c1e3bc2742d8848569891xt92183")); + } + + @GetMapping(value = "/paymentSQL/{id}") + public CommonResult paymentSQL(@PathVariable("id") Long id) + { + Payment payment = hashMap.get(id); + CommonResult result = new CommonResult(200,"from mysql,serverPort: "+serverPort,payment); + return result; + } + + + +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..a523f50a483a12cafcef8afb3897ccecae75885a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/src/main/resources/application.yml @@ -0,0 +1,21 @@ +server: + port: 9003 + +spring: + application: + name: nacos-payment-provider + cloud: + nacos: + discovery: + server-addr: localhost:8848 #配置Nacos地址 + +management: + endpoints: + web: + exposure: + include: '*' + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..a523f50a483a12cafcef8afb3897ccecae75885a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/classes/application.yml @@ -0,0 +1,21 @@ +server: + port: 9003 + +spring: + application: + name: nacos-payment-provider + cloud: + nacos: + discovery: + server-addr: localhost:8848 #配置Nacos地址 + +management: + endpoints: + web: + exposure: + include: '*' + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/classes/com/atguigu/springcloud/alibaba/PaymentMain9003.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/classes/com/atguigu/springcloud/alibaba/PaymentMain9003.class new file mode 100644 index 0000000000000000000000000000000000000000..de9197434adc379c2b3f53e21e147d09dbd32640 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/classes/com/atguigu/springcloud/alibaba/PaymentMain9003.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/classes/com/atguigu/springcloud/alibaba/controller/PaymentController.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/classes/com/atguigu/springcloud/alibaba/controller/PaymentController.class new file mode 100644 index 0000000000000000000000000000000000000000..08912032272fd59f1c89bf58d3db2e4dfbb3229d Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/classes/com/atguigu/springcloud/alibaba/controller/PaymentController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/cloudalibaba-provider-payment9003-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/cloudalibaba-provider-payment9003-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..7c68b9901ce3d6338fdceb06b46d9a856366b133 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/cloudalibaba-provider-payment9003-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..8166f51113de50db893f6fb26adbe4c290f3f22a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:30:43 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloudalibaba-provider-payment9003 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..044129640662ed43079dc19d2ef9994d9ab55fb7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\atguigu\springcloud\alibaba\controller\PaymentController.class +com\atguigu\springcloud\alibaba\PaymentMain9003.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..02118ea6cf17abcbb68b9020062712d241c9f43b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-provider-payment9003\src\main\java\com\atguigu\springcloud\alibaba\controller\PaymentController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-provider-payment9003\src\main\java\com\atguigu\springcloud\alibaba\PaymentMain9003.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9003/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/cloudalibaba-provider-payment9004.iml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/cloudalibaba-provider-payment9004.iml new file mode 100644 index 0000000000000000000000000000000000000000..85889cba4a416874b385f2a22afc4e96c6ddb1ad --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/cloudalibaba-provider-payment9004.iml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..9d8d1de625634563e08c9c66e47d1d7d9bd50782 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/pom.xml @@ -0,0 +1,55 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloudalibaba-provider-payment9004 + + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/src/main/java/com/atguigu/springcloud/alibaba/PaymentMain9004.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/src/main/java/com/atguigu/springcloud/alibaba/PaymentMain9004.java new file mode 100644 index 0000000000000000000000000000000000000000..a6df317388444ad07980ce06450018a866a8e09f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/src/main/java/com/atguigu/springcloud/alibaba/PaymentMain9004.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud.alibaba; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @auther zzyy + * @create 2020-02-25 16:13 + */ +@SpringBootApplication +@EnableDiscoveryClient +public class PaymentMain9004 +{ + public static void main(String[] args) { + SpringApplication.run(PaymentMain9004.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/src/main/java/com/atguigu/springcloud/alibaba/controller/PaymentController.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/src/main/java/com/atguigu/springcloud/alibaba/controller/PaymentController.java new file mode 100644 index 0000000000000000000000000000000000000000..9cc29dd637a3197d8e4d8a6cf3eeaf984dc84335 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/src/main/java/com/atguigu/springcloud/alibaba/controller/PaymentController.java @@ -0,0 +1,40 @@ +package com.atguigu.springcloud.alibaba.controller; + +import com.atguigu.springcloud.entities.CommonResult; +import com.atguigu.springcloud.entities.Payment; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; + +/** + * @auther zzyy + * @create 2020-02-25 16:13 + */ +@RestController +public class PaymentController +{ + @Value("${server.port}") + private String serverPort; + + public static HashMap hashMap = new HashMap<>(); + static + { + hashMap.put(1L,new Payment(1L,"28a8c1e3bc2742d8848569891fb42181")); + hashMap.put(2L,new Payment(2L,"bba8c1e3bc2742d8848569891ac32182")); + hashMap.put(3L,new Payment(3L,"6ua8c1e3bc2742d8848569891xt92183")); + } + + @GetMapping(value = "/paymentSQL/{id}") + public CommonResult paymentSQL(@PathVariable("id") Long id) + { + Payment payment = hashMap.get(id); + CommonResult result = new CommonResult(200,"from mysql,serverPort: "+serverPort,payment); + return result; + } + + + +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..4493f9c9f31b3bc9d4723f4b2dfab6c5412f94e1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/src/main/resources/application.yml @@ -0,0 +1,21 @@ +server: + port: 9004 + +spring: + application: + name: nacos-payment-provider + cloud: + nacos: + discovery: + server-addr: localhost:8848 #配置Nacos地址 + +management: + endpoints: + web: + exposure: + include: '*' + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..4493f9c9f31b3bc9d4723f4b2dfab6c5412f94e1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/classes/application.yml @@ -0,0 +1,21 @@ +server: + port: 9004 + +spring: + application: + name: nacos-payment-provider + cloud: + nacos: + discovery: + server-addr: localhost:8848 #配置Nacos地址 + +management: + endpoints: + web: + exposure: + include: '*' + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/classes/com/atguigu/springcloud/alibaba/PaymentMain9004.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/classes/com/atguigu/springcloud/alibaba/PaymentMain9004.class new file mode 100644 index 0000000000000000000000000000000000000000..9040b70078c010d15a71ff556024cdd3f1e3d699 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/classes/com/atguigu/springcloud/alibaba/PaymentMain9004.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/classes/com/atguigu/springcloud/alibaba/controller/PaymentController.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/classes/com/atguigu/springcloud/alibaba/controller/PaymentController.class new file mode 100644 index 0000000000000000000000000000000000000000..08912032272fd59f1c89bf58d3db2e4dfbb3229d Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/classes/com/atguigu/springcloud/alibaba/controller/PaymentController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/cloudalibaba-provider-payment9004-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/cloudalibaba-provider-payment9004-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..46142c2f77f63f9bf59f89b3f98cccf6f9cc9da7 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/cloudalibaba-provider-payment9004-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..9dcfe74b1a20f0a38cfb4180bf71e2df216f8325 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:30:44 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloudalibaba-provider-payment9004 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..d6d30a0d942404945a43a505fed58a3fe4663944 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +com\atguigu\springcloud\alibaba\PaymentMain9004.class +com\atguigu\springcloud\alibaba\controller\PaymentController.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..5a6cbff0656df31de790b2e47345dc843d1b9159 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-provider-payment9004\src\main\java\com\atguigu\springcloud\alibaba\PaymentMain9004.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-provider-payment9004\src\main\java\com\atguigu\springcloud\alibaba\controller\PaymentController.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-provider-payment9004/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/cloudalibaba-sentinel-service8401.iml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/cloudalibaba-sentinel-service8401.iml new file mode 100644 index 0000000000000000000000000000000000000000..7f5465534c49b97f64debefcdc3ae3dac156eb64 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/cloudalibaba-sentinel-service8401.iml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..4f85d7d603dce92d9853419e6814ab63bc83cca5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/pom.xml @@ -0,0 +1,78 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + cloudalibaba-sentinel-service8401 + + + + + + + com.atguigu.springcloud + cloud-api-commons + ${project.version} + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + com.alibaba.csp + sentinel-datasource-nacos + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + cn.hutool + hutool-all + 4.6.3 + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/java/com/atguigu/springcloud/alibaba/MainApp8401.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/java/com/atguigu/springcloud/alibaba/MainApp8401.java new file mode 100644 index 0000000000000000000000000000000000000000..d45027d1f2b3cd94927d56823be573a5142ad329 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/java/com/atguigu/springcloud/alibaba/MainApp8401.java @@ -0,0 +1,18 @@ +package com.atguigu.springcloud.alibaba; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @auther zzyy + * @create 2020-02-24 16:26 + */ +@EnableDiscoveryClient +@SpringBootApplication +public class MainApp8401 +{ + public static void main(String[] args) { + SpringApplication.run(MainApp8401.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/java/com/atguigu/springcloud/alibaba/controller/FlowLimitController.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/java/com/atguigu/springcloud/alibaba/controller/FlowLimitController.java new file mode 100644 index 0000000000000000000000000000000000000000..c80e67c9b38961ea368486b9adc326c514fec67e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/java/com/atguigu/springcloud/alibaba/controller/FlowLimitController.java @@ -0,0 +1,66 @@ +package com.atguigu.springcloud.alibaba.controller; + +import com.alibaba.csp.sentinel.annotation.SentinelResource; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.concurrent.TimeUnit; + +/** + * @auther zzyy + * @create 2020-02-24 16:26 + */ +@RestController +@Slf4j +public class FlowLimitController +{ + @GetMapping("/testA") + public String testA() + { + return "------testA"; + } + + @GetMapping("/testB") + public String testB() + { + log.info(Thread.currentThread().getName()+"\t"+"...testB"); + return "------testB"; + } + + + @GetMapping("/testD") + public String testD() + { +// try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } + log.info("testD 测试RT"); + + log.info("testD 异常比例"); + int age = 10/0; + return "------testD"; + } + + @GetMapping("/testE") + public String testE() + { + log.info("testE 测试异常数"); + int age = 10/0; + return "------testE 测试异常数"; + } + + @GetMapping("/testHotKey") + @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey", fallback = "") + public String testHotKey(@RequestParam(value = "p1",required = false) String p1, + @RequestParam(value = "p2",required = false) String p2) + { + //int age = 10/0; + return "------testHotKey"; + } + public String deal_testHotKey (String p1, String p2, BlockException exception) + { + return "------deal_testHotKey,o(╥﹏╥)o"; //sentinel系统默认的提示:Blocked by Sentinel (flow limiting) + } + +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/java/com/atguigu/springcloud/alibaba/controller/RateLimitController.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/java/com/atguigu/springcloud/alibaba/controller/RateLimitController.java new file mode 100644 index 0000000000000000000000000000000000000000..3619f69774f5ae0f9b75532bac7a15da9e295667 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/java/com/atguigu/springcloud/alibaba/controller/RateLimitController.java @@ -0,0 +1,45 @@ +package com.atguigu.springcloud.alibaba.controller; + +import com.alibaba.csp.sentinel.annotation.SentinelResource; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.atguigu.springcloud.alibaba.myhandler.CustomerBlockHandler; +import com.atguigu.springcloud.entities.CommonResult; +import com.atguigu.springcloud.entities.Payment; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @auther zzyy + * @create 2020-02-25 15:04 + */ +@RestController +public class RateLimitController +{ + @GetMapping("/byResource") + @SentinelResource(value = "byResource",blockHandler = "handleException") + public CommonResult byResource() + { + return new CommonResult(200,"按资源名称限流测试OK",new Payment(2020L,"serial001")); + } + public CommonResult handleException(BlockException exception) + { + return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服务不可用"); + } + + @GetMapping("/rateLimit/byUrl") + @SentinelResource(value = "byUrl") + public CommonResult byUrl() + { + return new CommonResult(200,"按url限流测试OK",new Payment(2020L,"serial002")); + } + + + @GetMapping("/rateLimit/customerBlockHandler") + @SentinelResource(value = "customerBlockHandler", + blockHandlerClass = CustomerBlockHandler.class, + blockHandler = "handlerException2") + public CommonResult customerBlockHandler() + { + return new CommonResult(200,"按客戶自定义",new Payment(2020L,"serial003")); + } +} \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/java/com/atguigu/springcloud/alibaba/myhandler/CustomerBlockHandler.java b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/java/com/atguigu/springcloud/alibaba/myhandler/CustomerBlockHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..cbd02697ec8b45b00d661645a90163842f6c8803 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/java/com/atguigu/springcloud/alibaba/myhandler/CustomerBlockHandler.java @@ -0,0 +1,21 @@ +package com.atguigu.springcloud.alibaba.myhandler; + +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.atguigu.springcloud.entities.CommonResult; +import com.atguigu.springcloud.entities.Payment; + +/** + * @auther zzyy + * @create 2020-02-25 15:32 + */ +public class CustomerBlockHandler +{ + public static CommonResult handlerException(BlockException exception) + { + return new CommonResult(4444,"按客戶自定义,global handlerException----1"); + } + public static CommonResult handlerException2(BlockException exception) + { + return new CommonResult(4444,"按客戶自定义,global handlerException----2"); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..4489a04bff1db31a87e4a821fdba6b7108783ea0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/src/main/resources/application.yml @@ -0,0 +1,34 @@ +server: + port: 8401 + +spring: + application: + name: cloudalibaba-sentinel-service + cloud: + nacos: + discovery: + server-addr: localhost:8848 #Nacos服务注册中心地址 + sentinel: + transport: + dashboard: localhost:8080 #配置Sentinel dashboard地址 + port: 8719 + datasource: + ds1: + nacos: + server-addr: localhost:8848 + dataId: cloudalibaba-sentinel-service + groupId: DEFAULT_GROUP + data-type: json + rule-type: flow + +management: + endpoints: + web: + exposure: + include: '*' + +feign: + sentinel: + enabled: true # 激活Sentinel对Feign的支持 + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..4489a04bff1db31a87e4a821fdba6b7108783ea0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/application.yml @@ -0,0 +1,34 @@ +server: + port: 8401 + +spring: + application: + name: cloudalibaba-sentinel-service + cloud: + nacos: + discovery: + server-addr: localhost:8848 #Nacos服务注册中心地址 + sentinel: + transport: + dashboard: localhost:8080 #配置Sentinel dashboard地址 + port: 8719 + datasource: + ds1: + nacos: + server-addr: localhost:8848 + dataId: cloudalibaba-sentinel-service + groupId: DEFAULT_GROUP + data-type: json + rule-type: flow + +management: + endpoints: + web: + exposure: + include: '*' + +feign: + sentinel: + enabled: true # 激活Sentinel对Feign的支持 + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/com/atguigu/springcloud/alibaba/MainApp8401.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/com/atguigu/springcloud/alibaba/MainApp8401.class new file mode 100644 index 0000000000000000000000000000000000000000..9792291527dbd3b4bcc0d0b9dd4ffc1d22d4b81c Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/com/atguigu/springcloud/alibaba/MainApp8401.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/com/atguigu/springcloud/alibaba/controller/FlowLimitController.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/com/atguigu/springcloud/alibaba/controller/FlowLimitController.class new file mode 100644 index 0000000000000000000000000000000000000000..40680522268c16e0a2eb9076d528e00a71c4b83c Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/com/atguigu/springcloud/alibaba/controller/FlowLimitController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/com/atguigu/springcloud/alibaba/controller/RateLimitController.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/com/atguigu/springcloud/alibaba/controller/RateLimitController.class new file mode 100644 index 0000000000000000000000000000000000000000..48fad36fc09378a43a2cce1a050e6408a104a235 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/com/atguigu/springcloud/alibaba/controller/RateLimitController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/com/atguigu/springcloud/alibaba/myhandler/CustomerBlockHandler.class b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/com/atguigu/springcloud/alibaba/myhandler/CustomerBlockHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..489e6c88ca465685e7f2ea68934185dcd363f3f2 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/classes/com/atguigu/springcloud/alibaba/myhandler/CustomerBlockHandler.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/cloudalibaba-sentinel-service8401-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/cloudalibaba-sentinel-service8401-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..fd631d3deb19546d8c3eb95dab944eb0fca866ef Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/cloudalibaba-sentinel-service8401-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..936964814675eb0757e57acf5372aeac61d1a098 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:30:39 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=cloudalibaba-sentinel-service8401 diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..64fc6cd05dfd75555d74e75680e49412c72ae2c1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,4 @@ +com\atguigu\springcloud\alibaba\MainApp8401.class +com\atguigu\springcloud\alibaba\myhandler\CustomerBlockHandler.class +com\atguigu\springcloud\alibaba\controller\FlowLimitController.class +com\atguigu\springcloud\alibaba\controller\RateLimitController.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..ed514608514b289ee37bfe27c432d9212b6531ce --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,4 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-sentinel-service8401\src\main\java\com\atguigu\springcloud\alibaba\controller\RateLimitController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-sentinel-service8401\src\main\java\com\atguigu\springcloud\alibaba\myhandler\CustomerBlockHandler.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-sentinel-service8401\src\main\java\com\atguigu\springcloud\alibaba\MainApp8401.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\cloudalibaba-sentinel-service8401\src\main\java\com\atguigu\springcloud\alibaba\controller\FlowLimitController.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/cloudalibaba-sentinel-service8401/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..eb30c7e5983c8e7cbee698c3b63d8b474ae036ab --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/pom.xml @@ -0,0 +1,134 @@ + + + + 4.0.0 + + com.atguigu.springcloud + cloud2020 + 1.0-SNAPSHOT + pom + + + cloud-consumer-order80 + cloud-api-commons + cloud-eureka-server7001 + cloud-eureka-server7002 + cloud-provider-payment8001 + cloud-provider-payment8002 + cloud-provider-payment8004 + cloud-consumerzk-order80 + cloud-providerconsul-payment8006 + cloud-consumerconsul-order80 + cloud-consumer-feign-order80 + cloud-provider-hystrix-payment8001 + cloud-consumer-feign-hystrix-order80 + cloud-consumer-hystrix-dashboard9001 + cloud-gateway-gateway9527 + cloud-config-center-3344 + cloud-config-client-3355 + cloud-config-client-3366 + cloud-stream-rabbitmq-provider8801 + cloud-stream-rabbitmq-consumer8802 + cloud-stream-rabbitmq-consumer8803 + cloudalibaba-provider-payment9001 + cloudalibaba-provider-payment9002 + cloudalibaba-consumer-nacos-order83 + cloudalibaba-config-nacos-client3377 + cloudalibaba-sentinel-service8401 + cloudalibaba-consumer-nacos-order84 + cloudalibaba-provider-payment9003 + cloudalibaba-provider-payment9004 + seata-order-service2001 + seata-storage-service2002 + seata-account-service2003 + + + + + UTF-8 + 1.8 + 1.8 + 4.12 + 1.2.17 + 1.16.18 + 5.1.47 + 1.1.16 + 1.3.0 + + + + + + + + org.springframework.boot + spring-boot-dependencies + 2.2.2.RELEASE + pom + import + + + + org.springframework.cloud + spring-cloud-dependencies + Hoxton.SR1 + pom + import + + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + 2.1.0.RELEASE + pom + import + + + mysql + mysql-connector-java + ${mysql.version} + + + com.alibaba + druid + ${druid.version} + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis.spring.boot.version} + + + junit + junit + ${junit.version} + + + log4j + log4j + ${log4j.version} + + + org.projectlombok + lombok + ${lombok.version} + true + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + true + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..e82e6cf3c917488c92e8d2433202f3f029d7101b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/pom.xml @@ -0,0 +1,73 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + seata-account-service2003 + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-seata + + + seata-all + io.seata + + + + + io.seata + seata-all + 0.9.0 + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.0.0 + + + mysql + mysql-connector-java + 5.1.37 + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + org.projectlombok + lombok + true + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/seata-account-service2003.iml b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/seata-account-service2003.iml new file mode 100644 index 0000000000000000000000000000000000000000..b8c521673d20e84d24ce398dd8ba804758756d91 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/seata-account-service2003.iml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/SeataAccountMainApp2003.java b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/SeataAccountMainApp2003.java new file mode 100644 index 0000000000000000000000000000000000000000..755e7aec3e684fc025ad6145e92409c292141059 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/SeataAccountMainApp2003.java @@ -0,0 +1,22 @@ +package com.atguigu.springcloud.alibaba; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; + +/** + * @auther zzyy + * @create 2019-12-13 21:59 + */ +@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) +@EnableDiscoveryClient +@EnableFeignClients +public class SeataAccountMainApp2003 +{ + public static void main(String[] args) + { + SpringApplication.run(SeataAccountMainApp2003.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.java b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..9e30ddfaa90283b7ef2f7150ca8e1e106dfd396f --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.java @@ -0,0 +1,47 @@ +package com.atguigu.springcloud.alibaba.config; + +import com.alibaba.druid.pool.DruidDataSource; +import io.seata.rm.datasource.DataSourceProxy; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.transaction.SpringManagedTransactionFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +import javax.sql.DataSource; + +/** + * @auther zzyy + * @create 2019-12-11 16:58 + * 使用Seata对数据源进行代理 + */ +@Configuration +public class DataSourceProxyConfig { + + @Value("${mybatis.mapperLocations}") + private String mapperLocations; + + @Bean + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource druidDataSource(){ + return new DruidDataSource(); + } + + @Bean + public DataSourceProxy dataSourceProxy(DataSource dataSource) { + return new DataSourceProxy(dataSource); + } + + @Bean + public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception { + SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); + sqlSessionFactoryBean.setDataSource(dataSourceProxy); + sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations)); + sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory()); + return sqlSessionFactoryBean.getObject(); + } + +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/config/MyBatisConfig.java b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/config/MyBatisConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..4a96321027ca85ecbf6d6a3490dda09f0a3079bf --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/config/MyBatisConfig.java @@ -0,0 +1,13 @@ +package com.atguigu.springcloud.alibaba.config; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Configuration; + +/** + * @auther zzyy + * @create 2019-12-11 16:57 + */ +@Configuration +@MapperScan({"com.atguigu.springcloud.alibaba.dao"}) +public class MyBatisConfig { +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/controller/AccountController.java b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/controller/AccountController.java new file mode 100644 index 0000000000000000000000000000000000000000..39581665768c57cfd597fe62d6ab2e496294c318 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/controller/AccountController.java @@ -0,0 +1,28 @@ +package com.atguigu.springcloud.alibaba.controller; + +import com.atguigu.springcloud.alibaba.domain.CommonResult ; +import com.atguigu.springcloud.alibaba.service.AccountService ; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.math.BigDecimal; + +@RestController +public class AccountController { + + @Resource + AccountService accountService; + + /** + * 扣减账户余额 + */ + @RequestMapping("/account/decrease") + public CommonResult decrease(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money){ + accountService.decrease(userId,money); + return new CommonResult(200,"扣减账户余额成功!"); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/dao/AccountDao.java b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/dao/AccountDao.java new file mode 100644 index 0000000000000000000000000000000000000000..cf8df0a69d997237ac1ebd6bf61a015030d695f2 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/dao/AccountDao.java @@ -0,0 +1,17 @@ +package com.atguigu.springcloud.alibaba.dao; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Repository; + +import java.math.BigDecimal; + +@Mapper +public interface AccountDao { + + /** + * 扣减账户余额 + */ + void decrease(@Param("userId") Long userId, @Param("money") BigDecimal money); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/domain/Account.java b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/domain/Account.java new file mode 100644 index 0000000000000000000000000000000000000000..303d9a4b100d7216be87c6f4ff326c98475964d5 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/domain/Account.java @@ -0,0 +1,35 @@ +package com.atguigu.springcloud.alibaba.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Account { + + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 总额度 + */ + private BigDecimal total; + + /** + * 已用额度 + */ + private BigDecimal used; + + /** + * 剩余额度 + */ + private BigDecimal residue; +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/domain/CommonResult.java b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/domain/CommonResult.java new file mode 100644 index 0000000000000000000000000000000000000000..48d3dbdf76b043164d90b94dcae5009019e58625 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/domain/CommonResult.java @@ -0,0 +1,24 @@ +package com.atguigu.springcloud.alibaba.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @auther zzyy + * @create 2019-12-11 16:41 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CommonResult +{ + private Integer code; + private String message; + private T data; + + public CommonResult(Integer code, String message) + { + this(code,message,null); + } +} \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/service/AccountService.java b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/service/AccountService.java new file mode 100644 index 0000000000000000000000000000000000000000..eb87faf7e3049e0bf8cee4e390b0afad34b955f8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/service/AccountService.java @@ -0,0 +1,17 @@ +package com.atguigu.springcloud.alibaba.service; + +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.math.BigDecimal; + + +public interface AccountService { + + /** + * 扣减账户余额 + * @param userId 用户id + * @param money 金额 + */ + void decrease(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/service/impl/AccountServiceImpl.java b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/service/impl/AccountServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..2522f57fc4a2fe7dbdd5c5087b2432cde09d1ccd --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/java/com/atguigu/springcloud/alibaba/service/impl/AccountServiceImpl.java @@ -0,0 +1,40 @@ +package com.atguigu.springcloud.alibaba.service.impl; + + +import com.atguigu.springcloud.alibaba.dao.AccountDao; +import com.atguigu.springcloud.alibaba.service.AccountService ; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.concurrent.TimeUnit; + +/** + * 账户业务实现类 + * Created by zzyy on 2019/11/11. + */ +@Service +public class AccountServiceImpl implements AccountService { + + private static final Logger LOGGER = LoggerFactory.getLogger(AccountServiceImpl.class); + + + @Resource + AccountDao accountDao; + + /** + * 扣减账户余额 + */ + @Override + public void decrease(Long userId, BigDecimal money) { + LOGGER.info("------->account-service中扣减账户余额开始"); + //模拟超时异常,全局事务回滚 + //暂停几秒钟线程 + try { TimeUnit.SECONDS.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } + accountDao.decrease(userId,money); + LOGGER.info("------->account-service中扣减账户余额结束"); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..cb16cea54c18cb7610e3324e8704478e9364f1e8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/resources/application.yml @@ -0,0 +1,32 @@ +server: + port: 2003 + +spring: + application: + name: seata-account-service + cloud: + alibaba: + seata: + tx-service-group: fsp_tx_group + nacos: + discovery: + server-addr: localhost:8848 + datasource: + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://localhost:3306/seata_account + username: root + password: root + +feign: + hystrix: + enabled: false + +logging: + level: + io: + seata: info + +mybatis: + mapperLocations: classpath:mapper/*.xml + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/resources/file.conf b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/resources/file.conf new file mode 100644 index 0000000000000000000000000000000000000000..9a6526f1dc85e00939ab7576cb259276bed14d2d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/resources/file.conf @@ -0,0 +1,142 @@ +transport { + # tcp udt unix-domain-socket + type = "TCP" + #NIO NATIVE + server = "NIO" + #enable heartbeat + heartbeat = true + #thread factory for netty + thread-factory { + boss-thread-prefix = "NettyBoss" + worker-thread-prefix = "NettyServerNIOWorker" + server-executor-thread-prefix = "NettyServerBizHandler" + share-boss-worker = false + client-selector-thread-prefix = "NettyClientSelector" + client-selector-thread-size = 1 + client-worker-thread-prefix = "NettyClientWorkerThread" + # netty boss thread size,will not be used for UDT + boss-thread-size = 1 + #auto default pin or 8 + worker-thread-size = 8 + } + shutdown { + # when destroy server, wait seconds + wait = 3 + } + serialization = "seata" + compressor = "none" +} + +service { + + vgroup_mapping.fsp_tx_group = "default" #修改自定义事务组名称 + + default.grouplist = "127.0.0.1:8091" + enableDegrade = false + disable = false + max.commit.retry.timeout = "-1" + max.rollback.retry.timeout = "-1" + disableGlobalTransaction = false +} + + +client { + async.commit.buffer.limit = 10000 + lock { + retry.internal = 10 + retry.times = 30 + } + report.retry.count = 5 + tm.commit.retry.count = 1 + tm.rollback.retry.count = 1 +} + +## transaction log store +store { + ## store mode: file、db + mode = "db" + + ## file store + file { + dir = "sessionStore" + + # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions + max-branch-session-size = 16384 + # globe session size , if exceeded throws exceptions + max-global-session-size = 512 + # file buffer size , if exceeded allocate new buffer + file-write-buffer-cache-size = 16384 + # when recover batch read size + session.reload.read_size = 100 + # async, sync + flush-disk-mode = async + } + + ## database store + db { + ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc. + datasource = "dbcp" + ## mysql/oracle/h2/oceanbase etc. + db-type = "mysql" + driver-class-name = "com.mysql.jdbc.Driver" + url = "jdbc:mysql://127.0.0.1:3306/seata" + user = "root" + password = "123456" + min-conn = 1 + max-conn = 3 + global.table = "global_table" + branch.table = "branch_table" + lock-table = "lock_table" + query-limit = 100 + } +} +lock { + ## the lock store mode: local、remote + mode = "remote" + + local { + ## store locks in user's database + } + + remote { + ## store locks in the seata's server + } +} +recovery { + #schedule committing retry period in milliseconds + committing-retry-period = 1000 + #schedule asyn committing retry period in milliseconds + asyn-committing-retry-period = 1000 + #schedule rollbacking retry period in milliseconds + rollbacking-retry-period = 1000 + #schedule timeout retry period in milliseconds + timeout-retry-period = 1000 +} + +transaction { + undo.data.validation = true + undo.log.serialization = "jackson" + undo.log.save.days = 7 + #schedule delete expired undo_log in milliseconds + undo.log.delete.period = 86400000 + undo.log.table = "undo_log" +} + +## metrics settings +metrics { + enabled = false + registry-type = "compact" + # multi exporters use comma divided + exporter-list = "prometheus" + exporter-prometheus-port = 9898 +} + +support { + ## spring + spring { + # auto proxy the DataSource bean + datasource.autoproxy = false + } +} + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/resources/mapper/AccountMapper.xml b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/resources/mapper/AccountMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..490633f1c2a20b34793c7541564644d6824a7f5c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/resources/mapper/AccountMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + UPDATE t_account + SET + residue = residue - #{money},used = used + #{money} + WHERE + user_id = #{userId}; + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/resources/registry.conf b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/resources/registry.conf new file mode 100644 index 0000000000000000000000000000000000000000..6d5fbaddbf9be01d588f36ab05afc0b8b79c3487 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/src/main/resources/registry.conf @@ -0,0 +1,76 @@ +registry { + # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa + type = "nacos" + + nacos { + serverAddr = "localhost:8848" + namespace = "" + cluster = "default" + } + eureka { + serviceUrl = "http://localhost:8761/eureka" + application = "default" + weight = "1" + } + redis { + serverAddr = "localhost:6379" + db = "0" + } + zk { + cluster = "default" + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + consul { + cluster = "default" + serverAddr = "127.0.0.1:8500" + } + etcd3 { + cluster = "default" + serverAddr = "http://localhost:2379" + } + sofa { + serverAddr = "127.0.0.1:9603" + application = "default" + region = "DEFAULT_ZONE" + datacenter = "DefaultDataCenter" + cluster = "default" + group = "SEATA_GROUP" + addressWaitTime = "3000" + } + file { + name = "file.conf" + } +} + +config { + # file、nacos 、apollo、zk、consul、etcd3 + type = "file" + + nacos { + serverAddr = "localhost" + namespace = "" + } + consul { + serverAddr = "127.0.0.1:8500" + } + apollo { + app.id = "seata-server" + apollo.meta = "http://192.168.1.204:8801" + } + zk { + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + etcd3 { + serverAddr = "http://localhost:2379" + } + file { + name = "file.conf" + } +} + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..cb16cea54c18cb7610e3324e8704478e9364f1e8 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/application.yml @@ -0,0 +1,32 @@ +server: + port: 2003 + +spring: + application: + name: seata-account-service + cloud: + alibaba: + seata: + tx-service-group: fsp_tx_group + nacos: + discovery: + server-addr: localhost:8848 + datasource: + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://localhost:3306/seata_account + username: root + password: root + +feign: + hystrix: + enabled: false + +logging: + level: + io: + seata: info + +mybatis: + mapperLocations: classpath:mapper/*.xml + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/SeataAccountMainApp2003.class b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/SeataAccountMainApp2003.class new file mode 100644 index 0000000000000000000000000000000000000000..e6aaa3b24dc123d34337bd0eb52acb295b3ade49 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/SeataAccountMainApp2003.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.class b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..196f748f297af9f579fabf72bbc93750f4927ef9 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/config/MyBatisConfig.class b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/config/MyBatisConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..49aa0e5e4810cc81315af9d5cd80aa055f74a6ad Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/config/MyBatisConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/controller/AccountController.class b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/controller/AccountController.class new file mode 100644 index 0000000000000000000000000000000000000000..c5a89b5a481d2850857952b61f7b09d1ee6859db Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/controller/AccountController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/dao/AccountDao.class b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/dao/AccountDao.class new file mode 100644 index 0000000000000000000000000000000000000000..0e16d0d9ba0edd4ba9e587e146fa9fd24f21cef1 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/dao/AccountDao.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/domain/Account.class b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/domain/Account.class new file mode 100644 index 0000000000000000000000000000000000000000..6a756bdc7e3ee4ae2d8d4ea6a7ff4c34208ffafd Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/domain/Account.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/domain/CommonResult.class b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/domain/CommonResult.class new file mode 100644 index 0000000000000000000000000000000000000000..a56c07ca0189c781124ab6a3995ac814aa4b42f3 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/domain/CommonResult.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/service/AccountService.class b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/service/AccountService.class new file mode 100644 index 0000000000000000000000000000000000000000..a1094084064ab1ec84b585d98871bd76de8f1d17 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/service/AccountService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/service/impl/AccountServiceImpl.class b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/service/impl/AccountServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..93e4861f796df39f92310f1244611da1006ba48b Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/com/atguigu/springcloud/alibaba/service/impl/AccountServiceImpl.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/file.conf b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/file.conf new file mode 100644 index 0000000000000000000000000000000000000000..9a6526f1dc85e00939ab7576cb259276bed14d2d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/file.conf @@ -0,0 +1,142 @@ +transport { + # tcp udt unix-domain-socket + type = "TCP" + #NIO NATIVE + server = "NIO" + #enable heartbeat + heartbeat = true + #thread factory for netty + thread-factory { + boss-thread-prefix = "NettyBoss" + worker-thread-prefix = "NettyServerNIOWorker" + server-executor-thread-prefix = "NettyServerBizHandler" + share-boss-worker = false + client-selector-thread-prefix = "NettyClientSelector" + client-selector-thread-size = 1 + client-worker-thread-prefix = "NettyClientWorkerThread" + # netty boss thread size,will not be used for UDT + boss-thread-size = 1 + #auto default pin or 8 + worker-thread-size = 8 + } + shutdown { + # when destroy server, wait seconds + wait = 3 + } + serialization = "seata" + compressor = "none" +} + +service { + + vgroup_mapping.fsp_tx_group = "default" #修改自定义事务组名称 + + default.grouplist = "127.0.0.1:8091" + enableDegrade = false + disable = false + max.commit.retry.timeout = "-1" + max.rollback.retry.timeout = "-1" + disableGlobalTransaction = false +} + + +client { + async.commit.buffer.limit = 10000 + lock { + retry.internal = 10 + retry.times = 30 + } + report.retry.count = 5 + tm.commit.retry.count = 1 + tm.rollback.retry.count = 1 +} + +## transaction log store +store { + ## store mode: file、db + mode = "db" + + ## file store + file { + dir = "sessionStore" + + # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions + max-branch-session-size = 16384 + # globe session size , if exceeded throws exceptions + max-global-session-size = 512 + # file buffer size , if exceeded allocate new buffer + file-write-buffer-cache-size = 16384 + # when recover batch read size + session.reload.read_size = 100 + # async, sync + flush-disk-mode = async + } + + ## database store + db { + ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc. + datasource = "dbcp" + ## mysql/oracle/h2/oceanbase etc. + db-type = "mysql" + driver-class-name = "com.mysql.jdbc.Driver" + url = "jdbc:mysql://127.0.0.1:3306/seata" + user = "root" + password = "123456" + min-conn = 1 + max-conn = 3 + global.table = "global_table" + branch.table = "branch_table" + lock-table = "lock_table" + query-limit = 100 + } +} +lock { + ## the lock store mode: local、remote + mode = "remote" + + local { + ## store locks in user's database + } + + remote { + ## store locks in the seata's server + } +} +recovery { + #schedule committing retry period in milliseconds + committing-retry-period = 1000 + #schedule asyn committing retry period in milliseconds + asyn-committing-retry-period = 1000 + #schedule rollbacking retry period in milliseconds + rollbacking-retry-period = 1000 + #schedule timeout retry period in milliseconds + timeout-retry-period = 1000 +} + +transaction { + undo.data.validation = true + undo.log.serialization = "jackson" + undo.log.save.days = 7 + #schedule delete expired undo_log in milliseconds + undo.log.delete.period = 86400000 + undo.log.table = "undo_log" +} + +## metrics settings +metrics { + enabled = false + registry-type = "compact" + # multi exporters use comma divided + exporter-list = "prometheus" + exporter-prometheus-port = 9898 +} + +support { + ## spring + spring { + # auto proxy the DataSource bean + datasource.autoproxy = false + } +} + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/mapper/AccountMapper.xml b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/mapper/AccountMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..490633f1c2a20b34793c7541564644d6824a7f5c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/mapper/AccountMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + UPDATE t_account + SET + residue = residue - #{money},used = used + #{money} + WHERE + user_id = #{userId}; + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/registry.conf b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/registry.conf new file mode 100644 index 0000000000000000000000000000000000000000..6d5fbaddbf9be01d588f36ab05afc0b8b79c3487 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/classes/registry.conf @@ -0,0 +1,76 @@ +registry { + # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa + type = "nacos" + + nacos { + serverAddr = "localhost:8848" + namespace = "" + cluster = "default" + } + eureka { + serviceUrl = "http://localhost:8761/eureka" + application = "default" + weight = "1" + } + redis { + serverAddr = "localhost:6379" + db = "0" + } + zk { + cluster = "default" + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + consul { + cluster = "default" + serverAddr = "127.0.0.1:8500" + } + etcd3 { + cluster = "default" + serverAddr = "http://localhost:2379" + } + sofa { + serverAddr = "127.0.0.1:9603" + application = "default" + region = "DEFAULT_ZONE" + datacenter = "DefaultDataCenter" + cluster = "default" + group = "SEATA_GROUP" + addressWaitTime = "3000" + } + file { + name = "file.conf" + } +} + +config { + # file、nacos 、apollo、zk、consul、etcd3 + type = "file" + + nacos { + serverAddr = "localhost" + namespace = "" + } + consul { + serverAddr = "127.0.0.1:8500" + } + apollo { + app.id = "seata-server" + apollo.meta = "http://192.168.1.204:8801" + } + zk { + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + etcd3 { + serverAddr = "http://localhost:2379" + } + file { + name = "file.conf" + } +} + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..c7e80bd9829005744c736b628c06f433b83005cc --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:31:12 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=seata-account-service2003 diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..cd048f5f690dadc15291f2d3ecbd92b29a3d2c59 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,9 @@ +com\atguigu\springcloud\alibaba\controller\AccountController.class +com\atguigu\springcloud\alibaba\service\impl\AccountServiceImpl.class +com\atguigu\springcloud\alibaba\SeataAccountMainApp2003.class +com\atguigu\springcloud\alibaba\domain\CommonResult.class +com\atguigu\springcloud\alibaba\config\MyBatisConfig.class +com\atguigu\springcloud\alibaba\domain\Account.class +com\atguigu\springcloud\alibaba\service\AccountService.class +com\atguigu\springcloud\alibaba\dao\AccountDao.class +com\atguigu\springcloud\alibaba\config\DataSourceProxyConfig.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..d89a0ec7210ba9d5779fb8f7ed0722fca3b8df56 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,9 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-account-service2003\src\main\java\com\atguigu\springcloud\alibaba\service\AccountService.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-account-service2003\src\main\java\com\atguigu\springcloud\alibaba\dao\AccountDao.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-account-service2003\src\main\java\com\atguigu\springcloud\alibaba\domain\Account.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-account-service2003\src\main\java\com\atguigu\springcloud\alibaba\domain\CommonResult.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-account-service2003\src\main\java\com\atguigu\springcloud\alibaba\controller\AccountController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-account-service2003\src\main\java\com\atguigu\springcloud\alibaba\service\impl\AccountServiceImpl.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-account-service2003\src\main\java\com\atguigu\springcloud\alibaba\config\DataSourceProxyConfig.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-account-service2003\src\main\java\com\atguigu\springcloud\alibaba\config\MyBatisConfig.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-account-service2003\src\main\java\com\atguigu\springcloud\alibaba\SeataAccountMainApp2003.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/seata-account-service2003-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/seata-account-service2003-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..e0e4627975bc6dda00ebcb86c694d40627d6e744 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-account-service2003/target/seata-account-service2003-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..9608d81af1ff1cde6ec26d7d11cc87cac43a2f45 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/pom.xml @@ -0,0 +1,81 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + seata-order-service2001 + + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-seata + + + seata-all + io.seata + + + + + io.seata + seata-all + 0.9.0 + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + + mysql + mysql-connector-java + 5.1.37 + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.0.0 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + true + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/seata-order-service2001.iml b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/seata-order-service2001.iml new file mode 100644 index 0000000000000000000000000000000000000000..8dfaf3e5dcc086093d04940fb2b7eb0e19ba9ca9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/seata-order-service2001.iml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/SeataOrderMainApp2001.java b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/SeataOrderMainApp2001.java new file mode 100644 index 0000000000000000000000000000000000000000..7c8386f7787090a6b04689252f65f33e1227f3aa --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/SeataOrderMainApp2001.java @@ -0,0 +1,23 @@ +package com.atguigu.springcloud.alibaba; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; + +/** + * @auther zzyy + * @create 2020-02-26 15:15 + */ +@EnableDiscoveryClient +@EnableFeignClients +@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//取消数据源的自动创建 +public class SeataOrderMainApp2001 +{ + + public static void main(String[] args) + { + SpringApplication.run(SeataOrderMainApp2001.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.java b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..c770cf36422e643a4b166cbce58f50e82b3beef0 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.java @@ -0,0 +1,46 @@ +package com.atguigu.springcloud.alibaba.config; + +import com.alibaba.druid.pool.DruidDataSource; +import io.seata.rm.datasource.DataSourceProxy; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.transaction.SpringManagedTransactionFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import javax.sql.DataSource; + +/** + * @auther zzyy + * @create 2019-12-11 16:58 + * 使用Seata对数据源进行代理 + */ +@Configuration +public class DataSourceProxyConfig { + + @Value("${mybatis.mapperLocations}") + private String mapperLocations; + + @Bean + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource druidDataSource(){ + return new DruidDataSource(); + } + + @Bean + public DataSourceProxy dataSourceProxy(DataSource dataSource) { + return new DataSourceProxy(dataSource); + } + + @Bean + public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception { + SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); + sqlSessionFactoryBean.setDataSource(dataSourceProxy); + sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations)); + sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory()); + return sqlSessionFactoryBean.getObject(); + } + +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/config/MyBatisConfig.java b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/config/MyBatisConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..4a96321027ca85ecbf6d6a3490dda09f0a3079bf --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/config/MyBatisConfig.java @@ -0,0 +1,13 @@ +package com.atguigu.springcloud.alibaba.config; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Configuration; + +/** + * @auther zzyy + * @create 2019-12-11 16:57 + */ +@Configuration +@MapperScan({"com.atguigu.springcloud.alibaba.dao"}) +public class MyBatisConfig { +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/controller/OrderController.java b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/controller/OrderController.java new file mode 100644 index 0000000000000000000000000000000000000000..abaae7c908395e81bebe3dcfd268182abc3e934b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/controller/OrderController.java @@ -0,0 +1,28 @@ +package com.atguigu.springcloud.alibaba.controller; + +import com.atguigu.springcloud.alibaba.domain.CommonResult; +import com.atguigu.springcloud.alibaba.domain.Order; +import com.atguigu.springcloud.alibaba.service.OrderService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-26 15:24 + */ +@RestController +public class OrderController +{ + @Resource + private OrderService orderService; + + + @GetMapping("/order/create") + public CommonResult create(Order order) + { + orderService.create(order); + return new CommonResult(200,"订单创建成功"); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/dao/OrderDao.java b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/dao/OrderDao.java new file mode 100644 index 0000000000000000000000000000000000000000..0c761202cdbf9e25e95902c271d0db8d8ead7d51 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/dao/OrderDao.java @@ -0,0 +1,19 @@ +package com.atguigu.springcloud.alibaba.dao; + +import com.atguigu.springcloud.alibaba.domain.Order; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * @auther zzyy + * @create 2020-02-26 15:17 + */ +@Mapper +public interface OrderDao +{ + //1 新建订单 + void create(Order order); + + //2 修改订单状态,从零改为1 + void update(@Param("userId") Long userId,@Param("status") Integer status); +} \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/domain/CommonResult.java b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/domain/CommonResult.java new file mode 100644 index 0000000000000000000000000000000000000000..08054f5f273136b6f3de98bc1807a1dde8ce6eba --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/domain/CommonResult.java @@ -0,0 +1,24 @@ +package com.atguigu.springcloud.alibaba.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @auther zzyy + * @create 2020-02-26 15:16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CommonResult +{ + private Integer code; + private String message; + private T data; + + public CommonResult(Integer code, String message) + { + this(code,message,null); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/domain/Order.java b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/domain/Order.java new file mode 100644 index 0000000000000000000000000000000000000000..78ac46712caf813250f16cd623344dfe36484c44 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/domain/Order.java @@ -0,0 +1,29 @@ +package com.atguigu.springcloud.alibaba.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * @auther zzyy + * @create 2020-02-26 15:16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Order +{ + private Long id; + + private Long userId; + + private Long productId; + + private Integer count; + + private BigDecimal money; + + private Integer status; //订单状态:0:创建中;1:已完结 +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/service/AccountService.java b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/service/AccountService.java new file mode 100644 index 0000000000000000000000000000000000000000..927f22fe405e4cde9487dbc983808447956acbde --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/service/AccountService.java @@ -0,0 +1,19 @@ +package com.atguigu.springcloud.alibaba.service; + +import com.atguigu.springcloud.alibaba.domain.CommonResult; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.math.BigDecimal; + +/** + * @auther zzyy + * @create 2020-02-26 15:22 + */ +@FeignClient(value = "seata-account-service") +public interface AccountService +{ + @PostMapping(value = "/account/decrease") + CommonResult decrease(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/service/OrderService.java b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/service/OrderService.java new file mode 100644 index 0000000000000000000000000000000000000000..004d07c346edbfc0f031f481d4ab749e38a46ad6 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/service/OrderService.java @@ -0,0 +1,12 @@ +package com.atguigu.springcloud.alibaba.service; + +import com.atguigu.springcloud.alibaba.domain.Order; + +/** + * @auther zzyy + * @create 2020-02-26 15:19 + */ +public interface OrderService +{ + void create(Order order); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/service/StorageService.java b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/service/StorageService.java new file mode 100644 index 0000000000000000000000000000000000000000..217e9bccdc3a72c43746a19494178c1b992ab775 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/service/StorageService.java @@ -0,0 +1,19 @@ +package com.atguigu.springcloud.alibaba.service; + +import com.atguigu.springcloud.alibaba.domain.CommonResult; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.math.BigDecimal; + +/** + * @auther zzyy + * @create 2020-02-26 15:22 + */ +@FeignClient(value = "seata-storage-service") +public interface StorageService +{ + @PostMapping(value = "/storage/decrease") + CommonResult decrease(@RequestParam("productId") Long productId, @RequestParam("count") Integer count); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/service/impl/OrderServiceImpl.java b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/service/impl/OrderServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..a136c885ef6231a7592778b1f760bdaa4b94e3ae --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/java/com/atguigu/springcloud/alibaba/service/impl/OrderServiceImpl.java @@ -0,0 +1,59 @@ +package com.atguigu.springcloud.alibaba.service.impl; + +import com.atguigu.springcloud.alibaba.dao.OrderDao; +import com.atguigu.springcloud.alibaba.domain.Order; +import com.atguigu.springcloud.alibaba.service.AccountService; +import com.atguigu.springcloud.alibaba.service.OrderService; +import com.atguigu.springcloud.alibaba.service.StorageService; +import io.seata.spring.annotation.GlobalTransactional; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * @auther zzyy + * @create 2020-02-26 15:20 + */ +@Service +@Slf4j +public class OrderServiceImpl implements OrderService +{ + @Resource + private OrderDao orderDao; + @Resource + private StorageService storageService; + @Resource + private AccountService accountService; + + /** + * 创建订单->调用库存服务扣减库存->调用账户服务扣减账户余额->修改订单状态 + * 简单说:下订单->扣库存->减余额->改状态 + */ + @Override + @GlobalTransactional(name = "fsp-create-order",rollbackFor = Exception.class) + public void create(Order order) + { + log.info("----->开始新建订单"); + //1 新建订单 + orderDao.create(order); + + //2 扣减库存 + log.info("----->订单微服务开始调用库存,做扣减Count"); + storageService.decrease(order.getProductId(),order.getCount()); + log.info("----->订单微服务开始调用库存,做扣减end"); + + //3 扣减账户 + log.info("----->订单微服务开始调用账户,做扣减Money"); + accountService.decrease(order.getUserId(),order.getMoney()); + log.info("----->订单微服务开始调用账户,做扣减end"); + + //4 修改订单状态,从零到1,1代表已经完成 + log.info("----->修改订单状态开始"); + orderDao.update(order.getUserId(),0); + log.info("----->修改订单状态结束"); + + log.info("----->下订单结束了,O(∩_∩)O哈哈~"); + + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..a353cc1f8ca0a52ddd31624abd102f9f470e52d9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/resources/application.yml @@ -0,0 +1,31 @@ +server: + port: 2001 + +spring: + application: + name: seata-order-service + cloud: + alibaba: + seata: + #自定义事务组名称需要与seata-server中的对应 + tx-service-group: fsp_tx_group + nacos: + discovery: + server-addr: localhost:8848 + datasource: + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://localhost:3306/seata_order + username: root + password: root + +feign: + hystrix: + enabled: false + +logging: + level: + io: + seata: info + +mybatis: + mapperLocations: classpath:mapper/*.xml \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/resources/file.conf b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/resources/file.conf new file mode 100644 index 0000000000000000000000000000000000000000..7666fd55ae20db66aa2ae32feac3dfc0eff08800 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/resources/file.conf @@ -0,0 +1,141 @@ +transport { + # tcp udt unix-domain-socket + type = "TCP" + #NIO NATIVE + server = "NIO" + #enable heartbeat + heartbeat = true + #thread factory for netty + thread-factory { + boss-thread-prefix = "NettyBoss" + worker-thread-prefix = "NettyServerNIOWorker" + server-executor-thread-prefix = "NettyServerBizHandler" + share-boss-worker = false + client-selector-thread-prefix = "NettyClientSelector" + client-selector-thread-size = 1 + client-worker-thread-prefix = "NettyClientWorkerThread" + # netty boss thread size,will not be used for UDT + boss-thread-size = 1 + #auto default pin or 8 + worker-thread-size = 8 + } + shutdown { + # when destroy server, wait seconds + wait = 3 + } + serialization = "seata" + compressor = "none" +} + +service { + + vgroup_mapping.fsp_tx_group = "default" #修改自定义事务组名称 + + default.grouplist = "127.0.0.1:8091" + enableDegrade = false + disable = false + max.commit.retry.timeout = "-1" + max.rollback.retry.timeout = "-1" + disableGlobalTransaction = false +} + + +client { + async.commit.buffer.limit = 10000 + lock { + retry.internal = 10 + retry.times = 30 + } + report.retry.count = 5 + tm.commit.retry.count = 1 + tm.rollback.retry.count = 1 +} + +## transaction log store +store { + ## store mode: file、db + mode = "db" + + ## file store + file { + dir = "sessionStore" + + # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions + max-branch-session-size = 16384 + # globe session size , if exceeded throws exceptions + max-global-session-size = 512 + # file buffer size , if exceeded allocate new buffer + file-write-buffer-cache-size = 16384 + # when recover batch read size + session.reload.read_size = 100 + # async, sync + flush-disk-mode = async + } + + ## database store + db { + ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc. + datasource = "dbcp" + ## mysql/oracle/h2/oceanbase etc. + db-type = "mysql" + driver-class-name = "com.mysql.jdbc.Driver" + url = "jdbc:mysql://127.0.0.1:3306/seata" + user = "root" + password = "123456" + min-conn = 1 + max-conn = 3 + global.table = "global_table" + branch.table = "branch_table" + lock-table = "lock_table" + query-limit = 100 + } +} +lock { + ## the lock store mode: local、remote + mode = "remote" + + local { + ## store locks in user's database + } + + remote { + ## store locks in the seata's server + } +} +recovery { + #schedule committing retry period in milliseconds + committing-retry-period = 1000 + #schedule asyn committing retry period in milliseconds + asyn-committing-retry-period = 1000 + #schedule rollbacking retry period in milliseconds + rollbacking-retry-period = 1000 + #schedule timeout retry period in milliseconds + timeout-retry-period = 1000 +} + +transaction { + undo.data.validation = true + undo.log.serialization = "jackson" + undo.log.save.days = 7 + #schedule delete expired undo_log in milliseconds + undo.log.delete.period = 86400000 + undo.log.table = "undo_log" +} + +## metrics settings +metrics { + enabled = false + registry-type = "compact" + # multi exporters use comma divided + exporter-list = "prometheus" + exporter-prometheus-port = 9898 +} + +support { + ## spring + spring { + # auto proxy the DataSource bean + datasource.autoproxy = false + } +} + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/resources/mapper/OrderMapper.xml b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/resources/mapper/OrderMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..a7be9aff7b3e2238387997f1b90f076d9864abf4 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/resources/mapper/OrderMapper.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + insert into t_order (id,user_id,product_id,count,money,status) + values (null,#{userId},#{productId},#{count},#{money},0); + + + + + update t_order set status = 1 + where user_id=#{userId} and status = #{status}; + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/resources/registry.conf b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/resources/registry.conf new file mode 100644 index 0000000000000000000000000000000000000000..38edd4a39058a3f2885ca64a297d6c8facc66e4b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/src/main/resources/registry.conf @@ -0,0 +1,75 @@ +registry { + # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa + type = "nacos" + + nacos { + serverAddr = "localhost:8848" + namespace = "" + cluster = "default" + } + eureka { + serviceUrl = "http://localhost:8761/eureka" + application = "default" + weight = "1" + } + redis { + serverAddr = "localhost:6379" + db = "0" + } + zk { + cluster = "default" + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + consul { + cluster = "default" + serverAddr = "127.0.0.1:8500" + } + etcd3 { + cluster = "default" + serverAddr = "http://localhost:2379" + } + sofa { + serverAddr = "127.0.0.1:9603" + application = "default" + region = "DEFAULT_ZONE" + datacenter = "DefaultDataCenter" + cluster = "default" + group = "SEATA_GROUP" + addressWaitTime = "3000" + } + file { + name = "file.conf" + } +} + +config { + # file、nacos 、apollo、zk、consul、etcd3 + type = "file" + + nacos { + serverAddr = "localhost" + namespace = "" + } + consul { + serverAddr = "127.0.0.1:8500" + } + apollo { + app.id = "seata-server" + apollo.meta = "http://192.168.1.204:8801" + } + zk { + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + etcd3 { + serverAddr = "http://localhost:2379" + } + file { + name = "file.conf" + } +} + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..a353cc1f8ca0a52ddd31624abd102f9f470e52d9 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/application.yml @@ -0,0 +1,31 @@ +server: + port: 2001 + +spring: + application: + name: seata-order-service + cloud: + alibaba: + seata: + #自定义事务组名称需要与seata-server中的对应 + tx-service-group: fsp_tx_group + nacos: + discovery: + server-addr: localhost:8848 + datasource: + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://localhost:3306/seata_order + username: root + password: root + +feign: + hystrix: + enabled: false + +logging: + level: + io: + seata: info + +mybatis: + mapperLocations: classpath:mapper/*.xml \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/SeataOrderMainApp2001.class b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/SeataOrderMainApp2001.class new file mode 100644 index 0000000000000000000000000000000000000000..aed42535a20c71555227dc8e6c0c4d19b99e0db1 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/SeataOrderMainApp2001.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.class b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..19368a155ee6f9dd6e7d7007a947d0e35366a806 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/config/MyBatisConfig.class b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/config/MyBatisConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..49aa0e5e4810cc81315af9d5cd80aa055f74a6ad Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/config/MyBatisConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/controller/OrderController.class b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/controller/OrderController.class new file mode 100644 index 0000000000000000000000000000000000000000..834d909ee199a15ad5b9471dcd2575dedfc6285d Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/controller/OrderController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/dao/OrderDao.class b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/dao/OrderDao.class new file mode 100644 index 0000000000000000000000000000000000000000..113ba80d150793d3bacea50f2de6eee5453192f6 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/dao/OrderDao.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/domain/CommonResult.class b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/domain/CommonResult.class new file mode 100644 index 0000000000000000000000000000000000000000..a56c07ca0189c781124ab6a3995ac814aa4b42f3 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/domain/CommonResult.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/domain/Order.class b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/domain/Order.class new file mode 100644 index 0000000000000000000000000000000000000000..3bc16a4dd3ef133a205007e96147f351c3721ee9 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/domain/Order.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/service/AccountService.class b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/service/AccountService.class new file mode 100644 index 0000000000000000000000000000000000000000..b45778a99c67e8e1ffa2746735c1b59fe26ee524 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/service/AccountService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/service/OrderService.class b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/service/OrderService.class new file mode 100644 index 0000000000000000000000000000000000000000..932848a92fdee3543789e98d17e71799620552c4 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/service/OrderService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/service/StorageService.class b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/service/StorageService.class new file mode 100644 index 0000000000000000000000000000000000000000..a8a6c7bdcf257a2a663287c92973b7f55c726984 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/service/StorageService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/service/impl/OrderServiceImpl.class b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/service/impl/OrderServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..4818ba82c2441365fcdb2e49909d902c85bac5ea Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/com/atguigu/springcloud/alibaba/service/impl/OrderServiceImpl.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/file.conf b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/file.conf new file mode 100644 index 0000000000000000000000000000000000000000..7666fd55ae20db66aa2ae32feac3dfc0eff08800 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/file.conf @@ -0,0 +1,141 @@ +transport { + # tcp udt unix-domain-socket + type = "TCP" + #NIO NATIVE + server = "NIO" + #enable heartbeat + heartbeat = true + #thread factory for netty + thread-factory { + boss-thread-prefix = "NettyBoss" + worker-thread-prefix = "NettyServerNIOWorker" + server-executor-thread-prefix = "NettyServerBizHandler" + share-boss-worker = false + client-selector-thread-prefix = "NettyClientSelector" + client-selector-thread-size = 1 + client-worker-thread-prefix = "NettyClientWorkerThread" + # netty boss thread size,will not be used for UDT + boss-thread-size = 1 + #auto default pin or 8 + worker-thread-size = 8 + } + shutdown { + # when destroy server, wait seconds + wait = 3 + } + serialization = "seata" + compressor = "none" +} + +service { + + vgroup_mapping.fsp_tx_group = "default" #修改自定义事务组名称 + + default.grouplist = "127.0.0.1:8091" + enableDegrade = false + disable = false + max.commit.retry.timeout = "-1" + max.rollback.retry.timeout = "-1" + disableGlobalTransaction = false +} + + +client { + async.commit.buffer.limit = 10000 + lock { + retry.internal = 10 + retry.times = 30 + } + report.retry.count = 5 + tm.commit.retry.count = 1 + tm.rollback.retry.count = 1 +} + +## transaction log store +store { + ## store mode: file、db + mode = "db" + + ## file store + file { + dir = "sessionStore" + + # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions + max-branch-session-size = 16384 + # globe session size , if exceeded throws exceptions + max-global-session-size = 512 + # file buffer size , if exceeded allocate new buffer + file-write-buffer-cache-size = 16384 + # when recover batch read size + session.reload.read_size = 100 + # async, sync + flush-disk-mode = async + } + + ## database store + db { + ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc. + datasource = "dbcp" + ## mysql/oracle/h2/oceanbase etc. + db-type = "mysql" + driver-class-name = "com.mysql.jdbc.Driver" + url = "jdbc:mysql://127.0.0.1:3306/seata" + user = "root" + password = "123456" + min-conn = 1 + max-conn = 3 + global.table = "global_table" + branch.table = "branch_table" + lock-table = "lock_table" + query-limit = 100 + } +} +lock { + ## the lock store mode: local、remote + mode = "remote" + + local { + ## store locks in user's database + } + + remote { + ## store locks in the seata's server + } +} +recovery { + #schedule committing retry period in milliseconds + committing-retry-period = 1000 + #schedule asyn committing retry period in milliseconds + asyn-committing-retry-period = 1000 + #schedule rollbacking retry period in milliseconds + rollbacking-retry-period = 1000 + #schedule timeout retry period in milliseconds + timeout-retry-period = 1000 +} + +transaction { + undo.data.validation = true + undo.log.serialization = "jackson" + undo.log.save.days = 7 + #schedule delete expired undo_log in milliseconds + undo.log.delete.period = 86400000 + undo.log.table = "undo_log" +} + +## metrics settings +metrics { + enabled = false + registry-type = "compact" + # multi exporters use comma divided + exporter-list = "prometheus" + exporter-prometheus-port = 9898 +} + +support { + ## spring + spring { + # auto proxy the DataSource bean + datasource.autoproxy = false + } +} + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/mapper/OrderMapper.xml b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/mapper/OrderMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..a7be9aff7b3e2238387997f1b90f076d9864abf4 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/mapper/OrderMapper.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + insert into t_order (id,user_id,product_id,count,money,status) + values (null,#{userId},#{productId},#{count},#{money},0); + + + + + update t_order set status = 1 + where user_id=#{userId} and status = #{status}; + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/registry.conf b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/registry.conf new file mode 100644 index 0000000000000000000000000000000000000000..38edd4a39058a3f2885ca64a297d6c8facc66e4b --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/classes/registry.conf @@ -0,0 +1,75 @@ +registry { + # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa + type = "nacos" + + nacos { + serverAddr = "localhost:8848" + namespace = "" + cluster = "default" + } + eureka { + serviceUrl = "http://localhost:8761/eureka" + application = "default" + weight = "1" + } + redis { + serverAddr = "localhost:6379" + db = "0" + } + zk { + cluster = "default" + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + consul { + cluster = "default" + serverAddr = "127.0.0.1:8500" + } + etcd3 { + cluster = "default" + serverAddr = "http://localhost:2379" + } + sofa { + serverAddr = "127.0.0.1:9603" + application = "default" + region = "DEFAULT_ZONE" + datacenter = "DefaultDataCenter" + cluster = "default" + group = "SEATA_GROUP" + addressWaitTime = "3000" + } + file { + name = "file.conf" + } +} + +config { + # file、nacos 、apollo、zk、consul、etcd3 + type = "file" + + nacos { + serverAddr = "localhost" + namespace = "" + } + consul { + serverAddr = "127.0.0.1:8500" + } + apollo { + app.id = "seata-server" + apollo.meta = "http://192.168.1.204:8801" + } + zk { + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + etcd3 { + serverAddr = "http://localhost:2379" + } + file { + name = "file.conf" + } +} + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..0e9f745ced9e8be2608771bef0f0deefd11ab7af --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:31:08 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=seata-order-service2001 diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..2f4d523d7dbe8c9c3b8c19a1fcc17510e7c15de3 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,11 @@ +com\atguigu\springcloud\alibaba\service\OrderService.class +com\atguigu\springcloud\alibaba\domain\CommonResult.class +com\atguigu\springcloud\alibaba\config\MyBatisConfig.class +com\atguigu\springcloud\alibaba\SeataOrderMainApp2001.class +com\atguigu\springcloud\alibaba\service\impl\OrderServiceImpl.class +com\atguigu\springcloud\alibaba\controller\OrderController.class +com\atguigu\springcloud\alibaba\domain\Order.class +com\atguigu\springcloud\alibaba\service\AccountService.class +com\atguigu\springcloud\alibaba\service\StorageService.class +com\atguigu\springcloud\alibaba\config\DataSourceProxyConfig.class +com\atguigu\springcloud\alibaba\dao\OrderDao.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..7d8a2cb77e6c17c5da1bbb263cfa4326d3a75e40 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,11 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-order-service2001\src\main\java\com\atguigu\springcloud\alibaba\service\OrderService.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-order-service2001\src\main\java\com\atguigu\springcloud\alibaba\controller\OrderController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-order-service2001\src\main\java\com\atguigu\springcloud\alibaba\dao\OrderDao.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-order-service2001\src\main\java\com\atguigu\springcloud\alibaba\service\impl\OrderServiceImpl.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-order-service2001\src\main\java\com\atguigu\springcloud\alibaba\service\StorageService.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-order-service2001\src\main\java\com\atguigu\springcloud\alibaba\domain\CommonResult.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-order-service2001\src\main\java\com\atguigu\springcloud\alibaba\config\DataSourceProxyConfig.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-order-service2001\src\main\java\com\atguigu\springcloud\alibaba\SeataOrderMainApp2001.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-order-service2001\src\main\java\com\atguigu\springcloud\alibaba\service\AccountService.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-order-service2001\src\main\java\com\atguigu\springcloud\alibaba\config\MyBatisConfig.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-order-service2001\src\main\java\com\atguigu\springcloud\alibaba\domain\Order.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/seata-order-service2001-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/seata-order-service2001-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..378dec9e2c03f0c069ceba8d7d5f7cb325293a29 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-order-service2001/target/seata-order-service2001-1.0-SNAPSHOT.jar differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/pom.xml b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..7a79764a4f8b07743897442362ea25d367b85846 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/pom.xml @@ -0,0 +1,75 @@ + + + + cloud2020 + com.atguigu.springcloud + 1.0-SNAPSHOT + + 4.0.0 + + seata-storage-service2002 + + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-seata + + + seata-all + io.seata + + + + + io.seata + seata-all + 0.9.0 + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.0.0 + + + mysql + mysql-connector-java + 5.1.37 + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + org.projectlombok + lombok + true + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/seata-storage-service2002.iml b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/seata-storage-service2002.iml new file mode 100644 index 0000000000000000000000000000000000000000..b8c521673d20e84d24ce398dd8ba804758756d91 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/seata-storage-service2002.iml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + file://$MODULE_DIR$/src/main/resources/application.yml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/SeataStorageServiceApplication2002.java b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/SeataStorageServiceApplication2002.java new file mode 100644 index 0000000000000000000000000000000000000000..0349b7e29370129e06f167f7024ccb77d0b5ec3d --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/SeataStorageServiceApplication2002.java @@ -0,0 +1,27 @@ +package com.atguigu.springcloud.alibaba; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ForkJoinWorkerThread; + +/** + * @auther zzyy + * @create 2019-12-12 17:31 + */ +@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) +@EnableDiscoveryClient +@EnableFeignClients +public class SeataStorageServiceApplication2002 +{ + public static void main(String[] args) + { + SpringApplication.run(SeataStorageServiceApplication2002.class, args); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.java b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..51cb1f0f479349261d189fa18a4410f36f65d395 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.java @@ -0,0 +1,47 @@ +package com.atguigu.springcloud.alibaba.config; + +import com.alibaba.druid.pool.DruidDataSource; +import io.seata.rm.datasource.DataSourceProxy; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.transaction.SpringManagedTransactionFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +import javax.sql.DataSource; + +/** + * @auther zzyy + * @create 2020-02-26 16:24 + * 使用Seata对数据源进行代理 + */ +@Configuration +public class DataSourceProxyConfig { + + @Value("${mybatis.mapperLocations}") + private String mapperLocations; + + @Bean + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource druidDataSource(){ + return new DruidDataSource(); + } + + @Bean + public DataSourceProxy dataSourceProxy(DataSource dataSource) { + return new DataSourceProxy(dataSource); + } + + @Bean + public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception { + SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); + sqlSessionFactoryBean.setDataSource(dataSourceProxy); + sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations)); + sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory()); + return sqlSessionFactoryBean.getObject(); + } + +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/config/MyBatisConfig.java b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/config/MyBatisConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..4a96321027ca85ecbf6d6a3490dda09f0a3079bf --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/config/MyBatisConfig.java @@ -0,0 +1,13 @@ +package com.atguigu.springcloud.alibaba.config; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Configuration; + +/** + * @auther zzyy + * @create 2019-12-11 16:57 + */ +@Configuration +@MapperScan({"com.atguigu.springcloud.alibaba.dao"}) +public class MyBatisConfig { +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/controller/StorageController.java b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/controller/StorageController.java new file mode 100644 index 0000000000000000000000000000000000000000..2c939d53b34b9c42e8cdc9cf5080136fd109c06e --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/controller/StorageController.java @@ -0,0 +1,24 @@ +package com.atguigu.springcloud.alibaba.controller; + + +import com.atguigu.springcloud.alibaba.domain.CommonResult ; +import com.atguigu.springcloud.alibaba.service.StorageService ; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class StorageController { + + @Autowired + private StorageService storageService; + + /** + * 扣减库存 + */ + @RequestMapping("/storage/decrease") + public CommonResult decrease(Long productId, Integer count) { + storageService.decrease(productId, count); + return new CommonResult(200,"扣减库存成功!"); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/dao/StorageDao.java b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/dao/StorageDao.java new file mode 100644 index 0000000000000000000000000000000000000000..7b481b4fc3585e367412da2230b07640dcd6d5f1 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/dao/StorageDao.java @@ -0,0 +1,11 @@ +package com.atguigu.springcloud.alibaba.dao; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +@Mapper +public interface StorageDao { + + //扣减库存 + void decrease(@Param("productId") Long productId, @Param("count") Integer count); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/domain/CommonResult.java b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/domain/CommonResult.java new file mode 100644 index 0000000000000000000000000000000000000000..89995716f4472550b05c944d44f78f5d87a70202 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/domain/CommonResult.java @@ -0,0 +1,23 @@ +package com.atguigu.springcloud.alibaba.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Created by macro on 2019/8/29. + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CommonResult +{ + private Integer code; + private String message; + private T data; + + public CommonResult(Integer code, String message) + { + this(code,message,null); + } +} \ No newline at end of file diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/domain/Storage.java b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/domain/Storage.java new file mode 100644 index 0000000000000000000000000000000000000000..7daeeb3b309ba663bf945c744bd7e8596d85e3e4 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/domain/Storage.java @@ -0,0 +1,29 @@ +package com.atguigu.springcloud.alibaba.domain; + +import lombok.Data; + +@Data +public class Storage { + + private Long id; + + /** + * 产品id + */ + private Long productId; + + /** + * 总库存 + */ + private Integer total; + + /** + * 已用库存 + */ + private Integer used; + + /** + * 剩余库存 + */ + private Integer residue; +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/service/StorageService.java b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/service/StorageService.java new file mode 100644 index 0000000000000000000000000000000000000000..36c3bbe4bdf2457078a65f15bb69954fd64790ca --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/service/StorageService.java @@ -0,0 +1,9 @@ +package com.atguigu.springcloud.alibaba.service; + + +public interface StorageService { + /** + * 扣减库存 + */ + void decrease(Long productId, Integer count); +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/service/impl/StorageServiceImpl.java b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/service/impl/StorageServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..5b6bfef59228f50ce489a4d6cb85f316c8ab35de --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/java/com/atguigu/springcloud/alibaba/service/impl/StorageServiceImpl.java @@ -0,0 +1,30 @@ +package com.atguigu.springcloud.alibaba.service.impl; + +import com.atguigu.springcloud.alibaba.dao.StorageDao; +import com.atguigu.springcloud.alibaba.service.StorageService ; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + + +@Service +public class StorageServiceImpl implements StorageService { + + private static final Logger LOGGER = LoggerFactory.getLogger(StorageServiceImpl.class); + + @Resource + private StorageDao storageDao; + + /** + * 扣减库存 + */ + @Override + public void decrease(Long productId, Integer count) { + LOGGER.info("------->storage-service中扣减库存开始"); + storageDao.decrease(productId,count); + LOGGER.info("------->storage-service中扣减库存结束"); + } +} diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/resources/application.yml b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..a40577c190be8205d7807f8976b50d690efd4277 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/resources/application.yml @@ -0,0 +1,28 @@ +server: + port: 2002 + +spring: + application: + name: seata-storage-service + cloud: + alibaba: + seata: + tx-service-group: fsp_tx_group + nacos: + discovery: + server-addr: localhost:8848 + datasource: + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://localhost:3306/seata_storage + username: root + password: root + +logging: + level: + io: + seata: info + +mybatis: + mapperLocations: classpath:mapper/*.xml + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/resources/file.conf b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/resources/file.conf new file mode 100644 index 0000000000000000000000000000000000000000..8b4b7f3c474ace280373b9c56864871098f91c92 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/resources/file.conf @@ -0,0 +1,73 @@ +transport { + # tcp udt unix-domain-socket + type = "TCP" + #NIO NATIVE + server = "NIO" + #enable heartbeat + heartbeat = true + #thread factory for netty + thread-factory { + boss-thread-prefix = "NettyBoss" + worker-thread-prefix = "NettyServerNIOWorker" + server-executor-thread-prefix = "NettyServerBizHandler" + share-boss-worker = false + client-selector-thread-prefix = "NettyClientSelector" + client-selector-thread-size = 1 + client-worker-thread-prefix = "NettyClientWorkerThread" + # netty boss thread size,will not be used for UDT + boss-thread-size = 1 + #auto default pin or 8 + worker-thread-size = 8 + } + shutdown { + # when destroy server, wait seconds + wait = 3 + } + serialization = "seata" + compressor = "none" +} + +service { + #vgroup->rgroup + vgroup_mapping.fsp_tx_group = "default" + #only support single node + default.grouplist = "127.0.0.1:8091" + #degrade current not support + enableDegrade = false + #disable + disable = false + #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent + max.commit.retry.timeout = "-1" + max.rollback.retry.timeout = "-1" + disableGlobalTransaction = false +} + +client { + async.commit.buffer.limit = 10000 + lock { + retry.internal = 10 + retry.times = 30 + } + report.retry.count = 5 + tm.commit.retry.count = 1 + tm.rollback.retry.count = 1 +} + +transaction { + undo.data.validation = true + undo.log.serialization = "jackson" + undo.log.save.days = 7 + #schedule delete expired undo_log in milliseconds + undo.log.delete.period = 86400000 + undo.log.table = "undo_log" +} + +support { + ## spring + spring { + # auto proxy the DataSource bean + datasource.autoproxy = false + } +} + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/resources/mapper/StorageMapper.xml b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/resources/mapper/StorageMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..1c5bd63c63d9401e60efcf27a06b0cf2dbe432ae --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/resources/mapper/StorageMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + UPDATE + t_storage + SET + used = used + #{count},residue = residue - #{count} + WHERE + product_id = #{productId} + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/resources/registry.conf b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/resources/registry.conf new file mode 100644 index 0000000000000000000000000000000000000000..f8a61c1f98ad438258112ee2812d14257d506219 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/src/main/resources/registry.conf @@ -0,0 +1,54 @@ +registry { + # file 、nacos 、eureka、redis、zk + type = "nacos" + + nacos { + serverAddr = "localhost:8848" + namespace = "" + cluster = "default" + } + eureka { + serviceUrl = "http://localhost:8761/eureka" + application = "default" + weight = "1" + } + redis { + serverAddr = "localhost:6381" + db = "0" + } + zk { + cluster = "default" + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + file { + name = "file.conf" + } +} + +config { + # file、nacos 、apollo、zk + type = "file" + + nacos { + serverAddr = "localhost" + namespace = "" + cluster = "default" + } + apollo { + app.id = "fescar-server" + apollo.meta = "http://192.168.1.204:8801" + } + zk { + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + file { + name = "file.conf" + } +} + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/application.yml b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..a40577c190be8205d7807f8976b50d690efd4277 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/application.yml @@ -0,0 +1,28 @@ +server: + port: 2002 + +spring: + application: + name: seata-storage-service + cloud: + alibaba: + seata: + tx-service-group: fsp_tx_group + nacos: + discovery: + server-addr: localhost:8848 + datasource: + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://localhost:3306/seata_storage + username: root + password: root + +logging: + level: + io: + seata: info + +mybatis: + mapperLocations: classpath:mapper/*.xml + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/SeataStorageServiceApplication2002.class b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/SeataStorageServiceApplication2002.class new file mode 100644 index 0000000000000000000000000000000000000000..0b76ffe90c14e8328117313b405707b832990803 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/SeataStorageServiceApplication2002.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.class b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..196f748f297af9f579fabf72bbc93750f4927ef9 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/config/DataSourceProxyConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/config/MyBatisConfig.class b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/config/MyBatisConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..49aa0e5e4810cc81315af9d5cd80aa055f74a6ad Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/config/MyBatisConfig.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/controller/StorageController.class b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/controller/StorageController.class new file mode 100644 index 0000000000000000000000000000000000000000..bd3343e42b022e0d731b358285102696349f2d7d Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/controller/StorageController.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/dao/StorageDao.class b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/dao/StorageDao.class new file mode 100644 index 0000000000000000000000000000000000000000..c4ecfaa0bbb219c13b65e8983e6be0bbc7cfd505 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/dao/StorageDao.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/domain/CommonResult.class b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/domain/CommonResult.class new file mode 100644 index 0000000000000000000000000000000000000000..80e51c9e0366b07a9b79abb11ad79217198e1bba Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/domain/CommonResult.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/domain/Storage.class b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/domain/Storage.class new file mode 100644 index 0000000000000000000000000000000000000000..245cbed05ba981f271575f753a236f481c8df18c Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/domain/Storage.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/service/StorageService.class b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/service/StorageService.class new file mode 100644 index 0000000000000000000000000000000000000000..03afd673139e890df37ea2583814515a3e1be91f Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/service/StorageService.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/service/impl/StorageServiceImpl.class b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/service/impl/StorageServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d7897db5ffbdef8918cb1957d5efa6fb7f6244ed Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/com/atguigu/springcloud/alibaba/service/impl/StorageServiceImpl.class differ diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/file.conf b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/file.conf new file mode 100644 index 0000000000000000000000000000000000000000..8b4b7f3c474ace280373b9c56864871098f91c92 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/file.conf @@ -0,0 +1,73 @@ +transport { + # tcp udt unix-domain-socket + type = "TCP" + #NIO NATIVE + server = "NIO" + #enable heartbeat + heartbeat = true + #thread factory for netty + thread-factory { + boss-thread-prefix = "NettyBoss" + worker-thread-prefix = "NettyServerNIOWorker" + server-executor-thread-prefix = "NettyServerBizHandler" + share-boss-worker = false + client-selector-thread-prefix = "NettyClientSelector" + client-selector-thread-size = 1 + client-worker-thread-prefix = "NettyClientWorkerThread" + # netty boss thread size,will not be used for UDT + boss-thread-size = 1 + #auto default pin or 8 + worker-thread-size = 8 + } + shutdown { + # when destroy server, wait seconds + wait = 3 + } + serialization = "seata" + compressor = "none" +} + +service { + #vgroup->rgroup + vgroup_mapping.fsp_tx_group = "default" + #only support single node + default.grouplist = "127.0.0.1:8091" + #degrade current not support + enableDegrade = false + #disable + disable = false + #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent + max.commit.retry.timeout = "-1" + max.rollback.retry.timeout = "-1" + disableGlobalTransaction = false +} + +client { + async.commit.buffer.limit = 10000 + lock { + retry.internal = 10 + retry.times = 30 + } + report.retry.count = 5 + tm.commit.retry.count = 1 + tm.rollback.retry.count = 1 +} + +transaction { + undo.data.validation = true + undo.log.serialization = "jackson" + undo.log.save.days = 7 + #schedule delete expired undo_log in milliseconds + undo.log.delete.period = 86400000 + undo.log.table = "undo_log" +} + +support { + ## spring + spring { + # auto proxy the DataSource bean + datasource.autoproxy = false + } +} + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/mapper/StorageMapper.xml b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/mapper/StorageMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..1c5bd63c63d9401e60efcf27a06b0cf2dbe432ae --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/mapper/StorageMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + UPDATE + t_storage + SET + used = used + #{count},residue = residue - #{count} + WHERE + product_id = #{productId} + + + + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/registry.conf b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/registry.conf new file mode 100644 index 0000000000000000000000000000000000000000..f8a61c1f98ad438258112ee2812d14257d506219 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/classes/registry.conf @@ -0,0 +1,54 @@ +registry { + # file 、nacos 、eureka、redis、zk + type = "nacos" + + nacos { + serverAddr = "localhost:8848" + namespace = "" + cluster = "default" + } + eureka { + serviceUrl = "http://localhost:8761/eureka" + application = "default" + weight = "1" + } + redis { + serverAddr = "localhost:6381" + db = "0" + } + zk { + cluster = "default" + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + file { + name = "file.conf" + } +} + +config { + # file、nacos 、apollo、zk + type = "file" + + nacos { + serverAddr = "localhost" + namespace = "" + cluster = "default" + } + apollo { + app.id = "fescar-server" + apollo.meta = "http://192.168.1.204:8801" + } + zk { + serverAddr = "127.0.0.1:2181" + session.timeout = 6000 + connect.timeout = 2000 + } + file { + name = "file.conf" + } +} + + + diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/maven-archiver/pom.properties b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/maven-archiver/pom.properties new file mode 100644 index 0000000000000000000000000000000000000000..0c71d2e4d1573a30852294255aa57cdca5132e9a --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Thu Apr 16 08:31:10 CST 2020 +version=1.0-SNAPSHOT +groupId=com.atguigu.springcloud +artifactId=seata-storage-service2002 diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..de8a0f265af1f1913445f4c41ebd692bf545838c --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,9 @@ +com\atguigu\springcloud\alibaba\domain\CommonResult.class +com\atguigu\springcloud\alibaba\SeataStorageServiceApplication2002.class +com\atguigu\springcloud\alibaba\dao\StorageDao.class +com\atguigu\springcloud\alibaba\config\MyBatisConfig.class +com\atguigu\springcloud\alibaba\service\impl\StorageServiceImpl.class +com\atguigu\springcloud\alibaba\controller\StorageController.class +com\atguigu\springcloud\alibaba\domain\Storage.class +com\atguigu\springcloud\alibaba\service\StorageService.class +com\atguigu\springcloud\alibaba\config\DataSourceProxyConfig.class diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..b75c32b3b525ee2781f6b846f7ed4c5aed705cb7 --- /dev/null +++ b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,9 @@ +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-storage-service2002\src\main\java\com\atguigu\springcloud\alibaba\service\impl\StorageServiceImpl.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-storage-service2002\src\main\java\com\atguigu\springcloud\alibaba\config\MyBatisConfig.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-storage-service2002\src\main\java\com\atguigu\springcloud\alibaba\SeataStorageServiceApplication2002.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-storage-service2002\src\main\java\com\atguigu\springcloud\alibaba\controller\StorageController.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-storage-service2002\src\main\java\com\atguigu\springcloud\alibaba\service\StorageService.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-storage-service2002\src\main\java\com\atguigu\springcloud\alibaba\config\DataSourceProxyConfig.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-storage-service2002\src\main\java\com\atguigu\springcloud\alibaba\domain\CommonResult.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-storage-service2002\src\main\java\com\atguigu\springcloud\alibaba\dao\StorageDao.java +C:\Users\Administrator\Desktop\LearningNotes\SpringCloud\SpringCloud2020\cloud2020\seata-storage-service2002\src\main\java\com\atguigu\springcloud\alibaba\domain\Storage.java diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/seata-storage-service2002-1.0-SNAPSHOT.jar b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/seata-storage-service2002-1.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..4b9807f1776a7a971b4275f87a448d885c4c2f38 Binary files /dev/null and b/SpringCloud/SpringCloud2020/cloud2020/seata-storage-service2002/target/seata-storage-service2002-1.0-SNAPSHOT.jar differ diff --git "a/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/README.md" "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b5f0dbc13d1aea7576097e950acb48fc3d7f731f --- /dev/null +++ "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/README.md" @@ -0,0 +1,167 @@ +# 配置Sentinel规则持久化到Nacos中 + +## 前言 + +Sentinel如果没有配置持久化的话,默认是将规则存储在内存中的,如果服务重启那么定义的规则也会没有,需要我们再次手动创建规则。这样其实对我们来说是非常麻烦的一件事,因此这里重点说说Sentinel规则持久化到Nacos中,每次启动服务,只需要从Nacos拉取规则,加载到Sentinel中即可 + +## 安装依赖 + +如果要使用Sentinel持久化到Nacos,首先需要在项目文件中导入pom依赖 + +```xml + + + com.alibaba.csp + sentinel-datasource-nacos + +``` + +## 修改yml文件 + +然后我们找到原来配置sentinel的配置文件,添加datasouce相关 + +```bash +server: + port: 8603 + +spring: + application: + name: mogu-web + cloud: + nacos: + discovery: + server-addr: localhost:8848 + namespace: dev + config: + server-addr: localhost:8848 + file-extension: yaml + #指定分组 + group: dev + #指定命名空间 + namespace: dev + + # 配置Sentinel流控 + sentinel: + transport: + #配置Sentinel dashboard地址 + dashboard: localhost:8070 + #默认8719端口,如果被占用会向上扫描。 + port: 8719 + + # sentinel持久化到nacos + datasource: + flow: + nacos: + # nacos连接地址 + server-addr: ${spring.cloud.nacos.discovery.server-addr} + # nacos中的配置名称 + data-id: ${spring.application.name}-flow-rules + group-id: DEFAULT_GROUP + data-type: json + rule-type: flow + degrade: + nacos: + server-addr: ${spring.cloud.nacos.discovery.server-addr} + data-id: ${spring.application.name}-degrade-rules + group-id: DEFAULT_GROUP + data-type: json + rule-type: degrade +``` + +在上面我们分别配置了sentinel的流控规则和降级规则 + +## 创建配置文件 + +然后我们需要到Nacos中创建配置文件 + +- mogu-web-flow-rules:流量规则 +- mogu-web-degrade-rules:降级规则 + +因为我们没有指定对应的namespace,也就是命名空间,所以我们就默认在public下创建,这样在dev 或者 prod下都可以进行使用 + +![image-20201002112029866](images/image-20201002112029866.png) + +### mogu-web-flow-rules + +首先创建流量规则,主要用于接口的流量控制 + +![image-20201002111931443](images/image-20201002111931443.png) + +规则如下所示: + +```bash +[ + { + "clusterMode": false, + "controlBehavior": 0, + "count": 1, + "grade": 1, + "limitApp": "default", + "resource": "/index/getBlogByLevel", + "strategy": 0 + } +] +``` + +字段含义:【所有属性来⾃源码FlowRule类】 + +- **resource**:资源名称 +- **limitApp**:来源应⽤ +- **grade**:阈值类型 0 线程数 1 QPS +- **count**:单机阈值 +- **strategy**:流控模式, 0 直接 1 关联 2 链路 +- **controlBehavior**:流控效果, 0 快速失败 1 Warm Up 2 排队等待 +- **clusterMode**: true/false 是否集群 + +### mogu-web-degrade-rules + +首先创建降级规则,主要用于接口的请求出错时,快速返回 + +![image-20201002111905809](images/image-20201002111905809.png) + +规则如下所示: + +```bash +[ + { + "count": 1, + "grade": 2, + "resource": "/index/getBlogByLevel", + "timeWindow": 5 + } +] +``` + +字段含义:【所有属性来⾃源码DegradeRule类】 + +- **resource**:资源名称 +- **grade**:降级策略 0 RT 1 异常⽐例 2 异常数 +- **count**:阈值 +- **timeWindow**:时间窗 + +## 测试 + +创建完成后,我们启动项目测试,因为我们添加的是mogu-web的流控规则,所以我们只需要访问主页即可 + +```bash +# 输入首页地址 +http://localhost:9527 +``` + +然后发现成功跳转出500页面,说明我们的流控规则已经生效 + +![image-20201002112307192](images/image-20201002112307192.png) + +然后到我们的sentinel图形化页面 + +```bash +http://localhost:8070 +``` + +输入默认账号和密码:sentinel sentinel + +![image-20201002112409723](images/image-20201002112409723.png) + +![image-20201002112435951](images/image-20201002112435951.png) + +能够发现已经有一条流控规则和降级规则了~,到这里为止已经成功将规则持久化到nacos中了,更多的规则,我们只需要修改对应的配置文件即可 \ No newline at end of file diff --git "a/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002111905809.png" "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002111905809.png" new file mode 100644 index 0000000000000000000000000000000000000000..f762f761c43292ee3c4671d1abc1e1c4db5ed2fc Binary files /dev/null and "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002111905809.png" differ diff --git "a/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002111931443.png" "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002111931443.png" new file mode 100644 index 0000000000000000000000000000000000000000..ecc65d7c93a785c38bcee7c7cfd3cd88a2876475 Binary files /dev/null and "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002111931443.png" differ diff --git "a/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002112029866.png" "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002112029866.png" new file mode 100644 index 0000000000000000000000000000000000000000..6ea7159479929397fbfa7d236341391607adfc44 Binary files /dev/null and "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002112029866.png" differ diff --git "a/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002112307192.png" "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002112307192.png" new file mode 100644 index 0000000000000000000000000000000000000000..595a5290f90f6f8e7b99740e971a08207888841b Binary files /dev/null and "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002112307192.png" differ diff --git "a/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002112409723.png" "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002112409723.png" new file mode 100644 index 0000000000000000000000000000000000000000..14cf4b44f36f4c5dedd38ccda69be8bdbebd30b7 Binary files /dev/null and "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002112409723.png" differ diff --git "a/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002112435951.png" "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002112435951.png" new file mode 100644 index 0000000000000000000000000000000000000000..379c1c8bc5037b117a37f6d88eba6e286e53abb6 Binary files /dev/null and "b/SpringCloud/\351\205\215\347\275\256Sentinel\350\247\204\345\210\231\346\214\201\344\271\205\345\214\226\345\210\260Nacos\344\270\255/images/image-20201002112435951.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/README.md" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..640cef505b8c0ac584967e1515b59eaaa54110f0 --- /dev/null +++ "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/README.md" @@ -0,0 +1,542 @@ +# 初识SpringSecurity + +## 参考 + +来源于黑马程序员: [手把手教你精通新版SpringSecurity](https://www.bilibili.com/video/BV1EE411u7YV?p=1) + +## 权限管理概念 + +权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源。权限管 +理几乎出现在任何系统里面,前提是需要有用户和密码认证的系统。 + +> 在权限管理的概念中,有两个非常重要的名词: +> +> - 认证:通过用户名和密码成功登陆系统后,让系统得到当前用户的角色身份。 +> - 授权:系统根据当前用户的角色,给其授予对应可以操作的权限资源。 + +## 完成权限管理需要三个对象 + +- 用户:主要包含用户名,密码和当前用户的角色信息,可实现认证操作。 +- 角色:主要包含角色名称,角色描述和当前角色拥有的权限信息,可实现授权操作。 +- 权限:权限也可以称为菜单,主要包含当前权限名称,url地址等信息,可实现动态展示菜单。 + +> 注:这三个对象中,用户与角色是多对多的关系,角色与权限是多对多的关系,用户与权限没有直接关系, +> 二者是通过角色来建立关联关系的。 + +## 初识SpringSecurity + +Spring Security是spring采用AOP思想,基于servlet过滤器实现的安全框架。它提供了完善的认证机制和方法级的 +授权功能。是一款非常优秀的权限管理框架。 + +### 创建SpringSecurity + +Spring Security主要jar包功能介绍 + +- spring-security-core.jar:核心包,任何Spring Security功能都需要此包。 +- spring-security-web.jar:web工程必备,包含过滤器和相关的Web安全基础结构代码。 +- spring-security-config.jar:用于解析xml配置文件,用到Spring Security的xml配置文件的就要用到此包。 +- spring-security-taglibs.jar:Spring Security提供的动态标签库,jsp页面可以用。 + +导入pom依赖 + +```pom + + org.springframework.security + spring-security-taglibs + 5.1.5.RELEASE + + + org.springframework.security + spring-security-config + 5.1.5.RELEASE + +``` + +最终依赖树 + +![image-20200919183927385](images/image-20200919183927385.png) + +### 配置web.xml + +```xml + +Archetype Created Web Application + + + springSecurityFilterChain + org.springframework.web.filter.DelegatingFilterProxy + + + springSecurityFilterChain + /* + + +``` + +### 配置SpringSecurity.xml + +```xml + + + + + + + + + + + + + + + + + + +``` + +## SpringSecurity常用过滤器介绍 + +过滤器是一种典型的AOP思想 + +### SecurityContextPersistenceFilter + +首当其冲的一个过滤器,作用之重要,自不必多言。 + +SecurityContextPersistenceFilter主要是使用SecurityContextRepository在session中保存或更新一SecurityContext,并将SecurityContext给以后的过滤器使用,来为后续filter建立所需的上下文。SecurityContext中存储了当前用户的认证以及权限信息。 + +### WebAsyncManagerIntegrationFilter + +此过滤器用于集成SecurityContext到Spring异步执行机制中的WebAsyncManager +### HeaderWriterFilter + +向请求的Header中添加相应的信息,可在http标签内部使用security:headers来控制(仅限于JSP页面) + +### CsrfFilter + +csrf又称跨域请求伪造,SpringSecurity会对所有post请求验证是否包含系统生成的csrf的token信息, +如果不包含,则报错。起到防止csrf攻击的效果。 + +### LogoutFilter + +匹配URL为/logout的请求,实现用户退出,清除认证信息。 + +### UsernamePasswordAuthenticationFilter + +认证操作全靠这个过滤器,默认匹配URL为/login且必须为POST请求。 + +### DefaultLoginPageGeneratingFilter + +如果没有在配置文件中指定认证页面,则由该过滤器生成一个默认认证页面。 + +### DefaultLogoutPageGeneratingFilter + +由此过滤器可以生产一个默认的退出登录页面 + +### BasicAuthenticationFilter + +此过滤器会自动解析HTTP请求中头部名字为Authentication,且以Basic开头的头信息。 + +### RequestCacheAwareFilter + +通过HttpSessionRequestCache内部维护了一个RequestCache,用于缓存HttpServletRequest + +### SecurityContextHolderAwareRequestFilter + +针对ServletRequest进行了一次包装,使得request具有更加丰富的API + +### AnonymousAuthenticationFilter + +当SecurityContextHolder中认证信息为空,则会创建一个匿名用户存入到SecurityContextHolder中。 +spring security为了兼容未登录的访问,也走了一套认证流程,只不过是一个匿名的身份。 + +> 当用户以游客身份登录的时候,也就是可以通过设置某些接口可以匿名访问 + +### SessionManagementFilter + +SecurityContextRepository限制同一用户开启多个会话的数量 + +### ExceptionTranslationFilter + +异常转换过滤器位于整个springSecurityFilterChain的后方,用来转换整个链路中出现的异常 + +### FilterSecurityInterceptor + +获取所配置资源访问的授权信息,根据SecurityContextHolder中存储的用户信息来决定其是否有权 +限 + +> 该过滤器限制哪些资源可以访问,哪些不能够访问 + +## SpringSecurity过滤器链加载原理 + +通过前面十五个过滤器功能的介绍,对于SpringSecurity简单入门中的疑惑是不是在心中已经有了答案了呀? +但新的问题来了!我们并没有在web.xml中配置这些过滤器啊?它们都是怎么被加载出来的? + +### DelegatingFilterProxy + +我们在web.xml中配置了一个名称为springSecurityFilterChain的过滤器DelegatingFilterProxy,接下我直接对 +DelegatingFilterProxy源码里重要代码进行说明,其中删减掉了一些不重要的代码,大家注意我写的注释就行了! + +![image-20200919191221857](images/image-20200919191221857.png) + +![image-20200919191241102](images/image-20200919191241102.png) + +![image-20200919191302644](images/image-20200919191302644.png) + +第二步debug结果如下 + +![image-20200919191331949](images/image-20200919191331949.png) + +由此可知,DelegatingFilterProxy通过springSecurityFilterChain这个名称,得到了一个FilterChainProxy过滤器,最终在第三步执行了这个过滤器。 + +### FilterChainProxy + +注意代码注释!注意代码注释!注意代码注释! + +![image-20200919191609357](images/image-20200919191609357.png) + +![image-20200919191701128](images/image-20200919191701128.png) + +![image-20200919191724782](images/image-20200919191724782.png) + +第二步debug结果如下图所示,惊不惊喜?十五个过滤器都在这里了! + +![image-20200919191746095](images/image-20200919191746095.png) + +再看第三步,怀疑这么久!原来这些过滤器还真是都被封装进SecurityFilterChain中了。 + +### SecurityFilterChain + +最后看SecurityFilterChain,这是个接口,实现类也只有一个,这才是web.xml中配置的过滤器链对象! + +![image-20200919191830091](images/image-20200919191830091.png) + +![image-20200919191841552](images/image-20200919191841552.png) + +### 总结 + +通过此章节,我们对SpringSecurity工作原理有了一定的认识。但理论千万条,功能第一条,探寻底层,是 +为了更好的使用框架。 + +那么,言归正传!到底如何使用自己的页面来实现SpringSecurity的认证操作呢?要完成此功能,首先要有一套 +自己的页面! + +## SpringSecurity使用自定义认证页面 + +在SpringSecurity主配置文件中指定认证页面配置信息 + +![image-20200919191951927](images/image-20200919191951927.png) + +修改认证页面的请求地址 + +![image-20200919192105365](images/image-20200919192105365.png) + +再次启动项目后就可以看到自定义的酷炫认证页面了! + +![image-20200919192142213](images/image-20200919192142213.png) + +然后你开开心心的输入了用户名user,密码user,就出现了如下的界面: + +![image-20200919192203613](images/image-20200919192203613.png) + +403什么异常?这是SpringSecurity中的权限不足!这个异常怎么来的?还记得上面SpringSecurity内置认证页面源码中的那个_csrf隐藏input吗?问题就在这了! + +完整的spring-security配置如下 + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +## SpringSecurity的csrf防护机制 + +CSRF(Cross-site request forgery)跨站请求伪造,是一种难以防范的网络攻击方式。 + +SpringSecurity中CsrfFilter过滤器说明 + +![image-20200919193139125](images/image-20200919193139125.png) + +![image-20200919193203700](images/image-20200919193203700.png) + +通过源码分析,我们明白了,自己的认证页面,请求方式为POST,但却没有携带token,所以才出现了403权限不 +足的异常。那么如何处理这个问题呢? + +方式一:直接禁用csrf,不推荐。 + +方式二:在认证页面携带token请求。 + +### 禁用csrf防护机制 + +在SpringSecurity主配置文件中添加禁用crsf防护的配置。 + +![image-20200919194217293](images/image-20200919194217293.png) + +### 在认证页面携带token请求 + +![image-20200919194236585](images/image-20200919194236585.png) + +注:HttpSessionCsrfTokenRepository对象负责生成token并放入session域中。 + +## SpringSecurity使用数据库数据完成认证 + +### 认证流程 + +先看主要负责认证的过滤器UsernamePasswordAuthenticationFilter,有删减,注意注释。 + +![image-20200919194541154](images/image-20200919194541154.png) + +![image-20200919194554290](images/image-20200919194554290.png) + +上面的过滤器的意思就是,我们发送的登录请求,请求地址需要是 /login,请求方法 post,然后用户名 username,密码为 password + +### AuthenticationManager + +由上面源码得知,真正认证操作在AuthenticationManager里面!然后看AuthenticationManager的实现类ProviderManager: + +![image-20200919195156738](images/image-20200919195156738.png) + +![image-20200919195209419](images/image-20200919195209419.png) + +### AbstractUserDetailsAuthenticationProvider + +咱们继续再找到AuthenticationProvider的实现类AbstractUserDetailsAuthenticationProvider + +![image-20200919195243996](images/image-20200919195243996.png) + +### AbstractUserDetailsAuthenticationProvider中authenticate返回值 + +按理说到此已经知道自定义认证方法的怎么写了,但咱们把返回的流程也大概走一遍,上面不是说到返回了一个 +UserDetails对象对象吗?跟着它,就又回到了AbstractUserDetailsAuthenticationProvider对象中authenticate方法的最后一行了。 + +![image-20200919195340553](images/image-20200919195340553.png) + +### UsernamePasswordAuthenticationToken + +来到UsernamePasswordAuthenticationToken对象发现里面有两个构造方法 + +![image-20200919195400048](images/image-20200919195400048.png) + +![image-20200919195407334](images/image-20200919195407334.png) + +### AbstractAuthenticationToken + +再点进去super(authorities)看看: + +![image-20200919195433849](images/image-20200919195433849.png) + +由此,咱们需要牢记自定义认证业务逻辑返回的UserDetails对象中一定要放置权限信息啊! + +现在可以结束源码分析了吧?先不要着急! + +咱们回到最初的地方UsernamePasswordAuthenticationFilter,你看好看了,这可是个过滤器,咱们分析这么 +久,都没提到doFilter方法,你不觉得心里不踏实? + +可是这里面也没有doFilter呀?那就从父类找! + +### AbstractAuthenticationProcessingFilter + +点开AbstractAuthenticationProcessingFilter,删掉不必要的代码! + +![image-20200919195547370](images/image-20200919195547370.png) + +![image-20200919195601300](images/image-20200919195601300.png) + +可见AbstractAuthenticationProcessingFilter这个过滤器对于认证成功与否,做了两个分支,成功执行 +successfulAuthentication,失败执行unsuccessfulAuthentication。 + +在successfulAuthentication内部,将认证信息存储到了SecurityContext中。并调用了loginSuccess方法,这就是 +常见的“记住我”功能!此功能具体应用,咱们后续再研究! + +## 初步实现认证功能 + +让我们自己的UserService接口继承UserDetailsService,毕竟SpringSecurity是只认UserDetailsService的: + +### 创建UserDetailsService + +```java +public interface UserService extends UserDetailsService { + public void save(SysUser user); + public List findAll(); + public Map toAddRolePage(Integer id); + public void addRoleToUser(Integer userId, Integer[] ids); +} +``` + +### 编写loadUserByUsername业务 + +```java +@Override +public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + SysUser sysUser = userDao.findByName(username); + if(sysUser==null){ + //若用户名不对,直接返回null,表示认证失败。 + return null; + } + List authorities = new ArrayList<>(); + List roles = sysUser.getRoles(); + for (SysRole role : roles) { + authorities.add(new SimpleGrantedAuthority(role.getRoleName())); + } + //最终需要返回一个SpringSecurity的UserDetails对象,{noop}表示不加密认证。 + return new User(sysUser.getUsername(), "{noop}"+sysUser.getPassword(), authorities); +} +``` + +### 在SpringSecurity主配置文件中指定认证使用的业务对象 + +```xml + + + + + +``` + +## 加密认证 + +### 在IOC容器中提供加密对象 + +```xml + + + + + + + + + +``` + +### 修改认证方法 + +去掉{noop},该方法可以让我们的密码不加密 + +```java +@Override +public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + SysUser sysUser = userDao.findByName(username); + if(sysUser==null){ + //若用户名不对,直接返回null,表示认证失败。 + return null; + } + List authorities = new ArrayList<>(); + List roles = sysUser.getRoles(); + for (SysRole role : roles) { + authorities.add(new SimpleGrantedAuthority(role.getRoleName())); + } + //最终需要返回一个SpringSecurity的UserDetails对象,{noop}表示不加密认证。 + return new User(sysUser.getUsername(), sysUser.getPassword(), authorities); +} +``` + +### 修改添加用户的操作 + +```java +@Service +@Transactional +public class UserServiceImpl implements UserService { + @Autowired + private UserDao userDao; + @Autowired + private RoleService roleService; + @Autowired + private BCryptPasswordEncoder passwordEncoder; + @Override + public void save(SysUser user) { + //对密码进行加密,然后再入库 + user.setPassword(passwordEncoder.encode(user.getPassword())); + userDao.save(user); + } +} +``` + +### 手动将数据库中用户密码改为加密后的密文 + +![image-20200919202157273](images/image-20200919202157273.png) \ No newline at end of file diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919183927385.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919183927385.png" new file mode 100644 index 0000000000000000000000000000000000000000..a564a9c9ffb563c86c028bdb1d388f0612c95fda Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919183927385.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191221857.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191221857.png" new file mode 100644 index 0000000000000000000000000000000000000000..f11424d42c305baff554fea5d1a8a2962c1f6704 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191221857.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191241102.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191241102.png" new file mode 100644 index 0000000000000000000000000000000000000000..d20da6f2fdda2f9d6ab4fa73c9c84b08f4ebb0d3 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191241102.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191302644.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191302644.png" new file mode 100644 index 0000000000000000000000000000000000000000..5c4f2e5d206cfd1dd7a2358e50c25d3cbbf505c2 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191302644.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191331949.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191331949.png" new file mode 100644 index 0000000000000000000000000000000000000000..710448507dc1013a3c75af70f5dd003d84b54899 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191331949.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191609357.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191609357.png" new file mode 100644 index 0000000000000000000000000000000000000000..52b11c4ace842fd6a25a4b0cd597a7d442b126ea Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191609357.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191701128.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191701128.png" new file mode 100644 index 0000000000000000000000000000000000000000..6e3822796c023463ae17161d0401571240b47e91 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191701128.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191724782.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191724782.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ba891b0e1f71c42759facca2306c8b2fc0b0ae7 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191724782.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191746095.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191746095.png" new file mode 100644 index 0000000000000000000000000000000000000000..8ea6433ba0f48bebc5d430e05100c98c1d045165 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191746095.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191830091.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191830091.png" new file mode 100644 index 0000000000000000000000000000000000000000..3eea1c27061d6e247be1af3228790742a0e416ef Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191830091.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191841552.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191841552.png" new file mode 100644 index 0000000000000000000000000000000000000000..85515d71ec991cb40c6d564fe2d088095dc65295 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191841552.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191951927.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191951927.png" new file mode 100644 index 0000000000000000000000000000000000000000..03deb6ca76e8dedb8350d5bd132ce988e07bdeed Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919191951927.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919192105365.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919192105365.png" new file mode 100644 index 0000000000000000000000000000000000000000..b3e521af46f67e5c4c2c3959f85be2620a395f2c Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919192105365.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919192142213.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919192142213.png" new file mode 100644 index 0000000000000000000000000000000000000000..13f54be4dd713c57c169a7c9826a756747a9d040 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919192142213.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919192203613.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919192203613.png" new file mode 100644 index 0000000000000000000000000000000000000000..5ea27f2f582f8429e1755e6b925d32b19fa86411 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919192203613.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919193139125.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919193139125.png" new file mode 100644 index 0000000000000000000000000000000000000000..dd957ccd224e3336a0345b711f59e3e6893b5ff7 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919193139125.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919193203700.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919193203700.png" new file mode 100644 index 0000000000000000000000000000000000000000..169ba7c02cf16b8119659356fcb89500d9ebd510 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919193203700.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919194217293.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919194217293.png" new file mode 100644 index 0000000000000000000000000000000000000000..1fc0967a0b0a0bb4eb0b7850248ffdec8e8b5492 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919194217293.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919194236585.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919194236585.png" new file mode 100644 index 0000000000000000000000000000000000000000..055f24ac921f509c7cfbf53fc5381bf18f7bae5c Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919194236585.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919194541154.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919194541154.png" new file mode 100644 index 0000000000000000000000000000000000000000..24f2419f2708744996e731421f360525493dc803 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919194541154.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919194554290.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919194554290.png" new file mode 100644 index 0000000000000000000000000000000000000000..3439da63b34004fb2b943f9aca77b391af22efa2 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919194554290.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195156738.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195156738.png" new file mode 100644 index 0000000000000000000000000000000000000000..73a30c9f3cdc3d769a7c4d5d7968c2952cc2b70a Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195156738.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195209419.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195209419.png" new file mode 100644 index 0000000000000000000000000000000000000000..fbe2b09b14b33ae1badfff220e4609d3541ce069 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195209419.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195243996.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195243996.png" new file mode 100644 index 0000000000000000000000000000000000000000..6ffbf65969898e3b84bf6a1837019a094d9275ea Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195243996.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195340553.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195340553.png" new file mode 100644 index 0000000000000000000000000000000000000000..8b5499c47f626af1795d804c6255d62e8bc7d04f Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195340553.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195400048.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195400048.png" new file mode 100644 index 0000000000000000000000000000000000000000..ab5730a479f6577150f8ddb0d63bddc303d7a1df Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195400048.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195407334.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195407334.png" new file mode 100644 index 0000000000000000000000000000000000000000..486151bcbfd46994b76614b5e18f8d8c31603573 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195407334.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195433849.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195433849.png" new file mode 100644 index 0000000000000000000000000000000000000000..827e089c4b691dcbd99b65af5848c6efa82f90d4 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195433849.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195547370.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195547370.png" new file mode 100644 index 0000000000000000000000000000000000000000..e6dda82b21b5405d1fd73c4d32ba08d70de2c78f Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195547370.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195601300.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195601300.png" new file mode 100644 index 0000000000000000000000000000000000000000..3447e322cc722f36b644e831e6e69a3a10398136 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919195601300.png" differ diff --git "a/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919202157273.png" "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919202157273.png" new file mode 100644 index 0000000000000000000000000000000000000000..a10ad0875f5d172f68f0137a2bef3a555efa7003 Binary files /dev/null and "b/SpringSecurity/1_\345\210\235\350\257\206SpringSecurity/images/image-20200919202157273.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/README.md" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b1bd6bb97890bbad2b43ae3572de75d7a05ed6a9 --- /dev/null +++ "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/README.md" @@ -0,0 +1,327 @@ +# SpringSecurity认证过程 + +## 参考 + +来源于黑马程序员: [手把手教你精通新版SpringSecurity](https://www.bilibili.com/video/BV1EE411u7YV?p=17) + +## 设置用户状态 + +用户认证业务里,我们封装User对象时,选择了三个构造参数的构造方法,其实还有另一个构造方法: + +```java +public User(String username, String password, boolean enabled, boolean accountNonExpired, +boolean credentialsNonExpired, boolean accountNonLocked, Collection +authorities) { + if (username != null && !"".equals(username) && password != null) { + this.username = username; + this.password = password; + this.enabled = enabled; + this.accountNonExpired = accountNonExpired; + this.credentialsNonExpired = credentialsNonExpired; + this.accountNonLocked = accountNonLocked; + this.authorities = Collections.unmodifiableSet(sortAuthorities(authorities)); + } else { + throw new IllegalArgumentException("Cannot pass null or empty values to constructor"); + } +} +``` + +可以看到,这个构造方法里多了四个布尔类型的构造参数,其实我们使用的三个构造参数的构造方法里这四个布尔 +值默认都被赋值为了true,那么这四个布尔值到底是何意思呢? + +- boolean enabled 是否可用 +- boolean accountNonExpired 账户是否失效 +- boolean credentialsNonExpired 密码是否失效 +- boolean accountNonLocked 账户是否锁定 + +![image-20200919214537040](images/image-20200919214537040.png) + +在蘑菇博客中,就是这里进行定义的,然后在通过下面代码来进行判断该用户是否处于正常 + +```java + /** + * 通过管理员Admin,生成一个SpringSecurity用户 + * @param admin + * @return + */ + public static SecurityUser create(Admin admin) { + boolean enabled = admin.getStatus() == EStatus.ENABLE; + return new SecurityUser( + admin.getUid(), + admin.getUserName(), + admin.getPassWord(), + enabled, + mapToGrantedAuthorities(admin.getRoleNames()) + ); + } +``` + +## 注销功能 + +注意:一旦开启了csrf防护功能,logout处理器便只支持POST请求方式了!修改header.jsp中注销请求: + +```html +
+ + + +``` + +## 记住我功能 + +### 流程分析 + +还记得前面咱们分析认证流程时,提到的记住我功能吗?现在继续跟踪找到AbstractRememberMeServices对象的loginSuccess方法: + +![image-20200919215441535](images/image-20200919215441535.png) + +再点进去上面if判断中的rememberMeRequested方法,还在当前类中 + +![image-20200919215510847](images/image-20200919215510847.png)![image-20200919215502008](images/image-20200919215502008.png) + +如果上面方法返回true,就表示页面勾选了记住我选项了。继续顺着调用的方法找到PersistentTokenBasedRememberMeServices的onLoginSuccess方法: + +![image-20200919215604473](images/image-20200919215604473.png) + +### 记住我功能页面代码 + +注意name和value属性的值不要写错哦! + +![image-20200919215750642](images/image-20200919215750642.png) + +先测试一下,认证通过后,关掉浏览器,再次打开页面,发现还要认证!为什么没有起作用呢?这是因为remember me功能使用的过滤器RememberMeAuthenticationFilter默认是不开启的! + +### 开启remember me过滤器 + +```java + + + + + + +``` + +说明:RememberMeAuthenticationFilter中功能非常简单,会在打开浏览器时,自动判断是否认证,如果没有则 +调用autoLogin进行自动认证。 + +### remember me安全性分析 + +记住我功能方便是大家看得见的,但是安全性却令人担忧。因为Cookie毕竟是保存在客户端的,很容易盗取,而且 Cookie的值还与用户名、密码这些敏感数据相关,虽然加密了,但是将敏感信息存在客户端,还是不太安全。那么 这就要提醒喜欢使用此功能的,用完网站要及时手动退出登录,清空认证信息。 + +此外,SpringSecurity还提供了remember me的另一种相对更安全的实现机制 :在客户端的cookie中,仅保存一个 +无意义的加密串(与用户名、密码等敏感数据无关),然后在db中保存该加密串-用户信息的对应关系,自动登录 +时,用cookie中的加密串,到db中验证,如果通过,自动登录才算通过。 + +### 持久化remember me信息 + +创建一张表,注意这张表的名称和字段都是固定的,不要修改。 + +```sql +CREATE TABLE `persistent_logins` ( +`username` varchar(64) NOT NULL, +`series` varchar(64) NOT NULL, +`token` varchar(64) NOT NULL, +`last_used` timestamp NOT NULL, +PRIMARY KEY (`series`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 +``` + +然后将spring-security.xml中 改为: + +```xml + + +``` + +最后测试发现数据库中自动多了一条记录: + +![image-20200919220254094](images/image-20200919220254094.png) + +## 显示当前认证信息 + +在header.jsp中找到页面头部最右侧图片处添加如下信息: + +```jsp + +或者 + +``` + +## 授权准备工作 + +为了模拟授权操作,咱们临时编写两个业务功能:处理器代码: + +![image-20200920084345762](images/image-20200920084345762.png) + +aside.jsp页面: + +![image-20200920084406261](images/image-20200920084406261.png) + +## 动态展示菜单 + +在aside.jsp对每个菜单通过SpringSecurity标签库指定访问所需角色 + +![image-20200920084933415](images/image-20200920084933415.png) + +![image-20200920084945102](images/image-20200920084945102.png) + +![image-20200920084959631](images/image-20200920084959631.png) + +我们做个测试,xiaozhi这个用户现在只有普通用户角色ROLE_USER,用xiaozhi登录后,果然只看到了订单管理: + +![image-20200920085153413](images/image-20200920085153413.png) + +那么问题来了,是不是现在已经授权成功了呢?答案是否定的!你可以试试直接去访问产品的http请求地址: + +![image-20200920085214629](images/image-20200920085214629.png) + +我们发现xiaozhi其实是可以操作产品模块的,只是没有把产品功能展示给xiaozhi而已! + +总结一句:页面动态菜单的展示只是为了用户体验,并未真正控制权限! + +## 授权操作 + +### IOC容器介绍 + +![image-20200920092132700](images/image-20200920092132700.png) + +从这里我们就可以知道,我们的spring-security.xml需要放到父容器中被保护起来,不能放到子容器中被直接访问 + +说明:SpringSecurity可以通过注解的方式来控制类或者方法的访问权限。注解需要对应的注解支持,若注解放在 +controller类中,对应注解支持应该放在mvc配置文件中,因为controller类是有mvc配置文件扫描并创建的,同 +理,注解放在service类中,对应注解支持应该放在spring配置文件中。由于我们现在是模拟业务操作,并没有 +service业务代码,所以就把注解放在controller类中了。 + +### 开启授权的注解支持 + +这里给大家演示三类注解,但实际开发中,用一类即可! + +```xml + + +``` + +### 在注解支持对应类或者方法上添加注解 + +![image-20200920093528937](images/image-20200920093528937.png) + +![image-20200920093540583](images/image-20200920093540583.png) + +我们也可以使用多种注解的方式 + +```java +@Controller +@RequestMapping("/product") +public class ProductController { + + //@Secured({"ROLE_PRODUCT","ROLE_ADMIN"})//springSecurity内部制定的注解 + //@RolesAllowed({"ROLE_PRODUCT","ROLE_ADMIN"})//jsr250注解 + @PreAuthorize("hasAnyAuthority('ROLE_PRODUCT','ROLE_ADMIN')")//spring的el表达式注解 + @RequestMapping("/findAll") + public String findAll(){ + return "product-list"; + } +} +``` + +## 权限不足异常处理 + +大家也发现了,每次权限不足都出现403页面,着实难堪!体会一下: + +![image-20200920093821600](images/image-20200920093821600.png) + +用户体验不是很好,现在我们立马消灭它! + +![image-20200920094756860](images/image-20200920094756860.png) + +### 方式一:在spring-security.xml配置文件中处理 + +```xml + + + + + + +``` + +### 方式二:在web.xml中处理 + +```bash + + 403 + /403.jsp + +``` + +### 方式三:编写异常处理器 + +拦截器和过滤器的区别 + +- 拦截器:可以在Spring中进行使用 +- 过滤器:只能在web.xml中进行配置,也就是只能在web工程中使用 + +或者我们可以实现一个Spring给我们提供好的接口 + +```java +@Component +public class HandlerControllerException implements HandlerExceptionResolver { + /** + * @param httpServletRequest + * @param httpServletResponse + * @param o 出现异常的对象 + * @param e 出现的异常信息 + * @return ModelAndView + */ + @Override + public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { + ModelAndView mv = new ModelAndView(); + //将异常信息放入request域中,基本不用 + mv.addObject("errorMsg", e.getMessage()); + //指定不同异常跳转的页面 + if(e instanceof AccessDeniedException){ + mv.setViewName("redirect:/403.jsp"); + }else { + mv.setViewName("redirect:/500.jsp"); + } + return mv; + } +} +``` + +下面一个更简单的方式,通过注解就相当于我们实现了 HandlerExceptionResolver + +```java +@ControllerAdvice +public class HandlerControllerAdvice{ + + @ExceptionHandler(AccessDeniedException.class) + public String handlerException(){ + return "redirect:/403.jsp"; + } + + @ExceptionHandler(RuntimeException.class) + public String runtimeHandlerException(){ + return "redirect:/500.jsp"; + } +} +``` + diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919214537040.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919214537040.png" new file mode 100644 index 0000000000000000000000000000000000000000..a36cd5c462fb5579f923ad394153d2d31288bcfc Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919214537040.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215441535.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215441535.png" new file mode 100644 index 0000000000000000000000000000000000000000..a91908928f04ec9b1a7d21ca8bc4cfce9a4d4586 Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215441535.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215502008.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215502008.png" new file mode 100644 index 0000000000000000000000000000000000000000..407bdb746e470ebc3e1e92fcd372e3979871b841 Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215502008.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215510847.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215510847.png" new file mode 100644 index 0000000000000000000000000000000000000000..e1d78e4f454a2caecca44db98c2e8c9d490455ff Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215510847.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215604473.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215604473.png" new file mode 100644 index 0000000000000000000000000000000000000000..72b6f2ac3e228c79d4a29b514a413f448f20879d Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215604473.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215750642.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215750642.png" new file mode 100644 index 0000000000000000000000000000000000000000..cd8b479b81e9b09fe17115f7b9e935b6feb6246c Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919215750642.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919220254094.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919220254094.png" new file mode 100644 index 0000000000000000000000000000000000000000..999c0c193f3c56adea671c1acdafd7c85b10535f Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200919220254094.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084345762.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084345762.png" new file mode 100644 index 0000000000000000000000000000000000000000..1d2ae18f88eb54d21c31be87598dde7fb087eaa0 Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084345762.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084406261.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084406261.png" new file mode 100644 index 0000000000000000000000000000000000000000..53c221a6f194ae05ef770c76bbc648864c490cd9 Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084406261.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084933415.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084933415.png" new file mode 100644 index 0000000000000000000000000000000000000000..9c55ba34f2e87692d2ca4748704e04af203be835 Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084933415.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084945102.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084945102.png" new file mode 100644 index 0000000000000000000000000000000000000000..b46bb25382fab21e2cf263877e421c68e8ccc119 Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084945102.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084959631.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084959631.png" new file mode 100644 index 0000000000000000000000000000000000000000..b8a948831a4d0f0ea255226033a2917211250649 Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920084959631.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920085153413.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920085153413.png" new file mode 100644 index 0000000000000000000000000000000000000000..2106ef7dccd31303fff21405422afb8fda873f21 Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920085153413.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920085214629.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920085214629.png" new file mode 100644 index 0000000000000000000000000000000000000000..5c5c961862db9a64c472e08ed911a04c1896fd14 Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920085214629.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920092132700.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920092132700.png" new file mode 100644 index 0000000000000000000000000000000000000000..ff729ab2ad87389bfe2e74fe06eec5dd8dd87dda Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920092132700.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920093528937.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920093528937.png" new file mode 100644 index 0000000000000000000000000000000000000000..82f895f900e0042c927acc82b0537f5c270c2b8e Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920093528937.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920093540583.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920093540583.png" new file mode 100644 index 0000000000000000000000000000000000000000..f40a11001a86defb70d396e332a96dde1e517f3f Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920093540583.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920093821600.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920093821600.png" new file mode 100644 index 0000000000000000000000000000000000000000..6179cf0d7a9c3e0a3776dd57e3894e4f9dd79428 Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920093821600.png" differ diff --git "a/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920094756860.png" "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920094756860.png" new file mode 100644 index 0000000000000000000000000000000000000000..b4f6367433845d4aa9c4d9d11e718d7e242fc537 Binary files /dev/null and "b/SpringSecurity/2_SpringSecurity\345\234\250MVC\351\241\271\347\233\256\344\270\255\347\232\204\344\275\277\347\224\250/images/image-20200920094756860.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/README.md" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..51e839d0f92512903723ccfba9f7811a3331708b --- /dev/null +++ "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/README.md" @@ -0,0 +1,470 @@ +# SpringSecurity在单机环境下使用 + +## 参考 + +来源于黑马程序员: [手把手教你精通新版SpringSecurity](https://www.bilibili.com/video/BV1EE411u7YV?p=33) + +## 技术选型 + +SpringBoot2.1.3,SpringSecurity,MySQL,mybatis,jsp + +## 初步整合认证第一版 + +### 创建工程并导入jar包 + +先只导入SpringBoot + +```xml + + org.springframework.boot + spring-boot-starter-parent + 2.1.3.RELEASE + + + + + + org.springframework.boot + spring-boot-starter-web + + +``` + +### 提供处理器 + +```java +@Controller +@RequestMapping("/product") +public class ProductController { + @RequestMapping + @ResponseBody + public String hello(){ + return "success"; + } +} +``` + +### 编写启动类 + +```java +@SpringBootApplication +public class SecurityApplication { + public static void main(String[] args) { + SpringApplication.run(SecurityApplication.class, args); + } +} +``` + +### 测试效果 + +使用SpringBoot内置tomcat启动项目,即可访问处理器。 + +![image-20200920192128613](images/image-20200920192128613.png) + +### 加入SpringSecurity的jar包 + +```xml + + org.springframework.boot + spring-boot-starter-security + +``` + +### 重启再次测试 + +SpringBoot已经为SpringSecurity提供了默认配置,默认所有资源都必须认证通过才能访问。 + +![image-20200920192210458](images/image-20200920192210458.png) + +那么问题来了!此刻并没有连接数据库,也并未在内存中指定认证用户,如何认证呢? + +其实SpringBoot已经提供了默认用户名user,密码在项目启动时随机生成,如图: + +![image-20200920192235998](images/image-20200920192235998.png) + +认证通过后可以继续访问处理器资源: + +![image-20200920192255766](images/image-20200920192255766.png) + +## 整合认证第二版 + +加入jsp,使用自定义认证页面 + +### 说明 + +SpringBoot官方是不推荐在SpringBoot中使用jsp的,那么到底可以使用吗?答案是肯定的! + +不过需要导入tomcat插件启动项目,不能再用SpringBoot默认tomcat了。 + +我们不能 通过启动类的方式来进行启动了,因为它会不识别Jsp页面,必须导入jar包,然后更换方法 + +### 导入SpringBoot的tomcat启动插件jar包 + +```xml + + org.springframework.boot + spring-boot-starter-tomcat + + + org.apache.tomcat.embed + tomcat-embed-jasper + +``` + +### 加入jsp页面等静态资源 + +在src/main目录下创建webapp目录 + +![image-20200920192528568](images/image-20200920192528568.png) + +这时webapp目录并不能正常使用,因为只有web工程才有webapp目录,在pom文件中修改项目为web工程 + +![image-20200920192549742](images/image-20200920192549742.png) + +这时webapp目录,可以正常使用了! + +![image-20200920192656366](images/image-20200920192656366.png) + +导入第一天案例中静态资源,注意WEB-INF就不用了哈! + +![image-20200920192716037](images/image-20200920192716037.png) + +修改login.jsp中认证的url地址 + +![image-20200920192740415](images/image-20200920192740415.png) + +修改header.jsp中退出登录的url地址 + +![image-20200920192756254](images/image-20200920192756254.png) + +### 提供SpringSecurity配置类 + +```java +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(securedEnabled=true) +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private UserService userService; + + @Bean + public BCryptPasswordEncoder passwordEncoder(){ + return new BCryptPasswordEncoder(); + } + + //指定认证对象的来源 + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userService).passwordEncoder(passwordEncoder()); + } + //SpringSecurity配置信息 + public void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/login.jsp", "failer.jsp", "/css/**", "/img/**", "/plugins/**").permitAll() + .antMatchers("/product").hasAnyRole("USER") + .anyRequest().authenticated() + .and() + .formLogin() + .loginPage("/login.jsp") + .loginProcessingUrl("/login") + .successForwardUrl("/index.jsp") + .failureForwardUrl("/failer.jsp") + .and() + .logout() + .logoutSuccessUrl("/logout") + .invalidateHttpSession(true) + .logoutSuccessUrl("/login.jsp") + .and() + .csrf() + .disable(); + } +} +``` + +### 修改产品处理器 + +有页面了,就跳转一个真的吧! + +```java +@Controller +@RequestMapping("/product") +public class ProductController { + @RequestMapping("/findAll") + public String findAll(){ + return "product-list"; + } +} +``` + +### 配置视图解析器 + +![image-20200920194505651](images/image-20200920194505651.png) + +### 使用tomcat插件启动项目 + +![image-20200920194522836](images/image-20200920194522836.png) + +### 测试效果 + +自定义的认证页面 + +![image-20200920194537008](images/image-20200920194537008.png) + +认证成功页面 + +![image-20200920194548999](images/image-20200920194548999.png) + +## 整合认证第三版【数据库认证】 + +### 数据库环境准备 + +依然使用security_authority数据库,sql语句在第一天资料里。 + +### 导入数据库操作相关jar包 + +```xml + + + mysql + mysql-connector-java + 5.1.47 + + + + tk.mybatis + mapper-spring-boot-starter + 2.1.5 + + + + tk.mybatis + mapper-spring-boot-starter + 2.1.5 + +``` + +### 在配置文件中添加数据库操作相关配置 + +![image-20200920194644145](images/image-20200920194644145.png) + +### 在启动类上添加扫描dao接口包注解 + +![image-20200920194847462](images/image-20200920194847462.png) + +### 创建用户pojo对象 + +这里直接实现SpringSecurity的用户对象接口,并添加角色集合私有属性。注意接口属性都要标记不参与json的处理 + +```java +@Data +public class SysRole implements GrantedAuthority { + + private Integer id; + private String roleName; + private String roleDesc; +} +``` + + + +### 创建角色pojo对象 + +这里直接使用SpringSecurity的角色规范,我们实现UserDetails的类型 + +```java +@Data +public class SysUser implements UserDetails { + + private Integer id; + private String username; + private String password; + private Integer status; + private List roles; + + @JsonIgnore + @Override + public Collection getAuthorities() { + return roles; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getUsername() { + return username; + } + + @JsonIgnore + @Override + public boolean isAccountNonExpired() { + return true; + } + + @JsonIgnore + @Override + public boolean isAccountNonLocked() { + return true; + } + + @JsonIgnore + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @JsonIgnore + @Override + public boolean isEnabled() { + return true; + } +} +``` + +### 提供角色mapper接口 + +```java +public interface RoleMapper extends Mapper { + @Select("SELECT r.id, r.role_name roleName, r.role_desc roleDesc " + + "FROM sys_role r, sys_user_role ur " + + "WHERE r.id=ur.rid AND ur.uid=#{uid}") + public List findByUid(Integer uid); +} +``` + +### 提供用户mapper接口 + +这里就用到了Mybatis的一对多进行操作 + +```java +public interface UserMapper extends Mapper { + + @Select("select * from sys_user where username = #{username}") + @Results({ + @Result(id = true, property = "id", column = "id"), + @Result(property = "roles", column = "id", javaType = List.class, + many = @Many(select = "com.itheima.mapper.RoleMapper.findByUid")) + }) + public SysUser findByName(String username); +} +``` + +### 提供认证service接口 + +```java +@Service +@Transactional +public class UserServiceImpl implements UserService { + @Autowired + private UserMapper userMapper; + @Override + public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { + return userMapper.findByUsername(s); + } +} +``` + +### 在启动类中把加密对象放入IOC容器 + +```java +@SpringBootApplication +@MapperScan("com.itheima.mapper") +public class SecurityApplication { + public static void main(String[] args) { + SpringApplication.run(SecurityApplication.class, args); + } + @Bean + public BCryptPasswordEncoder passwordEncoder(){ + return new BCryptPasswordEncoder(); + } +} +``` + +### 修改配置类 + +```java +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(securedEnabled=true) +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private UserService userService; + + @Bean + public BCryptPasswordEncoder passwordEncoder(){ + return new BCryptPasswordEncoder(); + } + + //指定认证对象的来源 + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userService).passwordEncoder(passwordEncoder()); + } + //SpringSecurity配置信息 + public void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/login.jsp", "failer.jsp", "/css/**", "/img/**", "/plugins/**").permitAll() + .antMatchers("/product").hasAnyRole("USER") + .anyRequest().authenticated() + .and() + .formLogin() + .loginPage("/login.jsp") + .loginProcessingUrl("/login") + .successForwardUrl("/index.jsp") + .failureForwardUrl("/failer.jsp") + .and() + .logout() + .logoutSuccessUrl("/logout") + .invalidateHttpSession(true) + .logoutSuccessUrl("/login.jsp") + .and() + .csrf() + .disable(); + } +} +``` + +大功告成尽管测试,注意还是用插件启动项目,使用数据库表中的用户名和密码。 + +### 整合实现授权功能 + +在启动类上添加开启方法级的授权注解 + +![image-20200920201619857](images/image-20200920201619857.png) + +### 在产品处理器类上添加注解 + +要求产品列表功能必须具有ROLE_ADMIN角色才能访问! + +![image-20200920201804274](images/image-20200920201804274.png) + +### 重启项目测试 + +再次访问产品列表发现权限不足 + +![image-20200920202057441](images/image-20200920202057441.png) + +### 指定自定义异常页面 + +编写异常处理器拦截403异常 + +```java +@ControllerAdvice +public class HandleControllerException { + @ExceptionHandler(RuntimeException.class) + public String exceptionHandler(RuntimeException e){ + if(e instanceof AccessDeniedException){ + //如果是权限不足异常,则跳转到权限不足页面! + return "redirect:/403.jsp"; + } + //其余的异常都到500页面! + return "redirect:/500.jsp"; + } +} +``` + +再次测试产品列表就可以到自定义异常页面了 + +![image-20200920202215597](images/image-20200920202215597.png) \ No newline at end of file diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192128613.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192128613.png" new file mode 100644 index 0000000000000000000000000000000000000000..5cb717517e4edd72299da8e2f0b4b5c2809aa8e0 Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192128613.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192210458.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192210458.png" new file mode 100644 index 0000000000000000000000000000000000000000..c63ea227cedc338926667a3232c5fa5b3c3a15fc Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192210458.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192235998.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192235998.png" new file mode 100644 index 0000000000000000000000000000000000000000..58177b520b488e6632c7d95a3747d2e812365dba Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192235998.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192255766.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192255766.png" new file mode 100644 index 0000000000000000000000000000000000000000..1e798d5946db1c976ff62945066b8fa141b44906 Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192255766.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192528568.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192528568.png" new file mode 100644 index 0000000000000000000000000000000000000000..871b17dad8bf42f7d20dcd2a9a6ea7be6245ac6a Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192528568.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192549742.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192549742.png" new file mode 100644 index 0000000000000000000000000000000000000000..3f0f0335093f8740d337395f387f733eaec4f7da Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192549742.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192656366.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192656366.png" new file mode 100644 index 0000000000000000000000000000000000000000..e4a17e2f9498cded99052375ed4a0359be826cf9 Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192656366.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192716037.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192716037.png" new file mode 100644 index 0000000000000000000000000000000000000000..57e4112c543cb24f6f3fbb49f74316fbe82fa951 Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192716037.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192740415.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192740415.png" new file mode 100644 index 0000000000000000000000000000000000000000..4009d65449bf6b9700654219ed9104cea4f18687 Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192740415.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192756254.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192756254.png" new file mode 100644 index 0000000000000000000000000000000000000000..8f75ed7876fe70cade8ac00fc73954d5c5c49e32 Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920192756254.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194505651.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194505651.png" new file mode 100644 index 0000000000000000000000000000000000000000..7b40687f739a33009911758d469d0fa59d9ea5bc Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194505651.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194522836.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194522836.png" new file mode 100644 index 0000000000000000000000000000000000000000..dc1fa986b0539a2466b29008fcd838190fd928bd Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194522836.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194537008.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194537008.png" new file mode 100644 index 0000000000000000000000000000000000000000..c8b5b886a7b18e707f48b0643cc8f3cda2f44d64 Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194537008.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194548999.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194548999.png" new file mode 100644 index 0000000000000000000000000000000000000000..cd809658a82815af6ca4db293ef6f9184512bb85 Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194548999.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194644145.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194644145.png" new file mode 100644 index 0000000000000000000000000000000000000000..986fc19ac39c72a48f2d4ec438af2f79dc1fb38b Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194644145.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194847462.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194847462.png" new file mode 100644 index 0000000000000000000000000000000000000000..2b628c06b60907bf2746d65ed306af103e47eaf6 Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920194847462.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920201619857.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920201619857.png" new file mode 100644 index 0000000000000000000000000000000000000000..3acb27bd2d5f3d42940e1f429b2dfb1ded709af5 Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920201619857.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920201804274.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920201804274.png" new file mode 100644 index 0000000000000000000000000000000000000000..9ee5b0fb7d78ee3b8a44e4c071e0e6ef4196d146 Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920201804274.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920202057441.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920202057441.png" new file mode 100644 index 0000000000000000000000000000000000000000..68ee7d17b04e4d5fed8a28e151d749b7ff5f8eb7 Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920202057441.png" differ diff --git "a/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920202215597.png" "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920202215597.png" new file mode 100644 index 0000000000000000000000000000000000000000..bf53afb48970a812e513af8479cfbe49eced38ca Binary files /dev/null and "b/SpringSecurity/3_SpringSecurity\345\234\250\345\215\225\346\234\272\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920202215597.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/README.md" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..2b249ee3caa22bbbedf88f35debb1ab10910586b --- /dev/null +++ "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/README.md" @@ -0,0 +1,1157 @@ +# SpringSecurity在分布式环境下的使用 + +## 参考 + +来源于黑马程序员: [手把手教你精通新版SpringSecurity](https://www.bilibili.com/video/BV1EE411u7YV?p=43) + +## 分布式认证概念说明 + +分布式认证,即我们常说的单点登录,简称SSO,指的是在多应用系统的项目中,用户只需要登录一次,就可以访 +问所有互相信任的应用系统。 + +## 分布式认证流程图 + +首先,我们要明确,在分布式项目中,每台服务器都有各自独立的session,而这些session之间是无法直接共享资 +源的,所以,session通常不能被作为单点登录的技术方案。最合理的单点登录方案流程如下图所示: + +![image-20200920202612159](images/image-20200920202612159.png) + +**总结一下,单点登录的实现分两大环节:** + +- **用户认证:**这一环节主要是用户向认证服务器发起认证请求,认证服务器给用户返回一个成功的令牌token, + 主要在认证服务器中完成,即图中的A系统,注意A系统只能有一个。 +- **身份校验:**这一环节是用户携带token去访问其他服务器时,在其他服务器中要对token的真伪进行检验,主 + 要在资源服务器中完成,即图中的B系统,这里B系统可以有很多个。 + +## JWT介绍 + +### 概念说明 + +从分布式认证流程中,我们不难发现,这中间起最关键作用的就是token,token的安全与否,直接关系到系统的 +健壮性,这里我们选择使用JWT来实现token的生成和校验。 +JWT,全称JSON Web Token,官网地址https://jwt.io,是一款出色的分布式身份校验方案。可以生成token,也可以解析检验token。 + +### JWT生成的token由三部分组成 + +- **头部**:主要设置一些规范信息,签名部分的编码格式就在头部中声明。 +- **载荷**:token中存放有效信息的部分,比如用户名,用户角色,过期时间等,但是不要放密码,会泄露! +- **签名**:将头部与载荷分别采用base64编码后,用“.”相连,再加入**盐**,最后使用头部声明的编码类型进行编 + 码,就得到了签名。【通过随机盐在进行加密】 + +### JWT生成token的安全性分析 + +从JWT生成的token组成上来看,要想避免token被伪造,主要就得看签名部分了,而签名部分又有三部分组成,其中头部和载荷的base64编码,几乎是透明的,毫无安全性可言,那么最终守护token安全的重担就落在了加入的盐上面了! + +试想:如果生成token所用的盐与解析token时加入的盐是一样的。岂不是类似于中国人民银行把人民币防伪技术 +公开了?大家可以用这个盐来解析token,就能用来伪造token。这时,我们就需要对盐采用非对称加密的方式进行加密,以达到生成token与校验token方所用的盐不一致的安全效果! + +## 非对称加密RSA介绍 + +- **基本原理:**同时生成两把密钥:私钥和公钥,私钥隐秘保存,公钥可以下发给信任客户端 +- **私钥加密**,持有私钥或公钥才可以解密 +- **公钥加密**,持有私钥才可解密 +- **优点**:安全,难以破解 +- **缺点**:算法比较耗时,为了安全,可以接受 +- **历史**:三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三 + 个人的名字缩写:RSA。 + +【总结】:也就是说,我们加密信息的时候,使用的是公钥,而验证token真伪的时候,使用的是公钥 + +## JWT相关工具类 + +### jar包 + +```xml + + io.jsonwebtoken + jjwt-api + 0.10.7 + + + + io.jsonwebtoken + jjwt-impl + 0.10.7 + runtime + + + + io.jsonwebtoken + jjwt-jackson + 0.10.7 + runtime + +``` + +### 载荷对象 + +```java +/** +* 为了方便后期获取token中的用户信息,将token中载荷部分单独封装成一个对象 +*/ +@Data +public class Payload { + +} +``` + +### JWT工具类 + +```java +/** + * 生成token以及校验token相关方法 + */ +public class JwtUtils { + + private static final String JWT_PAYLOAD_USER_KEY = "user"; + + /** + * 私钥加密token + * + * @param userInfo 载荷中的数据 + * @param privateKey 私钥 + * @param expire 过期时间,单位分钟 + * @return JWT + */ + public static String generateTokenExpireInMinutes(Object userInfo, PrivateKey privateKey, int expire) { + return Jwts.builder() + .claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo)) + .setId(createJTI()) + .setExpiration(DateTime.now().plusMinutes(expire).toDate()) + .signWith(privateKey, SignatureAlgorithm.RS256) + .compact(); + } + + /** + * 私钥加密token + * + * @param userInfo 载荷中的数据 + * @param privateKey 私钥 + * @param expire 过期时间,单位秒 + * @return JWT + */ + public static String generateTokenExpireInSeconds(Object userInfo, PrivateKey privateKey, int expire) { + return Jwts.builder() + .claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo)) + .setId(createJTI()) + .setExpiration(DateTime.now().plusSeconds(expire).toDate()) + .signWith(privateKey, SignatureAlgorithm.RS256) + .compact(); + } + + /** + * 公钥解析token + * + * @param token 用户请求中的token + * @param publicKey 公钥 + * @return Jws + */ + private static Jws parserToken(String token, PublicKey publicKey) { + return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token); + } + + private static String createJTI() { + return new String(Base64.getEncoder().encode(UUID.randomUUID().toString().getBytes())); + } + + /** + * 获取token中的用户信息 + * + * @param token 用户请求中的令牌 + * @param publicKey 公钥 + * @return 用户信息 + */ + public static Payload getInfoFromToken(String token, PublicKey publicKey, Class userType) { + Jws claimsJws = parserToken(token, publicKey); + Claims body = claimsJws.getBody(); + Payload claims = new Payload<>(); + claims.setId(body.getId()); + claims.setUserInfo(JsonUtils.toBean(body.get(JWT_PAYLOAD_USER_KEY).toString(), userType)); + claims.setExpiration(body.getExpiration()); + return claims; + } + + /** + * 获取token中的载荷信息 + * + * @param token 用户请求中的令牌 + * @param publicKey 公钥 + * @return 用户信息 + */ + public static Payload getInfoFromToken(String token, PublicKey publicKey) { + Jws claimsJws = parserToken(token, publicKey); + Claims body = claimsJws.getBody(); + Payload claims = new Payload<>(); + claims.setId(body.getId()); + claims.setExpiration(body.getExpiration()); + return claims; + } +} +``` + +### RSA工具类 + +非对称加密工具列 + +```java +public class RsaUtils { + + private static final int DEFAULT_KEY_SIZE = 2048; + /** + * 从文件中读取公钥 + * + * @param filename 公钥保存路径,相对于classpath + * @return 公钥对象 + * @throws Exception + */ + public static PublicKey getPublicKey(String filename) throws Exception { + byte[] bytes = readFile(filename); + return getPublicKey(bytes); + } + + /** + * 从文件中读取密钥 + * + * @param filename 私钥保存路径,相对于classpath + * @return 私钥对象 + * @throws Exception + */ + public static PrivateKey getPrivateKey(String filename) throws Exception { + byte[] bytes = readFile(filename); + return getPrivateKey(bytes); + } + + /** + * 获取公钥 + * + * @param bytes 公钥的字节形式 + * @return + * @throws Exception + */ + private static PublicKey getPublicKey(byte[] bytes) throws Exception { + bytes = Base64.getDecoder().decode(bytes); + X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes); + KeyFactory factory = KeyFactory.getInstance("RSA"); + return factory.generatePublic(spec); + } + + /** + * 获取密钥 + * + * @param bytes 私钥的字节形式 + * @return + * @throws Exception + */ + private static PrivateKey getPrivateKey(byte[] bytes) throws NoSuchAlgorithmException, InvalidKeySpecException { + bytes = Base64.getDecoder().decode(bytes); + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes); + KeyFactory factory = KeyFactory.getInstance("RSA"); + return factory.generatePrivate(spec); + } + + /** + * 根据密文,生存rsa公钥和私钥,并写入指定文件 + * + * @param publicKeyFilename 公钥文件路径 + * @param privateKeyFilename 私钥文件路径 + * @param secret 生成密钥的密文 + */ + public static void generateKey(String publicKeyFilename, String privateKeyFilename, String secret, int keySize) throws Exception { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + SecureRandom secureRandom = new SecureRandom(secret.getBytes()); + keyPairGenerator.initialize(Math.max(keySize, DEFAULT_KEY_SIZE), secureRandom); + KeyPair keyPair = keyPairGenerator.genKeyPair(); + // 获取公钥并写出 + byte[] publicKeyBytes = keyPair.getPublic().getEncoded(); + publicKeyBytes = Base64.getEncoder().encode(publicKeyBytes); + writeFile(publicKeyFilename, publicKeyBytes); + // 获取私钥并写出 + byte[] privateKeyBytes = keyPair.getPrivate().getEncoded(); + privateKeyBytes = Base64.getEncoder().encode(privateKeyBytes); + writeFile(privateKeyFilename, privateKeyBytes); + } + + private static byte[] readFile(String fileName) throws Exception { + return Files.readAllBytes(new File(fileName).toPath()); + } + + private static void writeFile(String destPath, byte[] bytes) throws IOException { + File dest = new File(destPath); + if (!dest.exists()) { + dest.createNewFile(); + } + Files.write(dest.toPath(), bytes); + } +} +``` + +## SpringSecurity+JWT+RSA分布式认证思路分析 + +SpringSecurity主要是通过过滤器来实现功能的!我们要找到SpringSecurity实现认证和校验身份的过滤器! +回顾集中式认证流程 + +### 用户认证 + +使用UsernamePasswordAuthenticationFilter过滤器中attemptAuthentication方法实现认证功能,该过滤 +器父类中successfulAuthentication方法实现认证成功后的操作。 + +### 身份校验 + +使用BasicAuthenticationFilter过滤器中doFilterInternal方法验证是否登录,以决定能否进入后续过滤器。 +分析分布式认证流程 + +### 用户认证 + +由于,分布式项目,多数是前后端分离的架构设计,我们要满足可以接受异步post的认证请求参数,需要修 +改UsernamePasswordAuthenticationFilter过滤器中attemptAuthentication方法,让其能够接收请求体。 + +另外,默认successfulAuthentication方法在认证通过后,是把用户信息直接放入session就完事了,现在我 +们需要修改这个方法,在认证通过后生成token并返回给用户。 + +### 身份校验 + +原来BasicAuthenticationFilter过滤器中doFilterInternal方法校验用户是否登录,就是看session中是否有用 +户信息,我们要修改为,验证用户携带的token是否合法,并解析出用户信息,交给SpringSecurity,以便于 +后续的授权功能可以正常使用。 + +## SpringSecurity+JWT+RSA分布式认证实现 + +### 创建父工程并导入jar包 + +```xml + + + 4.0.0 + + com.itheima + springboot_security_jwt_rsa_parent + pom + 1.0-SNAPSHOT + + heima_common + heima_auth_server + heima_source_product + + + + org.springframework.boot + spring-boot-starter-parent + 2.1.3.RELEASE + + + +``` + +## 通用模块 + +创建通用子模块并导入JWT相关jar包 + +```xml + + + + springboot_security_jwt_rsa_parent + com.itheima + 1.0-SNAPSHOT + + 4.0.0 + + heima_common + + + + io.jsonwebtoken + jjwt-api + 0.10.7 + + + io.jsonwebtoken + jjwt-impl + 0.10.7 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.10.7 + runtime + + + + com.fasterxml.jackson.core + jackson-databind + 2.9.9 + + + + org.springframework.boot + spring-boot-starter-logging + + + joda-time + joda-time + + + org.projectlombok + lombok + + + org.springframework.boot + spring-boot-starter-test + + + +``` + +### 导入工具类 + +工具类如下 + +![image-20200920210659250](images/image-20200920210659250.png) + +### Payload.java + +```java +/** + * 为了方便后期获取token中的用户信息,将token中载荷部分单独封装成一个对象 + */ +@Data +public class Payload { + private String id; + private T userInfo; + private Date expiration; +} +``` + +### JsonUtil.java + +```java +public class JsonUtils { + + public static final ObjectMapper mapper = new ObjectMapper(); + + private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class); + + public static String toString(Object obj) { + if (obj == null) { + return null; + } + if (obj.getClass() == String.class) { + return (String) obj; + } + try { + return mapper.writeValueAsString(obj); + } catch (JsonProcessingException e) { + logger.error("json序列化出错:" + obj, e); + return null; + } + } + + public static T toBean(String json, Class tClass) { + try { + return mapper.readValue(json, tClass); + } catch (IOException e) { + logger.error("json解析出错:" + json, e); + return null; + } + } + + public static List toList(String json, Class eClass) { + try { + return mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, eClass)); + } catch (IOException e) { + logger.error("json解析出错:" + json, e); + return null; + } + } + + public static Map toMap(String json, Class kClass, Class vClass) { + try { + return mapper.readValue(json, mapper.getTypeFactory().constructMapType(Map.class, kClass, vClass)); + } catch (IOException e) { + logger.error("json解析出错:" + json, e); + return null; + } + } + + public static T nativeRead(String json, TypeReference type) { + try { + return mapper.readValue(json, type); + } catch (IOException e) { + logger.error("json解析出错:" + json, e); + return null; + } + } +} +``` + +### jwtUitls.java + +```java +public class JwtUtils { + + private static final String JWT_PAYLOAD_USER_KEY = "user"; + + /** + * 私钥加密token + * + * @param userInfo 载荷中的数据 + * @param privateKey 私钥 + * @param expire 过期时间,单位分钟 + * @return JWT + */ + public static String generateTokenExpireInMinutes(Object userInfo, PrivateKey privateKey, int expire) { + return Jwts.builder() + .claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo)) + .setId(createJTI()) + .setExpiration(DateTime.now().plusMinutes(expire).toDate()) + .signWith(privateKey, SignatureAlgorithm.RS256) + .compact(); + } + + /** + * 私钥加密token + * + * @param userInfo 载荷中的数据 + * @param privateKey 私钥 + * @param expire 过期时间,单位秒 + * @return JWT + */ + public static String generateTokenExpireInSeconds(Object userInfo, PrivateKey privateKey, int expire) { + return Jwts.builder() + .claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo)) + .setId(createJTI()) + .setExpiration(DateTime.now().plusSeconds(expire).toDate()) + .signWith(privateKey, SignatureAlgorithm.RS256) + .compact(); + } + + /** + * 公钥解析token + * + * @param token 用户请求中的token + * @param publicKey 公钥 + * @return Jws + */ + private static Jws parserToken(String token, PublicKey publicKey) { + return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token); + } + + private static String createJTI() { + return new String(Base64.getEncoder().encode(UUID.randomUUID().toString().getBytes())); + } + + /** + * 获取token中的用户信息 + * + * @param token 用户请求中的令牌 + * @param publicKey 公钥 + * @return 用户信息 + */ + public static Payload getInfoFromToken(String token, PublicKey publicKey, Class userType) { + Jws claimsJws = parserToken(token, publicKey); + Claims body = claimsJws.getBody(); + Payload claims = new Payload<>(); + claims.setId(body.getId()); + claims.setUserInfo(JsonUtils.toBean(body.get(JWT_PAYLOAD_USER_KEY).toString(), userType)); + claims.setExpiration(body.getExpiration()); + return claims; + } + + /** + * 获取token中的载荷信息 + * + * @param token 用户请求中的令牌 + * @param publicKey 公钥 + * @return 用户信息 + */ + public static Payload getInfoFromToken(String token, PublicKey publicKey) { + Jws claimsJws = parserToken(token, publicKey); + Claims body = claimsJws.getBody(); + Payload claims = new Payload<>(); + claims.setId(body.getId()); + claims.setExpiration(body.getExpiration()); + return claims; + } +} +``` + +### RsaUtils.java + +```java +public class RsaUtils { + + private static final int DEFAULT_KEY_SIZE = 2048; + /** + * 从文件中读取公钥 + * + * @param filename 公钥保存路径,相对于classpath + * @return 公钥对象 + * @throws Exception + */ + public static PublicKey getPublicKey(String filename) throws Exception { + byte[] bytes = readFile(filename); + return getPublicKey(bytes); + } + + /** + * 从文件中读取密钥 + * + * @param filename 私钥保存路径,相对于classpath + * @return 私钥对象 + * @throws Exception + */ + public static PrivateKey getPrivateKey(String filename) throws Exception { + byte[] bytes = readFile(filename); + return getPrivateKey(bytes); + } + + /** + * 获取公钥 + * + * @param bytes 公钥的字节形式 + * @return + * @throws Exception + */ + private static PublicKey getPublicKey(byte[] bytes) throws Exception { + bytes = Base64.getDecoder().decode(bytes); + X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes); + KeyFactory factory = KeyFactory.getInstance("RSA"); + return factory.generatePublic(spec); + } + + /** + * 获取密钥 + * + * @param bytes 私钥的字节形式 + * @return + * @throws Exception + */ + private static PrivateKey getPrivateKey(byte[] bytes) throws NoSuchAlgorithmException, InvalidKeySpecException { + bytes = Base64.getDecoder().decode(bytes); + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes); + KeyFactory factory = KeyFactory.getInstance("RSA"); + return factory.generatePrivate(spec); + } + + /** + * 根据密文,生存rsa公钥和私钥,并写入指定文件 + * + * @param publicKeyFilename 公钥文件路径 + * @param privateKeyFilename 私钥文件路径 + * @param secret 生成密钥的密文 + */ + public static void generateKey(String publicKeyFilename, String privateKeyFilename, String secret, int keySize) throws Exception { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + SecureRandom secureRandom = new SecureRandom(secret.getBytes()); + keyPairGenerator.initialize(Math.max(keySize, DEFAULT_KEY_SIZE), secureRandom); + KeyPair keyPair = keyPairGenerator.genKeyPair(); + // 获取公钥并写出 + byte[] publicKeyBytes = keyPair.getPublic().getEncoded(); + publicKeyBytes = Base64.getEncoder().encode(publicKeyBytes); + writeFile(publicKeyFilename, publicKeyBytes); + // 获取私钥并写出 + byte[] privateKeyBytes = keyPair.getPrivate().getEncoded(); + privateKeyBytes = Base64.getEncoder().encode(privateKeyBytes); + writeFile(privateKeyFilename, privateKeyBytes); + } + + private static byte[] readFile(String fileName) throws Exception { + return Files.readAllBytes(new File(fileName).toPath()); + } + + private static void writeFile(String destPath, byte[] bytes) throws IOException { + File dest = new File(destPath); + if (!dest.exists()) { + dest.createNewFile(); + } + Files.write(dest.toPath(), bytes); + } +} +``` + +### 在通用子模块中编写测试类生成rsa公钥和私钥 + +```java +public class RsaUtilsTest { + private String publicFile = "D:\\auth_key\\rsa_key.pub"; + private String privateFile = "D:\\auth_key\\rsa_key"; + @Test + public void generateKey() throws Exception { + RsaUtils.generateKey(publicFile, privateFile, "heima", 2048); + } +} +``` + +执行后查看D:\auth_key目录发现私钥和公钥文件生成成功 + +![image-20200920211051749](images/image-20200920211051749.png) + +## 认证服务 + +创建认证服务工程并导入jar包 + +```xml + + + + springboot_security_jwt_rsa_parent + com.itheima + 1.0-SNAPSHOT + + 4.0.0 + + heima_auth_server + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + + + com.itheima + heima_common + 1.0-SNAPSHOT + + + mysql + mysql-connector-java + 5.1.47 + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.0 + + + +``` + +### 创建认证服务配置文件 + +```yaml +server: + port: 9001 +spring: + datasource: + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql:///security_authority + username: root + password: root +mybatis: + type-aliases-package: com.itheima.domain + configuration: + map-underscore-to-camel-case: true +logging: + level: + com.itheima: debug +rsa: + key: + pubKeyFile: D:\auth_key\id_key_rsa.pub + priKeyFile: D:\auth_key\id_key_rsa +``` + +### 提供解析公钥和私钥的配置类 + +```java +@Data +@ConfigurationProperties(prefix = "heima.key") +public class RsaKeyProperties { + private String pubKeyPath; + private String priKeyPath; + private PublicKey publicKey; + private PrivateKey privateKey; + @PostConstruct + public void loadKey() throws Exception { + publicKey = RsaUtils.getPublicKey(pubKeyPath); + privateKey = RsaUtils.getPrivateKey(priKeyPath); + } +} +``` + +### 创建认证服务启动类 + +```java +@SpringBootApplication +@MapperScan("com.itheima.mapper") +@EnableConfigurationProperties(RsaKeyProperties.class) +public class AuthApplication { + public static void main(String[] args) { + SpringApplication.run(AuthApplication.class, args); + } +} +``` + +### 将上面集中式案例中数据库认证相关代码复制到认证服务中 + +需要复制的代码如果所示: + +![image-20200920211547261](images/image-20200920211547261.png) + +注意这里要去掉mapper中继承的通用mapper接口,处理器类上换成@RestController,这里前后端绝对分离,不能再跳转页面了,要返回数据。 + +```java +public class JwtLoginFilter extends UsernamePasswordAuthenticationFilter { + + private AuthenticationManager authenticationManager; + private RsaKeyProperties prop; + + public JwtLoginFilter(AuthenticationManager authenticationManager, RsaKeyProperties prop) { + this.authenticationManager = authenticationManager; + this.prop = prop; + } + + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { + try { + SysUser sysUser = new ObjectMapper().readValue(request.getInputStream(), SysUser.class); + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(sysUser.getUsername(), sysUser.getPassword()); + return authenticationManager.authenticate(authRequest); + }catch (Exception e){ + try { + response.setContentType("application/json;charset=utf-8"); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + PrintWriter out = response.getWriter(); + Map resultMap = new HashMap(); + resultMap.put("code", HttpServletResponse.SC_UNAUTHORIZED); + resultMap.put("msg", "用户名或密码错误!"); + out.write(new ObjectMapper().writeValueAsString(resultMap)); + out.flush(); + out.close(); + }catch (Exception outEx){ + outEx.printStackTrace(); + } + throw new RuntimeException(e); + } + } + + public void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { + SysUser user = new SysUser(); + user.setUsername(authResult.getName()); + user.setRoles((List) authResult.getAuthorities()); + String token = JwtUtils.generateTokenExpireInMinutes(user, prop.getPrivateKey(), 24 * 60); + response.addHeader("Authorization", "Bearer "+token); + try { + response.setContentType("application/json;charset=utf-8"); + response.setStatus(HttpServletResponse.SC_OK); + PrintWriter out = response.getWriter(); + Map resultMap = new HashMap(); + resultMap.put("code", HttpServletResponse.SC_OK); + resultMap.put("msg", "认证通过!"); + out.write(new ObjectMapper().writeValueAsString(resultMap)); + out.flush(); + out.close(); + }catch (Exception outEx){ + outEx.printStackTrace(); + } + } +} +``` + +### 编写检验token过滤器 + +```java +public class JwtVerifyFilter extends BasicAuthenticationFilter { + + private RsaKeyProperties prop; + + public JwtVerifyFilter(AuthenticationManager authenticationManager, RsaKeyProperties prop) { + super(authenticationManager); + this.prop = prop; + } + + public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + String header = request.getHeader("Authorization"); + if (header == null || !header.startsWith("Bearer ")) { + //如果携带错误的token,则给用户提示请登录! + chain.doFilter(request, response); + response.setContentType("application/json;charset=utf-8"); + response.setStatus(HttpServletResponse.SC_FORBIDDEN); + PrintWriter out = response.getWriter(); + Map resultMap = new HashMap(); + resultMap.put("code", HttpServletResponse.SC_FORBIDDEN); + resultMap.put("msg", "请登录!"); + out.write(new ObjectMapper().writeValueAsString(resultMap)); + out.flush(); + out.close(); + } else { + //如果携带了正确格式的token要先得到token + String token = header.replace("Bearer ", ""); + //验证tken是否正确 + Payload payload = JwtUtils.getInfoFromToken(token, prop.getPublicKey(), SysUser.class); + SysUser user = payload.getUserInfo(); + if(user!=null){ + UsernamePasswordAuthenticationToken authResult = new UsernamePasswordAuthenticationToken(user.getUsername(), null, user.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authResult); + chain.doFilter(request, response); + } + } + } +} +``` + +### 编写SpringSecurity配置类 + +```java +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(securedEnabled=true) +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private UserService userService; + + @Autowired + private RsaKeyProperties prop; + + @Bean + public BCryptPasswordEncoder passwordEncoder(){ + return new BCryptPasswordEncoder(); + } + + //指定认证对象的来源 + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userService).passwordEncoder(passwordEncoder()); + } + //SpringSecurity配置信息 + public void configure(HttpSecurity http) throws Exception { + http.csrf() + .disable() + .authorizeRequests() + .antMatchers("/product").hasAnyRole("USER") + .anyRequest() + .authenticated() + .and() + .addFilter(new JwtLoginFilter(super.authenticationManager(), prop)) + .addFilter(new JwtVerifyFilter(super.authenticationManager(), prop)) + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + } +} +``` + +### 启动测试认证服务 + +认证请求 + +![image-20200920213350978](images/image-20200920213350978.png) + +认证通过结果 + +![image-20200920213403708](images/image-20200920213403708.png) + +token在Headers中: + +![image-20200920213423316](images/image-20200920213423316.png) + +验证认证请求 + +![image-20200920213442797](images/image-20200920213442797.png) + +## 资源服务 + +### 说明 + +资源服务可以有很多个,这里只拿产品服务为例,记住,资源服务中只能通过公钥验证认证。不能签发token! + +### 创建产品服务并导入jar包 + +根据实际业务导包即可,咱们就暂时和认证服务一样了。 + +```xml + + + + springboot_security_jwt_rsa_parent + com.itheima + 1.0-SNAPSHOT + + 4.0.0 + + heima_source_product + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + + + com.itheima + heima_common + 1.0-SNAPSHOT + + + mysql + mysql-connector-java + 5.1.47 + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.0 + + + +``` + +### 编写产品服务配置文件 + +切记这里只能有公钥地址! + +```yaml +server: + port: 9002 +spring: + datasource: + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql:///security_authority + username: root + password: root +mybatis: + type-aliases-package: com.itheima.domain + configuration: + map-underscore-to-camel-case: true +logging: + level: + com.itheima: debug +rsa: + key: + pubKeyFile: D:\auth_key\id_key_rsa.pub +``` + +### 编写读取公钥的配置类 + +```java +@ConfigurationProperties("rsa.key") +public class RsaKeyProperties { + + private String pubKeyFile; + + private PublicKey publicKey; + + @PostConstruct + public void createRsaKey() throws Exception { + publicKey = RsaUtils.getPublicKey(pubKeyFile); + } + + public String getPubKeyFile() { + return pubKeyFile; + } + + public void setPubKeyFile(String pubKeyFile) { + this.pubKeyFile = pubKeyFile; + } + + public PublicKey getPublicKey() { + return publicKey; + } + + public void setPublicKey(PublicKey publicKey) { + this.publicKey = publicKey; + } +} +``` + +### 编写启动类 + +```java +@SpringBootApplication +@MapperScan("com.itheima.mapper") +@EnableConfigurationProperties(RsaKeyProperties.class) +public class AuthSourceApplication { + public static void main(String[] args) { + SpringApplication.run(AuthSourceApplication.class, args); + } +} +``` + +### 复制认证服务中,用户对象,角色对象和校验认证的接口 + +这时目录结构如图: + +![image-20200920214004611](images/image-20200920214004611.png) + +复制认证服务中SpringSecurity配置类做修改,去掉“增加自定义认证过滤器”即可! + +```java +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(securedEnabled=true) +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private RsaKeyProperties prop; + + //SpringSecurity配置信息 + public void configure(HttpSecurity http) throws Exception { + http.csrf() + .disable() + .authorizeRequests() + .antMatchers("/product").hasAnyRole("USER") + .anyRequest() + .authenticated() + .and() + .addFilter(new JwtVerifyFilter(super.authenticationManager(), prop)) + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + } +} +``` + +### 编写产品处理器 + +```java +@RestController +@RequestMapping("/product") +public class ProductController { + @GetMapping + public String findAll(){ + return "产品测试成功!"; + } +} +``` + +### 启动产品服务做测试 + +携带token + +![image-20200920214127083](images/image-20200920214127083.png) + +在产品处理器上添加访问需要ADMIN角色 + +```java +@RestController +@RequestMapping("/product") +public class ProductController { + @Secured("ROLE_ADMIN") + @GetMapping + public String findAll(){ + return "产品测试成功!"; + } +} +``` + +重启测试权限不足 + +![image-20200920214208492](images/image-20200920214208492.png) + +在数据库中手动给用户添加ADMIN角色 + +![image-20200920214220620](images/image-20200920214220620.png) + +重新认证获取新token再测试OK了! + +![image-20200920214234884](images/image-20200920214234884.png) \ No newline at end of file diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920202612159.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920202612159.png" new file mode 100644 index 0000000000000000000000000000000000000000..6d97d6b7a84835860a11d1c2ea2101dee66f78be Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920202612159.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920210659250.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920210659250.png" new file mode 100644 index 0000000000000000000000000000000000000000..40380b2b907e6bc3180c718ea2a2555159dad10b Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920210659250.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920211051749.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920211051749.png" new file mode 100644 index 0000000000000000000000000000000000000000..9d4ebd7d328b013d8cb4cfa61806d2ec9bec0c03 Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920211051749.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920211547261.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920211547261.png" new file mode 100644 index 0000000000000000000000000000000000000000..cbcdfcdee8bcd940f95808ce42078fa400bbeb02 Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920211547261.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920213350978.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920213350978.png" new file mode 100644 index 0000000000000000000000000000000000000000..63dd1c80feb67fc6c6cfd7d0f38348640b48591b Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920213350978.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920213403708.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920213403708.png" new file mode 100644 index 0000000000000000000000000000000000000000..8b82ba686998b4ea369ebe5362ab3e3cb80804b2 Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920213403708.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920213423316.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920213423316.png" new file mode 100644 index 0000000000000000000000000000000000000000..2e674a0cbabb29c583bc8c2677c63d54720340e2 Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920213423316.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920213442797.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920213442797.png" new file mode 100644 index 0000000000000000000000000000000000000000..404363b2c4388d37f3311acc074300208a624a93 Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920213442797.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214004611.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214004611.png" new file mode 100644 index 0000000000000000000000000000000000000000..ba06703abd0f90b5b10d0ca4516042d42d4e586e Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214004611.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214127083.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214127083.png" new file mode 100644 index 0000000000000000000000000000000000000000..f0a9ecfbf8fc98d89d35a82e8db25435a9df87c7 Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214127083.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214208492.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214208492.png" new file mode 100644 index 0000000000000000000000000000000000000000..a5f672b7cbec6286df59a5728239fe5945a21ab6 Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214208492.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214220620.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214220620.png" new file mode 100644 index 0000000000000000000000000000000000000000..2447aa9f79f42b47a7b6f9930f418906bf807079 Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214220620.png" differ diff --git "a/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214234884.png" "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214234884.png" new file mode 100644 index 0000000000000000000000000000000000000000..a692300d09958620455cecaac6164d05d1ca7b7d Binary files /dev/null and "b/SpringSecurity/4_SpringSecurity\345\234\250\345\210\206\345\270\203\345\274\217\347\216\257\345\242\203\344\270\213\347\232\204\344\275\277\347\224\250/images/image-20200920214234884.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/README.md" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..394e737756ea979a62a111bf0c3966998a32be5a --- /dev/null +++ "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/README.md" @@ -0,0 +1,691 @@ +# OAuth2.0介绍 + +## 参考 + +来源于黑马程序员: [手把手教你精通新版SpringSecurity](https://www.bilibili.com/video/BV1EE411u7YV?p=52) + +## 概念说明 + +先说OAuth,OAuth是Open Authorization的简写。OAuth协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAuth的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAuth是安全的。 + +OAuth2.0是OAuth协议的延续版本,但不向前兼容(即完全废止了OAuth1.0)。 + +## 使用场景 + +假设,A网站是一个打印照片的网站,B网站是一个存储照片的网站,二者原本毫无关联。 +如果一个用户想使用A网站打印自己存储在B网站的照片,那么A网站就需要使用B网站的照片资源才行。 +按照传统的思考模式,我们需要A网站具有登录B网站的用户名和密码才行,但是,现在有了OAuth2,只需要A网 +站获取到使用B网站照片资源的一个通行令牌即可!这个令牌无需具备操作B网站所有资源的权限,也无需永久有 +效,只要满足A网站打印照片需求即可。 +这么听来,是不是有点像单点登录?NONONO!千万不要混淆概念!单点登录是用户一次登录,自己可以操作其 +他关联的服务资源。OAuth2则是用户给一个系统授权,可以直接操作其他系统资源的一种方式。 +但SpringSecurity的OAuth2也是可以实现单点登录的! + +总结一句:SpringSecurity的OAuth2可以做服务之间资源共享,也可以实现单点登录! + +![image-20200920215239045](images/image-20200920215239045.png) + +## OAuth2.0中四种授权方式 + +为了说明四种模式先准备一张图 + +![image-20200920215356835](images/image-20200920215356835.png) + +### 授权码模式(authorization code) + +#### 流程 + +说明:【A服务客户端】需要用到【B服务资源服务】中的资源 + +- 第一步:【A服务客户端】将用户自动导航到【B服务认证服务】,这一步用户需要提供一个回调地址,以备 + 【B服务认证服务】返回授权码使用。 +- 第二步:用户点击授权按钮表示让【A服务客户端】使用【B服务资源服务】,这一步需要用户登录B服务,也 + 就是说用户要事先具有B服务的使用权限。 +- 第三步:【B服务认证服务】生成授权码,授权码将通过第一步提供的回调地址,返回给【A服务客户端】。 + 注意这个授权码并非通行【B服务资源服务】的通行凭证。 +- 第四步:【A服务认证服务】携带上一步得到的授权码向【B服务认证服务】发送请求,获取通行凭证token。 +- 第五步:【B服务认证服务】给【A服务认证服务】返回令牌token和更新令牌refresh token。 + +#### 使用场景 + +授权码模式是OAuth2中最安全最完善的一种模式,应用场景最广泛,可以实现服务之间的调用,常见的微 +信,QQ等第三方登录也可采用这种方式实现。 + +### 简化模式(implicit) + +#### 流程 + +说明:简化模式中没有【A服务认证服务】这一部分,全部有【A服务客户端】与B服务交互,整个过程不再有 +授权码,token直接暴露在浏览器。 + +- 第一步:【A服务客户端】将用户自动导航到【B服务认证服务】,这一步用户需要提供一个回调地址,以备 + 【B服务认证服务】返回token使用,还会携带一个【A服务客户端】的状态标识state。 +- 第二步:用户点击授权按钮表示让【A服务客户端】使用【B服务资源服务】,这一步需要用户登录B服务,也 + 就是说用户要事先具有B服务的使用权限。 +- 第三步:【B服务认证服务】生成通行令牌token,token将通过第一步提供的回调地址,返回给【A服务客户 + 端】。 + +#### 使用场景 + +适用于A服务没有服务器的情况。比如:纯手机小程序,JavaScript语言实现的网页插件等 + +### 密码模式(resource owner password credentials) + +#### 流程 + +- 第一步:直接告诉【A服务客户端】自己的【B服务认证服务】的用户名和密码 +- 第二步:【A服务客户端】携带【B服务认证服务】的用户名和密码向【B服务认证服务】发起请求获取 + token。 +- 第三步:【B服务认证服务】给【A服务客户端】颁发token。 + +#### 使用场景 + +此种模式虽然简单,但是用户将B服务的用户名和密码暴露给了A服务,需要两个服务信任度非常高才能使 +用 + +### 客户端模式(client credentials) + +#### 流程 + +说明:这种模式其实已经不太属于OAuth2的范畴了。A服务完全脱离用户,以自己的身份去向B服务索取 +token。换言之,用户无需具备B服务的使用权也可以。完全是A服务与B服务内部的交互,与用户无关了。 + +- 第一步:A服务向B服务索取token。 +- 第二步:B服务返回token给A服务。 + +#### 使用场景 + +A服务本身需要B服务资源,与用户无关。 + +## OAuth2.0中表结构说明 + +### 说明 + +如果只是写个测试案例,完全可以不用连接数据库,直接将用户等信息写在项目中就行。但是,我们应该把眼光放在企业开发中。试想,我们自己做的一个软件,想使用微信第三方登录。难道你还指望微信去修改他们的代码,让我们去访问?想都别想!那么微信会怎么做呢?微信会提供好一个接入的入口,让我们自己去申请访问权限。这些数据自然而然需要保存在数据库中! + +所以,我们将直接讲解数据库版实现方式! + +### 建表语句 + +官方SQL地址: +https://github.com/spring-projects/spring-security-oauth/blob/master/spring-securityoauth2/ +src/test/resources/schema.sql + +### oauth_client_details【核心表】 + +| 字段名 | 字段说明 | +| ----------------------- | ------------------------------------------------------------ | +| client_id | 主键,必须唯一,不能为空. 用于唯一标识每一个客户端(client); 在注册时必须填写(也可由服务端自动生成). 对于不同的grant_type,该字段都是必须的. 在实际应用中的另一个名称叫appKey,与client_id是同一个概念 | +| resource_ids | 资源的编号,相当于要访问的资源服务器编号 | +| client_secret | 用于指定客户端(client)的访问密匙; 在注册时必须填写(也可由服务端自动生成). 对于不同的grant_type,该字段都是必须的. 在实际应用中的另一个名称叫appSecret,与client_secret是同一个概念. | +| scope | 指定客户端申请的权限范围,可选值包括read,write,trust;若有多个权限范围用逗号(,)分隔,如:“read,write”. scope的值与security.xml中配置的‹intercept-url的access属性有关系.如‹intercept-url的配置为‹intercept-url pattern="/m/**"access=“ROLE_MOBILE,SCOPE_READ”/>则说明访问该URL时的客户端必须有read权限范围. write的配置值为SCOPE_WRITE, trust的配置值为SCOPE_TRUST. 在实际应该中, 该值一般由服务端指定, 常用的值为read,write. | +| authorized_grant_types | 指定客户端支持的grant_type,可选值包括 + + 4.0.0 + + com.itheima + springboot_security_oauth + pom + 1.0-SNAPSHOT + + heima_oauth_source + heima_oauth_server + + + + org.springframework.boot + spring-boot-starter-parent + 2.1.3.RELEASE + + + + + Greenwich.RELEASE + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + +``` + +### 创建资源模块 + +#### 我们需要引入oauth2.0包 + +```xml + + org.springframework.cloud + spring-cloud-starter-oauth2 + 2.1.0.RELEASE + +``` + +完整如下 + +```xml + + + + springboot_security_oauth + com.itheima + 1.0-SNAPSHOT + + 4.0.0 + heima_oauth_source + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.cloud + spring-cloud-starter-oauth2 + 2.1.0.RELEASE + + + mysql + mysql-connector-java + 5.1.47 + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.0 + + + +``` + +#### 然后创建配置文件 + +```yaml +server: + port: 9002 +spring: + datasource: + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql:///security_authority + username: root + password: root + main: + allow-bean-definition-overriding: true #允许我们自己覆盖spring放入到IOC容器的对象 +mybatis: + type-aliases-package: com.itheima.domain + configuration: + map-underscore-to-camel-case: true +logging: + level: + com.itheima: debug +``` + +#### 提供启动类 + +```java +@SpringBootApplication +@MapperScan("com.itheima.mapper") +public class OauthSourceApplication { + public static void main(String[] args) { + SpringApplication.run(OauthSourceApplication.class, args); + } +} +``` + +#### 提供处理器 + +这里不再连数据库了 + +```java +@RestController +@RequestMapping("/product") +public class ProductController { + + @GetMapping("/findAll") + public String findAll(){ + return "产品列表查询成功!"; + } +} +``` + +#### 启动项目测试 + +由于此刻,项目中添加的有SpringBoot的Security包,默认不通过认证是无法访问处理器的,这个结果咱们在第三 +天都已经知道了!那么如何解决呢?第三天我们是采用单点登录的方式解决了这个问题,那么今天我们把这个资源交给OAuth2来管理,使用通行的token来访问资源! + +![image-20200921084540341](images/image-20200921084540341.png) + +#### 将访问资源作为OAuth2的资源来管理 + +复制昨天项目中用户和角色对象,即便是用OAuth2管理资源,也一样需要认证,这两个对象还是需要的。 + +![image-20200921084613952](images/image-20200921084613952.png) + +#### SysRole.java + +```java +public class SysRole implements GrantedAuthority { + + private Integer id; + private String roleName; + private String roleDesc; +} +``` + +#### SysUser.java + +```java +public class SysUser implements UserDetails { + + private Integer id; + private String username; + private String password; + private Integer status; + private List roles; +} +``` + +#### 编写资源管理配置类 + +```java +@Configuration +@EnableResourceServer +public class OauthSourceConfig extends ResourceServerConfigurerAdapter { + + // 只要配置了数据库的配置,就会将DataSource放入到IOC容器中 + @Autowired + private DataSource dataSource; + + /** + * 指定token的持久化策略 + * InMemoryTokenStore表示将token存储在内存 + * Redis表示将token存储在redis中 + * JdbcTokenStore存储在数据库中 + * @return + */ + @Bean + public TokenStore jdbcTokenStore(){ + return new JdbcTokenStore(dataSource); + } + + /** + * 指定当前资源的id和存储方案 + * @param resources + * @throws Exception + */ + @Override + public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + // 也就是当前资源服务的id + resources.resourceId("product_api").tokenStore(jdbcTokenStore()); + } + + @Override + public void configure(HttpSecurity http) throws Exception{ + http.authorizeRequests() + //指定不同请求方式访问资源所需要的权限,一般查询是read,其余是write。 + .antMatchers(HttpMethod.GET, "/**").access("#oauth2.hasScope('read')") + .antMatchers(HttpMethod.POST, "/**").access("#oauth2.hasScope('write')") + .antMatchers(HttpMethod.PATCH, "/**").access("#oauth2.hasScope('write')") + .antMatchers(HttpMethod.PUT, "/**").access("#oauth2.hasScope('write')") + .antMatchers(HttpMethod.DELETE, "/**").access("#oauth2.hasScope('write')") + .and() + .headers().addHeaderWriter((request, response) -> { + //允许跨域 + response.addHeader("Access-Control-Allow-Origin", "*"); + //如果是跨域的预检请求,则原封不动向下传达请求头信息 + if (request.getMethod().equals("OPTIONS")) { + response.setHeader("Access-Control-Allow-Methods", request.getHeader("Access-Control-Request-Method")); + response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers")); + } + }); + } +} +``` + +### 创建授权模块 + +#### 创建工程导入jar包 + +```xml + + + + springboot_security_oauth + com.itheima + 1.0-SNAPSHOT + + 4.0.0 + + heima_oauth_server + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.cloud + spring-cloud-starter-oauth2 + 2.1.0.RELEASE + + + mysql + mysql-connector-java + 5.1.47 + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.0 + + + +``` + +#### 编写配置文件 + +```yaml +server: + port: 9001 +spring: + datasource: + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql:///security_authority + username: root + password: root + main: + allow-bean-definition-overriding: true +mybatis: + type-aliases-package: com.itheima.domain + configuration: + map-underscore-to-camel-case: true +logging: + level: + com.itheima: debug +``` + +#### 提供启动类 + +```java +@SpringBootApplication +@MapperScan("com.itheima.mapper") +public class OauthServerApplication { + public static void main(String[] args) { + SpringApplication.run(OauthServerApplication.class, args); + } +} +``` + +#### 将之前所有认证的代码复制进来 + +![image-20200921091407835](images/image-20200921091407835.png) + +#### 提供SpringSecurity配置类 + +```java +@Configuration +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private UserService userService; + + @Bean + public BCryptPasswordEncoder passwordEncoder(){ + return new BCryptPasswordEncoder(); + } + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userService).passwordEncoder(passwordEncoder()); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .anyRequest().authenticated() + .and() + .formLogin() + .loginProcessingUrl("/login") + // 允许匿名访问 + .permitAll() + .and() + .csrf() + .disable(); + } + + //AuthenticationManager对象在OAuth2认证服务中要使用,提前放入IOC容器中【授权码模式使用】 + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } +} +``` + +#### 提供OAuth2授权配置类 + +```java +@Configuration +@EnableAuthorizationServer +public class OauthServerConfig extends AuthorizationServerConfigurerAdapter { + + //数据库连接池对象 + @Autowired + private DataSource dataSource; + + //认证业务对象 + @Autowired + private UserService userService; + + //授权模式专用对象 + @Autowired + private AuthenticationManager authenticationManager; + + //客户端信息来源 + @Bean + public JdbcClientDetailsService jdbcClientDetailsService(){ + return new JdbcClientDetailsService(dataSource); + } + + //token保存策略 + @Bean + public TokenStore tokenStore(){ + return new JdbcTokenStore(dataSource); + } + + //授权信息保存策略 + @Bean + public ApprovalStore approvalStore(){ + return new JdbcApprovalStore(dataSource); + } + + //授权码模式数据来源 + @Bean + public AuthorizationCodeServices authorizationCodeServices(){ + return new JdbcAuthorizationCodeServices(dataSource); + } + + //指定客户端信息的数据库来源 + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + clients.withClientDetails(jdbcClientDetailsService()); + } + + //检查token的策略 + @Override + public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { + security.allowFormAuthenticationForClients(); + security.checkTokenAccess("isAuthenticated()"); + } + + //OAuth2的主配置信息 + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints + .approvalStore(approvalStore()) + .authenticationManager(authenticationManager) + .authorizationCodeServices(authorizationCodeServices()) + .tokenStore(tokenStore()); + } +} +``` + +### 测试 + +#### 在数据库中手动添加客户端信息 + +所有要使用当前项目资源的项目,都是我们的客户端。比如我们之前举的例子,A服务打印照片,B服务存储照 +片。A服务要使用B服务的资源,那么A服务就是B服务的客户端。这里要区分用户的信息和客户端信息,用户信息是用户在B服务上注册的用户信息,在sys_user表中。客户端信息是A服务在B服务中注册的账号,在OAuth2的oauth_client_details表中。测试数据sql语句如下: + +```sql +INSERT INTO `oauth_client_details` (`client_id`,`resource_ids`,`client_secret`,`scope`,`authorized_grant_types`,`web_server_redirect_uri`,`authorities`,`access_token_validity`,`refresh_token_validity`,`additional_information`,`autoapprove`) VALUES +('heima_one','product_api','$2a$10$CYX9OMv0yO8wR8rE19N2fOaXDJondci5uR68k2eQJm50q8ESsDMlC','read, write','client_credentials,implicit,authorization_code,refresh_token,password','http://www.baidu.com',NULL,NULL,NULL,NULL,'false'); +``` + +这里注意resource_ids不要写错,回调地址web_server_redirect_uri先写成百度。 + +### 授权码模式测试 + +在地址栏访问地址 http://localhost:9001/oauth/authorize?response_type=code&client_id=heima_one +跳转到SpringSecurity默认认证页面,提示用户登录个人账户【这里是sys_user表中的数据】 + +![image-20200921100523431](images/image-20200921100523431.png) + +登录成功后询问用户是否给予操作资源的权限,具体给什么权限。Approve是授权,Deny是拒绝。这里我们选择read和write都给予Approve + +![image-20200921100715530](images/image-20200921100715530.png) + +点击Authorize后跳转到回调地址并获取授权码 + +![image-20200921101629786](images/image-20200921101629786.png) + +使用授权码到服务器申请通行令牌token + +![image-20200921101642658](images/image-20200921101642658.png) + +![image-20200921101650225](images/image-20200921101650225.png) + +重启资源服务器,然后携带通行令牌再次去访问资源服务器,大功告成! + +![image-20200921101856898](images/image-20200921101856898.png) + +### 简化模式测试 + +在地址栏访问地址 +http://localhost:9001/oauth/authorize?response_type=token&client_id=heima_one +由于上面用户已经登录过了,所以无需再次登录,其实和上面是有登录步骤的,这时,浏览器直接返回了token + +![image-20200921102043081](images/image-20200921102043081.png) + +直接访问资源服务器 + +![image-20200921102116171](images/image-20200921102116171.png) + +### 密码模式测试 + +申请token + +![image-20200921102249250](images/image-20200921102249250.png) + +![image-20200921102256833](images/image-20200921102256833.png) + +访问资源服务器 + +![image-20200921102306256](images/image-20200921102306256.png) + +### 客户端模式测试 + +申请token + +![image-20200921102459088](images/image-20200921102459088.png) + +![image-20200921102511728](images/image-20200921102511728.png) + +访问资源服务 + +![image-20200921102530258](images/image-20200921102530258.png) + +### 刷新Token + +前面三种模式中都会返回刷新token,因此我们如果想要刷新token 的时候,就需要携带对应的字段请求即可 + +![image-20200921102905852](images/image-20200921102905852.png) \ No newline at end of file diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200920215239045.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200920215239045.png" new file mode 100644 index 0000000000000000000000000000000000000000..bd473e7311edd677234bb6e31adb9fd448d151c5 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200920215239045.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200920215356835.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200920215356835.png" new file mode 100644 index 0000000000000000000000000000000000000000..cc11677c405620d2b3a1b1267b98871da7cd021b Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200920215356835.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921082500716.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921082500716.png" new file mode 100644 index 0000000000000000000000000000000000000000..d1c454147bb829b84688b6f3de0ed1a87609368e Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921082500716.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921082705037.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921082705037.png" new file mode 100644 index 0000000000000000000000000000000000000000..63b3e21de1bbca229a16881bab7bd41c30480798 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921082705037.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921083037635.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921083037635.png" new file mode 100644 index 0000000000000000000000000000000000000000..2034e2c6e822cf0636843710ffecc3e11ee367ec Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921083037635.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921083115098.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921083115098.png" new file mode 100644 index 0000000000000000000000000000000000000000..9bf73dd77654157fafbf922f9706c044d7fdb89c Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921083115098.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921084540341.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921084540341.png" new file mode 100644 index 0000000000000000000000000000000000000000..70be464d6c136c0b4024ea875cc1b83b2c20fc0f Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921084540341.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921084613952.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921084613952.png" new file mode 100644 index 0000000000000000000000000000000000000000..b0c7722fefbfcfac1a3c4ba3dc4bf55f06cb6e17 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921084613952.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921091407835.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921091407835.png" new file mode 100644 index 0000000000000000000000000000000000000000..5bf842a4521a13005b2c051467658ff8a59c3cc8 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921091407835.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921100523431.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921100523431.png" new file mode 100644 index 0000000000000000000000000000000000000000..e2ea7daeef1d7b210cb1504ff6913f2561615a44 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921100523431.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921100715530.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921100715530.png" new file mode 100644 index 0000000000000000000000000000000000000000..ff3bd1ad35b5ea3521cc8cd5aac5580ba530f5e9 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921100715530.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921101629786.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921101629786.png" new file mode 100644 index 0000000000000000000000000000000000000000..ca062e984c3edbdd2fb62811870cfb0382ad1a9a Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921101629786.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921101642658.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921101642658.png" new file mode 100644 index 0000000000000000000000000000000000000000..2ce0c29184634b45c2f356a822f2b1cc61e379db Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921101642658.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921101650225.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921101650225.png" new file mode 100644 index 0000000000000000000000000000000000000000..188d9f74e9b1c2d6ccc8cb2933f96fad2b3ad201 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921101650225.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921101856898.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921101856898.png" new file mode 100644 index 0000000000000000000000000000000000000000..699a204ab715e3264c9189d99bc881630912ac69 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921101856898.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102043081.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102043081.png" new file mode 100644 index 0000000000000000000000000000000000000000..1616fcd6b0ce3cf08ed3ff8b98920510706ee99b Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102043081.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102116171.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102116171.png" new file mode 100644 index 0000000000000000000000000000000000000000..147e18e85d4b1b66c22a3b24faf02bb43ac9967c Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102116171.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102249250.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102249250.png" new file mode 100644 index 0000000000000000000000000000000000000000..2a09e98474cda16f6c093aff843bb103a50dfc1f Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102249250.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102256833.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102256833.png" new file mode 100644 index 0000000000000000000000000000000000000000..53b36f67c3e590664ebe0a0157221200256005d2 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102256833.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102306256.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102306256.png" new file mode 100644 index 0000000000000000000000000000000000000000..6567b0ddb506c3ec7f27c6e5c9bdff2cbe032c69 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102306256.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102459088.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102459088.png" new file mode 100644 index 0000000000000000000000000000000000000000..ba7029d3824274afb2edd8b121bdf26e89642f76 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102459088.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102511728.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102511728.png" new file mode 100644 index 0000000000000000000000000000000000000000..a5b57dddfd27726f969f76ff5f8fd6f2b081d3b8 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102511728.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102530258.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102530258.png" new file mode 100644 index 0000000000000000000000000000000000000000..934a21c4f19e9005d6aba07d8969f368d74a9fe2 Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102530258.png" differ diff --git "a/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102905852.png" "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102905852.png" new file mode 100644 index 0000000000000000000000000000000000000000..64113d977ce5ba1156dd6fd1ee43a195679619cc Binary files /dev/null and "b/SpringSecurity/5_OAuth2.0\344\273\213\347\273\215/images/image-20200921102905852.png" differ diff --git a/SpringSecurity/README.md b/SpringSecurity/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5152dff428f6466702bfa5ee26dba655d1c4f671 --- /dev/null +++ b/SpringSecurity/README.md @@ -0,0 +1,11 @@ +## 介绍 + +> 来源Bilibili黑马程序员视频教程:[手把手教你精通新版SpringSecurity](https://www.bilibili.com/video/BV1EE411u7YV) + +## 目录 + +- [初识SpringSecurity](./1_初识SpringSecurity/README.md) +- [SpringSecurity在MVC项目中的使用](./2_SpringSecurity在MVC项目中的使用/README.md) +- [SpringSecurity在单机环境下的使用](./3_SpringSecurity在单机环境下的使用/README.md) +- [SpringSecurity在分布式环境下的使用](./4_SpringSecurity在分布式环境下的使用/README.md) +- [OAuth2.0介绍](./5_OAuth2.0介绍/README.md) diff --git "a/Vue/Vue\344\270\255Html\345\222\214Markdown\344\272\222\347\233\270\350\275\254\346\215\242/README.md" "b/Vue/Vue\344\270\255Html\345\222\214Markdown\344\272\222\347\233\270\350\275\254\346\215\242/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..977638f0338eff798c0f14852cdd77720e2226ac --- /dev/null +++ "b/Vue/Vue\344\270\255Html\345\222\214Markdown\344\272\222\347\233\270\350\275\254\346\215\242/README.md" @@ -0,0 +1,113 @@ +# Vue中Html和Markdown互相转换 + +## 前言 + +最近想实现的一个功能,就是将系统中的博客进行导出成Markdown格式,后面经过了调研发现有两种方法能够满足需求,一个是Java后台中将HTML转换成Markdown, 然后导出。第二种方式是在客户端将Html转换成Markdown + +## 前台处理 + +### MarkdownToHtml + +#### 安装 + +前台处理Markdown转换成Html,使用的是一款Vue组件 `showdown`:[点我传送](https://github.com/showdownjs/showdown) + +前端处理的好处是不需要占用后端的计算资源,因此首选是让客户端做这种处理的事情 + +首先我们需要安装依赖 + +``` +npm install showdown --save +``` + +或者使用CDN + +``` + https://unpkg.com/showdown/dist/showdown.min.js +``` + +#### Markdown 转成 Html + +``` +var showdown = require('showdown'), + converter = new showdown.Converter(), + text = '# hello, markdown!', + html = converter.makeHtml(text); +``` + +### HtmlToMarkdown + +#### 安装 + +前台处理Html转换成Markdown,使用的是一款Vue组件 `turndown`:[点我传送](https://github.com/domchristie/turndown) + +首先安装依赖 + +``` +npm install turndown --save +``` + +或使用CDN加速 + +``` + +``` + +#### 使用 + +``` +// For Node.js +var TurndownService = require('turndown') +var turndownService = new TurndownService() +var markdown = turndownService.turndown('

Hello world!

') +``` + +## 后端处理 + +后端处理使用的是 `flexmark-java` :[点我传送](https://github.com/vsch/flexmark-java) + +### 引入依赖 + +``` + + + com.vladsch.flexmark + flexmark-all + ${flexmark.version} + +``` + +### MarkdownToHtml + +``` + /** + * Markdown转Html + * @param markdown + * @return + */ + public static String markdownToHtml(String markdown) { + MutableDataSet options = new MutableDataSet(); + Parser parser = Parser.builder(options).build(); + HtmlRenderer renderer = HtmlRenderer.builder(options).build(); + Node document = parser.parse(markdown); + String html = renderer.render(document); + return html; + } +``` + +### HtmlToMarkdown + +``` + /** + * Html 转 Markdown + * @param html + * @return + */ + public static String htmlToMarkdown(String html) { + MutableDataSet options = new MutableDataSet(); + String markdown = FlexmarkHtmlConverter.builder(options).build().convert(html); + System.out.println(markdown); + return markdown; + } +``` + diff --git "a/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/README.md" "b/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ebe471cfc20247ea13ae12b07bb5495a53b4efa5 --- /dev/null +++ "b/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/README.md" @@ -0,0 +1,83 @@ +# Vue中防止XSS脚本攻击 + +最近写了一个博客评论模块,因为引入了表情包,所以就将原来的v-text的形式,改成了v-html,也就是渲染html标签,但是这样不可不免的会带来问题,就是XSS跨站脚本攻击 + +XSS解决方案官网:[点我传送](https://jsxss.com/zh/index.html) + +## XSS脚本攻击 + +跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页面时,嵌入Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击! + +例如我在评论框输入以下内容 + +``` +链接 +``` + +这个时候评论就会出现一个超链接 + +![image-20200430090311752](images/image-20200430090311752.png) + +只要我们点击这个链接后,就会出现一个alert弹框 + +![image-20200430090351946](images/image-20200430090351946.png) + +上面代码因为写的的是循环10次后,alert消失,但是如果是`while(true)`,那么后果不堪设想,会进入无止无休的弹框 + +## 解决XSS脚本攻击 + +首先需要安装`xss`模块 + +``` +npm install xss --save +``` + +然后在`main.js`中引入 + +``` +import xss from 'xss' +// 定义全局XSS解决方法 +Object.defineProperty(Vue.prototype, '$xss', { + value: xss +}) +``` + +然后针对需要渲染的页面,调用`$xss()`方法 + +``` +
+``` + +我们在点击刚刚的页面,发现已经不会有弹框了,但是有出来了新的问题,就是我引入的标签也被过滤了 + +![image-20200430092519608](images/image-20200430092519608.png) + +引入xss后 + +![image-20200430092619240](images/image-20200430092619240.png) + +这个时候,我们就需要自定义拦截规则了,我们在data中添加如下配置,下面是自定义白名单,也就是什么标签以及标签的属性能够正常使用,其它的都会被拦截 + +``` + data() { + return { + // xss白名单配置 + options : { + whiteList: { + a: ['href', 'title', 'target'], + span: ['class'] + } + } + }; + }, +``` + +然后在使用的时候,增加option配置 + +``` +
+``` + +这个时候,表情已经成功显示了,并且原来的脚本攻击也不生效,达到了我们的目的~ + +![image-20200430092858561](images/image-20200430092858561.png) \ No newline at end of file diff --git "a/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430090311752.png" "b/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430090311752.png" new file mode 100644 index 0000000000000000000000000000000000000000..cb2bb38b00756e17942127ac4c6b37e3f3d0c5a0 Binary files /dev/null and "b/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430090311752.png" differ diff --git "a/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430090351946.png" "b/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430090351946.png" new file mode 100644 index 0000000000000000000000000000000000000000..e75c49cab572775cb27186b548a5623482724307 Binary files /dev/null and "b/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430090351946.png" differ diff --git "a/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430092519608.png" "b/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430092519608.png" new file mode 100644 index 0000000000000000000000000000000000000000..287486934dfa5c5fd22de7adab9a477fd1d42ade Binary files /dev/null and "b/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430092519608.png" differ diff --git "a/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430092619240.png" "b/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430092619240.png" new file mode 100644 index 0000000000000000000000000000000000000000..c24e307e2a6c568acea8aacd737f469d6e09c656 Binary files /dev/null and "b/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430092619240.png" differ diff --git "a/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430092858561.png" "b/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430092858561.png" new file mode 100644 index 0000000000000000000000000000000000000000..f47c982f887e191aab09638215a28c61cd3b4f54 Binary files /dev/null and "b/Vue/Vue\344\270\255\351\230\262\346\255\242XSS\350\204\232\346\234\254\346\224\273\345\207\273/images/image-20200430092858561.png" differ diff --git "a/Vue/Vue\345\206\205\345\256\271\351\241\265\351\235\242SEO\344\274\230\345\214\226\346\226\271\346\241\210/README.md" "b/Vue/Vue\345\206\205\345\256\271\351\241\265\351\235\242SEO\344\274\230\345\214\226\346\226\271\346\241\210/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..18fc82808ceaaa693486042ab2a9070e67e432b9 --- /dev/null +++ "b/Vue/Vue\345\206\205\345\256\271\351\241\265\351\235\242SEO\344\274\230\345\214\226\346\226\271\346\241\210/README.md" @@ -0,0 +1,28 @@ +# Vue内容页面SEO优化方案 + +课程预览所浏览到的页面就是课程详情页面,需要先确定课程详情页面的技术方案后方可确定课程预览的技术方案。而Vue作为单页面应用技术,非常不利于SEO优化 + +## 技术需求 + +课程详情页面是向用户展示课程信息的窗口,课程相当于网站的商品,本页面的访问量会非常大。此页面的内容设计不仅要展示出课程核心重要的内容而且用户访问页面的速度要有保证,有统计显示打开一个页面超过4秒用户就走掉了,所以本页面的性能要求是本页面的重要需求。本页面另一个需求就是SEO,要非常有利于爬虫抓取页面上信息,并且生成页面快照,利于用户通过搜索引擎 + +## 解决方案 + +如何在保证SEO的前提下提高页面的访问速度: + +### 方案1: + +对于信息获取类的需求,要想提高页面速度就要使用缓存来减少或避免对数据库的访问,从而提高页面的访问速度。下图是使用缓存与不使用缓存的区别 + +![image-20200922081529651](images/image-20200922081529651.png) + +此页面为动态页面,会根据课程的不同而不同,方案一采用传统的JavaEEServlet/jsp的方式在Tomcat完成页面渲染,相比不加缓存速度会有提升。 + +- 优点:使用redis作为缓存,速度有提升。 +- 缺点:采用Servlet/jsp动态页面渲染技术,服务器使用Tomcat,面对高并发量的访问存在性能瓶颈 + +### 方案2 + +对于不会频繁改变的信息可以采用页面静态化的技术提前让页面生成html静态页面存储在nginx服务器,用户直接访问nginx即可,对于一些动态信息可以访问服务端获取json数据在页面渲染。 + +![image-20200922082109474](images/image-20200922082109474.png) \ No newline at end of file diff --git "a/Vue/Vue\345\206\205\345\256\271\351\241\265\351\235\242SEO\344\274\230\345\214\226\346\226\271\346\241\210/images/image-20200922081529651.png" "b/Vue/Vue\345\206\205\345\256\271\351\241\265\351\235\242SEO\344\274\230\345\214\226\346\226\271\346\241\210/images/image-20200922081529651.png" new file mode 100644 index 0000000000000000000000000000000000000000..e56bb2cbd0954a9bbafc5a9372aabc9fc05b92e4 Binary files /dev/null and "b/Vue/Vue\345\206\205\345\256\271\351\241\265\351\235\242SEO\344\274\230\345\214\226\346\226\271\346\241\210/images/image-20200922081529651.png" differ diff --git "a/Vue/Vue\345\206\205\345\256\271\351\241\265\351\235\242SEO\344\274\230\345\214\226\346\226\271\346\241\210/images/image-20200922082109474.png" "b/Vue/Vue\345\206\205\345\256\271\351\241\265\351\235\242SEO\344\274\230\345\214\226\346\226\271\346\241\210/images/image-20200922082109474.png" new file mode 100644 index 0000000000000000000000000000000000000000..f1e62ccefbb46b1edeb7b0732df180a8d5f7a9b7 Binary files /dev/null and "b/Vue/Vue\345\206\205\345\256\271\351\241\265\351\235\242SEO\344\274\230\345\214\226\346\226\271\346\241\210/images/image-20200922082109474.png" differ diff --git "a/Vue/Vue\345\212\250\346\200\201\350\256\241\347\256\227Table\350\241\250\346\240\274\347\232\204\351\253\230\345\272\246/README.md" "b/Vue/Vue\345\212\250\346\200\201\350\256\241\347\256\227Table\350\241\250\346\240\274\347\232\204\351\253\230\345\272\246/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..d8789b26518e9ff0d13872f469a279da615b997d --- /dev/null +++ "b/Vue/Vue\345\212\250\346\200\201\350\256\241\347\256\227Table\350\241\250\346\240\274\347\232\204\351\253\230\345\272\246/README.md" @@ -0,0 +1,20 @@ +前言 +-- + +因为每个用户不同的电脑屏幕宽高度,造成了Table表格的高度不一致,因此想要动态计算出table的高度,让其能够正常的铺满整个屏幕 + +代码 +-- + +![](http://image.moguit.cn/2652bc26060547bf8fabb9636979303a) + +完整代码如下:首先计算  窗口的高度 - 搜索框的高度 - 固定数值 + +```js + mounted () { + // 计算搜索框的高度 + var searchBarHeight = window.getComputedStyle(this.$refs.searchBar).height.replace('px', '') + searchBarHeight = parseInt(searchBarHeight) + this.tableHeight = window.innerHeight - searchBarHeight - 270 + }, +``` diff --git "a/Vue/Vue\350\256\260\344\270\200\346\254\241\350\257\241\345\274\202\347\232\204\351\224\231\350\257\257Uncaught_TypeError_Cannot read property_disabled_of_null/README.md" "b/Vue/Vue\350\256\260\344\270\200\346\254\241\350\257\241\345\274\202\347\232\204\351\224\231\350\257\257Uncaught_TypeError_Cannot read property_disabled_of_null/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..d736ae2e001e0a7fce90b21ad13dec014bd6748f --- /dev/null +++ "b/Vue/Vue\350\256\260\344\270\200\346\254\241\350\257\241\345\274\202\347\232\204\351\224\231\350\257\257Uncaught_TypeError_Cannot read property_disabled_of_null/README.md" @@ -0,0 +1,45 @@ +前言 +-- + +之前制作了第三方登录页面,每次点击的时候,都会出现这个错误:Uncaught TypeError: Cannot read property 'disabled' of null + +![](http://image.moguit.cn/1577929824870.png) + +之前以为是因为我给input组件设置了disabled的原因 + + + + + +例如我对上面设置了disabled属性,让按钮无法被点击,但是我把全部的disabled都给删除后,还是有这样的错误 + + 经过了排查,发现是因为element-ui的其它组件而引起的:[Dropdown 下拉菜单](https://element.eleme.cn/#/zh-CN/component/dropdown) + +引入的代码如下所示: + + + + + + + + + + 主页 + 退出 + + + +从上面可以看出,当 isLogin = false的时候,el-dropdown-menu是不会被渲染出来的,那么就会存在问题了 + +因为el-dropdown如果没有设置它的子元素,就会报错,也就是刚刚我们看到的那个Uncaught TypeError: Cannot read property 'disabled' of null错误 + +我们只需要把原来的v-if改成v-show即可,如下所示: + + + 主页 + 退出 + + +那么错误就消失了~! \ No newline at end of file diff --git "a/Vue/Vue\351\241\271\347\233\256\344\270\255\345\274\225\345\205\245markdown\347\274\226\350\276\221\345\231\250vditor/README.md" "b/Vue/Vue\351\241\271\347\233\256\344\270\255\345\274\225\345\205\245markdown\347\274\226\350\276\221\345\231\250vditor/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..67e8d0b38a0c4b07dd6886edad0d445dce7e43dc --- /dev/null +++ "b/Vue/Vue\351\241\271\347\233\256\344\270\255\345\274\225\345\205\245markdown\347\274\226\350\276\221\345\231\250vditor/README.md" @@ -0,0 +1,214 @@ +# Vue项目中引入markdown编辑器vditor + +## 前言 + +这阵子在Github上看到一个非常不错的Markdown编辑器[Vditor](https://github.com/Vanessa219/vditor),和我使用Typora写博客的体验几乎一致,所以这次就打算在项目中集成一下vditor + +演示地址:https://vditor.b3log.org/demo/vue.html + +## 安装依赖 + +首先我们需要安装对应的依赖 + +```bash +npm install vditor --save +``` + +然后到html页面中,引入对应的CDN文件 + +```bash + + + +``` + +## 封装成组件 + +为了以后使用更加的方便,这里我对vditor再次进行了封装,创建一个MarkdownEditor的文件夹,idex.vue如下 + +```vue + + + + + +``` + +通过上述的代码,可以修改我们的上传逻辑和返回的结果 + +```js +let request = new XMLHttpRequest() +// 图片上传路径 +request.open('POST', process.env.PICTURE_API + '/ckeditor/imgUpload?token=' + getToken()) +``` + +关于更多的配置,可以去 [官网](https://github.com/Vanessa219/vditor) + +封装完成后,我们就可以在其它的页面直接使用了 + +```vue +// 引入组件 +import MarkdownEditor from "../../components/MarkdownEditor"; + +// 声明组件 +components: { + MarkdownEditor +}, +``` + +然后在页面中进行使用 + +```html + +``` + +## 效果 + +最后我们看引入后的效果 + +![image-20200830110212424](images/image-20200830110212424.png) + diff --git "a/Vue/Vue\351\241\271\347\233\256\344\270\255\345\274\225\345\205\245markdown\347\274\226\350\276\221\345\231\250vditor/images/image-20200830110212424.png" "b/Vue/Vue\351\241\271\347\233\256\344\270\255\345\274\225\345\205\245markdown\347\274\226\350\276\221\345\231\250vditor/images/image-20200830110212424.png" new file mode 100644 index 0000000000000000000000000000000000000000..90bf4c3261acbe771d7e705bf1ba0823f23751d8 Binary files /dev/null and "b/Vue/Vue\351\241\271\347\233\256\344\270\255\345\274\225\345\205\245markdown\347\274\226\350\276\221\345\231\250vditor/images/image-20200830110212424.png" differ diff --git "a/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245CDN\345\212\240\351\200\237/README.md" "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245CDN\345\212\240\351\200\237/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..9f598dfd0cde142cbe20f1e8e200712fcaf2d8ed --- /dev/null +++ "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245CDN\345\212\240\351\200\237/README.md" @@ -0,0 +1,94 @@ +# Vue项目引入CDN加速 + +## 前言 + +最近领取的阿里云服务器,使用的是1M带宽,因此在加载一下样式,例如 ElementUI,Ckeditor的时候,非常的慢,所以考虑是用CDN来加速。 + + + +## 引入Vue和Element + +首先我们需要引入的是Element的CDN加速:[传送门](https://element.eleme.cn/#/zh-CN/component/installation) + +目前可以通过 [unpkg.com/element-ui](https://unpkg.com/element-ui/) 获取到最新版本的资源,在页面上引入 js 和 css 文件即可开始使用。 + +``` + + + + +``` + +我们得到下面的最新版本,也就是 2.13.1,写入我们的index.html文件内 + +``` + + + + + + + 蘑菇云后台管理系统 + + + + + + + + + + + +
+ + + + +``` + +## 引入Ckeditor + +同时我们还是用了Ckeditor,这个时候,我们就需要通过BootCDN,找到Ckeditor进行引入。 + +BootCDN 是 [Bootstrap 中文网](https://www.bootcss.com/)支持并维护的前端开源项目免费 CDN 服务,致力于为 Bootstrap、jQuery、Angular、Vuejs 一样优秀的前端开源项目提供稳定、快速的免费 CDN 加速服务。BootCDN 所收录的开源项目主要同步于 [cdnjs](https://github.com/cdnjs/cdnjs) 仓库。 + +![image-20200419154459550](images/image-20200419154459550.png) + +然后在package.json找到我们的版本号 + +![image-20200419154536899](images/image-20200419154536899.png) + +选择对应的版本,引入即可 + +``` + +``` + +## 修改main.js文件 + +因为我们使用CDN的方式引入文件了,因此就不需要导入element-ui了,我们将下面的代码注释 + +``` +// element使用CDN全局引入,因此这里可以注释 +// import ElementUI from 'element-ui' +// import 'element-ui/lib/theme-chalk/index.css' +// import locale from 'element-ui/lib/locale/lang/en' + +// Vue.use(ElementUI, { locale }) +``` + + + +## 修改webpack.base.conf.js + +找到webpack.base.conf.js文件,添加下面的内容 + +``` + externals: { + "CKEDITOR": "window.CKEDITOR", + 'vue': 'Vue', + 'element-ui': 'ELEMENT' + }, +``` + diff --git "a/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245CDN\345\212\240\351\200\237/images/image-20200419154459550.png" "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245CDN\345\212\240\351\200\237/images/image-20200419154459550.png" new file mode 100644 index 0000000000000000000000000000000000000000..bc928c105371d6bf52d7094f94674c7d6822c922 Binary files /dev/null and "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245CDN\345\212\240\351\200\237/images/image-20200419154459550.png" differ diff --git "a/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245CDN\345\212\240\351\200\237/images/image-20200419154536899.png" "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245CDN\345\212\240\351\200\237/images/image-20200419154536899.png" new file mode 100644 index 0000000000000000000000000000000000000000..7025f665210aa365aa08903ee56f9cac67d5e368 Binary files /dev/null and "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245CDN\345\212\240\351\200\237/images/image-20200419154536899.png" differ diff --git "a/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/README.md" "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..d0f4357239144e2c8c7d904c3978ebc954ac8a93 --- /dev/null +++ "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/README.md" @@ -0,0 +1,98 @@ +# Vue项目引入侧边导航栏 + +## 前言 + +今天打算给蘑菇博客添加一个侧边导航栏,因为之前看很多博客项目都是有侧边目录导航的,能够非常方便的我们进行信息的检索,刚好今天在逛Github的时候,发现了一款不错的侧边导航栏:[vue-side-catalog](https://github.com/yaowei9363/vue-side-catalog),基本上能满足自己的需求,下面看看最终的效果图,如下所示 + +![image-20200601162626276](images/image-20200601162626276.png) + +我们通过点击左侧的导航,就能够快速定位到我们的内容了,非常棒~ + +## 安装 + +### 官网 + +首先我们需要进入**[ vue-side-catalog](https://github.com/yaowei9363/vue-side-catalog)**的官网,然后下载对应的源码,下载完成后,我们使用一下命令进行项目启动 + +``` +# 安装依赖 +npm install + +# 启动 +npm run serve +``` + +启动完成后,然后进入 `http://localhost:8080/` 就能看到demo了 + +然后我们需要做的就是将源码中的components组件复制到我们的项目中 + +![image-20200601170240984](images/image-20200601170240984.png) + + + +然后在我们项目的components文件夹下,创建一个VueSideCatalog中,然后把刚刚的代码复制进去,修改main.vue 为 index.vue + +![image-20200601170404584](images/image-20200601170404584.png) + +### 安装依赖 + +因为vue-side-catalog还依赖 `lodash.debounce` 和 `odash.throttle"` 因此我们还需要在我们的项目中,安装这两个的依赖 + +``` +npm install lodash.debounce --save +npm install lodash.throttle --save +``` + +### 使用 + +在完成上面的步骤后,我们就可以开始使用了,首先引入我们的组件 + +``` +import SideCatalog from "../components/VueSideCatalog" +``` + +然后配置catalogProps + +``` + +import SideCatalog from "../components/VueSideCatalog" +export default { + components: { + SideCatalog, + }, + data() { + return { + vhtml: "", + catalogProps:{ + containerElementSelector: '.demo', + }, + }; + }, + mounted(){ + setTimeout(()=>{ + this.vhtml=` +

h1

+

h2

+

n3

+ `; + },2000); + }, +} +``` + +运行成功后就能够看到我们的效果了 + +![image-20200601190156611](images/image-20200601190156611.png) + +## 注意 + +我们在进行渲染的时候,需要把内容放在 mounted钩子函数中进行渲染,不能写在create钩子函数中,因为只有mounted函数才是在html渲染完成后调用的操作,然后在对dom节点进行操作,生成我们的目录 \ No newline at end of file diff --git "a/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601162626276.png" "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601162626276.png" new file mode 100644 index 0000000000000000000000000000000000000000..35f0e5e9857e08c9da022ac17afaea58ce0b1cb6 Binary files /dev/null and "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601162626276.png" differ diff --git "a/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601170240984.png" "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601170240984.png" new file mode 100644 index 0000000000000000000000000000000000000000..b0f7fbb8674cfa0207be639e2fd8e6d267a37c51 Binary files /dev/null and "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601170240984.png" differ diff --git "a/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601170404584.png" "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601170404584.png" new file mode 100644 index 0000000000000000000000000000000000000000..8a7ea7e4267e9969d1889ffde1d948299852289d Binary files /dev/null and "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601170404584.png" differ diff --git "a/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601190156611.png" "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601190156611.png" new file mode 100644 index 0000000000000000000000000000000000000000..de6b04b6e887a347bc8fb9601e2c5eeb8f1e17fb Binary files /dev/null and "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601190156611.png" differ diff --git "a/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601203808970.png" "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601203808970.png" new file mode 100644 index 0000000000000000000000000000000000000000..5c95e8644fa52ff638c1fee4c932e6d083f88f9d Binary files /dev/null and "b/Vue/Vue\351\241\271\347\233\256\345\274\225\345\205\245\344\276\247\350\276\271\345\257\274\350\210\252\346\240\217/images/image-20200601203808970.png" differ diff --git "a/Vue/el-select\345\233\240\344\270\272\347\273\221\345\256\232\347\232\204\345\200\274\344\270\272\346\225\264\346\225\260\350\200\214\346\227\240\346\263\225\351\273\230\350\256\244\351\200\211\346\213\251/README.md" "b/Vue/el-select\345\233\240\344\270\272\347\273\221\345\256\232\347\232\204\345\200\274\344\270\272\346\225\264\346\225\260\350\200\214\346\227\240\346\263\225\351\273\230\350\256\244\351\200\211\346\213\251/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..d51a9fccca90a9d1da367417d2463d842f222d35 --- /dev/null +++ "b/Vue/el-select\345\233\240\344\270\272\347\273\221\345\256\232\347\232\204\345\200\274\344\270\272\346\225\264\346\225\260\350\200\214\346\227\240\346\263\225\351\273\230\350\256\244\351\200\211\346\213\251/README.md" @@ -0,0 +1,36 @@ +前言 +-- + +今天在做蘑菇博客数据字典这块遇到一个问题,就是el-select绑定的值为整数而无法默认选择的问题,它会直接显示数字,而不是选择列表中的某个选项,这个问题仅仅在我们绑定的值是Int类型的时候,才会出现 + +![](http://image.moguit.cn/4058b9648d3f4abebc56112852aab25d) + +代码如下所示 + + + + + + + +这是因为 v-model 绑定的 form.menuLevel没有自动将Integer类型转为String类型,其实解决思路也比较清晰,就是在 :value部分,将原来的string类型,通过 parseInt() 方法转换为int类型即可,代码如下所示: + + + + + + + +我们看最后的效果图,发现能够正常显示了: + +![](http://image.moguit.cn/34240f6b0a44456bbd8b3867454b22f2) \ No newline at end of file diff --git "a/Vue/\344\275\277\347\224\250Vuex\350\277\233\350\241\214\344\270\244\344\270\252\351\241\265\351\235\242\351\200\273\350\276\221\344\272\244\344\272\222/README.md" "b/Vue/\344\275\277\347\224\250Vuex\350\277\233\350\241\214\344\270\244\344\270\252\351\241\265\351\235\242\351\200\273\350\276\221\344\272\244\344\272\222/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b9264226b0c95ca1a8604b7ccbe954a3baa90e79 --- /dev/null +++ "b/Vue/\344\275\277\347\224\250Vuex\350\277\233\350\241\214\344\270\244\344\270\252\351\241\265\351\235\242\351\200\273\350\276\221\344\272\244\344\272\222/README.md" @@ -0,0 +1,79 @@ +前言 +-- + +今天在写前端页面的时候,遇到这样一个问题,就是当一个页面由两个Vue文件构成的时候,如果在一个vue文件的时候进行了操作,那么需要将操作得到的数据传递给另外一个文件,那么另外页面就需要能够监听到前面这个页面的数据变化 + +这里以蘑菇博客举例,我们都知道蘑菇博客的头部是单独写在一个组件中,而下面的index的页面,又是另外一个vue文件,那么我在页面1点击搜索,页面2如何知道搜索的值呢? + +![](http://picture.moguit.cn//blog/admin/png/2020/3/7/1583583658750.png) + +解决方案 +---- + +其实解决的方案就是通过vuex来进行实现,步骤如下: + +* 页面1当点击提交按钮的时候,调用vuex的保存方法,将文本内容存储到vuex中 +* 然后页面2使用watch钩子函数,监听 vuex中内容的变化,如果改变了,那么就执行对应的函数 + +具体代码如下 +------ + +关于vuex的使用,可以参考:[Vuex学习指南-实现一个计数器](http://www.moguit.cn/#/info?blogUid=a00ebe1473c584ff94bdd40402a4d573) + +首先我们需要定义一个message状态,用于存储我们需要发送的内容 + + import {SET_MESSAGE} from './mutation-types' + + const app = { + // 全局状态 + state: { + // 消息,用于更新 + message: {} + }, + // getters是对数据的包装,例如对数据进行拼接,或者过滤 + getters: { + // 类似于计算属性 + // 增加的方法 + }, + // 如果我们需要更改store中的状态,一定要通过mutations来进行操作 + mutations: { + + [SET_MESSAGE] (state, message) { + state.message = message + } + }, + + // actions是我们定义的一些操作,正常情况下,我们很少会直接调用mutation方法来改变state + actions: { + + } + } + export default app + + +然后在页面1的时候引入 + + // vuex中有mapState方法,相当于我们能够使用它的getset方法 + import {mapMutations} from 'vuex' + +然后在method方法中,解析出刚刚我们定义的setMessage + + methods:{ + // 拿到vuex中的写的方法 + ...mapMutations(['setMessage']), + } + +最后在我们点击的时候,调用setMessage方法 + + // 存储到vuex中 + this.setMessage(message) + + +这样,我们的消息就放到了vuex中了,下面我们在页面2,添加watch的钩子函数,用于监听vuex中message状态的变化,如果改变了就会触发,那么我们就可以在这里编写业务逻辑代码了 + + watch: { + '$store.state.app.message': function (newFlag, oldFlag) { + console.log('监听到页面1的变化') + // 进行业务逻辑处理 + } + } \ No newline at end of file diff --git a/_coverpage.md b/_coverpage.md new file mode 100644 index 0000000000000000000000000000000000000000..f00d7686644d7db07b0fc23d7a569312bc2363db --- /dev/null +++ b/_coverpage.md @@ -0,0 +1,13 @@ + + +# LearningNotes + +- Java学习笔记,面试突击宝典,主要来源于B站上视频的学习,同时会记录平时一些学习和项目中遇到的问题,同步更新在蘑菇博客,如果对我的博客网站感兴趣的话,欢迎关注我的 蘑菇博客项目 笔记主要涵盖:Java,Spring,SpringCloud,计算机网络,操作系统,数据结构,Vue等 如果笔记对您有帮助的话,欢迎star支持,谢谢~ + +star +fork + +[Gitee]() +[Github]() +[开始阅读](README.md) + diff --git a/_navbar.md b/_navbar.md new file mode 100644 index 0000000000000000000000000000000000000000..881c3047ba7f30047bfd738d68c787cfb4ec5ea7 --- /dev/null +++ b/_navbar.md @@ -0,0 +1,5 @@ +- [笔记仓库](https://gitee.com/moxi159753/LearningNotes) +- [笔记文档](http://moxi159753.gitee.io/learningnotes) +- [蘑菇博客](http://moguit.cn/#/) +- [博客文档](http://moxi159753.gitee.io/mogu_blog_doc) + diff --git a/_sidebar.md b/_sidebar.md new file mode 100644 index 0000000000000000000000000000000000000000..251dfce67e91768849c71dc8460a51e18935e2e8 --- /dev/null +++ b/_sidebar.md @@ -0,0 +1,293 @@ +- [**学习笔记**](README.md) + + +- **Java** + - [equals和等等的区别](校招面试/基础面试题/1_equals和等等的区别/README.md) + - [代码块](./校招面试/基础面试题/2_代码块/README.md) + - [分布式锁](./校招面试/基础面试题/3_分布式锁/README.md) + - [MySQL的存储引擎](./校招面试/基础面试题/4_MySQL的存储引擎/README.md) + - [JDK动态代理和CGLIB动态代理](./校招面试/基础面试题/5_JDK动态代理和CGLIB动态代理/README.md) + - [Java注解和反射](./Java/Java注解和反射/README.md) + - [泛型的类型擦除](./Java/泛型的类型擦除/README.md) + - [Java使用Redis删除指定前缀Key](./Java/Java使用Redis删除指定前缀Key/README.md) + - [前端的一些跨域问题](./Java/前端的一些跨域问题/README.md) + - [使用Ip2region替代淘宝IP接口](./Java/使用Ip2region替代淘宝IP接口/README.md) + - [聊一聊-Java泛型中的通配符T,E,K,V](http://www.moguit.cn/#/info?blogUid=0aa459dc0ae9f9ad82cd22665d08a20d) + - [JVM类加载机制](./Java/JVM类加载机制/README.md) + - [VisualVM安装VisualGC插件](./Java/VisualVM安装VisualGC插件/README.md) + - [谈谈你对ThreadLocal的理解](./Java/谈谈你对ThreadLocal的理解/README.md) + - [谈谈你对AQS的理解](./Java/谈谈你对AQS的理解/README.md) + - [ArrayList扩容机制](./Java/ArrayList扩容机制/README.md) +- **Java8新特性** + - [HashMap变化](./校招面试/Java8新特性/1_HashMap变化/README.md) + - [Lambda表达式](./校招面试/Java8新特性/2_Lambda表达式/README.md) + - [方法引用和构造器](./校招面试/Java8新特性/3_方法引用和构造器/README.md) + - [强大的Stream](./校招面试/Java8新特性/4_强大的Stream/README.md) + - [并行流](./校招面试/Java8新特性/5_并行流/README.md) + - [Optional容器类](./校招面试/Java8新特性/6_Optional容器类/README.md) +- **NIO** + - [NIO是什么](./校招面试/NIO/NIO是什么/README.md) + - [IO到NIO的演变](./校招面试/NIO/NIO的使用案例/README.md) + - [传送门](http://www.moguit.cn/#/info?blogUid=28d61ec002594fc5a9c441ec8560f3ad) +- **JVM** + - [JVM与Java体系结构](JVM/1_内存与垃圾回收篇/1_JVM与Java体系结构/README.md) + - [类加载子系统](./JVM/1_内存与垃圾回收篇/2_类加载子系统/README.md) + - [运行时数据区概述及线程](./JVM/1_内存与垃圾回收篇/3_运行时数据区概述及线程/README.md) + - [程序计数器](./JVM/1_内存与垃圾回收篇/4_程序计数器/README.md) + - [虚拟机栈](./JVM/1_内存与垃圾回收篇/5_虚拟机栈/README.md) + - [本地方法接口](./JVM/1_内存与垃圾回收篇/6_本地方法接口/README.md) + - [本地方法栈](./JVM/1_内存与垃圾回收篇/7_本地方法栈/README.md) + - [堆](./JVM/1_内存与垃圾回收篇/8_堆/README.md) + - [方法区](./JVM/1_内存与垃圾回收篇/9_方法区/README.md) + - [对象实例化内存布局与访问定位](./JVM/1_内存与垃圾回收篇/10_对象实例化内存布局与访问定位/README.md) + - [直接内存](./JVM/1_内存与垃圾回收篇/11_直接内存/README.md) + - [执行引擎](./JVM/1_内存与垃圾回收篇/12_执行引擎/README.md) + - [StringTable](./JVM/1_内存与垃圾回收篇/13_StringTable/README.md) + - [垃圾回收概述](./JVM/1_内存与垃圾回收篇/14_垃圾回收概述/README.md) + - [垃圾回收相关算法](./JVM/1_内存与垃圾回收篇/15_垃圾回收相关算法/README.md) + - [垃圾回收相关概念](./JVM/1_内存与垃圾回收篇/16_垃圾回收相关概念/README.md) + - [垃圾回收器](./JVM/1_内存与垃圾回收篇/17_垃圾回收器/README.md) +- **JUC** + - [Volatile和JMM内存模型的可见性](./校招面试/JUC/1_谈谈Volatile/1_Volatile和JMM内存模型的可见性/README.md) + - [Volatile不保证原子性](./校招面试/JUC/1_谈谈Volatile/2_Volatile不保证原子性/README.md) + - [Volatile禁止指令重排](./校招面试/JUC/1_谈谈Volatile/3_Volatile禁止指令重排/README.md) + - [Volatile的应用](./校招面试/JUC/1_谈谈Volatile/4_Volatile的应用/README.md) + - [CAS底层原理](./校招面试/JUC/2_谈谈CAS/5_CAS底层原理/README.md) + - [原子类AtomicInteger的ABA问题](./校招面试/JUC/3_谈谈原子类的ABA问题/6_原子类AtomicInteger的ABA问题/README.md) + - [ArrayList为什么是线程不安全的](./校招面试/JUC/4_ArrayList为什么线程不安全/ArrayList线程不安全的举例/README.md) + - [TransferValue是什么](./校招面试/JUC/5_TransferValue是什么/README.md) + - [Java锁之读写锁](./校招面试/JUC/6_Java的锁/Java锁之读写锁/README.md) + - [Java锁之公平锁和非公平锁](./校招面试/JUC/6_Java的锁/Java锁之公平锁和非公平锁/README.md) + - [Java锁之可重入锁和递归锁](./校招面试/JUC/6_Java的锁/Java锁之可重入锁和递归锁/README.md) + - [Java锁之自旋锁](./校招面试/JUC/6_Java的锁/Java锁之自旋锁/README.md) + - [CountDownLatch是什么](./校招面试/JUC/7_CountDownLatch_CyclicBarrier_Semaphore使用/CountDownLatch/README.md) + - [CyclicBarrier是什么](./校招面试/JUC/7_CountDownLatch_CyclicBarrier_Semaphore使用/CyclicBarrier/README.md) + - [Semaphore是什么](./校招面试/JUC/7_CountDownLatch_CyclicBarrier_Semaphore使用/Semaphore/README.md) + - [Java中的阻塞队列](./校招面试/JUC/8_阻塞队列/README.md) + - [Synchronized和Lock的区别与好处](./校招面试/JUC/Synchronized和Lock的区别与好处/README.md) + - [Java线程池详解](./校招面试/JUC/10_线程池/README.md) + - [死锁编码及快速定位](./校招面试/JUC/11_死锁编码及快速定位/README.md) + - [JVM体系结构](./校招面试/JUC/12_JVM/JVM体系结构/README.md) + - [什么是GCRoots能做什么](./校招面试/JUC/12_JVM/JVM面试题汇总/1_什么是GCRoots能做什么/README.md) + - [JVM参数调优](./校招面试/JUC/12_JVM/JVM面试题汇总/2_JVM参数调优/README.md) + - [Java中的强引用_软引用_弱引用_虚引用分别是什么](./校招面试/JUC/12_JVM/JVM面试题汇总/3_Java中的强引用_软引用_弱引用_虚引用分别是什么/README.md) + - [Java内存溢出OOM](./校招面试/JUC/12_JVM/JVM面试题汇总/4_Java内存溢出OOM/README.md) + - [垃圾回收器](./校招面试/JUC/12_JVM/JVM面试题汇总/5_垃圾回收器/README.md) + - [Linux相关命令](./校招面试/JUC/13_Linux相关命令/README.md) + - [Github学习](./校招面试/JUC/14_Github学习/README.md) + - [乐观锁和悲观锁](./校招面试/JUC/15_乐观锁和悲观锁/README.md) + - [源码](./校招面试/JUC/Code) +- **中间件** + - [消息队列的面试连环炮](./校招面试/面试扫盲学习/1_消息队列的面试连环炮/README.md) + - [分布式搜索引擎的面试连环炮](./校招面试/面试扫盲学习/2_分布式搜索引擎的面试连环炮/README.md) + - [分布式缓存](./校招面试/面试扫盲学习/3_分布式缓存/README.md) + - [Redis的面试连环炮](./校招面试/面试扫盲学习/4_Redis的面试连环炮/README.md) + - [Redis的面试连环炮2](./校招面试/面试扫盲学习/5_Redis的面试连环炮2/README.md) + - [分布式系统的面试连环炮](./校招面试/面试扫盲学习/6_分布式系统的面试连环炮/README.md) + - [分布式系统幂等性与顺序性及分布式锁](./校招面试/面试扫盲学习/7_分布式系统幂等性与顺序性及分布式锁/README.md) + - [分布式Session解决方案](./校招面试/面试扫盲学习/8_分布式Session解决方案/README.md) + - [Spring中的事务](./校招面试/面试扫盲学习/9_Spring中的事务/README.md) + - [设计一个高并发系统](./校招面试/面试扫盲学习/10_设计一个高并发系统/README.md) + - [数据库分库分表的面试连环炮](./校招面试/面试扫盲学习/11_数据库分库分表的面试连环炮/README.md) + - [MySQL读写复制及主从同步时延](./校招面试/面试扫盲学习/12_MySQL读写复制及主从同步时延/README.md) + - [常见的消息队列有哪些?](http://www.moguit.cn/#/info?blogUid=3a309d5c258c58e7b03a99cda13f650c) + - [5个方案告诉你:高并发环境下,先操作数据库还是先操作缓存?](http://www.moguit.cn/#/info?blogUid=b73aba84b0890c3c282a18c4fb0aab3d) +- **SpringCloud** + - [SpringCloud是什么](./SpringCloud/SpringCloud2020/1_SpringCloud是什么/README.md) + - [搭建Eureka集群](./SpringCloud/SpringCloud2020/3_搭建Eureka集群/README.md) + - [Eureka停更后的替换](./SpringCloud/SpringCloud2020/4_Eureka停更后的替换/README.md) + - [Ribbon负载均衡](./SpringCloud/SpringCloud2020/5_Ribbon负载均衡/README.md) + - [OpenFeign实现服务调用](./SpringCloud/SpringCloud2020/6_OpenFeign实现服务调用/README.md) + - [Hystrix中的服务降级和熔断](./SpringCloud/SpringCloud2020/7_Hystrix中的服务降级和熔断/README.md) + - [服务网关Gateway](./SpringCloud/SpringCloud2020/8_服务网关Gateway/README.md) + - [分布式配置中心SpringCloudConfig](./SpringCloud/SpringCloud2020/9_分布式配置中心SpringCloudConfig/README.md) + - [消息总线Bus](./SpringCloud/SpringCloud2020/10_消息总线Bus/README.md) + - [消息驱动SpringCloudStream](./SpringCloud/SpringCloud2020/11_消息驱动SpringCloudStream/README.md) + - [SpringCloudSleuth分布式请求链路跟踪](./SpringCloud/SpringCloud2020/12_SpringCloudSleuth分布式请求链路跟踪/README.md) + - [使用Nacos实现服务注册发现以及服务配置等功能](./SpringCloud/SpringCloud2020/13_Nacos是什么/README.md) + - [SpringCloudAlibabaSentinel实现熔断和限流](./SpringCloud/SpringCloud2020/14_SpringCloudAlibabaSentinel实现熔断和限流/README.md) + - [SpringCloudAlibabaSeata处理分布式事务](./SpringCloud/SpringCloud2020/15_SpringCloudAlibabaSeata处理分布式事务/README.md) + - [使用Zipkin搭建蘑菇博客链路追踪](./SpringCloud/使用Zipkin搭建蘑菇博客链路追踪/README.md) + - [源码](./SpringCloud/SpringCloud2020/SpringCloud2020) +- **SpringSecurity** + - [初识SpringSecurity](./SpringSecurity/1_初识SpringSecurity/README.md) + - [SpringSecurity在MVC项目中的使用](./SpringSecurity/2_SpringSecurity在MVC项目中的使用/README.md) + - [SpringSecurity在单机环境下的使用](./SpringSecurity/3_SpringSecurity在单机环境下的使用/README.md) + - [SpringSecurity在分布式环境下的使用](./SpringSecurity/4_SpringSecurity在分布式环境下的使用/README.md) + - [OAuth2.0介绍](./SpringSecurity/5_OAuth2.0介绍/README.md) +- **ElasticStack** + - [ElasticSearch介绍与安装](./ElasticStack/1_ElasticSearch介绍与安装) + - [Beats入门简介](./ElasticStack/2_Beats入门简介) + - [Kibana安装与介绍](./ElasticStack/3_Kibana安装与介绍) + - [Logstash入门简介](./ElasticStack/4_Logstash入门简介) + - [ElasticStack综合案例](./ElasticStack/5_ElasticStack综合案例) + - [使用ELK搭建蘑菇博客日志收集](./ElasticStack/6_使用ELK搭建蘑菇博客日志收集) +- **算法学习** + - [斐波那契数列](./数据结构/1_斐波那契数列/README.md) + - [青蛙跳台阶](./数据结构/2_青蛙跳台阶/README.md) + - [找出丑数](./数据结构/3_找出丑数/README.md) + - [二维数组中的查找](./数据结构/4_二维数组中的查找/README.md) + - [替换空格](./数据结构/5_替换空格/README.md) + - [两个栈实现一个队列](./数据结构/6_两个栈实现一个队列/README.md) + - [旋转数组的最小数字](./数据结构/7_旋转数组的最小数字/README.md) + - [调整数组顺序使奇数位于偶数前面](./数据结构/8_调整数组顺序使奇数位于偶数前面/README.md) + - [包含min函数的栈](./数据结构/9_包含min函数的栈/README.md) + - [栈的压入弹出序列](./数据结构/10_栈的压入弹出序列/README.md) + - [从尾到头打印链表](./数据结构/11_从尾到头打印链表/README.md) + - [链表中倒数第K个节点](./数据结构/12_链表中倒数第K个节点/README.md) + - [反转链表](./数据结构/13_反转链表/README.md) + - [合并两个排序的链表](./数据结构/14_合并两个排序的链表/README.md) + - [复杂链表的复制](./数据结构/15_复杂链表的复制/README.md) + - [两个链表的公共结点](./数据结构/16_两个链表的公共结点/README.md) + - [孩子们的游戏(圆圈中最后剩下的数)](./数据结构/17_孩子们的游戏(圆圈中最后剩下的数/README.md)) + - [链表中环的入口结点](./数据结构/18_链表中环的入口结点/README.md) + - [二进制中1的个数](./数据结构/19_二进制中1的个数/README.md) + - [不用加减乘除做加法](./数据结构/20_不用加减乘除做加法/README.md) + - [数组中出现次数超过一半的数字](./数据结构/21_数组中出现次数超过一半的数字/README.md) + - [整数中1出现的次数](./数据结构/22_整数中1出现的次数/README.md) + - [数组中只出现一次的数字](./数据结构/23_数组中只出现一次的数字/README.md) + - [树的遍历](./数据结构/24_树的遍历/README.md) + - [重建二叉树](./数据结构/25_重建二叉树/README.md) + - [树的子结构](./数据结构/26_树的子结构/README.md) + - [二叉树的镜像](./数据结构/27_二叉树的镜像/README.md) + - [从上往下打印二叉树](./数据结构/28_从上往下打印二叉树/README.md) + - [二叉搜索树的后序遍历序列](./数据结构/29_二叉搜索树的后序遍历序列/README.md) + - [二叉树中和为某一值的路径](./数据结构/30_二叉树中和为某一值的路径/README.md) + - [二叉搜索树与双向链表](./数据结构/31_二叉搜索树与双向链表/README.md) + - [最小的K个数](./数据结构/32_最小的K个数/README.md) + - [数据流中的中位数](./数据结构/33_数据流中的中位数/README.md) + - [ 二叉树的下一个节点](./数据结构/34_二叉树的下一个节点/README.md) + - [对称的二叉树](./数据结构/35_对称的二叉树/README.md) + - [按之字形顺序打印二叉树](./数据结构/36_按之字形顺序打印二叉树/README.md) + - [把二叉树打印成多行](./数据结构/37_把二叉树打印成多行/README.md) + - [二叉搜索树的第K个节点](./数据结构/38_二叉搜索树的第K个节点/README.md) + - [序列化二叉树](./数据结构/39_序列化二叉树/README.md) + - [连续子数组的最大和](./数据结构/40_连续子数组的最大和/README.md) + - [矩形覆盖](./数据结构/41_矩形覆盖/README.md) + - [排序算法-冒泡插入选择](./数据结构/42_排序算法-冒泡插入选择/README.md) + - [希尔排序](./数据结构/43_希尔排序/README.md) + - [归并排序](./数据结构/44_归并排序/README.md) + - [快速排序](./数据结构/45_快速排序/README.md) + - [动态规划算法](./数据结构/动态规划算法/README.md) + - [源码](./数据结构/NowCode) +- **SpringBoot** + - [Eureka管理页面配置接口返回git信息](./SpringBoot/Eureka管理页面配置接口返回git信息/README.md) + - [Java如何通过IP地址获取地区](./SpringBoot/Java如何通过IP地址获取地区/README.md) + - [SpringSecurity造成无法使用iframe的内嵌页面的解决方法](./SpringBoot/SpringSecurity造成无法使用iframe的内嵌页面的解决方法/README.md) + - [SpringBoot解决时区问题](./SpringBoot/SpringBoot解决时区问题/README.md) + - [SpringBoot项目中使用字符串占位符](./SpringBoot/SpringBoot项目中使用字符串占位符/README.md) + - [SpringBoot中使用注解的方式创建队列和交换机](./SpringBoot/SpringBoot中使用注解的方式创建队列和交换机/README.md) + - [解决升级SpringBoot2.X后无法向eureka注册服务的问题](./SpringBoot/解决升级SpringBoot2.X后无法向eureka注册服务的问题/README.md) + - [使用DevTool实现SpringBoot项目热部署](./SpringBoot/使用DevTool实现SpringBoot项目热部署/README.md) + - [使用自定义日志接口收集用户访问日志](./SpringBoot/使用自定义日志接口收集用户访问日志/README.md) + - [Bean的生命周期](./SpringBoot/Bean的生命周期/README.md) +- **Vue** + - [Axios中拦截器的使用](./Vue/Axios中拦截器的使用/README.md) + - [ElementUI中Upload如何批量上传](./Vue/ElementUI中Upload如何批量上传/README.md) + - [el-select因为绑定的值为整数而无法默认选择](./Vue/el-select因为绑定的值为整数而无法默认选择/README.md) + - [Vue动态计算Table表格的高度](./Vue/Vue动态计算Table表格的高度/README.md) + - [Vue对Element中的e-tag添加@click事件无效](./Vue/Vue对Element中的e-tag添加@click事件无效/README.md) + - [Vue使用Echarts制作一个文章贡献度表](./Vue/Vue使用Echarts制作一个文章贡献度表/README.md) + - [Vue中input框自动聚焦](./Vue/Vue中input框自动聚焦/README.md) + - [Vue使用vue-count-to插件对数字显示美化](./Vue/Vue使用vue-count-to插件对数字显示美化/README.md) + - [Vue项目如何关闭Eslint校验](./Vue/Vue项目如何关闭Eslint校验/README.md) + - [Vue项目使用阿里巴巴矢量图标库](./Vue/Vue项目使用阿里巴巴矢量图标库/README.md) + - [Vue项目引入CDN加速](./Vue/Vue项目引入CDN加速/README.md) + - [Vue制作一个评论模块](./Vue/Vue制作一个评论模块/README.md) + - [Vue中Html和Markdown互相转换](./Vue/Vue中Html和Markdown互相转换/README.md) + - [Vue中对数组变化监听](./Vue/Vue中对数组变化监听/README.md) + - [Vue中使用Vue-cropper进行图片裁剪](./Vue/Vue中使用Vue-cropper进行图片裁剪/README.md) + - [Vuex学习指南-实现一个计数器](./Vue/VueX/Vuex学习指南-实现一个计数器/README.md) + - [Vue中防止XSS脚本攻击](./Vue/VueX/Vue中防止XSS脚本攻击/README.md) + - [Vue如何使用G2绘制图片](./Ant/G2/Vue如何使用G2绘制图片/README.md) + - [使用Vuex进行两个页面逻辑交互](./Vue/使用Vuex进行两个页面逻辑交互/README.md) +- **杂记** + - [CKEditor前端样式和编辑器的样式不一致的问题](./杂记/CKEditor前端样式和编辑器的样式不一致的问题/README.md) + - [Ckeidtor中上传图片添加token信息](./杂记/ckeidtor中上传图片添加token信息/README.md) + - [CLion搭建C语言开发环境](./杂记/CLion搭建C语言开发环境/README.md) + - [Elasticsearch介绍与安装](./杂记/Elasticsearch介绍与安装/README.md) + - [Github项目配置Actions](./杂记/Github项目配置Actions/README.md) + - [SpringBoot+Vue如何集成第三方登录登录JustAuth](./杂记/SpringBoot+Vue如何集成第三方登录登录JustAuth/README.md) + - [SpringBoot项目启动增加自定义Banner](./杂记/SpringBoot项目启动增加自定义Banner/README.md) + - [VSCode服务版搭建教程,让平板化为生产力工具](./杂记/VSCode服务版搭建教程/README.md) + - [Windows平台编写bat脚本让后台启动多个程序](./杂记/Windows平台编写bat脚本让后台启动多个程序/README.md) + - [记一次蘑菇博客差点被删库的经历](./杂记/记一次蘑菇博客差点被删库的经历/README.md) + - [解决git默认不区分大小写的问题](./杂记/解决git默认不区分大小写的问题/README.md) + - [蘑菇博客从Eureka迁移到Nacos](./杂记/蘑菇博客从Eureka迁移到Nacos/README.md) + - [Docker搭建蘑菇博客(Eureka版)](./杂记/Docker搭建蘑菇博客(Eureka版)/README.md) + - [Docker搭建蘑菇博客(Nacos版)](./杂记/Docker搭建蘑菇博客(Nacos版)/README.md) + - [蘑菇博客Nacos安装指南](./杂记/蘑菇博客Nacos安装指南/README.md) + - [蘑菇博客Sentinel安装指南](./杂记/蘑菇博客Sentinel安装指南/README.md) + - [蘑菇博客QQ小程序发布指南](./杂记/蘑菇博客QQ小程序发布指南/README.md) + - [蘑菇博客后台登录页面增加粒子特效](./杂记/蘑菇博客后台登录页面增加粒子特效/README.md) + - [蘑菇博客集成MarkDown编辑器tui-editor](./杂记/蘑菇博客集成MarkDown编辑器tui-editor/README.md) + - [蘑菇博客配置七牛云存储](./杂记/蘑菇博客配置七牛云存储/README.md) + - [蘑菇博客配置域名解析](./杂记/蘑菇博客配置域名解析/README.md) + - [蘑菇博客切换搜索模式](./杂记/蘑菇博客切换搜索模式/README.md) + - [蘑菇博客如何部署到阿里云服务器](./杂记/蘑菇博客如何部署到阿里云服务器/README.md) + - [蘑菇博客如何扩展新的功能和页面](./杂记/蘑菇博客如何扩展新的功能和页面/README.md) + - [蘑菇博客使用GithubAction完成持续集成](./杂记/蘑菇博客使用GithubAction完成持续集成/README.md) + - [蘑菇博客使用SQL语句进行搜索出的内容忽略大小写并添加高亮效果](./杂记/蘑菇博客使用SQL语句进行搜索出的内容忽略大小写并添加高亮效果/README.md) + - [蘑菇博客添加本地Markdown文件上传功能](./杂记/蘑菇博客添加本地Markdown文件上传功能/README.md) + - [如何给七牛云中的文件配置防盗链](./杂记/如何给七牛云中的文件配置防盗链/README.md) + - [如何使用docsify给蘑菇博客编写开发文档](./杂记/如何使用docsify给蘑菇博客编写开发文档/README.md) + - [如何制作github小徽章](./杂记/如何制作github小徽章/README.md) + - [使用JustAuth集成QQ登录](./杂记/使用JustAuth集成QQ登录/README.md) + - [使用开源项目申请JetBrains全家桶](./杂记/使用开源项目申请JetBrains全家桶/README.md) + - [什么是CICD](./杂记/什么是CICD/README.md) + - [罗技K380快捷键](./杂记/罗技K380快捷键/README.md) + - [将PDF转换为Kindle能识别的MOBI格式](./杂记/将PDF转换为Kindle能识别的MOBI格式/README.md) + - [OCR文字识别软件](./杂记/OCR文字识别软件/README.md) +- **Linux** + - [Linux下查看文件和文件夹占用空间大小](./Linux/Linux下查看文件和文件夹占用空间大小/README.md) + - [Linux下通过nginx配置https](./Linux/Linux下通过nginx配置https/README.md) + - [CentOS下如何安装Nginx](./Linux/CentOS下如何安装Nginx/README.md) + - [记一次因代码出错不断输出日志占满Docker容器硬盘的排查经历](./Linux/记一次因代码出错不断输出日志占满Docker容器硬盘的排查经历/README.md) + - [CentOS下安装Nacos](./Linux/CentOS下安装Nacos/README.md) +- **Redis** + - [Redis中的数据结构](./Redis/Redis中的数据结构/README.md) + - [Redis中的跳跃表](./Redis/Redis中的跳跃表/README.md) + - [Redis缓存穿透-布隆过滤器](./Redis/Redis缓存穿透-布隆过滤器/README.md) + - [大白话谈IO模型](./Redis/大白话谈IO模型/README.md) + - [IO多路复用底层原理](./Redis/IO多路复用底层原理/README.md) + - [Redis实现分布式锁](./Redis/Redis实现分布式锁/README.md) +- **JavaScript** + - [Js设置二级域名和顶级域名下共享Cookie](./JavaScript/Js设置二级域名和顶级域名下共享Cookie/README.md) + - [如何通过Js将时间转换为刚刚_几分钟前_几小时前](./JavaScript/如何通过Js将时间转换为刚刚_几分钟前_几小时前/README.md) +- **数据库** + - [MyBatis常见面试题](./数据库/MyBatis常见面试题/README.md) + - [MyBatis的缓存机制](./数据库/MyBatis的缓存机制/README.md) + - [MySQL索引](./数据库/MySQL索引/README.md) +- **操作系统** + - [进程和线程通信](./操作系统/1_进程和线程通信/README.md) +- **计算机网络** + - [三次握手和四次挥手](./计算机网络/1_三次握手和四次挥手/README.md) + - [https和http](./计算机网络/2_https和http/README.md) + - [TCP中的拥塞控制和流量控制](./计算机网络/3_TCP中的拥塞控制和流量控制/README.md) + - [物理层](./计算机网络/4_物理层/README.md) + - [数据链路层](./计算机网络/5_数据链路层/README.md) + - [http中的状态码](./计算机网络/http中的状态码/README.md) +- **面经** + - [京东面经](./校招面试/面经汇总/1_京东面经/README.md) + - [字节跳动面试总结](./校招面试/面经汇总/2_字节跳动面试总结/README.md) + - [京东零售提前批Java一面](./校招面试/面经汇总/3_京东零售提前批Java一面/README.md) + - [京东零售提前批Java二面](./校招面试/面经汇总/4_京东零售提前批Java二面/README.md) + - [滴滴出行提前批Java123面](./校招面试/面经汇总/5_滴滴出行提前批Java123面/README.md) +- **Golang基础** + - [Go语言的安装](./Golang/Golang基础/0_Go语言的安装/README.md) + - [Go语言发展简史](./Golang/Golang基础/1_Go语言发展简史/README.md) + - [Go的变量](./Golang/Golang基础/2_Go的变量/README.md) + - [Go的数据类型](./Golang/Golang基础/3_Go的数据类型/README.md) + - [Go的运算符](./Golang/Golang基础/4_Go的运算符/README.md) + - [Go的流程控制](./Golang/Golang基础/5_Go的流程控制/README.md) + - [Go的数组](./Golang/Golang基础/6_Go的数组/README.md) + - [Go的切片](./Golang/Golang基础/7_Go的切片/README.md) + - [Go的map](./Golang/Golang基础/8_Go的map/README.md) + - [Go的函数](./Golang/Golang基础/9_Go的函数/README.md) + - [Go中的日期函数](./Golang/Golang基础/10_Go中的日期函数/README.md) + - [Go中的指针](./Golang/Golang基础/11_Go中的指针/README.md) + - [Go中的结构体](./Golang/Golang基础/12_Go中的结构体/README.md) + - [Go中的包以及GoMod](./Golang/Golang基础/13_Go中的包以及GoMod/README.md) + - [Go中的接口](./Golang/Golang基础/14_Go中的接口/README.md) + - [goroutine实现并行和并发](./Golang/Golang基础/15_goroutine实现并行和并发/README.md) + - [Golang中的反射](./Golang/Golang基础/16_Golang中的反射/README.md) \ No newline at end of file diff --git a/doc/icon/favicon.ico b/doc/icon/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..5af9b3340edfceff7f885b0b5ca3e3d649cacbbb Binary files /dev/null and b/doc/icon/favicon.ico differ diff --git a/doc/icon/favicon2.ico b/doc/icon/favicon2.ico new file mode 100644 index 0000000000000000000000000000000000000000..b29eb4aa9b1806afdf1a45e728616d6cf1a84ed5 Binary files /dev/null and b/doc/icon/favicon2.ico differ diff --git a/doc/images/qq/group.png b/doc/images/qq/group.png new file mode 100644 index 0000000000000000000000000000000000000000..ea93fc51640c1a19cbc62fb42ef48dd8e35dfed8 Binary files /dev/null and b/doc/images/qq/group.png differ diff --git a/doc/images/qq/qq.png b/doc/images/qq/qq.png new file mode 100644 index 0000000000000000000000000000000000000000..f4479018ff22595a98139b29246b73b6283749af Binary files /dev/null and b/doc/images/qq/qq.png differ diff --git a/doc/images/qq/qqGroup.png b/doc/images/qq/qqGroup.png new file mode 100644 index 0000000000000000000000000000000000000000..ba049b7b014c0196e74c3bb7a86764da7a718a2a Binary files /dev/null and b/doc/images/qq/qqGroup.png differ diff --git a/doc/images/qq/qqGroup2.png b/doc/images/qq/qqGroup2.png new file mode 100644 index 0000000000000000000000000000000000000000..984bb821c2e9e04b9d87cffbbae892f6f957ef92 Binary files /dev/null and b/doc/images/qq/qqGroup2.png differ diff --git a/doc/images/qq/wx.png b/doc/images/qq/wx.png new file mode 100644 index 0000000000000000000000000000000000000000..ec5e84502ffbe3ab4793ddb5c8c9a547cb8852a4 Binary files /dev/null and b/doc/images/qq/wx.png differ diff --git a/doc/images/qq/zfb.png b/doc/images/qq/zfb.png new file mode 100644 index 0000000000000000000000000000000000000000..46fc1250af5c36ae93e1d21939492f11d90c0345 Binary files /dev/null and b/doc/images/qq/zfb.png differ diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..5af9b3340edfceff7f885b0b5ca3e3d649cacbbb Binary files /dev/null and b/favicon.ico differ diff --git a/index.html b/index.html new file mode 100644 index 0000000000000000000000000000000000000000..72c7fa45773d9ed6d8e29a9d45e5252300a3dbe0 --- /dev/null +++ b/index.html @@ -0,0 +1,45 @@ + + + + + Java学习笔记 + + + + + + +
+ + + + + + + + + + + + + + + + + + + diff --git "a/\344\271\246\347\261\215/2020\346\234\200\346\226\260Java\351\235\242\350\257\225\351\242\230\345\217\212\347\255\224\346\241\210.pdf" "b/\344\271\246\347\261\215/2020\346\234\200\346\226\260Java\351\235\242\350\257\225\351\242\230\345\217\212\347\255\224\346\241\210.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..e9fd6f53570fc03902ebab01a0900ee4fe69c620 Binary files /dev/null and "b/\344\271\246\347\261\215/2020\346\234\200\346\226\260Java\351\235\242\350\257\225\351\242\230\345\217\212\347\255\224\346\241\210.pdf" differ diff --git "a/\344\271\246\347\261\215/Java\351\235\242\350\257\225\345\256\235\345\205\270.pdf" "b/\344\271\246\347\261\215/Java\351\235\242\350\257\225\345\256\235\345\205\270.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..2ba45f092801d76fbc46280baa113cdb09523927 Binary files /dev/null and "b/\344\271\246\347\261\215/Java\351\235\242\350\257\225\345\256\235\345\205\270.pdf" differ diff --git "a/\345\237\272\347\241\200\345\274\200\345\217\221/\344\273\200\344\271\210\346\230\257Lowcode\346\227\240\344\273\243\347\240\201\350\247\243\345\206\263\346\226\271\346\241\210/README.md" "b/\345\237\272\347\241\200\345\274\200\345\217\221/\344\273\200\344\271\210\346\230\257Lowcode\346\227\240\344\273\243\347\240\201\350\247\243\345\206\263\346\226\271\346\241\210/README.md" deleted file mode 100644 index 49d910bb39307f5eeb324ab07232ecbbad46c99e..0000000000000000000000000000000000000000 --- "a/\345\237\272\347\241\200\345\274\200\345\217\221/\344\273\200\344\271\210\346\230\257Lowcode\346\227\240\344\273\243\347\240\201\350\247\243\345\206\263\346\226\271\346\241\210/README.md" +++ /dev/null @@ -1,313 +0,0 @@ -# 什么是Lowcode无代码解决方案 - -## 前言 - -Lowcode,即无代码/低代码,是一种创建应用的方法,它可以让开发人员使用最少的编码知识,来快速开发应用程序。它可以在图形界面中,使用可视化建模的方式,来组装和配置应用程序。开发人员可以直接跳过所有的基础架构,只关注于使用代码来实现业务逻辑 - -中台之后,便是无代码编程。 - -规模化的组织,经常要面临这样的挑战:每个应用的基础设施是相同的,部分的代码也是相同的,甚至于它们可能只是数据模型不同而已。结果却导致了,他/她们要一次又一次地重新编写一个应用。 - -对于一个新的应用而言,它需要对接大量的三方(非自己团队)服务。服务之间的不断变化 ,导致了对应的使用方也需要发生变化。不断变化的业务,导致了前台的设计不断变化。为了应对快速谈的的前台服务,后台便诞生了中台,以提供快速的响应能力。而随着中台进一步沉淀,从某种形式上趋于稳定,而前台仍然需要快速地响应能力。 - -于是乎,作为一个前端开发人员,我们不断提炼和复用代码,想着的模式在上一篇文章 [减少代码量的 7~8 种方式](https://www.phodal.com/blog/code-reuse/) 中提到了: - -- 脚手架 -- 组件库 -- 模式库 -- 模板和模板应用 - -对应的,我们还创建了一系列的 CLI、工具集、编程器插件以及设计系统,以完成整个系统的快速开发。然而,我们还缺少一套有效的工具,来统一化的管理这些工具。 - -换句话来说,就是:我们需要一个**前端的中台**,它便是无代码/低代码编程。 - -## 什么是无代码编程? - -无代码/低代码是一种创建应用的方法,它可以让开发人员使用最少的编码知识,来快速开发应用程序。它可以在图形界面中,使用可视化建模的方式,来组装和配置应用程序。开发人员可以直接跳过所有的基础架构,只关注于使用代码来实现业务逻辑。 - -当然,从开发人员的角度来看,降低代码量,可能是: - -1. 框架本身处理了复杂性。毕竟 **“复杂度同力一样不会消失,也不会凭空产生,它总是从一个物体转移到另一个物体或一种形式转为另一种形式。”** -2. 代码生成减少了工作量。大量的复制、粘贴需要更多的时间。 - -### 流程 - -只是凭借这个概念,我们是无法理解无代码编程的。于是,我画了一张图来展示相应的架构和流程: - -![image-20200304095343976](images/image-20200304095343976.png) - -依照我的观点来看,我将无代码编程分为了两部分: - -- 用于构建 UI 的编辑器——一种在线的拖拽式 UI 设计和页面构建工具 -- 用于编写业务逻辑的流编辑器——通过流编程的方式来编写业务代码(多数是对于数据的处理) - -**UI 编程器**。为了设计出我们的 UI 构建器,我们需要准备好一系列的基础设施: - -- **UI 编程器**。用于拖拽式设计 UI。 -- 空白脚手架。一个带有完整的应用生命周期的项目,但是它是一个空白的项目——用于我们在构建 UI 的过程中,随时随地的添加组件和代码。 -- 设计系统。我们需要一个完整的组件库,大量的页面模板,以及一定数量的模板应用,减少相应的开发工具量。 -- 代码片段集。它将设计系统中的组件库进一步实例化成代码段,在完成编辑后通过 CLI 来动态编辑代码。 -- DSL(领域特定语言,可选)。中间生成物,用于隔离框架与设计。 - -**流编程器**。随后,为了在 - -- **流编程器**。用于拖拽式、输入编写业务代码。 -- 后端服务。如果不能提供现成的后端服务,则需要拥有一个标准的 API 规范,以及相应的 mock server。 -- 模式库。包含相应的业务处理代码,如通用的登录、数据获取、UI 交互等。 -- DSL(领域特定语言,可选)。同上 - -当然了,我们还需要能**实时预览**构建出来的应用。随后,我们执行了构建,而后构建出了一个半成品应用。开发人员只需要在它的基础上开发应用即可。而在开发人员开发的过程中,我们可以设计一系列的工具,来帮助开发人员更快速地构建应用。 - -- 编辑器插件。包含设计系统、模式库等的自动完成代码,以及组织内部常用的代码库。 -- 调试工具。对于混合类型的应用而言,我们还需要一个开发工具来快速构建应用。 - -从上述的流程上来看,无代码编程还具有以下的特点: - -- 拖放式界面。又或者是可视化模型——基于节点和箭头 -- 基于视觉的设计。 -- 可扩展的设计。如对于插件、插件商店,社区等一系列的支持。 -- 跨平台功能。支持 PC Web 应用开发,支持移动应用构架等。 -- 强大的部署后。即平台包含着整个应用的生命周期。 -- 拥有丰富的集成支持。可以随意的找到需要的组件,以及对应的后台服务。 -- 配置化。它也意味着大量的自定义配置。 -- 自制的领域特定语言(可选)。用于构建时优化。 - -### 优缺点 - -相应的,它具有以下的一些特点: - -1. 高效。不用多说,节省时间和开发成本。 -2. 有限的 Bug,安全性。 -3. 低成本。其所需的预算非常有限。 -4. 易用(取决于设计)。 -5. 开发速度更快。 -6. 开发过程中的 AI 。 -7. 维护成本低。 - -对应的相应的缺点有: - -1. 仍然需要编程技能。 -2. 受限的自定义能力。 -3. 可扩展性成了新的问题。 -4. 集成受限。 - -就当前而言,低代码开发平台通常分为两大类: - -- 对于外部:制作简单的产品,如网络移动应用程序 -- 对于内部:为您的团队或企业创建业务应用程序 - -诸如只使用 CRUD、表单、验证、简单聚合、分页等简易的服务。最常见的例子就是表单构建了,诸如金数据这样的应用,便是可以直接通过拖拽元素来生成,相应的开源实现有 jQuery Form Builder。对于开发人员来说,我们只需要定义好数据模型,再通过拖拽来决定元素的位置即可。从这种角度来看,只要能使用 Serverless 构建的应用和服务,都可以直接使用低代码开发模式。 - -### 开发流程对比 - -从我们的理解来看,传统应用的开发流程是: - -1. 分析、设计、确认、规划需求 -2. 设计系统架构 -3. 搭建前后端项目。选择技术栈、从零开始搭建或者从脚手架中创建。 -4. 搭建持续集成。 -5. 创建线框图和高保真原型。 -6. 设计数据模型,定义前后端契约,即 API URI、方法、字段等。 -7. 前后端实现业务逻辑。 -8. 前端实现 UI 页面。 -9. 集成第三方后端服务。 -10. 功能需求测试(DEV、QA、ST、UAT) -11. 跨功能需求测试(安全性、性能等) -12. 部署到生产环境。 - -而,低代码开发流程: - -1. 分析、设计、确认、规划需求 -2. 选择需要的第三方 API -3. 在可视 IDE 中绘制应用程序的工作流程、数据模型和用户界面。 -4. 连接 API——通常使用服务、函数发现。 -5. 编写业务逻辑(可选)。手动代码添加到前端或者自定义自动生成的 SQL 查询。 -6. 用户验收测试。 -7. 部署到生产环境。 - -从步骤上来看,无代码编程少了几个步骤。这些步骤都因为大量丰富的内部系统集成,而变得非常简单。 - -### 适用场景 - -就当前而言,无代码编程实际上是一种高度的场景预设的模式。因此,它存在一定的适用场景: - -- **模型驱动开发**。 -- **快速 UI 构建**。 -- **极简的业务功能**。使用这样的工具,也意味着,我们对于交互和可 -- **IT 资源受限**。在资源受限的情况下,能快速开发出符合业务需求的应用最重要。 - -而从流程上来看,对于一部分的应用来说,我们并不能实现无代码编程——存在一些业务上的不同之处。因此,**多数场景之下,只是实现了低代码编程**。 - -若是想真实的无代码编程,则需要一些更特定的场景: - -- 设计表格(输入数据) -- 创建报告(组织数据) -- 常规调度和自动化过程(操纵数据) - -更多的场景正在探索中。 - -## 无代码编程的挑战 - -无代码编程,除了需要准备好上述的一系列基础设施,还不可避免地会遇到一系列挑战。 - -- 谁来写这部分代码? -- 客户端的基础设施准备。 -- 服务端的服务平台搭建。 -- 统一用户体验设计。设计出一系列能便利组合的组件,及对应的模板页面。与此同时,它们还能适应于不同的风格,即有多样性的主题支持。 -- DevOps 流水线设计。低代码编程,依赖于一系列的自动化工具,以实现构建、调试、部署以及维护,同时还包含应用的测试。 -- 领域语言设计。 -- 自动化测试。如果我们的前端代码是自动生成的,那么我们还需要对它们进行测试吗?这是一个好问题,而如果代码是自动生成的,那么测试也应该是自动生成的。毕竟要在平台上,编写大量的自动化测试,以保证平台的质量。 - -其中,有一些部分略微复杂一些,我们大概可以探索一下。 - -### 谁来写这部分代码? - -在我们创建这样一个平台和工具时,我们要考虑的第一个问题是,我们这个工具是为谁写的? - -- 没有编程经验的人。如业务人员,他/她们对于业务系统有着非常丰富的经验。这也意味着,我们 -- 有编程知识,但是没有经验的人。 -- 有一定经验的开发人员。 -- 有丰富经验的开发人员。对于专业的人来说,自动化就意味着缺少灵活度。甚至与自己编写相比,他/她们要花费更多的时间来修复生成的代码。 - -显然,对于相当有经验的开发人员而言,这个工具并不一定是他/她们所需要的。 - -### 客户端基础设施 - -从我的理解来看,它适合于 **快速的 MVP 构建**,并且生成的代码还应该方便修改,而不是诸如早期的 DreamWeaver 或者 FrontPage 这样的工具。 - -而与此同时,由于面向的开发人员水平不同,我们所需要做的工具也不同: - -1. 支持云构建和调试。 -2. GUI 编程应用。 -3. 代码生成。 -4. 设计系统体系构建。组件库搭建,模板应用创建等。 -5. … - -更难的是,容易让开发人员能接受代码生成。 - -### 服务端 - -对于一个低代码平台而言,它对应的后端应该: - -1. 大量可用地现有服务。身份验证、安全性、推送能力、地图等等 -2. 快速构建出后端服务。若是有内部 Serverless 或者 FaaS 方案,可以说是再好不过了。 -3. 方便与第三方服务集成。 -4. 灵活性。支持多语言等。 - -统一的后端服务 API,对于后端服务来说,我们需要一个通用的范式。所有的 API 应该按照这样的范式来设计。不过,作为一个 API 的消费方,我们可能没有这么大的权力,但是我们可以采用**装饰器模式**,即封装第三方 API 成统一的方式。为此,我们采用的方式,仍然是: - -- 契约。诸如 Swagger UI,它可以直接创建一个简易可用的服务。 -- BFF。即我们一一去按我们的需要,去封装这些第三方应用。 -- 查询语言。与自己编写 BFF 相比,更简单的方式是采用:**GraphQL** 这样的后端查询语言,便捷性更高、模式更加灵活。 - -在开发前的设计期里,我们需要首先设计出对应的领域模型。 - -### 领域语言设计 - -低代码环境使用(图形)**建模语言**来指定整个系统、产品的行为。它意味着: - -1. 将数据结构、领域模式应用到程序的各个层级中。 -2. 将业务规则、决策融入到应用中(层级)。 - -这也就意味着,我们需要设计一个模型语言。而它对于我们而言,实际上是领域特定语言(DSL)。如下是一个简单的 DSL 示例,用于描述使用到的组件: - -``` - { - "style": "", - "id": 2, - "blocks": [ - { - "content": { - "content": "content", - "title": "hello" - }, - "type": "card" - } - ] - } -``` - -除此,我们还需要设计对应的布局 DSL,诸如于: - -``` -H:[circle1(circle1.height)] // set aspect-ratio for circle1 -HV:[circle2..5(circle1)] // use same width/height for other circles -H:|[circle1]-[circle2]-[circle3]-[circle4]-[circle5]| -V:|~[circle1..5]~| // center all circles vertically -``` - -最后,我们还需要将流代码,转换为真实的项目代码。三种类型的 DSL 结合下来,都不是一个轻松的工具。 - -## 原型设计 - -写好现有的组件,通用型接口。如常见的登录接口,。对于使用登录接口的业务来说,它们只关心三部分的内容: - -1. 成功登录。 -2. 取消登录。 -3. 登录失败。对于客户端而言,可以视为取消登录。对于服务端来说,则可能是密码错误、用户名不存在、账号被锁定等。 - -对应于以上情景,又有一些通用的逻辑处理: - -1. 登录成功。保存 Token,并返回历史页面。 -2. 登录失败。弹出一个自定义内容的提示框。 - -这些代码是相似的。 - -### 前端原型 - -在一些简单的前端应用里: - -- 模板。只是在使用这些模板,再为这些模板设置相应的属性,绑定对应的值。 -- 数据。其过程都只是在各种保存变量的值,并 CRUD 这些变量的路上。为此,我们需要一个数据处理的管道架构设计,用于处理这些值。 -- 函数。事实上,我们的所有函数都只是一些管理函数,只用于处理这些对应的逻辑。 - -这些常见的功能都可以做成一些组件,它们对于某些应用来说,代码相应的重复。 - -- 无限加载页面。只需要绑定上 API,再控制一下元素的显示与隐藏即可。 -- 表单。定义好字段即类型,对应的前后台逻辑都有了。除此,我们还需要为它们自定义好常见的规则,如正则表达式。而一旦表单之间有联动,那么这个组件的设计就更加麻烦了。 -- 卡片式元素。 -- 表单和表格展示。 -- 常见图表。事实上,已经有一系列的图表工具了,我们只是在它们在基础上,进行了二次封装而已——使得它们可以变成领域语言的形式。 -- 高级的响应式布局。与每个应用独立开发布局不同的是,低代码平台需要提供一套强大的自定义、响应式布局设计——即要满足移动端的通用模式,还要满足桌面版的通用模式。如对于大量数据来说,桌面端使用的是 Pagination,移动端使用的是无限滚动。 - -### 后端原型 - -事实上,对于后端来说,低成本平台意味着,代码生成及服务生成。而服务本身是有限的,既然是业务上发生了一些变化,后端服务也可能并不会发生变化。 - -它也意味着: - -- 微服务化。每个后端服务要尽可能的小。 -- API 规范化。即采用统一的 API 格式,接受统一的权限管理 -- 大量的 API 服务。 -- 快速集成第三方服务方案。集成第三方服务是开发应用不可避免的情况。为了应对这个问题,我们需要做准备好对应的创建服务逻辑,传入第三方服务所需要的参数,便可以直接生成我们的转发服务。 - -那么,问题来了,既然如此,我们是否能提供一个定制的工具呢?让每个人可以创建自己的组件流? - -答案,显然是可以的。 - -### 概念证明 - -于是乎,在我最近设计的 PoC (概念证明)里,采用的是 Anguar 框架。相应的基本思想如下: - -1. 使用 Material Design 作为组件库,使用 CDK 的 Drag 来实现拖拽功能。每个拖拽的组件,称为 element(元素),由 ElementDispatcher 由根据数据生成对应的组件。可拖拽的部分由两部分组成:**布局** + **元素**。 -2. UI 构建完后,生成对应的 DSL,目前采用的是 JSON。毕竟数据结构是最简单的领域特定语言。 -3. 借由 Angular Schematics 解析这部分的 DSL,来生成相应的项目代码。 - -## 其它 - -相关开源项目: - -- 拖拽式 Web 建造工具:https://grapesjs.com/ -- 基于 Flow 的编程工具:https://noflojs.org/ -- DSL 布局生成器:https://github.com/ijzerenhein/autolayout.js/ -- 可视化数据流编辑器:https://github.com/Gregwar/blocks.js -- 基于 React 的内容生成器:https://github.com/vigetlabs/colonel-kurtz - -参考资料: - -1. https://www.process.st/low-code/ -2. https://medium.com/@stefan.dreverman/decisions-to-take-for-your-low-code-architecture-c0768b606f -3. https://medium.com/@stefan.dreverman/analyzing-coinmarketcap-data-with-neo4j-4930ba0068e1 -4. https://www.outsystems.com/blog/what-is-low-code.html -5. https://medium.com/@stefan.dreverman/starting-a-low-code-application-architecture-13170fcd6fc7 -6. https://www.quora.com/What-is-low-code \ No newline at end of file diff --git "a/\345\237\272\347\241\200\345\274\200\345\217\221/\344\273\200\344\271\210\346\230\257Lowcode\346\227\240\344\273\243\347\240\201\350\247\243\345\206\263\346\226\271\346\241\210/images/image-20200304095343976.png" "b/\345\237\272\347\241\200\345\274\200\345\217\221/\344\273\200\344\271\210\346\230\257Lowcode\346\227\240\344\273\243\347\240\201\350\247\243\345\206\263\346\226\271\346\241\210/images/image-20200304095343976.png" deleted file mode 100644 index d4ce78229e2da47bd38fcdd30f52a186d3faf97d..0000000000000000000000000000000000000000 Binary files "a/\345\237\272\347\241\200\345\274\200\345\217\221/\344\273\200\344\271\210\346\230\257Lowcode\346\227\240\344\273\243\347\240\201\350\247\243\345\206\263\346\226\271\346\241\210/images/image-20200304095343976.png" and /dev/null differ diff --git "a/\346\223\215\344\275\234\347\263\273\347\273\237/1_\350\277\233\347\250\213\345\222\214\347\272\277\347\250\213\351\200\232\344\277\241/READMD.md" "b/\346\223\215\344\275\234\347\263\273\347\273\237/1_\350\277\233\347\250\213\345\222\214\347\272\277\347\250\213\351\200\232\344\277\241/README.md" similarity index 90% rename from "\346\223\215\344\275\234\347\263\273\347\273\237/1_\350\277\233\347\250\213\345\222\214\347\272\277\347\250\213\351\200\232\344\277\241/READMD.md" rename to "\346\223\215\344\275\234\347\263\273\347\273\237/1_\350\277\233\347\250\213\345\222\214\347\272\277\347\250\213\351\200\232\344\277\241/README.md" index 10146d49d5a3b4bfc7b76e3235942c68ca9f2652..23778adb2f297379ef648fce1a63f01d1e145f4d 100644 --- "a/\346\223\215\344\275\234\347\263\273\347\273\237/1_\350\277\233\347\250\213\345\222\214\347\272\277\347\250\213\351\200\232\344\277\241/READMD.md" +++ "b/\346\223\215\344\275\234\347\263\273\347\273\237/1_\350\277\233\347\250\213\345\222\214\347\272\277\347\250\213\351\200\232\344\277\241/README.md" @@ -40,6 +40,16 @@ - 信号量机制(Semaphore):包括无名线程信号量和命名线程信号量 - 信号机制(Signal):类似进程间的信号处理,线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。 +## 为什么用多线程而不用多进程 + +多进程下,进程的上下文包括了虚拟机内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的状态 + +多线程是属于同一个进程,此时因为虚拟机内存是共享的,所以在切换时,虚拟内存这些资源都保存不懂,只需要切换线程的私有数据、寄存器等不共享的数据。 + +上下文切换,但同进程内的线程切换,要比多进程间的切换消耗更少的资源,这也是多进程代替多进程的优势。 + +多进程与多线程的区别:本质的区别在于每个进程拥有自己的一套变量,而线程则共享数据。共享变量使线程之间的通信比进程之间的通信更有效、更容易。在有些操作系统中,与进程相比,线程更加轻量级,创建、撤销一个线程比启动新进程的开销要小得多。 + ## 线程如何按照自己指定的顺序执行 我们在日常的多线程开发中,可能有时会想让每个线程都按照我们指定的顺序来运行,而不是让CPU随机调度,这样可能会让我们在日常开发的工作中带来不必要的。 diff --git "a/\346\223\215\344\275\234\347\263\273\347\273\237/2_\346\255\273\351\224\201\347\232\204\344\272\247\347\224\237\344\270\216\350\247\243\345\206\263/README.md" "b/\346\223\215\344\275\234\347\263\273\347\273\237/2_\346\255\273\351\224\201\347\232\204\344\272\247\347\224\237\344\270\216\350\247\243\345\206\263/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a7c78f7c5e804bbaac9bca4c2ea72c067f97e655 --- /dev/null +++ "b/\346\223\215\344\275\234\347\263\273\347\273\237/2_\346\255\273\351\224\201\347\232\204\344\272\247\347\224\237\344\270\216\350\247\243\345\206\263/README.md" @@ -0,0 +1 @@ +# 死锁的产生与解决 \ No newline at end of file diff --git "a/\346\225\260\346\215\256\345\272\223/MyBatis\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230/README.md" "b/\346\225\260\346\215\256\345\272\223/MyBatis\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..c8358f1948820eaf1161ee52df88eed1b082c150 --- /dev/null +++ "b/\346\225\260\346\215\256\345\272\223/MyBatis\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230/README.md" @@ -0,0 +1,158 @@ +#### 1、#{}和${}的区别是什么? + +答:${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc.Driver。#{}是sql的参数占位符,Mybatis会将sql中的#{}替换为?号,在sql执行前会使用PreparedStatement的参数设置方法,按序给sql的?号占位符设置参数值,比如ps.setInt(0, parameterValue),#{item.name}的取值方式为使用反射从参数对象中获取item对象的name属性值,相当于param.getItem().getName()。 + + + +#### 2、Xml映射文件中,除了常见的select|insert|updae|delete标签之外,还有哪些标签? + +答:还有很多其他的标签,,加上动态sql的9个标签,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成策略标签。 + + + +#### 3、最佳实践中,通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗? + +答:Dao接口,就是人们常说的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement,举例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。在Mybatis中,每一个标签均会被解析为MappedStatement对象,标签内的sql会被解析为BoundSql对象。 + + + +#### 18、为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里? + +答:Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。 + +面试题看似都很简单,但是想要能正确回答上来,必定是研究过源码且深入的人,而不是仅会使用的人或者用的很熟的人,以上所有面试题及其答案所涉及的内容,在我的Mybatis系列博客中都有详细讲解和原理分析。 + +## 来源 + +https://my.oschina.net/zudajun/blog/747682 \ No newline at end of file diff --git "a/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/README.md" "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..7cefc56b44c5e16a7bbfe2b382337b6c4961df6f --- /dev/null +++ "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/README.md" @@ -0,0 +1,308 @@ +# MyBatis 缓存机制 + +## 来源 + +转载于 博客园 [吴振照](https://home.cnblogs.com/u/wuzhenzhao/) 的博客:https://www.cnblogs.com/wuzhenzhao/p/11103043.html + +## 前言 + +  缓存是一般的ORM 框架都会提供的功能,目的就是提升查询的效率和减少数据库的压力。跟Hibernate 一样,MyBatis 也有一级缓存和二级缓存,并且预留了集成第三方缓存的接口。 + +  缓存体系结构: + +img + +MyBatis 跟缓存相关的类都在cache 包里面,其中有一个Cache 接口,只有一个默认的实现类 PerpetualCache,它是用HashMap 实现的。我们可以通过 以下类找到这个缓存的庐山真面目 + +**DefaultSqlSession** + +  -> **BaseExecutor** + +    -> **PerpetualCache** localCache + +      ->**private Map cache = new HashMap();** + +  除此之外,还有很多的装饰器,通过这些装饰器可以额外实现很多的功能:回收策略、日志记录、定时刷新等等。但是无论怎么装饰,经过多少层装饰,最后使用的还是基本的实现类(默认PerpetualCache)。可以通过 CachingExecutor 类 Debug 去查看。 + +![img](images/1383365-20190628165835198-1731504252.png) + +  所有的缓存实现类总体上可分为三类:基本缓存、淘汰算法缓存、装饰器缓存。 + +![img](images/1383365-20190628172253737-1751427739.png) + +## 一级缓存(本地缓存) + +  一级缓存也叫本地缓存,MyBatis 的一级缓存是在会话(SqlSession)层面进行缓存的。MyBatis 的一级缓存是默认开启的,不需要任何的配置。首先我们必须去弄清楚一个问题,在MyBatis 执行的流程里面,涉及到这么多的对象,那么缓存PerpetualCache 应该放在哪个对象里面去维护?如果要在同一个会话里面共享一级缓存,这个对象肯定是在SqlSession 里面创建的,作为SqlSession 的一个属性。 + +  DefaultSqlSession 里面只有两个属性,Configuration 是全局的,所以缓存只可能放在Executor 里面维护——SimpleExecutor/ReuseExecutor/BatchExecutor 的父类BaseExecutor 的构造函数中持有了PerpetualCache。在同一个会话里面,多次执行相同的SQL 语句,会直接从内存取到缓存的结果,不会再发送SQL 到数据库。但是不同的会话里面,即使执行的SQL 一模一样(通过一个Mapper 的同一个方法的相同参数调用),也不能使用到一级缓存。 + +  每当我们使用MyBatis开启一次和数据库的会话,MyBatis会创建出一个SqlSession对象表示一次数据库会话。 + +  在对数据库的一次会话中,我们有可能会反复地执行完全相同的查询语句,如果不采取一些措施的话,每一次查询都会查询一次数据库,而我们在极短的时间内做了完全相同的查询,那么它们的结果极有可能完全相同,由于查询一次数据库的代价很大,这有可能造成很大的资源浪费。 + +  为了解决这一问题,减少资源的浪费,MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候,如果判断先前有个完全一样的查询,会直接从缓存中直接将结果取出,返回给用户,不需要再进行一次数据库查询了。 + +  如下图所示,MyBatis会在一次会话的表示----一个SqlSession对象中创建一个本地缓存(local cache),对于每一次查询,都会尝试根据查询的条件去本地缓存中查找是否在缓存中,如果在缓存中,就直接从缓存中取出,然后返回给用户;否则,从数据库读取数据,将查询结果存入缓存并返回给用户。 + +![img](images/1383365-20190628172851422-987384747.png) + +一级缓存的生命周期有多长? + +1. MyBatis在开启一个数据库会话时,会 创建一个新的SqlSession对象,SqlSession对象中会有一个新的Executor对象,Executor对象中持有一个新的PerpetualCache对象;当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。 +2. 如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用; +3. 如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据,但是该对象仍可使用; +4. SqlSession中执行了任何一个update操作(update()、delete()、insert()) ,都会清空PerpetualCache对象的数据,但是该对象可以继续使用; + +SqlSession 一级缓存的工作流程: + +1. 对于某个查询,根据statementId,params,rowBounds来构建一个key值,根据这个key值去缓存Cache中取出对应的key值存储的缓存结果 +2. 判断从Cache中根据特定的key值取的数据数据是否为空,即是否命中; +3. 如果命中,则直接将缓存结果返回; +4. 如果没命中: + +1. 1. 去数据库中查询数据,得到查询结果; + 2. 将key和查询到的结果分别作为key,value对存储到Cache中; + 3. 将查询结果返回; + +  接下来我们来验证一下,MyBatis 的一级缓存到底是不是只能在一个会话里面共享,以及跨会话(不同session)操作相同的数据会产生什么问题。判断是否命中缓存:如果再次发送SQL 到数据库执行,说明没有命中缓存;如果直接打印对象,说明是从内存缓存中取到了结果。 + +1、在同一个session 中共享(不同session 不能共享) + +``` +//同Session +SqlSession session1 = sqlSessionFactory.openSession(); +BlogMapper mapper1 = session1.getMapper(BlogMapper.class); +System.out.println(mapper1.selectBlogById(1002)); +System.out.println(mapper1.selectBlogById(1002)); +``` + +  执行以上sql我们可以看到控制台打印如下信息(需配置mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl),会发现我们两次的查询就发送了一次查询数据库的操作,这说明了缓存在发生作用: + +*![img](images/1383365-20190628173854959-1659491558.png)* + +  PS:一级缓存在BaseExecutor 的query()——queryFromDatabase()中存入。在queryFromDatabase()之前会get()。 + +``` +public List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { + ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId()); +    。。。。。。try { + ++this.queryStack;//从缓存中获取 + list = resultHandler == null ? (List)this.localCache.getObject(key) : null; + if (list != null) { + this.handleLocallyCachedOutputParameters(ms, key, parameter, boundSql); + } else {//缓存中获取不到,查询数据库 + list = this.queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql); + } +    。。。。。。 + } +``` + +2.同一个会话中,update(包括delete)会导致一级缓存被清空 + +``` +//同Session +SqlSession session1 = sqlSessionFactory.openSession(); +BlogMapper mapper1 = session1.getMapper(BlogMapper.class); +System.out.println(mapper1.selectBlogById(1002)); +Blog blog3 = new Blog(); +blog3.setBid(1002); +blog3.setName("mybatis缓存机制修改"); +mapper1.updateBlog(blog3); +session1.commit();// 注意要提交事务,否则不会清除缓存 +System.out.println(mapper1.selectBlogById(1002)); +``` + +  一级缓存是在BaseExecutor 中的update()方法中调用clearLocalCache()清空的(无条件),query 中会判断。 + +``` +public int update(MappedStatement ms, Object parameter) throws SQLException { + ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId()); + if (this.closed) { + throw new ExecutorException("Executor was closed."); + } else {       //清除本地缓存 + this.clearLocalCache(); + return this.doUpdate(ms, parameter); + } +} +``` + +3.其他会话更新了数据,导致读取到脏数据(一级缓存不能跨会话共享) + +``` +SqlSession session1 = sqlSessionFactory.openSession(); +BlogMapper mapper1 = session1.getMapper(BlogMapper.class); +SqlSession session2 = sqlSessionFactory.openSession(); +BlogMapper mapper2 = session2.getMapper(BlogMapper.class); +System.out.println(mapper2.selectBlogById(1002)); +Blog blog3 = new Blog(); +blog3.setBid(1002); +blog3.setName("mybatis缓存机制1"); +mapper1.updateBlog(blog3); +session1.commit(); +System.out.println(mapper2.selectBlogById(1002)); +``` + +一级缓存的不足: + +  使用一级缓存的时候,因为缓存不能跨会话共享,不同的会话之间对于相同的数据可能有不一样的缓存。在有多个会话或者分布式环境下,会存在脏数据的问题。如果要解决这个问题,就要用到二级缓存。MyBatis 一级缓存(MyBaits 称其为 Local Cache)无法关闭,但是有两种级别可选: + +1. session 级别的缓存,在同一个 sqlSession 内,对同样的查询将不再查询数据库,直接从缓存中。 +2. statement 级别的缓存,避坑: 为了避免这个问题,可以将一级缓存的级别设为 statement 级别的,这样每次查询结束都会清掉一级缓存。 + +## 二级缓存: + +  二级缓存是用来解决一级缓存不能跨会话共享的问题的,范围是namespace 级别的,可以被多个SqlSession 共享(只要是同一个接口里面的相同方法,都可以共享),生命周期和应用同步。如果你的MyBatis使用了二级缓存,并且你的Mapper和select语句也配置使用了二级缓存,那么在执行select查询的时候,MyBatis会先从二级缓存中取输入,其次才是一级缓存,即MyBatis查询数据的顺序是:二级缓存 —> 一级缓存 —> 数据库。 + +  作为一个作用范围更广的缓存,它肯定是在SqlSession 的外层,否则不可能被多个SqlSession 共享。而一级缓存是在SqlSession 内部的,所以第一个问题,肯定是工作在一级缓存之前,也就是只有取不到二级缓存的情况下才到一个会话中去取一级缓存。第二个问题,二级缓存放在哪个对象中维护呢? 要跨会话共享的话,SqlSession 本身和它里面的BaseExecutor 已经满足不了需求了,那我们应该在BaseExecutor 之外创建一个对象。 + +  实际上MyBatis 用了一个装饰器的类来维护,就是CachingExecutor。如果启用了二级缓存,MyBatis 在创建Executor 对象的时候会对Executor 进行装饰。CachingExecutor 对于查询请求,会判断二级缓存是否有缓存结果,如果有就直接返回,如果没有委派交给真正的查询器Executor 实现类,比如SimpleExecutor 来执行查询,再走到一级缓存的流程。最后会把结果缓存起来,并且返回给用户。 + +![img](images/1383365-20190628180149776-546074458.png) + +  开启二级缓存的方法 + +第一步:配置 mybatis.configuration.cache-enabled=true,只要没有显式地设置cacheEnabled=false,都会用CachingExecutor 装饰基本的执行器。 + +第二步:在Mapper.xml 中配置标签: + +``` + +``` + +基本上就是这样。这个简单语句的效果如下: + +- 映射语句文件中的所有 select 语句的结果将会被缓存。 +- 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。 +- 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。 +- 缓存不会定时进行刷新(也就是说,没有刷新间隔)。 +- 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。 +- 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。 + +这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。可用的清除策略有: + +- `LRU` – 最近最少使用:移除最长时间不被使用的对象。 +- `FIFO` – 先进先出:按对象进入缓存的顺序来移除它们。 +- `SOFT` – 软引用:基于垃圾回收器状态和软引用规则移除对象。 +- `WEAK` – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。 + +默认的清除策略是 LRU。 + +flushInterval(刷新间隔)属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。 + +size(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。 + +readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。 + +  注:二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。 + +  Mapper.xml 配置了之后,select()会被缓存。update()、delete()、insert()会刷新缓存。:如果cacheEnabled=true,Mapper.xml 没有配置标签,还有二级缓存吗?(没有)还会出现CachingExecutor 包装对象吗?(会) + +  只要cacheEnabled=true 基本执行器就会被装饰。有没有配置,决定了在启动的时候会不会创建这个mapper 的Cache 对象,只是最终会影响到CachingExecutorquery 方法里面的判断。如果某些查询方法对数据的实时性要求很高,不需要二级缓存,怎么办?我们可以在单个Statement ID 上显式关闭二级缓存(默认是true): + +``` + + + + +``` + +  鉴于这是默认行为,显然你永远不应该以这样的方式显式配置一条语句。但如果你想改变默认的行为,只需要设置 flushCache 和 useCache 属性。比如,某些情况下你可能希望特定 select 语句的结果排除于缓存之外,或希望一条 select 语句清空缓存。类似地,你可能希望某些 update 语句执行时不要刷新缓存。 \ No newline at end of file diff --git "a/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628164226493-430550273.png" "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628164226493-430550273.png" new file mode 100644 index 0000000000000000000000000000000000000000..a5a8a1a02df80b657a3f14ef9ef1b52328f0d59a Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628164226493-430550273.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628165835198-1731504252.png" "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628165835198-1731504252.png" new file mode 100644 index 0000000000000000000000000000000000000000..ef6a0ec69a94f3dc10eb8d82136749d357d2efaf Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628165835198-1731504252.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628172253737-1751427739.png" "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628172253737-1751427739.png" new file mode 100644 index 0000000000000000000000000000000000000000..38bb835f87b9aaec57a3426172cbb686c6523299 Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628172253737-1751427739.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628172851422-987384747.png" "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628172851422-987384747.png" new file mode 100644 index 0000000000000000000000000000000000000000..eb0d30a4382a56527913c9ba83fb1ed0a5db2982 Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628172851422-987384747.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628173854959-1659491558.png" "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628173854959-1659491558.png" new file mode 100644 index 0000000000000000000000000000000000000000..54f57de55caed1d8e785be6648bee32989c90645 Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628173854959-1659491558.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628180149776-546074458.png" "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628180149776-546074458.png" new file mode 100644 index 0000000000000000000000000000000000000000..22eac007f75ef170d4a6e46122dfe14774969725 Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MyBatis\347\232\204\347\274\223\345\255\230\346\234\272\345\210\266/images/1383365-20190628180149776-546074458.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/README.md" "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..33a0774a196c0820a0f717f9575a4dc0e08089b5 --- /dev/null +++ "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/README.md" @@ -0,0 +1,453 @@ +# MySQL索引 + +## 索引的优点 + +最典型的例子就是查新华字典,通过查找目录快速定位到查找的字 + +- 大大减少了服务器需要扫描的数量 +- 帮助服务器避免排序和临时表 +- 将IO变成顺序IO + - 尽可能的降低磁盘的寻址时间,也就是局部性原理,就是很大一部分数据在未来的一段时间被连续访问 + - 在复制1G压缩包 和 1G小文件,前者的速度会大于后者 + - 减少IO的量,例如写SQL语句的时候,不要写 select * + - 减少IO的次数,一次IO能搞定的事,不使用3次IO + +## 索引的用处 + +- 快速查找匹配where子句的行 +- 从consideration中消除行,如果可以在多个索引之间进行选择,mysql通常会使用栈找到最少行的索引 +- 如果表具有多列索引,则优化器可以使用索引的最左匹配前缀来查找 +- 当有表连接的时候,从其他表检测行数据 +- 查找特定索引列min或max值 +- 如果排序或分组是,在可用索引的最左前缀上完成的,则对表进行排序和分组 +- 在某些清空下,可以优化查询以检索值而无需查询数据行 + +## 索引的分类 + +### 主键索引 + +如果你在创建索引的时候,使用的是主键这个值,那么就是主键索引,primary key + +我们建表的时候,例如下面这个建表语句 + +``` sql +CREATE TABLE `t_blog_sort` ( + `uid` varchar(32) NOT NULL COMMENT '唯一uid', + `sort_name` varchar(255) DEFAULT NULL COMMENT '分类内容', + `content` varchar(255) DEFAULT NULL COMMENT '分类简介', + `create_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间', + `update_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '更新时间', + `status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态', + `sort` int(11) DEFAULT '0' COMMENT '排序字段,越大越靠前', + `click_count` int(11) DEFAULT '0' COMMENT '点击数', + PRIMARY KEY (`uid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='博客分类表'; +``` + +这里面有使用到 PRIMARY KEY (`uid`),这就是主键索引 + +### 唯一索引 + +唯一索引 类似于普通索引,索引列的值必须唯一 + +唯一索引和主键索引的区别就是,唯一索引允许出现空值,而主键索引不能为空 + +```sql +create unique index index_name on table(column) +``` + +或者创建表时指定 + +```sql +unique index_name column +``` + +### 普通索引 + +当我们需要建立索引的字段,既不是主键索引,也不是唯一索引 + +那么就可以创建一个普通索引 + +```sql +create index index_name on table(column) +``` + +或者创建表时指定 + +``` sql +create table(..., index index_name column) +``` + +### 全文索引 + +lunce、solr和ElasticSearch就是做全文检索的,里面涉及到了倒排索引的概念,mysql很少使用全文索引。 + +要用来查找文本中的关键字,不是直接与索引中的值相比较,像是一个搜索引擎,配合 match against 使用,现在只有char,varchar,text上可以创建索引,在数据量比较大时,先将数据放在一个没有全文索引的表里,然后在利用create index创建全文索引,比先生成全文索引在插入数据快很多。 + +### 组合索引 + +目前,在业务不是特别复杂的时候,可能使用一个列作为索引,或者直接采用主键索引即可,但是如果业务变得复杂的时候,就需要用到组合索引,通过对多个列建立索引。 + +组合索引的用处,假设我现在表有个多个字段:id、name、age、gender,然后我经常使用以下的查询条件 + +```sql +select * from user where name = 'xx' and age = xx +``` + +这个时候,我们就可以通过组合 name 和 age 来建立一个组合索引,加快查询效率,建立成组合索引后,我的索引将包含两个key值 + +在多个字段上创建索引,遵循**最左匹配**原则 + +```sql +alter table t add index index_name(a,b,c); +``` + +## 索引的使用与否 + +### 索引的使用 + +MySQL每次只使用一个索引,与其说 数据库查询只能用一个索引,倒不如说,和全表扫描比起来,去分析两个索引 B+树更耗费时间,所以where A=a and B=b 这种查询使用(A,B)的组合索引最佳,B+树根据(A,B)来排序。 + +- 主键,unique字段 +- 和其他表做连接的字段需要加索引 +- 在where 里使用 >, >=, = , <, <=, is null 和 between等字段。 +- 使用不以通配符开始的like,where A like ‘China%’ +- 聚合函数里面的 MIN(), MAX()的字段 +- order by 和 group by字段 + +### 何时不使用索引 + +- 表记录太少 +- 数据重复且分布平均的字段(只有很少数据的列); +- 经常插入、删除、修改的表要减少索引 +- text,image 等类型不应该建立索引,这些列的数据量大(加入text的前10个字符唯一,也可以对text前10个字符建立索引) +- MySQL能估计出全表扫描比使用索引更快的时候,不使用索引 + +### 索引何时失效 + +- 组合索引为使用最左前缀,例如组合索引(A,B),where B = b 不会使用索引 +- like未使用最左前缀,where A like "%China" +- 搜索一个索引而在另一个索引上做 order by, where A = a order by B,只会使用A上的索引,因为查询只使用一个索引。 +- or会使索引失效。如果查询字段相同,也可以使用索引。例如 where A = a1 or A = a2(生效),where A=a or B = b (失效) +- 在索引列上的操作,函数upper()等,or、! = (<>),not in 等 + +## 面试技术名词 + +### 回表 + +首先我们需要知道,我们建立几个索引,就会生成几棵B+Tree,但是带有原始数据行的B+Tree只有一棵,另外一棵树上的叶子节点带的是主键值。 + +例如,我们通过主键建立了主键索引,然后在叶子节点上存放的是我们的数据 + +![image-20200629094621998](images/image-20200629094621998.png) + +当我们创建了两个索引时,一个是主键,一个是name,它还会在生成一棵B+Tree,这棵树的叶子节点存放的是主键,当我们通过name进行查找的时候,会得到一个主键,然后在通过主键再去上面的这个主键B+Tree中进行查找,我们称这个操作为 ==**回表**== + +![image-20200629094800800](images/image-20200629094800800.png) + +当我们的SQL语句使用的是下面这种的时候,它会查找第一颗树,直接返回我们的数据 + +```mysql +select * from tb where id = 1 +``` + +当我们使用下面这种查询的时候,它会先查找第二棵树得到我们的主键,然后拿着主键再去查询第一棵树 + +```mysql +select * from tb where name = 'gang' +``` + +回表就是通过普通列的索引进行检索,然后再去主键列进行检索,这个操作就是回表 + +==但是我们在使用检索的时候,尽量避免回表,因为这会造成两次B+Tree的查询,假设一次B+Tree查询需要三次IO操作,那么查询两次B+Tree就需要六次IO操作。== + +### 索引覆盖 + +我们看下面的两个SQL语句,看看它们的查询过程是一样的么? + +```SQL +select * from tb where id = 1 +select name from tb where name = zhou +``` + +答案是不一样的,首先我们看第二个语句,就是要输出的列中,就是我们的主键,当我们通过name建立的B+Tree进行查询的时候 + +![image-20200629094800800](images/image-20200629094800800.png) + +我们可以直接找到我们的数据,并得到主键,但是因为我们要返回的就是name,此时说明数据存在了,那么就直接把当前的name进行返回,而不需要通过主键再去主键B+Tree中进行查询。 + +这样一个不需要进行回表操作的过程,我们称为**索引覆盖** + +### 最左匹配 + +这里提到的 **最左匹配** 和 **索引下推** 都是针对于组合索引的。 + +例如,我们有这样一个索引 + +``` +name age:组合索引 +``` + +必须要先匹配name,才能匹配到age。这个我们就被称为最左匹配 + +例如下面的几条SQL语句,那些语句不会使用组合索引 + +```sql +where name = ? and age = ? +where name = ? +where age = ? +where age = ? and name = ? +``` + +根据最左匹配原则,我们的 3 不会使用组合索引的。 + +那为什么4的顺序不一样,也会使用组合索引呢? + +其实内部的优化器会进行调整,例如下面的一个连表操作 + +```sql +select * from tb1 join tb2 on tb1.id = tb2.id +``` + +其实在加载表的时候,并不一定是先加载tb1,在加载tb2,而是可能根据表的大小决定的,小的表优先加载进内存中。 + +### 索引下推 + +在说索引下推的时候,我们首先在举两个例子 + +```sql +select * from tb1 where name = ? and age = ? +``` + +在mysq 5.6之前,会先根据name去存储引擎中拿到所有的数据,然后在server层对age进行数据过滤 + +在mysql5.6之后,根据name 和 age两个列的值去获取数据,直到把数据返回。 + +通过对比能够发现,第一个的效率低,第二个的效率高,因为整体的IO量少了,原来是把数据查询出来,在server层进行筛选,而现在在存储引擎层面进行筛选,然后返回结果。我们把这个过程就称为 **索引下推** + +### 优化器 + +#### CBO + +基于成本的优化 + +#### RBO + +基于规则的优化 + +![image-20200629110258878](images/image-20200629110258878.png) + + + +## 索引匹配方式 + +### 全值匹配 + +全值匹配指的是和索引中所有的列进行匹配 + +```sql +explain select * from staffs where name = 'July' and age = 23 and pos = 'dev' +``` + +而我们建立了一个 包含 name、age、pos的组合索引,使用上面的SQL语句,就会进行全值匹配 + +### 匹配最左前缀 + +只匹配前面的几列 + +```sql +explain select * from staffs where name = 'July' and age = 23 +``` + +这个时候,只使匹配了前面两个列,而没有使用第三个列 + +现在我们使用下面的SQL语句进行验证,但我们输出值只包含ID的时候 + +```sql +explain select id from staffs where id = 1 +``` + +我们查看其任务计划,在某尾有 Extra字段,如果是Using index 表示是使用了覆盖索引 + +![image-20200629144438346](images/image-20200629144438346.png) + +然后我们在查看下面这条SQL语句 + +```sql +explain select * from staffs where id = 1 +``` + +通过查看任务计划,发现extra字段是NULL,说明没有使用覆盖索引 + +![image-20200629145948288](images/image-20200629145948288.png) + +### 匹配列前缀 + +可以匹配某一列值的开头部分 + +```sql +explain select * from staffs where name = 'J%' +explain select * from staffs where name = '%y' +``` + +### 匹配范围值 + +可以查找某个范围的数据 + +```sql +explain select * from staffs where name > 'Mary' +``` + +### 精确匹配某一列并范围匹配另外一列 + +可以查询某一列的全部和第二列的部分 + +```sql +explain select * from staffs where name = "July" and age > 25 +``` + +### 只访问索引的查询 + +查询的时候值需要访问索引,不需要访问数据行,本质上就是索引覆盖 + +```sql +explain select name,age,pos from staffs where name="July" and age=25 and pos = "dev" +``` + +## 哈希索引 + +### 概念 + +基于哈希的实现,只有精确匹配索引所有的列的查询才有效,在mysql中,只有memory的存储引擎显式支持哈希索引,哈希索引自身只需存储对应的hash值,索引索引的结构十分紧凑,这让哈希索引查找的速度非常快。 + +### 哈希索引的限制 + +- 哈希索引值包含哈希值和行指针,而不存储字段值。索引不能使用索引中的值来避免读取行 +- 哈希索引数据并不是按照索引值顺序存储的,所以无法进行排序 +- 哈希索引不支持部分列匹配查找,哈希索引是使用索引列的全部内容来计算哈希值 +- 哈希索引支持等值比较查询,也不支持任何范围查询 +- 访问哈希索引的数据非常快,除非有很多哈希冲突,当出现哈希冲突的时候,存储引擎必须遍历链表中的所有行指针,逐行进行比较,知道找到所有符合条件的行 +- 哈希冲突比较多的话,维护的代价也会很高 + +## 聚簇索引和非聚簇索引 + +### 聚簇索引 + +InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,聚簇索引就是按每张表的主键构造一棵B+树,同时叶子节点中存放的就是整张表的行记录数据,也将聚簇索引的叶子节点称为数据也,这个特性就决定了索引组织表中的数据也是索引的一部分。 + +==一句话来说:将索引和数据放在一起的,就称为聚簇索引== + +我们日常的工作中,根据实际情况自行添加的索引,都是辅助索引或者称为普通索引,辅助索引就是为了查找主键索引的二级索引,先找到主键索引然后再通过主键索引找数据,但是可能会存在**回表**的问题。 + +### 聚簇索引的优点 + +- 数据访问更快,因为聚簇索引将索引和数据保存在一个B+树中,因此从聚簇索引中获取数据比非聚簇索引更快 +- 聚簇索引对主键的排序和范围查找速度非常快 + +### 聚簇索引的缺点 + +- 插入速度严重依赖于排序,按照主键的顺序插入是最快的方式,否者会出现页分裂,严重影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列作为主键 +- 更新主键的代价很高,因为将会导致被更新的行移动,因此,对于InnoDB表,我们一般定义主键不可更新 +- 二级索引访问需要两次索引查找,第一次找到主键值,第二次 根据主键值查找行数据,一般我们需要尽量避免出现索引的二次查找,这个时候,用到的就是**索引的覆盖** + +### 非聚簇索引 + +非聚簇索引也被称为辅助索引,辅助索引在我们访问数据的时候总是需要两次查找。辅助索引叶子节点存储的不再是行的物理位置,而是主键值。通过辅助索引首先找到主键值,然后在通过主键值找到数据行的数据页,在通过数据页中的Page Directory找到数据行。 + +InnoDB辅助索引的叶子节点并不包含行记录的全部数据,叶子节点除了包含键值外,还包含了行数据的聚簇索引建。辅助索引的存在不影响数据在聚簇索引中的组织,所以一张表可以有多个辅助索引。在InnoDB中有时也称为辅助索引为二级索引 + +![image-20200629113413737](images/image-20200629113413737.png) + +## 组合索引 + +当包含多个列为索引,需要注意的是正确的顺序依赖于该索引的查询,同时需要考虑如何更好的满足排序和分组的需要 + + + +![image-20200629160704401](images/image-20200629160704401.png) + +第4个不走索引,是因为不满足最左匹配原则 + +第5个,因为跨过了b,所以只走a的索引 + +## 优化细节 + +- 当使用索引列进行查询的时候,尽量不要使用表达式,把计算放到业务层而不是数据库层 + + ```sql + select actor_id from actor where actor_id = 4 + select actor_id from actor where actor_id+1 = 5 + ``` + + 第一条语句走索引 + + ![image-20200629161629049](images/image-20200629161629049.png) + + 而第二条语句没有走主键索引 + + ![image-20200629161641522](images/image-20200629161641522.png) + +- 尽量使用主键查询,而不是其它索引,因为主键查询不会触发回表操作 + +- 使用前缀索引 + +有时候需要索引很长的字符串,这会让索引变得大且满,通常情况下可以使用某个列开始的部分字符串,这样大大的节约了索引空间,从而提高索引效率,但这会降低索引的选择性,索引的选择性是指不重复的索引值和数据表记录总数的比值,范围从1/#T 到 1 之间,索引的选择性越高,则查询效率越高,因为选择性更高的索引可以让mysql在查找的时候过滤掉更多的行。 + +一般情况下,某个列前缀的选择性也是足够高的,足以满足查询的性能,但是对应BLOG,TEXT,VARCHAR类型的列,必须要使用前缀索引,因为mysql不允许索引这些列的完整长度,使用该方法的诀窍在于选择足够长的前缀以保证较高的选择性,通过又不能太长 。 + +- 使用索引扫描来进行排序 +- union、all、in、or都能使用索引,但是推荐使用in + +```sql +explain select * from actor where actor_id = 1 union all select * from actor where actor_id = 2 + +explain select * from actor where actor_id in (1,2); + +explain select * from actor where actor_id = 1 or actor_id = 2; + +-- 关于or到底走不走索引,必须根据实际情况进行考虑 +``` + +- 范围列可以使用到索引 + +例如 范围条件是:<、<=、>、>=、between + +范围列可以用到索引,但是范围列后面的列无法用到索引,索引最多用于一个范围列,所以一般如果我们使用组合索引的时候,最好不要使用范围查找 + +![image-20200629160704401](images/image-20200629160704401.png) + +如倒数第一个所示,因为中间b使用了范围查找,所以后面的c是无法使用索引的,只能是a和b才能使用索引 + +- 强制类型转换会让索引失效,进行全表查询 + +例如下面这样一个例子所示,我们对 phone字段进行了强制类型转换 + +```sql +explain select * from user where phone = 13800001234 -- 不会触发索引(触发了字符串到整型转换) +explain select * from user where phone = '13800001234' -- 触发索引 +``` + +- 更新十分频繁,数据区分度不高的字段上不宜建立索引 + +更新会变更B+树,更新 频繁的字段建立索引会大大降低数据库性能 + +类似于性别这列的区分度不高的字段,建立索引是没有意义的,不能有效的过滤数据 + +一般区分度在百分80以上的时候,就可以建立索引,区分度可以使用 count(distinct(列名)) / count(*) 来进行计算 + +- 创建索引的列,不允许为null,可能会得到不符合预期的结果 +- 当需要进行表连接的时候,最好不要超过三张表,因为需要join的字段,数据类型必须一致(阿里规约) + - 允许数据的冗余,从而加快查询的效率 + - 目前是范式和反范式的混合使用 +- 能使用limit的时候,尽量使用limit +- 单表索引建议控制在5个以内 +- 单索引字段不允许超过5个(组合索引) +- 创建索引的时候应该尽量避免以下错误的概念 + +索引不是越多越好,不要在不了解系统的情况下进行优化 + +## 参考 + +https://www.cnblogs.com/jiawen010/p/11805241.html + +https://www.bilibili.com/video/BV1d5411p7MY?from=search&seid=6712050221639355647 \ No newline at end of file diff --git "a/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629094621998.png" "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629094621998.png" new file mode 100644 index 0000000000000000000000000000000000000000..4860b6fae73b35aa8c933347309cdecd05658f35 Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629094621998.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629094800800.png" "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629094800800.png" new file mode 100644 index 0000000000000000000000000000000000000000..076401148187d2ccf2d83176cb4a9c4d9eb729d5 Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629094800800.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629110258878.png" "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629110258878.png" new file mode 100644 index 0000000000000000000000000000000000000000..f1051089267e33baefde2ac9613ad98758ac5369 Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629110258878.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629113413737.png" "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629113413737.png" new file mode 100644 index 0000000000000000000000000000000000000000..ebecf1a5b78323af232e1ef807b3faf04183883f Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629113413737.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629144438346.png" "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629144438346.png" new file mode 100644 index 0000000000000000000000000000000000000000..f63d1579cf9527654ca00a06b3f3a236b74e65f7 Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629144438346.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629145948288.png" "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629145948288.png" new file mode 100644 index 0000000000000000000000000000000000000000..2178c93dc519a05e4cca8ab5510d26c91814949a Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629145948288.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629160704401.png" "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629160704401.png" new file mode 100644 index 0000000000000000000000000000000000000000..2d87e831009dc36610e773add202cdc73165e358 Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629160704401.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629161629049.png" "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629161629049.png" new file mode 100644 index 0000000000000000000000000000000000000000..7fb8e53e743179de1704c2b282d7ae04c4de0b85 Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629161629049.png" differ diff --git "a/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629161641522.png" "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629161641522.png" new file mode 100644 index 0000000000000000000000000000000000000000..c022b4aabccc11aa5e8602f0307c40f4948079a9 Binary files /dev/null and "b/\346\225\260\346\215\256\345\272\223/MySQL\347\264\242\345\274\225/images/image-20200629161641522.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/10_\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/10_\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..e3066ca5592c6c76a626fa29b67ea354a5a2c706 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/10_\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227/README.md" @@ -0,0 +1,41 @@ +# 栈的压入弹出序列 + +## 题目描述 + +输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的) + +## 思路 + +我们以:1 2 3 4 5 进行压入,下面的:2 4 5 3 1 是弹出序列 + +![image-20200424111056735](images/image-20200424111056735.png) + +- 首先我们需要有一个栈,列表 +- 按照pushV的方式压入栈 +- 弹出的时候,需要循环判断是否需要弹出 +- 判断是否需要弹出的时机,刚刚压入过后就弹 +- 判断需要弹出的情况的条件,压入栈的顶部 和 弹出栈的顶部数据相等 +- 然后我们还需要循环比较 + + + +``` +class Solution: + + def IsPopOrder(self, pushV, popV): + # 首先我们需要有一个栈 + if pushV == [] or len(pushV) != len(popV): + return None + stack = [] + index = 0 + for item in pushV: + # 压栈 + stack.append(item) + # 判断是否需要弹出,也就是插入的值,等于popV的第一个。这里需要循环判断 + while stack != [] and stack[-1] == popV[index]: + stack.pop() + index += 1 + # 判断 stack 中是否有元素,如果有,代表着False + return len(stack) == 0 +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/10_\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227/images/image-20200424111056735.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/10_\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227/images/image-20200424111056735.png" new file mode 100644 index 0000000000000000000000000000000000000000..63489f3d0d17cbe9ce3ae03ef4c020e9c8158ab8 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/10_\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227/images/image-20200424111056735.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/11_\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/11_\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..1dc6c04be938a0036606245667d4c9b93cdf5153 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/11_\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250/README.md" @@ -0,0 +1,85 @@ +# 从尾到头打印链表 + +## 题目描述 + +来源:https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035 + +输入一个链表,按链表从尾到头的顺序返回一个ArrayList。 + +## 思考 + +在python中定义链表 + +``` +# 链表结构 +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +# 打印链表 +def printChain(head): + node = head + while node: + print(node.val) + node = node.next + +if __name__ == '__main__': + # 创建链表 + l1 = ListNode(1) + l2 = ListNode(2) + l3 = ListNode(3) + l1.next = l2 + l2.next = l3 + printChain(l1) + +``` + +下面我们看题目是需要倒序输出,那么我们使用一个数组记录,每次插入到数组的前面 + +``` +while node: + print(node.val) + list.insert(0, node.val) + node = node.next +``` + +完整代码如下 + +``` +# 从头到尾打印链表 +# 输入一个链表,按链表从尾到头的顺序返回一个ArrayList。 + +# 链表结构 +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +# 打印链表 +def printChain(head): + node = head + while node: + print(node.val) + node = node.next + +class Solution: + # 返回从尾部到头部的列表值序列,例如[1,2,3] + def printListFromTailToHead(self, listNode): + node = listNode + list = [] + while node: + print(node.val) + list.insert(0, node.val) + node = node.next + return list +if __name__ == '__main__': + # 创建链表 + l1 = ListNode(1) + l2 = ListNode(2) + l3 = ListNode(3) + l1.next = l2 + l2.next = l3 + Solution().printListFromTailToHead(l1) +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/12_\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\254\254K\344\270\252\350\212\202\347\202\271/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/12_\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\254\254K\344\270\252\350\212\202\347\202\271/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ea2853a549abe51912b76d26b7c5e9bfaa4e4939 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/12_\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\254\254K\344\270\252\350\212\202\347\202\271/README.md" @@ -0,0 +1,107 @@ +# 链表中倒数第K个节点 + +## 描述 + +来源: + +输入一个链表,输出该链表中倒数第k个结点。 + +## 思路 + +其实这个解法和我们的上一题类似,就是使用一个数组来存储每个节点,最后我们输出第 len(list) - K 个节点即可 + +``` + while node: + list.append(node) + node = node.next + + # K比链表长度大 + if k > len(list): + return None + + return list[len(list) - k] +``` + +完整代码 + +``` +# 链表中倒数第K个节点 +# 输入一个链表,输出该链表中倒数第k个结点。 + +# 链表结构 +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +# 打印链表 +def printChain(head): + node = head + while node: + print(node.val) + node = node.next + +class Solution: + def FindKthToTail(self, head, k): + if k <= 0 or head == []: + return None + + node = head + list = [] + while node: + list.append(node) + node = node.next + + # K比链表长度大 + if k > len(list): + return None + + return list[len(list) - k] + +if __name__ == '__main__': + # 创建链表 + l1 = ListNode(1) + l2 = ListNode(2) + l3 = ListNode(3) + l4 = ListNode(4) + l5 = ListNode(5) + + l1.next = l2 + l2.next = l3 + l3.next = l4 + l4.next = l5 + + print(Solution().FindKthToTail(l1, 1)) +``` + +## 思路2 + +第二种方式就是我们需要使用两个指针,第一个指针先走K步,然后两个指针在同时行走,最后当第一个指针到达终点的时候,第二个指针就是倒数第K个值。 + +![image-20200425103015322](images/image-20200425103015322.png) + +完整代码 + +``` +class Solution: + + def FindKthToTail(self, head, k): + if k <= 0 or head == []: + return None + list = [] + first = head + second = head + # 先让第一个节点走 K步 + for i in range(0, k): + # 判断第一个是否走完 + if first == None: + return None + first = first.next + + # 然后两个节点在继续走,当first走到头的时候,second就是倒数第K个节点 + while first: + first = first.next + second = second.next + return second +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/12_\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\254\254K\344\270\252\350\212\202\347\202\271/images/image-20200425103015322.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/12_\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\254\254K\344\270\252\350\212\202\347\202\271/images/image-20200425103015322.png" new file mode 100644 index 0000000000000000000000000000000000000000..88f81611afa15174c30afe76a651fadf436580c5 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/12_\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\254\254K\344\270\252\350\212\202\347\202\271/images/image-20200425103015322.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/13_\345\217\215\350\275\254\351\223\276\350\241\250/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/13_\345\217\215\350\275\254\351\223\276\350\241\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a804c8850260d3ed7a5ddd3a9ff81ca384bd9e4e --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/13_\345\217\215\350\275\254\351\223\276\350\241\250/README.md" @@ -0,0 +1,87 @@ +# 反转链表 + +## 题目描述 + +来源:https://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca + +输入一个链表,反转链表后,输出新链表的表头。 + +## 思考 + +这个时候,我们就不能使用上一题的做法了 + +![image-20200425104541126](images/image-20200425104541126.png) + +反转后 + +![image-20200425104523244](images/image-20200425104523244.png) + + + +步骤: + +- 将现有的头换成尾,尾部的next换成None +- 将从第二个指针node开始,循环将next指向前一个 +- 需要一直有一个指针指向还没有反转的链表的头部 + +我们需要有三个指针,一个是左指针,中指针,右指针 + +``` +# 反转链表 +# 输入一个链表,反转链表后,输出新链表的表头。 + +# 链表结构 +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +# 打印链表 +def printChain(head): + node = head + while node: + print(node.val) + node = node.next + +class Solution: + def ReverseList(self, pHead): + if pHead == None: + return None + if pHead.next == None: + return pHead + + leftPointer = pHead + middlePointer = pHead.next + rightPointer = pHead.next.next + leftPointer.next = None + + while rightPointer != None: + middlePointer.next = leftPointer + leftPointer = middlePointer + middlePointer = rightPointer + rightPointer = rightPointer.next + + middlePointer.next = leftPointer + + return middlePointer + +if __name__ == '__main__': + # 创建链表 + l1 = ListNode(1) + l2 = ListNode(2) + l3 = ListNode(3) + l4 = ListNode(4) + l5 = ListNode(5) + + l1.next = l2 + l2.next = l3 + l3.next = l4 + l4.next = l5 + + print(Solution().ReverseList(l1)) +``` + + + + + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/13_\345\217\215\350\275\254\351\223\276\350\241\250/images/image-20200425104523244.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/13_\345\217\215\350\275\254\351\223\276\350\241\250/images/image-20200425104523244.png" new file mode 100644 index 0000000000000000000000000000000000000000..733775b778856a5fdc966ccf7e25deb539c72880 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/13_\345\217\215\350\275\254\351\223\276\350\241\250/images/image-20200425104523244.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/13_\345\217\215\350\275\254\351\223\276\350\241\250/images/image-20200425104541126.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/13_\345\217\215\350\275\254\351\223\276\350\241\250/images/image-20200425104541126.png" new file mode 100644 index 0000000000000000000000000000000000000000..9cbea12aa419a22f510499320797b405eabfcbe7 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/13_\345\217\215\350\275\254\351\223\276\350\241\250/images/image-20200425104541126.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/14_\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/14_\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..aabbcad71a7825f27a314e665ad3339c3ec02b7d --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/14_\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250/README.md" @@ -0,0 +1,66 @@ +# 合并两个排序的链表 + +## 描述 + +来源:https://www.nowcoder.com/practice/d8b6b4358f774294a89de2a6ac4d9337 + +输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。 + +## 思考 + +先有两个单调递增的链表 + +![image-20200425211851737](images/image-20200425211851737.png) + +合并后 + +![image-20200425211958540](images/image-20200425211958540.png) + +从上图发现,我们一共需要4个指针,第一个是头指针,第二个和第三个分别是控制两个链表的移动的指针,第四个指针是最小值的指针(前面的指针)。 + +## 代码 + +``` + +class Solution: + # 返回合并后列表 + def Merge(self, pHead1, pHead2): + + if pHead1 == None: + return pHead2 + if pHead2 == None: + return pHead1 + + # 得到最小的一个头结点 + newHead = pHead1 if pHead1.val < pHead2.val else pHead2 + # 链表1上的指针 和 链表2上的指针 + pTmp1 = pHead1 + pTmp2 = pHead2 + if newHead == pTmp1: + pTmp1 = pTmp1.next + if newHead == pTmp2: + pTmp2 = pTmp2.next + + # 前面的指针 + previousPointer = newHead + + # 链表1 和 链表2 都不为空的时候,开始合并 + while pTmp1 and pTmp2: + # 找出最小值,放在previousPointer指针后面 + if pTmp1.val < pTmp2.val: + previousPointer.next = pTmp1 + previousPointer = pTmp1 + pTmp1 = pTmp1.next + else: + previousPointer.next = pTmp2 + previousPointer = pTmp2 + pTmp2 = pTmp2.next + + if pTmp1 == None: + previousPointer.next = pTmp2 + if pTmp2 == None: + previousPointer.next = pTmp1 + + return newHead +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/14_\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250/images/image-20200425211851737.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/14_\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250/images/image-20200425211851737.png" new file mode 100644 index 0000000000000000000000000000000000000000..f504366345ba2842a0023d568ce42c031d83469b Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/14_\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250/images/image-20200425211851737.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/14_\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250/images/image-20200425211958540.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/14_\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250/images/image-20200425211958540.png" new file mode 100644 index 0000000000000000000000000000000000000000..25653dcc3b93bcc5f47fdc27b43b600284d10360 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/14_\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\347\232\204\351\223\276\350\241\250/images/image-20200425211958540.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..9689b76b1cc840080159f34be23bc9065a120a65 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/README.md" @@ -0,0 +1,104 @@ +# 复杂链表的复制 + +## 描述 + +来源:https://www.nowcoder.com/practice/f836b2c43afc4b35ad6adc41ec941dba + +输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空) + +## 思考 + +下图是复杂链表的数据结构 + +```python +# 链表结构 +class RandomListNode: + def __init__(self, x): + self.label = x + self.next = None + self.random = None +``` + + + +![image-20200425214035668](images/image-20200425214035668.png) + +最简单的思路是,使用python提供的深拷贝实现 + +```python +import copy +class Solution: + # 返回 RandomListNode + def Clone(self, pHead): + # write code here + return copy.deepcopy(pHead) +``` + +## 方法2 + +关于Random指针,因为我们不知道它是指向,因此我们每次都需要从头到尾进行遍历 + +我们要做的就是把上面的节点复制一份出来 + +![image-20200425215533799](images/image-20200425215533799.png) + +这样得到了: 11,22,33,44 的链表,就相当于在每个数的后面,同时又复制了一份,最后执行一下的方法 + +> A.next.random = a.random.next + +最后我们得到了两个链表 + +![image-20200425233303213](images/image-20200425233303213.png) + + + +完整图 + +![image-20200426105420274](images/image-20200426105420274.png) + +完整代码 + +```python +# 复杂链表的复制 +# 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点), +# 请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空) + +# 链表结构 +class Solution: + # 返回合并后列表 + def Clone(self, pHead): + if pHead == None: + return None + pTmp = pHead + # 复制一个一样的node,并且添加到之前的链表的每一个node后面 + while pTmp: + # 创建一个和原来一样的node + node = RandomListNode(pTmp.laebl) + node.next = pTmp.next + # 将原来的指向刚刚创建的节点 + pTmp.next = node + # 同时移动被复制的节点 + pTmp = node.next + + # 实现新建node的random的指向 + pTmp = pHead + while pHead: + # 将复制节点的random,指向 它Random的next + if pTmp.random: + pTmp.next.random = pTmp.random.next + pTmp = pTmp.next.next + + # 断开原来的node 和 新 node 之间的连接 + pTmp = pHead + newHead = pHead.next + pNewTmp = pHead.next + while pTmp: + pTmp.next = pTmp.next.next + if pNewTmp.next: + pNewTmp.next = pNewTmp.next.next + pNewTmp = pNewTmp.next + pTmp = pTmp.next + return newHead + +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/images/image-20200425214035668.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/images/image-20200425214035668.png" new file mode 100644 index 0000000000000000000000000000000000000000..4ab9d11dca0560b0ae99ae1f529a73ad184fa4fd Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/images/image-20200425214035668.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/images/image-20200425215533799.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/images/image-20200425215533799.png" new file mode 100644 index 0000000000000000000000000000000000000000..a9b139fc98f3376b75d39aa9e5d4afff8bc2e77c Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/images/image-20200425215533799.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/images/image-20200425233303213.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/images/image-20200425233303213.png" new file mode 100644 index 0000000000000000000000000000000000000000..4ea3347d92c33bf150a14b7f0c132b556e285963 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/images/image-20200425233303213.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/images/image-20200426105420274.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/images/image-20200426105420274.png" new file mode 100644 index 0000000000000000000000000000000000000000..5f6da499c976f4a9c3500bdf7559c1161d93e627 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/15_\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266/images/image-20200426105420274.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/16_\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\345\205\254\345\205\261\347\273\223\347\202\271/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/16_\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\345\205\254\345\205\261\347\273\223\347\202\271/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a0bec4f932a0bdb0378ec3c23a67f0391b6e8e5f --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/16_\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\345\205\254\345\205\261\347\273\223\347\202\271/README.md" @@ -0,0 +1,82 @@ +# 两个链表的公共结点 + +## 描述 + +来源:https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46 + +输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的) + +## 思考 + +也就是说两个链表具有公共的部分 + +![image-20200426084449089](images/image-20200426084449089.png) + +第一种方式就是遍历两个链表,找出公共的节点,并且时间复杂度为: `O(n^2)` + +第二种方式,只需要花费 `O(n)`的时间复杂度 + +首先我们需要准备两个指针,第一个指针指向第一个的头部,另一个指向第二个链表的头部,然后我们同时移动这两个指针,当有一个指针到头的时候,另一个指针还没有到头,我们记录到这个差值N + +然后在再次这样指向,但是首先需要保证那个长的链表先执行 N步,然后这两个节点再一次走,直到两个节点相交的时候,就得到了第一个公共节点。 + +## 代码 + +``` +class Solution: + + # 第一个参数给比较短的链表,第二个参数给长链表的值 + # def findEqual(self,): + + def FindFirstCommonNode(self, pHead1, pHead2): + + # 假设输入的两个链表,是同一个链表 + if pHead1 == pHead2: + return pHead1 + + pTmp1 = pHead1 + pTmp2 = pHead2 + + # 我们通过循环,让其中一个节点走到最后 + while pTmp1 and pTmp2: + pTmp1 = pTmp1.next + pTmp2 = pTmp2.next + + # 判断哪个链表先走到最后 + # 假设pTmp1,还没有走完,说明pTmp2是更短的 + if pTmp1: + k = 0 + # 寻找链表长度之间的差值 + while pTmp1: + pTmp1 = pTmp1.next + k += 1 + # 我们让pTmp1先跳N步 + pTmp2 = pHead2 + pTmp1 = pHead1 + for i in range(k): + pTmp1 = pTmp1.next + + # 当找到节点相等的时候,也就是说明该节点是公共节点 + while pTmp1 != pTmp2: + pTmp1 = pTmp1.next + pTmp2 = pTmp2.next + return pTmp1 + + # 假设pTmp2,还没有走完,说明pTmp1是更短的 + if pTmp2: + k = 0 + while pTmp2: + pTmp2 = pTmp2.next + k += 1 + # 我们让pTmp2先跳N步 + pTmp2 = pHead2 + pTmp1 = pHead1 + for i in range(k): + pTmp2 = pTmp2.next + + while pTmp1 != pTmp2: + pTmp1 = pTmp1.next + pTmp2 = pTmp2.next + return pTmp1 +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/16_\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\345\205\254\345\205\261\347\273\223\347\202\271/images/image-20200426084449089.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/16_\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\345\205\254\345\205\261\347\273\223\347\202\271/images/image-20200426084449089.png" new file mode 100644 index 0000000000000000000000000000000000000000..8c551950156a71a85df1657069ec55c553227240 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/16_\344\270\244\344\270\252\351\223\276\350\241\250\347\232\204\345\205\254\345\205\261\347\273\223\347\202\271/images/image-20200426084449089.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/17_\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260)/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/17_\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260)/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ed5792e862669653008e1328d1a413dc98add548 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/17_\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260)/README.md" @@ -0,0 +1,154 @@ +# 孩子们的游戏(圆圈中最后剩下的数) + +## 描述 + +来源:https://www.nowcoder.com/practice/f78a359491e64a50bce2d89cff857eb6 + +每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1) + +如果没有小朋友,请返回-1 + +## 方法1 + +首先第一种方法就是,循环遍历整个链表,每次找到后,把该节点删除,首先我们需要构建一个链表 + +```python +class ListNode: + def __init__(self, x): + self.val = x + self.next = None +``` + +然后在开始移动报数,我们移动 m-1步 + +``` +# 我们找到小朋友 +leftHead = None +for i in range(m-1): + leftHead = head + head = head.next +``` + +最后在把 m -1的那个节点移除链表 + +``` +leftHead.next = head.next +head = head.next +``` + +最后的输出条件,就是链表中只剩下一个结点了 + +``` +# 表示循环链表中,只剩下一个小朋友了 +if head == head.next: + return head.val +``` + +完整的代码如下 + +```python +# 孩子们的游戏(圆圈中最后剩下的数) +# 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老, +# 自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m, +# 让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物, +# 并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友, +# 可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢? +# (注:小朋友的编号是从0到n-1) +# 如果没有小朋友,请返回-1 +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +class Solution: + def LastRemaining_Solution(self, n, m): + if n == 0 or m == 0: + return -1 + + # 构建一个循环链表 + head = ListNode(0) + tempHead = head + for i in range(1, n): + node = ListNode(i) + head.next = node + head = head.next + + head.next = tempHead + head = tempHead + while head: + # 我们找到小朋友 + leftHead = None + for i in range(m-1): + leftHead = head + head = head.next + + leftHead.next = head.next + head = head.next + + # bakTmp = leftHead.next + # + # # while bakTmp.next != head: + # # bakTmp = bakTmp.next + + # 表示循环链表中,只剩下一个小朋友了 + if head == head.next: + return head.val + +if __name__ == '__main__': + print(Solution().LastRemaining_Solution(5, 2)) +``` + +## 方法2 + +![小朋友的游戏](images/小朋友的游戏.png) + +![小朋友的游戏公式](images/小朋友的游戏公式.png) + +这个题一开始小朋友们每个人自己的编号是确定的,就相当于我们列表里面的索引是确定的一样,然后让编号为0。 + +链表1:也就是 列表里面的第一个数开始报数,上图第一个链表蓝色的0,开始报数。报到 m-1 的数的 i小朋友 出列,圈里就少了一个数。定义为 f(n). + +链表2:这个时候 从 m-1 的下一个 m 开始 下一轮的循环,开始报数,也就是上图第二个链表的蓝色框。再次报到 m-1 的时候,这个ii小朋友会站出来。(但是这个时候 我们链表的 循环顺序 (m-(m-2)) 发生了变化,不再是从第一个数 【链表的表头 开始循环,而是m 这个数作为起始位置的】,与之前第一个 链表循环的时候的 顺序(0-n)不同了【起始位置为链表的表头】。此时表里少了一个小朋友。这个是题意,让我们这样来找的小朋友。所以定义为 f `(n-1). + +这样的话,就出现了 上图中的 链表2 ,链表3. 这样的不同的情况,这两个 找出来的第 m-1 个 小朋友 是同一个小朋友,但是 两个顺序却不相同。 + +链表3:这个图 是 以 m 为起始位置 来寻找第 m-1 个值的,它 就是 f(n-1) + + 如果说我们想由 链表3 得到 链表2 的话,那么 我们就需要把作为起始位置的m(下标为0) 移动到 下标为(m) 的位置,那么就是下标值 + m 。如图,我们需要移动的是 每个数值所对应的 下标 index值。让 m 在一个链表中作为起始位置来开始 报数 找 第 m - 1 个iii小朋友。 + +但是又由于 我们这样直接加上一个m 以后,这个 index 值有可能会大于 这个链表的长度,如果大于这个链表的长度的话,那么就是说移动到了这个链表的前一部分,所以要对我们的 这个数 对 链表的长的的一个取余: + +(iii+m)%n 我们一共是 n 个值,从0-(n-1); + +f(n-1) = iii + +所以 f(n) = f `(n-1) = (iii+m)%n + +所以 f(n) = (f(n-1)+m) + +那么这个通项表达式我们就找到了,再去编写代码。 + +```python +# -*- coding:utf-8 -*- +class Solution: + def LastRemaining_Solution(self, n, m): + # write code here + #通过推导公式可得 f(n) = (f(n-1)+m)%n + #首先判断,当我们这个链表里没有小朋友的时候,或者找到的小朋友报的数小于1 的时候,这个时候返回一个-1,题中表示 如果测试的是0个小朋友,数0个站出来,那么返回的值应为-1. + if n < 1 or m < 1: + return -1 + #只有一个人的时候,说明要找的就是这一个人。那么就返回下标0 编号。 + if n==1: + return 0 + value = 0 + #时间复杂度 o(n) + #从 2 开始 一直到 n 个小朋友 来循环,n 个数,所以为 n+1 + for index in range(2,n+1): + #现在数到的 m-1 这个值 的索引。对应上上面的公式。 + currentValue = (value+m) % index + #把找到的这个下标值 赋值给 value + value = currentValue + #返回编号 + return value +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/17_\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260)/images/\345\260\217\346\234\213\345\217\213\347\232\204\346\270\270\346\210\217.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/17_\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260)/images/\345\260\217\346\234\213\345\217\213\347\232\204\346\270\270\346\210\217.png" new file mode 100644 index 0000000000000000000000000000000000000000..22617a7fdcf84dfe66beba30e53a52174601e14a Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/17_\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260)/images/\345\260\217\346\234\213\345\217\213\347\232\204\346\270\270\346\210\217.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/17_\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260)/images/\345\260\217\346\234\213\345\217\213\347\232\204\346\270\270\346\210\217\345\205\254\345\274\217.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/17_\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260)/images/\345\260\217\346\234\213\345\217\213\347\232\204\346\270\270\346\210\217\345\205\254\345\274\217.png" new file mode 100644 index 0000000000000000000000000000000000000000..414e0f77b3b4d1171f268b5456a18899aa9b77b7 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/17_\345\255\251\345\255\220\344\273\254\347\232\204\346\270\270\346\210\217(\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260)/images/\345\260\217\346\234\213\345\217\213\347\232\204\346\270\270\346\210\217\345\205\254\345\274\217.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/18_\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/18_\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..c01a57f96f971a4503387725b0a666caf351b800 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/18_\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271/README.md" @@ -0,0 +1,92 @@ +# 链表中环的入口结点 + +## 描述 + +来源:https://www.nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4 + +给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null + +## 思考 + + + +![image-20200426105846170](images/image-20200426105846170.png) + +**如何确定是否有环** + +- 把所有出现的点,都放到list中 +- 如果下次的节点,在list中出现,说明出现了环 +- 但是这种时间复杂度比较高 + +**第二种方式** + +定义:两个 指针,一个是慢指针,一个是快指针 + +假设 slow 走了 L 步,那么 fast 就走了 2L 步。 + + 我们 链表的头部 到 链表的环的入口结点处 的距离是 S + +那么 从入口结点 到 我们 快慢指针相遇的地点 的距离 为 d。 + +链表的环中,慢指针走过的距离是d,那么没走过的距离是M。 + +我们不确定的是快指针在链表的环里走过了多少圈来与慢指针相遇,因此 将这个参数设置为n。 + +``` +那么 L = s + d +2L = 2(s+d) = n*(m + d) + d + s +由上面公式 推导出 n(m+d) = s + d +得到:s = n(m+d) -d; +s = nm + (n-1)(d) +s = m + (n-1)(m+d) +``` + +## 完整代码 + +``` +# -*- coding:utf-8 -*- +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None +class Solution: + def EntryNodeOfLoop(self, pHead): + # write code here + #首先需要定义两个指针,其中一个快,跳两步,一个慢跳一步。 + #循环跳 + #要么是快的指针 为 none(没有环),要么是快慢指针相等(有环)。 + if pHead == None: + return None + #定义两个指针,一个快的一个慢的。 + fastPointer = pHead + slowPointer = pHead + #当快指针存在时,而且快指针的结点指向的下一个也存在 + while fastPointer and fastPointer.next : + #那么让快指针走两步 + fastPointer = fastPointer.next.next + #让慢指针走一步 + slowPointer = slowPointer.next + #如果慢指针等于快指针时,那么就说明这个链表中有环。有环的话那么就跳出,break + if fastPointer == slowPointer: + break + #如果说两个指针没有相等的时候,快指针就已经走到链表的尽头了,说明这个链表没有环。那么就返回None。 + if fastPointer == None or fastPointer.next == None: + return None + #如果slow 走了 l 的长度 那么 fast 就走了 2l 的长度 + #假设 从开始到入口点的长度是 s;slow 在环里面走的长度是 d + + # 那么 L = s + d + #假设 环内 slow 没走的 长度 是 m; fast 走的长度是多少 + # fast 走的长度 就是 ( m + d ) * n + d + s = 2 L + #带入 ( m + d ) * n + d + s = 2 (s + d ) + # s = m + (n-1)(m+d) + #有环的话,那么就让快指针从头开始走,这次一次走一步, + fastPointer = pHead + #此时慢指针还在环里走着,没有走到结点 + while fastPointer != slowPointer: + fastPointer = fastPointer.next + slowPointer = slowPointer.next + #当两个指针相等时,就会相遇,这时返回一个指针的值,就为 入口结点处。 + return fastPointer +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/18_\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271/images/image-20200426105846170.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/18_\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271/images/image-20200426105846170.png" new file mode 100644 index 0000000000000000000000000000000000000000..afe768495cd40a954e77ff7f31b5d881beb330f8 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/18_\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271/images/image-20200426105846170.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/19_\344\272\214\350\277\233\345\210\266\344\270\2551\347\232\204\344\270\252\346\225\260/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/19_\344\272\214\350\277\233\345\210\266\344\270\2551\347\232\204\344\270\252\346\225\260/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b3da4f8f6e644c1780723b17ad29d30228af8815 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/19_\344\272\214\350\277\233\345\210\266\344\270\2551\347\232\204\344\270\252\346\225\260/README.md" @@ -0,0 +1,127 @@ +# 二进制中的1的个数 + +## 描述 + +来源:https://www.nowcoder.com/practice/8ee967e43c2c4ec193b040ea7fbb10b8 + +输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示 + +#### 补码 + +- 正数不变,负数就是它的正数的反码 + 1 + +- 一个负整数(或原码)与其补数(或补码)相加,和为模。 +- 对一个整数的补码再求补码,等于该整数自身。 + +- 补码的正零与负零表示方法相同 + +>-2 的 补码: +> +>-2 的二进制为 1 0 0 0 0 .......0 0 0 1 0 , +> +>-2 的 反码为: 1 1 1 1 1 .......1 1 1 0 1 +> +>-2 的 补码为: 1 1 1 1 1 .......1 1 1 1 0 +> +>对于任意一个数n: +> +>n = n & 0xFFFFFFFF + +#### 按位取反 ~ + +~,用法只有一个那就是按位取反,需要注意的是: + +- ~ 的按位取反,包括符号位 +- 正数各位取反变为负数,显示时转化为其补码 +- 负数本身需要先转换为补码(符号位不变,各位取反再加 1),再对其补码进行各位去反 + +##### 1. ~5 + +5 的二进制为 0101, + +~5 + +- (1)各位取反,1010 +- (2)变为负数,转化为其补码形式(符号位保持不变),各位取反 1(1101),再加1(1110),也即 -6 + +```python +>> ~5 +>> -6 +``` + +##### 2. ~(-5) + +-5 因为是负数,存储时存储的是其补码: + +- -5 的补码是:1011, +- ~(-5)将其各位取反(包括符号位),也即 0100(4) + +```python +>> ~(-5) +>> 4 +``` + +___ + +## 代码 + +```python +# 第一种 +class Solution: + def NumberOf1(self, n): + # 这一步是求补码的 + n = n & 0xFFFFFFFF + count = 0 + for c in str(bin(n)): + if c == "1": + count +=1 + return count + + def NumberOf2(self, n): + # 这一步是求补码的 + n = n & 0xFFFFFFFF + count = 0 + for i in range(32): + mask = 1 << i + if n & mask != 0: + count += 1 + return count + +#第二种: +class Solution: + def NumberOf1(self, n): + # write code here + #补码:正数不变,负数是它的正数的反码 + 1 + # -2 补码: -2 的 1 0000.。。000010, + # 1 1111.。。111101 + 1 + #-2 的补码就是 1 1111.。。111110 + #把输入的正数n转化为二进制的数,并把0b 替换掉,计算1的数量,如果输入的值不是正数的话 + #一个负整数(或原码)与其补数(或补码)相加,和为模。2 的32 次方 是模。 + #那么就是 2 的32 次方 然后 + n 这是在取一个负数的补码 就相当于 n & 0xffffffff + #然后计算 这个数里面 1 的 数量 + return bin(n).replace("0b", "").count("1") if n >= 0 else bin(2 ** 32 + n).replace("0b", "").count("1") + + +#第三种: +# -*- coding:utf-8 -*- +class Solution2: + def NumberOf1(self, n): + # write code here + # 1 出现的次数为0 次 + count = 0 + #判断 这个数 n 是不是负数,如果是负数的话 求其补码: + if n < 0: + n = n & 0xffffffff + #如果这个数不是0 的话,那么它在二进制的表示中至少有一位是1,所以一开始我们赋值 count +=1. + while n: + count += 1 + #把一个整数先减去1,再和原整数做与运算,会把该整数最右边的1 变从成0,那么一个二进制中有多少个1,就可以进行多少次这样的操作。 + n = (n - 1) & n + return count + """ + 例如:一个二进制1100, 它的第二位 是从最右边数起的一个1,减去一个1后,第二位变成0,它后面的两位0变成1,而前面的1保持不变,因此结果是1011. + 那把 这个整数 和它 减去1 的结果 做一个按位 与运算,相当于 把 最右边的 1 变成 0,。 + 1011 和 1100 做 按位与 运算 1100 & 1011 结果为 1000,那么刚好是我们 要得到 将最右边的1 变成0 的结果 1000. + +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/1_\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/1_\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ec84eb73ec5339dddf373769b82a80ff3c3a36ad --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/1_\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227/README.md" @@ -0,0 +1,95 @@ +# 斐波那契数列 + +## 题目 + +大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。 + +n<=39 + +## 菲波那切数列是什么 + +``` +0 1 1 2 3 5 8 13 + +n = 0, num = 0 +n = 1, num = 1 +n = 2, num = 1 +..... + +当 n = k(n>1),f(k) = f(k-1) + f(k-2) +当 n = 1, f(1) = 1 +当 n = 0, f(0) = 0 +``` + + + +## 递归方法实现 + +``` +# 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0) n<=39 +class Solution: + def Fibonacci(self, n): + if n == 0: + return 0; + if n == 1: + return 1; + if n > 0: + return self.Fibonacci(n - 1) + self.Fibonacci(n -2); + else: + return None + +if __name__ == '__main__': + print(Solution().Fibonacci(10)) +``` + +### 存在问题 + +但是这样存在问题,随着n提升,时间复杂度不断增加 + +![image-20200422211936865](images/image-20200422211936865.png) + +我们发现对于某个值,我们重复计算了很多遍 + + + +## 非递归实现 + +我们继续查看刚刚的规律 + +``` +当 n = 2的时候, h = f(1) + f(0) = 1 + 0 = 1 +当 n = 3的时候, h = f(2) + f(1) = 1 + 1 = 2 +当 n = 4的时候, h = f(3) + f(2) = 3 + 1 = 4 +``` + +我们可以从n = 2,一直循环,直到我们计算出我们输入的值为n的时候 + +我们只需要从最小的开始计算,每次保留中间结果,最后得出我们的第n个的结果。 + +``` +# 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0) n<=39 +class Solution: + + # 非递归实现 + # 当 n = 2的时候, h = f(1) + f(0) = 1 + 0 = 1 + # 当 n = 3的时候, h = f(2) + f(1) = 1 + 1 = 2 + # 当 n = 4的时候, h = f(3) + f(2) = 3 + 1 = 4 + def Fibonacci2(self, n): + if n == 0: + return 0; + if n == 1: + return 1; + + ret = 0 + a = 1 + b = 0 + for i in range(0, n-1): + ret = a + b + b = a + a = ret + return ret + +if __name__ == '__main__': + print(Solution().Fibonacci2(10)) +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/1_\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227/images/image-20200422211936865.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/1_\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227/images/image-20200422211936865.png" new file mode 100644 index 0000000000000000000000000000000000000000..d5cc4c7bd2357b4789b538a1ba8081fa35b257c0 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/1_\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227/images/image-20200422211936865.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/20_\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/20_\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..c651bd48a0e52417a4597b2956cdd99ec6720062 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/20_\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225/README.md" @@ -0,0 +1,78 @@ +# 不用加减乘除做加法 + +## 描述 + +来源:https://www.nowcoder.com/practice/59ac416b4b944300b617d4f7f111b215 + +写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。 + +## 思考 + +对于数字运算,如果说四则运算不能用的话,那么我们只能用位运算来做了。 + +我们以 5 + 17 为例 结果为 22,那么 22 的计算结果,我们可以分为三步 来进行: + +​ 第一步: 只做各位相加不进位 也就是说 没一位上的数字 相应的来相加 但是不进位,那么 5 + 7 为 12 + +​ 个位数 5 和 7 相加 不进位 是2 十位是0 和1 相加 为 1 + +​ 第二步: 5 + 7 中有进位,进位值 是10 ; + +​ 第三步: 把前面两个结果 加起来: 12 + 10 = 22 + +以上为我们用十进制计算的 策略,那么 我们用于位运算中是不是也合适,我们来举个栗子: + +还是以 5 + 17 为例,那么 5 的二进制是101 ; 17 的二进制是 10001; + +第一步:各位相加 但不进位: 101 + 10001 = 10110 不进位的话 结果为 10100 (最后一位两个数都是1,相加的结果需要进位,但是这一位不进位,意味着结果仍然是0) + +第二步: 记下进位,它只在最后一位相加时产生了一个进位。 + +第三步: 把前面两个结果相加,得到的结果是 10110. + +**那么现在我们把前面的 二进制的加法用位运算来替代的话** + +第一步的 求 和 运算就是 不考虑 进位的话,对每一位来相加,0 和0 以及 1 和1 的结果都是0 , 0+1 或者 1+0 的结果 都是1;那么我们会看出它与我们学过的异或运算相同,就是相同为假,不同为真,所以叫 异 或 XOR 。 + +第二步: 对0 加 0、1加0、0加1 而言,都不会产生进位,只有1+1 的时候,会产生一个进位。此时 我们可以想象成两个数 先做了一个 位 与 & 运算,然后再向 左移 一位。只有两个数是1 的时候,位与 & 得到的结果是 1,其余的都是0。 + +第三步:把前面两个步骤的结果再相加,然后在继续判断是否有进位,直到没有进位为止,那么此时的相加的过程,依然是重复前面的两步,直到不产生进位为止。 + +![不用加减法算和运算](images/不用加减法算和运算.png) + + + +## 代码 + +```python +# -*- coding:utf-8 -*- +class Solution: + def Add(self, num1, num2): + #第一种代码:循环。简洁但是原理相同,那么我们以下面第二段代码为例;来解析。 + # while (num2): + # num1, num2 = (num1 ^ num2) & 0xFFFFFFFF, ((num1 & num2) << 1) & 0xFFFFFFFF + # return num1 if num1 <= 0x7FFFFFFF else ~(num1 ^ 0xFFFFFFFF) + + #第二种代码: + #首先两个数做 一个 异或 运算^ 那就是 在不进位的情况下,让两个相加 求和。 + xorNum = num1 ^ num2 + #让两个数 做 位与 操作,然后再向 左 移 一位,得到它 向前进位的值。 + andNum = (num1 & num2) << 1 + #判断,当 进位 的值不等于0 的时候,说明 一直有进位,也就是 过程没有结束。 + while andNum != 0: + #那么我们就继续上面的操作。但是这次的 数值 改为上次的两个结果, + #一个 是异或的结果,一个是 与 操作 & 以后 左移一位的 结果。 + tmp1 = xorNum ^ andNum + tmp2 = (xorNum & andNum) << 1 + #因为如果这个数为负数的话,那么负数 左移 一位与正数 不同,负数 是数值变小,正数 数值变大 + #如果是正数的话那么这一步就 不变,如果是负数的话,这一步就对负数来起作用。 + #对于python来说 负数的 二进制 可能会有无数个1,我们用这个方法让它变成一个可数的数字长度。 + tmp1 = tmp1 & 0xffffffff + + xorNum = tmp1 + andNum = tmp2 + #一个负整数(或原码)与其补数(或补码)相加,和为模。 0xffffffff + # ~(xorNum ^ 0xFFFFFFFF) 这个是 异或数 与 模 来 异或,最后 按位 取反 来求得 负数的补码。 + return xorNum if xorNum <= 0x7ffffff else ~(xorNum ^ 0xFFFFFFFF) +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/20_\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225/images/\344\270\215\347\224\250\345\212\240\345\207\217\346\263\225\347\256\227\345\222\214\350\277\220\347\256\227.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/20_\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225/images/\344\270\215\347\224\250\345\212\240\345\207\217\346\263\225\347\256\227\345\222\214\350\277\220\347\256\227.png" new file mode 100644 index 0000000000000000000000000000000000000000..16c8ae6f46fd15d0678cda30b183b4160119f9f4 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/20_\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225/images/\344\270\215\347\224\250\345\212\240\345\207\217\346\263\225\347\256\227\345\222\214\350\277\220\347\256\227.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/21_\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/21_\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..cb97cae0a76226b9ece36dd7887389f752da7b98 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/21_\346\225\260\347\273\204\344\270\255\345\207\272\347\216\260\346\254\241\346\225\260\350\266\205\350\277\207\344\270\200\345\215\212\347\232\204\346\225\260\345\255\227/README.md" @@ -0,0 +1,86 @@ +# 数组中出现次数超过一半的数字 + +## 题目描述 + +数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 + +## 常规代码 + +使用一个字典,来记录每个数出现的次数 + +``` +# 数组中出现次数超过一半的数字 +# 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 +# -*- coding:utf-8 -*- +class Solution: + def MoreThanHalfNum_Solution(self, numbers): + numsCount = {} + numLen = len(numbers) + for num in numbers: + if num in numsCount: + numsCount[num] += 1 + else: + numsCount[num] = 1 + # 找出超过一半的数 + if numsCount[num] > numLen >> 1: + return num + return 0 +``` + + + +>上述代码的空间和时间复杂度都是:O(n) +> +>如果我们要做到,空间复杂度为:O(1),时间复杂O(n) + +## 升级代码 + +> 思路:抵消掉 遇到不相同的数字就相互抵消掉,最终剩下的数字就可能是出现次数大于数组长度一半的数字。首先我们来遍历数字,遍历的时候需要记录上次出现的数字是什么,进而判断 下次出现的数字是否与现在这个数字相等,如果不相等的话,那么就把两个数字抵消掉,到最后没有抵消掉的数字,就可能是出现的次数大于数组长度的一半。 +> +> +>我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,另一个是次数;当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1,如果下一个数字和我们之前保存的数字不同,则凑数减1.如果次数为0 ,我们需要保存下一次出现的次数,然后把次数设置为1. + +``` +class Solution: + def MoreThanHalfNum_Solution(self, numbers): + #定义变量 上次出现的数字为0 + last = 0 + #上次出现的数字的数量为0 + lastCount = 0 + #遍历数组中的数字 + for num in numbers: + #如果说这个数字出现的次数为0了。 + if lastCount == 0: + #那么就把上次出现的数字,变为需要保存的那个数字。 + last = num + #并把次数设置为1 次,出现了这一次。 + lastCount = 1 + else: + #否则就判断,这个数字是不是与上次出现的次数相同,如果相同的话,那么我们这个数字出现的次数就加1. + if num == last: + lastCount += 1 + #如果不同的话,那么我们就让这两个数字抵消掉,那么这个数字出现的次数需要减 1; + else: + lastCount -= 1 + #如果最后遍历完事之后 这个记录数字出现次数的 值为0 的话,那么就说明我们的这个数组里面的数刚好可以两两抵消掉 + if lastCount == 0: + return 0 + #否则的话,就说明 数组里面 留下了没有抵消掉的数 + else: + #这种情况是last可能是大于一半的数字 + #这个时候把 记录数字次数的变量 计数 为0 + lastCount = 0 + #遍历数组中的数 + for num in numbers: + #如果这个数与我们记录的数相等的话 + if num == last: + #让这个计数加1 + lastCount += 1 + #最后判断一下,这个数的计数次数,是不是大于 我们数组长度的一半,如果是的话,就返回这个数,如果不是就返回0. + if lastCount > (len(numbers)>> 1): + return last + return 0 +``` + + + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/22_\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/22_\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b928466cbaaa36d9f9a202cad34f18aa60afb831 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/22_\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260/README.md" @@ -0,0 +1,95 @@ +# 整数中1出现的个数 + +[题目传送门](https://www.nowcoder.com/practice/bd7f978302044eee894445e244c7eee6?tpId=13&tqId=11184&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) + +## 题目描述 + +求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数) + +## 思路 + +![整数中1出现的次数](images/整数中1出现的次数.png) + +如上图所示,如果那个数 是我们 的 1-n 中 n 这个数,那么这个数就是一个特别大的数,不能遍历计算每个数字的1 的个数, 那就只能去寻找1在数字中出现的规律来。 + +那么我们可以把 这个数字中 ,分段来 看 1 在这个数字片段中可能出现的情况都有多少。 + +**若 以上 栗子 中的 十万位上的 0 那一位 为 数字1 的话,有多少种 可能? ** + +​ 首先 直接 为1 的话,这个数就会大于 我们的n 这个数,所以 它需要 向前一位借 一位,来计算 可能出现的 情况 有多少种,那么就是 一共 有 + +`0-3458` 个数 那么就一共是 3459 中可能性。 + +​ **那么十万位 后面 出现1 的情况有多少种 可能性 ?** + +​ 0 后面一共有5 位,每 一 位 的数字 可能的情况 是 0-9 共 十 个数字,也就是说 后面 为的可能性是 `10^5`. + +那么就是说对于 十万位数字是0 来说,一共有3459*(10^5 )种 可能。 + +​ **接下来我们在考虑一个 数字 那就是 万 位 上的数字,8,如果8 这一位为1 的话,有多少种可能性?** + +如果8 为1 的话,那么就是我们前面的数字 有 1-34590,共`34591`种情况,后面 是一共 4 位,那么就有 `10^4 `种情况。 + +那么就是说对于 万位数字是0 来说,一共有34591*(10^4) 种 可能。 + +​ **我们再考虑另一个特殊的,那就是我们的百位上的 1 那一位,除了现在的n 的百位上是1,那么其他 这个一位为1 的情况,一共有多少种可能?** + +如果说1 这个数字不变的话,那么1前面 的位数 可能为1 的可能性就是 0-3459082,后面的两位的 可能性为 0-90,不能大于90,如果大于的话,需要 跟 百位来借 一位了,我们先考虑这种不借位的可能性,那就是 + +3459083*91,如果借位的话,那么前面就是 0-3459081,后面就10^2-91 为9 种 情况,那么最后 一共有 + +3459083 x 91+3459082 x 9,最后推导为 3459082 x 91 + 91 + 3459082 x 9,最后为 3459082 *10^2 +91种 可能性。 + +分析了三种特殊的情况,那么我们可以用递归的方式来找,只不过因为递归的话 时间复杂度比较高,那么我们可以写一个 与递归等价的 while 循环来实现,递归和 while 循环是可以互相转换的。 + +## 代码 + +``` +class Solution: + def NumberOf1Between1AndN_Solution(self, n): + #循环的出口是 highValue = 0 + + #我们从最低位开始一个位一个位的来寻找 1 的可能出现的 情况次数。 + + # 一开始 精准度为1.高位低位中位 先赋值为1. + preceise = 1 + # 高位数 + highValue = 1 + # 低位数 + lowValue = 1 + # 中位数 + midValue =1 + + #计数 后面的位数。 + count = 0 + #计数 1 的次数和 + sumNum = 0 + #循环的 出口是我们找不到最高位了,那么这个时候就说明,我们遍历到了 这个数字的最高位。 + while highValue != 0: + #高位 先将这个数 除以10 得到高位 + highValue = n // (preceise * 10) + #中位 先将这个数 与 10 取余。 + midValue = (n // preceise)%10 + #低位 先将这个数 除以 1 那么低位就是个位后面的,没有就是0. + lowValue = n % preceise + #每遍历一次 向右移一位,那么就是说 精准度要乘以10. + preceise *= 10 + #如果这个数是0 的话, + + if midValue == 0: + #那么它就是高位的值,乘以 10^后面的位数 次方,但是这个时候 对于中位 来说 它是个位,后面没有位,所以是0, + num = (highValue)* pow(10,count) + #如果这个数 大于1 的话, + elif midValue > 1: + #那么它 就是 最高位加1 乘以 10^后面的位数 次方, + num = (highValue+1)*pow(10,count) + else: + #否则的话 它就是等于1 的情况了,对于等于1 的1情况,又是比较特殊的情况,它需要 最高位 * 它10 的后面位数个数的次方,然后要加上我们低位 的数值再加 1, 原因在上面的分析中已经给出。 + num = highValue*pow(10,count)+(lowValue+1) + #最后 我们1 出现的 次数 就是这 三个 num 的和,。 + sumNum += num + #没循环一次,这个三个就往左移一次吗,那么这个时候它们 后面的位数也就会 多一位。 + count += 1 + #最后返回这个 次数和。 + return sumNum +``` \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/22_\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260/images/\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/22_\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260/images/\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.png" new file mode 100644 index 0000000000000000000000000000000000000000..c61cc64225b95fbea89efca9fd8ec31ebdc73877 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/22_\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260/images/\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/23_\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/23_\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..1b2686759773a2e5e38738b52129eb38d8e8731f --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/23_\346\225\260\347\273\204\344\270\255\345\217\252\345\207\272\347\216\260\344\270\200\346\254\241\347\232\204\346\225\260\345\255\227/README.md" @@ -0,0 +1,34 @@ +# 数组中只出现一次的数字 + +## 题目 + +一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 + +## 思路 + +这里我们需要做的就是,首先使用一个字典来进行存储,如果这个字典中原来有值了,那么我们就把这个字典删除,否则,按key为array[i],然后值设置成1,当我们遍历完成后,就会让剩下的数留下来,那么我们就通过遍历将他们查询出来返回即可。时间复杂度为 O(n) + +## 代码 + +``` +# 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 +class Solution: + # 返回[a,b] 其中ab是出现一次的两个数字 + def FindNumsAppearOnce(self, array): + dict = {} + for i in range(len(array)): + if dict.get(array[i]) != None: + del dict[array[i]] + else: + dict[array[i]] = 1 + if len(dict) == 0: + return None + list = [] + for key in dict: + list.append(key) + return list[0], list[1] +if __name__ == '__main__': + array = [2,4,3,6,3,2,5,5] + print(Solution().FindNumsAppearOnce(array)) +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/24_\346\240\221\347\232\204\351\201\215\345\216\206/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/24_\346\240\221\347\232\204\351\201\215\345\216\206/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..02e154d8c3abafc5b77bd7cc2013d54b9da49551 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/24_\346\240\221\347\232\204\351\201\215\345\216\206/README.md" @@ -0,0 +1,192 @@ +# 树的遍历 + +## 什么叫做树? + +**树状图**是一种[数据结构](https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1450),它是由n(n>=0)个有限结点组成一个具有层次关系的[集合](https://baike.baidu.com/item/%E9%9B%86%E5%90%88)。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点: + +每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点外,每个子结点可以分为多个不相交的子树; + +叶节点没有子节点,根节点没有父节点。 + +## 什么是二叉树? + +每个节点最多含有两个子树的树称为二叉树。下图就是一个二叉树。 + +在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。 + +一棵深度为k,且有2^k-1个节点的二叉树,称为满二叉树。这种树的特点是每一层上的节点数都是最大节点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树。具有n个节点的完全二叉树的深度为floor(log2n)+1。深度为k的完全二叉树,至少有2k-1个节点,至多有2k-1个节点 + +## 构建一个二叉树 + +如图所示,我们如果要构建下面的二叉树,应该是怎么定义的 + +![image-20200528223617759](images/image-20200528223617759.png) + +代码如下 + +``` +class TreeNode(object): + def __init__(self, x): + self.val = x + self.left = None + self.right = None + +if __name__ == '__main__': + t1 = TreeNode(1) + t2 = TreeNode(2) + t3 = TreeNode(3) + t4 = TreeNode(4) + t5 = TreeNode(5) + t6 = TreeNode(6) + t7 = TreeNode(7) + t8 = TreeNode(8) + t1.left = t2 + t1.right = t3 + t2.left = t4 + t2.right = t5 + t3.left = t6 + t3.right = t7 + t6.right = t8 +``` + +## 二叉树的遍历: + +遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,[树的遍历](https://baike.baidu.com/item/%E6%A0%91%E7%9A%84%E9%81%8D%E5%8E%86)实质上是将二叉树的各个结点转换成为一个线性序列来表示。 + +设L、D、R分别表示遍历左子树、访问根结点和遍历右子树, 则对一棵二叉树的遍历有三种情况:DLR(称为先根次序遍历),LDR(称为中根次序遍历),LRD (称为后根次序遍历)。 + +> 针对上图,我们看看先序、中序、后序遍历 +> +> 先序遍历:1 2 4 5 3 6 8 7 +> +> 中序遍历:4 2 5 1 6 8 3 7 +> +> 后序遍历:4 5 2 8 6 7 3 1 + +## 递归遍历 + +```python +class TreeNode(object): + def __init__(self, x): + self.val = x + self.left = None + self.right = None + +# 递归先序遍历 +def preOrderRecusive(root): + if root == None: + return None + print(root.val, end=" ") + preOrderRecusive(root.left) + preOrderRecusive(root.right) + +# 递归中序遍历 +def midOrderRecusive(root): + if root == None: + return None + midOrderRecusive(root.left) + print(root.val, end=" ") + midOrderRecusive(root.right) + +# 递归后序遍历 +def latOrderRecusive(root): + if root == None: + return None + latOrderRecusive(root.left) + latOrderRecusive(root.right) + print(root.val, end=" ") + +if __name__ == '__main__': + t1 = TreeNode(1) + t2 = TreeNode(2) + t3 = TreeNode(3) + t4 = TreeNode(4) + t5 = TreeNode(5) + t6 = TreeNode(6) + t7 = TreeNode(7) + t8 = TreeNode(8) + t1.left = t2 + t1.right = t3 + t2.left = t4 + t2.right = t5 + t3.left = t6 + t3.right = t7 + t6.right = t8 + + preOrderRecusive(t1) + print() + midOrderRecusive(t1) + print() + latOrderRecusive(t1) +``` + + + +运行结果 + +``` +1 2 4 5 3 6 8 7 +4 2 5 1 8 6 3 7 +4 5 2 8 6 7 3 1 +``` + +## 非递归遍历 + +递归和循环是可以互相转换的,下面是非递归先序遍历,使用一个stack用于存储经过的节点,并且输出,但没有指针指向为空的时候,我们需要将stack中保存的节点,进行pop出栈,并把它的右节点,重新赋值给tempNode指针,直到所有节点都遍历完成为止。 + +``` +# 非递归先序遍历 +def preOrder(root): + if root == None: + return None + stack = [] + tempNode = root + while tempNode != None or stack: + print(tempNode.val, end=" ") + stack.append(tempNode) + tempNode = tempNode.left + while tempNode == None and stack != None: + tempNode = stack.pop() + tempNode = tempNode.right +``` + +``` +# 非递归中序遍历 +def midOrder(root): + if root == None: + return None + stack = [] + tempNode = root + while tempNode != None or stack: + stack.append(tempNode) + tempNode = tempNode.left + while tempNode == None and stack != []: + tempNode = stack.pop() + print(tempNode.val, end=" ") + tempNode = tempNode.right +``` + +``` +# 非递归后序遍历 +def latOrder(root): + if root == None: + return None + stack = [] + tempNode = root + while tempNode != None or stack: + stack.append(tempNode) + tempNode = tempNode.left + while tempNode == None and stack != []: + # 后序遍历,pop的方式有变化,不能在右子树不为空的时候pop + node = stack[-1] # 因此这里不出列 + tempNode = node.right + # 当右节点没有的时候,才能够pop + if node.right == None: + print(node.val, end=" ") + node = stack.pop() + # 判断pop的节点,是否是上一个节点 + while stack and node == stack[-1].right: + node = stack.pop() + print(node.val, end=" ") +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/24_\346\240\221\347\232\204\351\201\215\345\216\206/images/image-20200528223617759.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/24_\346\240\221\347\232\204\351\201\215\345\216\206/images/image-20200528223617759.png" new file mode 100644 index 0000000000000000000000000000000000000000..91ec75d9bd567b7052575930a925acd4d615cec2 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/24_\346\240\221\347\232\204\351\201\215\345\216\206/images/image-20200528223617759.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/25_\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/25_\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..5c25444ee4e6d29e5db596938858bf848399da6c --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/25_\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/README.md" @@ -0,0 +1,63 @@ +# 重建二叉树 + +## 来源 + +https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6 + +## 题目 + +输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。 + +## 重建过程 + +先找到根节点,也就是先序遍历的第一个节点,即1为根节点 + +然后从中序遍历中寻找,在1左边的属于左子树(4,7,2),右边的属于右子树:(5,3,8,6) + +然后在从先序遍历的第二个节点中寻找出2,作为根节点的左孩子,我们在寻找2节点的左孩子和右孩子,发现只有(4,7)为左节点,没有右节点,然后我们再从先序遍历中寻找出下一个节点,即为4,然后找出4节点的右孩子,即为7。到这里位置,左子树已经构建成功。 + +构建右子树时,我们需要从先序遍历中,再次输出一个节点3,作为根节点的右子树,然后在从刚刚分类好的中序遍历中,寻找到子树3的左孩子和右孩子,左孩子为(5),右孩子为(8,6),我们继续出列先序遍历,得到5,即3节点的左孩子,然后在出列得到6,也就是3的右孩子,然后在中序遍历中寻找到6的左孩子和右孩子,最后发现只剩下8在,6的左边,因此右孩子为8 + +![image-20200529144737938](images/image-20200529144737938.png) + +## 代码 + +``` +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + # 返回构造的TreeNode根节点 + def reConstructBinaryTree(self, pre, tin): + # 取出pre的值 + if not pre or not tin: + return None + if len(pre) != len(tin): + return None + root = pre[0] + # 新建立节点 + rootNode = TreeNode(root) + # 找出这个节点,在中序遍历对应的角标 + pos = tin.index(root) + # 取出中序遍历 左子树 + tinLeft = tin[:pos] + # 取出中序遍历 右子树 + tinRight = tin[pos+1:] + # 取出先序遍历的 左子树 + preLeft = pre[1:pos+1] + # 取出先序遍历的 右子树 + preRight = pre[pos+1:] + + leftNode = self.reConstructBinaryTree(preLeft, tinLeft) + rightNode = self.reConstructBinaryTree(preRight, tinRight) + + if leftNode: + rootNode.left = leftNode + if rightNode: + rootNode.right = rightNode + return rootNode +``` + +代码的实现,使用了递归的方式,也就是采用了分治法,将要解决的问题一分为二,这里指的是先序遍历和中序遍历。 \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/25_\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/images/image-20200529144737938.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/25_\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/images/image-20200529144737938.png" new file mode 100644 index 0000000000000000000000000000000000000000..583d096b309ceeb00cf9d1605b06fd5d4cdfc9fb Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/25_\351\207\215\345\273\272\344\272\214\345\217\211\346\240\221/images/image-20200529144737938.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/26_\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/26_\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..85517ad92a5b51d01239e579eed3e3a4dff52c06 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/26_\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204/README.md" @@ -0,0 +1,60 @@ +# 树的子结构 + +## 来源 + +https://www.nowcoder.com/practice/6e196c44c7004d15b1610b9afca8bd88 + +## 题目 + +输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构) + +## 思路 + +首先我们需要考虑的是,什么才是子结构,如下图所示,rootB就是rootA的子结构 + +![image-20200529153030088](images/image-20200529153030088.png) + +遍历过程如下,首先先遍历rootB的根节点,然后rootA的根节点比较,如果一样,就继续遍历rootB的左右子树,不一样,我们就换个其他节点进行遍历,但我们遍历到rootA的2节点时候,发现和rootB的根节点一样,那么这个时候,就在遍历RootB的左子树,发现也和rootA的一样,在遍历右子树,也相等,这个时候,在rootB全部遍历完成后,我们就能够确定,rootB为rootA的子结构了。 + +## 代码 + +``` +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + def HasSubtree(self, pRoot1, pRoot2): + if pRoot1 == None or pRoot2 == None: + return None + + def hasEqual(pRoot1, pRoot2): + if pRoot2 == None: + return True + if pRoot1 == None: + return None + if pRoot1.val == pRoot2.val: + if pRoot2.left == None: + leftEqual = True + else: + leftEqual = hasEqual(pRoot1.left, pRoot2.left) + if pRoot2.right == None: + rightEqual = True + else: + rightEqual = hasEqual(pRoot1.right, pRoot2.right) + # 左边相等和右边相等的时候,才返回 + return leftEqual and rightEqual + return False + + ret = hasEqual(pRoot1, pRoot2) + if ret: + return True + + ret = self.HasSubtree(pRoot1.left, pRoot2) + if ret: + return True + ret = self.HasSubtree(pRoot1.right, pRoot2) + return ret +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/26_\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204/images/image-20200529153030088.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/26_\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204/images/image-20200529153030088.png" new file mode 100644 index 0000000000000000000000000000000000000000..6877f8dbbb2c531eda03823acbc8549c6666fbf8 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/26_\346\240\221\347\232\204\345\255\220\347\273\223\346\236\204/images/image-20200529153030088.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/27_\344\272\214\345\217\211\346\240\221\347\232\204\351\225\234\345\203\217/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/27_\344\272\214\345\217\211\346\240\221\347\232\204\351\225\234\345\203\217/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..96e2cb7d4ba8ccc4054a95856eaf892f7ac152bd --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/27_\344\272\214\345\217\211\346\240\221\347\232\204\351\225\234\345\203\217/README.md" @@ -0,0 +1,86 @@ +# 二叉树的镜像 + +## 来源 + +https://www.nowcoder.com/practice/564f4c26aa584921bc75623e48ca3011 + +## 题目 + +操作给定的二叉树,将其变换为源二叉树的镜像。 + +## 输入描述: + +``` +二叉树的镜像定义:源二叉树 + 8 + / \ + 6 10 + / \ / \ + 5 7 9 11 + 镜像二叉树 + 8 + / \ + 10 6 + / \ / \ + 11 9 7 5 +``` + +## 代码1 + +我们就对每个节点的左右子树进行交换即可,也就是需要使用一个temp变量来存储交换的节点。然后在重复它的左子树和右子树 + +``` +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + # 返回镜像树的根节点 + def Mirror(self, root): + if root == None: + return None + # 处理左子树 + temp = root.left + root.left = root.right + root.right = temp + self.Mirror(root.left) + self.Mirror(root.right) +``` + +## 代码2 + +利用栈(或队列)遍历树的所有节点 node ,并交换每个node 的左 / 右子节点。 + +算法流程: + +- 特例处理: 当 root为空时,直接返回 null; +- 初始化: 栈(或队列),本文用栈,并加入根节点 root +- 循环交换: 当栈 stack为空时跳出; + - 出栈: 记为 node ; + - 添加子节点: 将 node 左和右子节点入栈; + - 交换: 交换 node 的左 / 右子节点。 +- 返回值: 返回根节点 root。 + +图示: + +![111](images/111.gif) + +代码: + +```python +class Solution: + def Mirror(self, root): + if root == None: + return None + stack = [root] + while stack: + node = stack.pop() + if node.left: + stack.append(node.left) + if node.right: + stack.append(node.right) + node.right,node.left = node.left, node.right + return root +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/27_\344\272\214\345\217\211\346\240\221\347\232\204\351\225\234\345\203\217/images/111.gif" "b/\346\225\260\346\215\256\347\273\223\346\236\204/27_\344\272\214\345\217\211\346\240\221\347\232\204\351\225\234\345\203\217/images/111.gif" new file mode 100644 index 0000000000000000000000000000000000000000..2150829c38509f543584bf3e3f4d37c09d46f0c7 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/27_\344\272\214\345\217\211\346\240\221\347\232\204\351\225\234\345\203\217/images/111.gif" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/28_\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/28_\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b2c0770d02c8ee049af54b239f0c17cda6d475d2 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/28_\344\273\216\344\270\212\345\276\200\344\270\213\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221/README.md" @@ -0,0 +1,38 @@ +# 从上往下打印二叉树 + +## 来源 + +https://www.nowcoder.com/practice/7fe2212963db4790b57431d9ed259701 + +## 题目 + +从上往下打印出二叉树的每个节点,同层节点从左至右打印。 + +## 代码 + +``` +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + # 返回从上到下每个节点值列表,例:[1,2,3] + def PrintFromTopToBottom(self, root): + if root == None: + return [] + # 将输入的节点存入support中 + support = [root] + ret = [] + while support: + tempNode = support[0] + ret.append(tempNode.val) + if tempNode.left: + support.append(tempNode.left) + if tempNode.right: + support.append(tempNode.right) + # 删除已经输出的节点 + del support[0] + return ret +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/29_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/29_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a94c20e89a0bf23dc1b3e550747d3f4c10624087 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/29_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227/README.md" @@ -0,0 +1,55 @@ +# 二叉搜索树的后序遍历序列 + +https://www.nowcoder.com/practice/a861533d45854474ac791d90e447bafd + +## 题目 + +输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。 + +## 什么是二叉搜索树 + +二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的[二叉树](https://baike.baidu.com/item/二叉树/1602879): 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为[二叉排序树](https://baike.baidu.com/item/二叉排序树/10905079)。二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势;所以应用十分广泛,例如在文件系统和数据库系统一般会采用这种数据结构进行高效率的排序与检索操作 + +![image-20200531202449227](images/image-20200531202449227.png) + +## 思路 + +给定一个二叉树,后序遍历的结果如下所示 + +![image-20200531203027879](images/image-20200531203027879.png) + +代码如下 + +``` +class Solution: + def VerifySquenceOfBST(self, sequence): + if sequence == []: + return False + + # 找ROOT节点,也就是最后一个 + root = sequence[-1] + # 删除队列中的末尾节点 + del sequence[-1] + # 寻找出划分的节点 + index = None + for i in range(len(sequence)): + # 只寻找一次,就不进入了 + if index == None and sequence[i] > root: + index = i + # 当我们找到一个大的数,然后往后又找到一个更小的数,那么就无法组成二叉搜索树 + if index != None and sequence[i] < root: + return False + + if sequence[:index] == []: + left = True + else: + # 寻找左子树和右子树 + left = self.VerifySquenceOfBST(sequence[:index]) + if sequence[index:] == []: + right = True + else: + right = self.VerifySquenceOfBST(sequence[index:]) + # 返回结果 + return left and right +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/29_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227/images/image-20200531202449227.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/29_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227/images/image-20200531202449227.png" new file mode 100644 index 0000000000000000000000000000000000000000..610371cc5059b8c1a191a2fbfe128cce1d1e65d5 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/29_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227/images/image-20200531202449227.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/29_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227/images/image-20200531203027879.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/29_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227/images/image-20200531203027879.png" new file mode 100644 index 0000000000000000000000000000000000000000..c1a983835a25c54dbd51d65bc33983a09515778b Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/29_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\345\220\216\345\272\217\351\201\215\345\216\206\345\272\217\345\210\227/images/image-20200531203027879.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/2_\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/2_\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..1e0bcf1adc49760cfe3d29e428cac85336459b97 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/2_\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266/README.md" @@ -0,0 +1,94 @@ +# 青蛙跳台阶 + +## 题目 + +一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果) + +## 找规律 + +``` + + +``` + +![image-20200422221734432](images/image-20200422221734432.png) + +代码实现 + +``` +class Solution: + def JumpFloor(self, n): + if n == 0: + return 0; + if n == 1: + return 1; + if n == 2: + return 2; + + ret = 0 + a = 1 + b = 2 + for i in range(3, n + 1): + ret = a + b + a = b + b = ret + return ret + +if __name__ == '__main__': + print(Solution().JumpFloor(10)) +``` + + + +# 变态跳台阶 + +## 题目 + +一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 + +## 找规律 + +``` +当 n = 1 1 +当 n = 2 2 +当 n = 3 4 +当 n = 4 8 +当 n = n 2^(n-1) +``` + +通过找规律的方法解题: + +``` +class Solution: + def jumpFloorII(self, number): + return pow(2, number -1) +``` + +找出通项 + +``` +f(n) = f(n-1) + f(n-2) + ..... + f(1) +f(n-1) = f(n-2) + ..... + f(1) +# 我们结合上面的式子,移项可得 +f(n) = 2f(n-1),n > 1 +f(1) = 1 +``` + +解法 + +``` +class Solution: + def JumpFloorII(self, n): + if n == 1: + return 1; + ret = 0 + a = 1 + for i in range(2, n + 1): + ret = 2 * a + a = ret + return ret + +if __name__ == '__main__': + print(Solution().JumpFloorII(10)) +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/2_\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266/images/image-20200422221734432.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/2_\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266/images/image-20200422221734432.png" new file mode 100644 index 0000000000000000000000000000000000000000..613de8973f1822088ed62e767dd0c4e09b7cdbfd Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/2_\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266/images/image-20200422221734432.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/30_\344\272\214\345\217\211\346\240\221\344\270\255\345\222\214\344\270\272\346\237\220\344\270\200\345\200\274\347\232\204\350\267\257\345\276\204/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/30_\344\272\214\345\217\211\346\240\221\344\270\255\345\222\214\344\270\272\346\237\220\344\270\200\345\200\274\347\232\204\350\267\257\345\276\204/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..75b86193ebf91d41b259a4539e90f17fd81f2454 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/30_\344\272\214\345\217\211\346\240\221\344\270\255\345\222\214\344\270\272\346\237\220\344\270\200\345\200\274\347\232\204\350\267\257\345\276\204/README.md" @@ -0,0 +1,59 @@ +# 二叉树中和为某一值的路径 + +https://www.nowcoder.com/practice/b736e784e3e34731af99065031301bca + +## 描述 + +输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。 + +## 思考 + +假设现在我们需要找出和为23的路径,那么就需要采用广度优先搜索进行遍历,层层进行叠加,最后找到叶子节点 + +![image-20200531205621259](images/image-20200531205621259.png) + +## 代码 + +``` +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None + +import copy +class Solution: + # 返回二维列表,内部每个列表表示找到的路径 + def FindPath(self, root, expectNumber): + if root == None: + return None + ret = [] + # 用于存放路径 + supportArrayList = [[root.val]] + # 存放中间节点,把root节点放入 + support = [root] + # 广度优先遍历 + while support: + temp = support[0] + tempArrayList = supportArrayList[0] + # 判断是否是叶子节点 + if temp.left == None and temp.right == None: + # 判断路径中的值,是否等于expectNum,往该条数组中插入 + if sum(tempArrayList) == expectNumber: + ret.insert(0, tempArrayList) + + if temp.left: + support.append(temp.left) + newTempArrayList = copy.copy(tempArrayList) + newTempArrayList.append(temp.left.val) + supportArrayList.append(newTempArrayList) + if temp.right: + support.append(temp.right) + newTempArrayList = copy.copy(tempArrayList) + newTempArrayList.append(temp.right.val) + supportArrayList.append(newTempArrayList) + + del support[0] + del tempArrayList[0] + return ret +``` \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/30_\344\272\214\345\217\211\346\240\221\344\270\255\345\222\214\344\270\272\346\237\220\344\270\200\345\200\274\347\232\204\350\267\257\345\276\204/images/image-20200531205621259.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/30_\344\272\214\345\217\211\346\240\221\344\270\255\345\222\214\344\270\272\346\237\220\344\270\200\345\200\274\347\232\204\350\267\257\345\276\204/images/image-20200531205621259.png" new file mode 100644 index 0000000000000000000000000000000000000000..1f69d004a2c725f718c7d89618ff0b780be374ae Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/30_\344\272\214\345\217\211\346\240\221\344\270\255\345\222\214\344\270\272\346\237\220\344\270\200\345\200\274\347\232\204\350\267\257\345\276\204/images/image-20200531205621259.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/31_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\216\345\217\214\345\220\221\351\223\276\350\241\250/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/31_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\216\345\217\214\345\220\221\351\223\276\350\241\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..8b566a61d46ace34199e2e02bade0fd149ac6c0f --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/31_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\344\270\216\345\217\214\345\220\221\351\223\276\350\241\250/README.md" @@ -0,0 +1,43 @@ +# 二叉搜索树与双向链表 + +https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5 + +## 题目描述 + +输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 + +## 代码 + +``` +class Solution: + def Convert(self, pRootOfTree): + # write code here + if pRootOfTree == None: + return None + + def find_right(node): + while node.right: + node = node.right + return node + + leftNode = self.Convert(pRootOfTree.left) + rightNode = self.Convert(pRootOfTree.right) + + retNode = leftNode + + if leftNode: + leftNode = find_right(leftNode) + else: + retNode = pRootOfTree + + pRootOfTree.left = leftNode + pRootOfTree.right = rightNode + + if leftNode != None: + leftNode.right = pRootOfTree + if rightNode != None: + rightNode.left = pRootOfTree + + return retNode +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/32_\346\234\200\345\260\217\347\232\204K\344\270\252\346\225\260/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/32_\346\234\200\345\260\217\347\232\204K\344\270\252\346\225\260/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..2b82a109be97a73110e74f189ce165cd481bfbfe --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/32_\346\234\200\345\260\217\347\232\204K\344\270\252\346\225\260/README.md" @@ -0,0 +1,40 @@ +# 最小的K个数 + +https://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf + +## 描述 + +输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。 + +## 思考 + +最大堆和最小堆是二叉堆的两种形式。 + +最大堆:根结点的键值是所有堆结点键值中最大者,且每个结点的值都比其孩子的值大。 + +最小堆:根结点的键值是所有堆结点键值中最小者,且每个结点的值都比其孩子的值小 + +![image-20200531214512859](images/image-20200531214512859.png) + +## 代码 + +我们首先需要用一个长度为K的数组,来记录最小值,并且这个数组是排序的,首先需要初始化K数组的值,我们设置为最大,然后遍历每次查找的时候,需要从里面的数组进行比较,然后如果大小超过了K,那么把最大的数给剔除。 + +``` +class Solution: + def GetLeastNumbers_Solution(self, tinput, k): + array = [] + if k > len(tinput): + return array + for i in range(k): + array.append(1000000) + for key in tinput: + for index in range(len(array)): + if key < array[index]: + array.insert(index, key) + break + if len(array) > k: + del array[-1] + return array +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/32_\346\234\200\345\260\217\347\232\204K\344\270\252\346\225\260/images/image-20200531214512859.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/32_\346\234\200\345\260\217\347\232\204K\344\270\252\346\225\260/images/image-20200531214512859.png" new file mode 100644 index 0000000000000000000000000000000000000000..724f9bd5cb057d0870321e086ae2ddb139ec34da Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/32_\346\234\200\345\260\217\347\232\204K\344\270\252\346\225\260/images/image-20200531214512859.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/33_\346\225\260\346\215\256\346\265\201\344\270\255\347\232\204\344\270\255\344\275\215\346\225\260/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/33_\346\225\260\346\215\256\346\265\201\344\270\255\347\232\204\344\270\255\344\275\215\346\225\260/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..99179de5649ff9e6f2a049e113673a19e4b903db --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/33_\346\225\260\346\215\256\346\265\201\344\270\255\347\232\204\344\270\255\344\275\215\346\225\260/README.md" @@ -0,0 +1,195 @@ +# 数据流中的中位数 + +https://www.nowcoder.com/practice/9be0172896bd43948f8a32fb954e1be1 + +## 题目 + +如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。 + +## 思路 + +我们需要维护一个最大堆和最小堆 + +![image-20200606091334301](images/image-20200606091334301.png) + +## 代码 + +```python +# 未封装版本 +class Solution: + def __init__(self): + self.littleValueMaxHeap = [] + self.bigValueMinHeap = [] + self.maxHeapCount = 0 + self.minHeapCount = 0 + + def createMaxHeap(self, num): + self.littleValueMaxHeap.append(num) + tmpIndex = len(self.littleValueMaxHeap) - 1 + while tmpIndex != 0: + parentIndex = (tmpIndex - 1) >> 1 + if self.littleValueMaxHeap[parentIndex] < self.littleValueMaxHeap[tmpIndex]: + self.littleValueMaxHeap[parentIndex], self.littleValueMaxHeap[tmpIndex] = self.littleValueMaxHeap[tmpIndex], self.littleValueMaxHeap[parentIndex] + tmpIndex = parentIndex + else: + break + + def adjustMaxHeap(self, num): + if num < self.littleValueMaxHeap[0]: + self.littleValueMaxHeap[0] = num + maxHeapLen = len(self.littleValueMaxHeap) + tmpIndex = 0 + while tmpIndex < maxHeapLen: + leftIndex = tmpIndex * 2 + 1 + rightIndex = tmpIndex *2 + 2 + if rightIndex < maxHeapLen: + largerIndex = rightIndex if self.littleValueMaxHeap[leftIndex] < self.littleValueMaxHeap[rightIndex] else leftIndex + elif leftIndex < maxHeapLen: + largerIndex = leftIndex + else: + break + if self.littleValueMaxHeap[tmpIndex] < self.littleValueMaxHeap[largerIndex]: + self.littleValueMaxHeap[tmpIndex], self.littleValueMaxHeap[largerIndex] = self.littleValueMaxHeap[largerIndex], self.littleValueMaxHeap[tmpIndex] + tmpIndex = largerIndex + else: + break + + def createMinHeap(self, num): + self.bigValueMinHeap.append(num) + tmpIndex = len(self.bigValueMinHeap) - 1 + while tmpIndex != 0: + parentIndex = (tmpIndex - 1) >> 1 + if self.bigValueMinHeap[tmpIndex] < self.bigValueMinHeap[parentIndex]: + self.bigValueMinHeap[parentIndex], self.bigValueMinHeap[tmpIndex] = self.bigValueMinHeap[tmpIndex], self.bigValueMinHeap[parentIndex] + tmpIndex = parentIndex + else: + break + + def adjustMinHeap(self, num): + if num < self.bigValueMinHeap[0]: + self.littleValueMaxHeap[0] = num + minHeapLen = len(self.bigValueMinHeap) + tmpIndex = 0 + while tmpIndex < minHeapLen: + leftIndex = tmpIndex * 2 + 1 + rightIndex = tmpIndex *2 + 2 + if rightIndex < minHeapLen: + smallerIndex = rightIndex if self.bigValueMinHeap[rightIndex] < self.bigValueMinHeap[leftIndex] else leftIndex + elif leftIndex < minHeapLen: + smallerIndex = leftIndex + else: + break + if self.bigValueMinHeap[smallerIndex] < self.bigValueMinHeap[tmpIndex]: + self.bigValueMinHeap[tmpIndex], self.bigValueMinHeap[smallerIndex] = self.bigValueMinHeap[smallerIndex], self.bigValueMinHeap[tmpIndex] + tmpIndex = smallerIndex + else: + break + + def Insert(self, num): + if self.minHeapCount < self.maxHeapCount: + self.minHeapCount += 1 + if num < self.littleValueMaxHeap[0]: + tmpNum = self.littleValueMaxHeap[0] + self.adjustMaxHeap(num) + self.createMinHeap(tmpNum) + else: + self.createMinHeap(num) + else: + self.maxHeapCount += 1 + if self.littleValueMaxHeap == []: + self.createMaxHeap(num) + else: + if self.bigValueMinHeap[0] < num: + tmpNum = self.bigValueMinHeap[0] + self.adjustMinHeap(num) + self.createMaxHeap(tmpNum) + else: + self.createMaxHeap(num) + + + def GetMedian(self): + if self.minHeapCount < self.maxHeapCount: + return self.littleValueMaxHeap[0] + else: + return (self.bigValueMinHeap[0] + self.littleValueMaxHeap[0]) / 2 + +# 封装版本 +class Solution: + def __init__(self): + self.littleValueMaxHeap = [] + self.bigValueMinHeap = [] + self.maxHeapCount = 0 + self.minHeapCount = 0 + + def createHeap(self, num, heap, cmpFunc): + heap.append(num) + tmpIndex = len(heap) - 1 + while tmpIndex != 0: + parentIndex = (tmpIndex - 1) >> 1 + if cmpFunc(heap[tmpIndex], heap[parentIndex]): + heap[parentIndex], heap[tmpIndex] = heap[tmpIndex], heap[parentIndex] + tmpIndex = parentIndex + else: + break + + def adjustHeap(self, num, heap, cmpFunc): + if num < heap[0]: + heap[0] = num + heapLen = len(heap) + tmpIndex = 0 + while tmpIndex < heapLen: + leftIndex = tmpIndex * 2 + 1 + rightIndex = tmpIndex *2 + 2 + if rightIndex < heapLen: + largerIndex = rightIndex if cmpFunc(heap[rightIndex], heap[leftIndex]) else leftIndex + elif leftIndex < heapLen: + largerIndex = leftIndex + else: + break + if cmpFunc(heap[largerIndex], heap[tmpIndex]): + heap[tmpIndex], heap[largerIndex] = heap[largerIndex], heap[tmpIndex] + tmpIndex = largerIndex + else: + break + + def Insert(self, num): + def cmpMaxHeap(a, b): + return b < a + + def cmpMinHeap(a, b): + return a < b + + if self.minHeapCount < self.maxHeapCount: + self.minHeapCount += 1 + if num < self.littleValueMaxHeap[0]: + tmpNum = self.littleValueMaxHeap[0] + self.adjustHeap(num, self.littleValueMaxHeap, cmpMaxHeap) + self.createHeap(tmpNum, self.bigValueMinHeap, cmpMinHeap) + else: + self.createHeap(num, self.bigValueMinHeap, cmpMinHeap) + else: + self.maxHeapCount += 1 + if self.littleValueMaxHeap == []: + self.createHeap(num, self.littleValueMaxHeap, cmpMaxHeap) + else: + if self.bigValueMinHeap[0] < num: + tmpNum = self.bigValueMinHeap[0] + self.adjustHeap(num, self.bigValueMinHeap, cmpMinHeap) + self.createHeap(tmpNum, self.littleValueMaxHeap, cmpMaxHeap) + else: + self.createHeap(num, self.littleValueMaxHeap, cmpMaxHeap) + + def GetMedian(self): + if self.minHeapCount < self.maxHeapCount: + return self.littleValueMaxHeap[0] + else: + return (self.bigValueMinHeap[0] + self.littleValueMaxHeap[0]) / 2 + + +if __name__ == '__main__': + s = Solution() + for i in [5,2,3,4,1,6,7,0,8]: + s.Insert(i) + print(s.GetMedian()) +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/33_\346\225\260\346\215\256\346\265\201\344\270\255\347\232\204\344\270\255\344\275\215\346\225\260/images/image-20200606091334301.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/33_\346\225\260\346\215\256\346\265\201\344\270\255\347\232\204\344\270\255\344\275\215\346\225\260/images/image-20200606091334301.png" new file mode 100644 index 0000000000000000000000000000000000000000..9956d52cfe485b7871b825f55306893d65c0b38e Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/33_\346\225\260\346\215\256\346\265\201\344\270\255\347\232\204\344\270\255\344\275\215\346\225\260/images/image-20200606091334301.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/34_\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\350\212\202\347\202\271/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/34_\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\350\212\202\347\202\271/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..6f15d465becfa508982c77061584a681819b6a4e --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/34_\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\350\212\202\347\202\271/README.md" @@ -0,0 +1,47 @@ +# 二叉树的下一个节点 + +## 来源 + +https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e + +## 描述 + +给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 + +## 步骤 + +- 寻找右子树,如果存在就一直找右子树的最左边就是下一个节点 +- 没有右子树,就寻找它的父节点,一直找到它是父节点的左子树,打印父节点 + +![image-20200616211510448](images/image-20200616211510448.png) + +## 代码 + +``` +class TreeLinkNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None + self.next = None + +class Solution: + def GetNext(self, pNode): + # 1.寻找右子树,如果存在就一直找到右子树的最左边,就是下一个节点 + # 2.没有右子树,就寻找他的父节点,一直找到它是父节点的左子树,打印父节点 + if pNode.right: + tmpNode = pNode.right + while tmpNode.left: + tmpNode = tmpNode.left + return tmpNode + else: + tmpNode = pNode + while tmpNode.next: + if tmpNode.next.left == tmpNode: + return tmpNode.next + tmpNode = tmpNode.next + return None +``` + + + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/34_\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\350\212\202\347\202\271/images/image-20200616211510448.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/34_\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\350\212\202\347\202\271/images/image-20200616211510448.png" new file mode 100644 index 0000000000000000000000000000000000000000..48d9bd83fe915f41a9642b7cf6bad7c151082fd1 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/34_\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\350\212\202\347\202\271/images/image-20200616211510448.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/35_\345\257\271\347\247\260\347\232\204\344\272\214\345\217\211\346\240\221/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/35_\345\257\271\347\247\260\347\232\204\344\272\214\345\217\211\346\240\221/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..44f5c0953c8d63a3701fa0e7c4a1d41510b96eac --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/35_\345\257\271\347\247\260\347\232\204\344\272\214\345\217\211\346\240\221/README.md" @@ -0,0 +1,42 @@ +# 对称的二叉树 + +## 来源 + +https://www.nowcoder.com/practice/ff05d44dfdb04e1d83bdbdab320efbcb + +## 描述 + +请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。 + +## 思路 + +之前我们做过一道题目,就是二叉树的镜像,那么判断对称二叉树,就变成了二叉树和它的镜像是否相同 + +## 代码 + +``` +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + def isSymmetrical(self, pRoot): + + if pRoot == None: + return True + + def isMirror(left, right): + if left == None and right == None: + return True + elif left == None or right == None: + return False + if left.val != right.val: + return False + ret1 = isMirror(left.left, right.right) + ret2 = isMirror(left.right, right.left) + return ret1 and ret2 + + return isMirror(pRoot.left, pRoot.right) +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/36_\346\214\211\344\271\213\345\255\227\345\275\242\351\241\272\345\272\217\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/36_\346\214\211\344\271\213\345\255\227\345\275\242\351\241\272\345\272\217\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..1535a6cee9fec055d248992aaec1f203b72f299d --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/36_\346\214\211\344\271\213\345\255\227\345\275\242\351\241\272\345\272\217\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221/README.md" @@ -0,0 +1,64 @@ +# 按之字形顺序打印二叉树 + +## 来源 + +https://www.nowcoder.com/practice/91b69814117f4e8097390d107d2efbe0 + +## 描述 + +请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。 + +## 思路 + +我们使用到了两个数组,用于保留每一行的结果,同时两个数组交替进行存储,最后通过ret数组来记录输出值 + +![image-20200624203223700](images/image-20200624203223700.png) + +## 代码 + +``` +# 按之字形顺序打印二叉树 +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + def Print(self, pRoot): + if pRoot == None: + return [] + # write code here + stack1 = [pRoot] + stack2 = [] + # 存储打印 + ret = [] + # 当1和2中有空时 + while stack1 or stack2: + if stack1: + tmpRet = [] + while stack1: + # 取出stack1中的一个节点 + tmpNode = stack1.pop() + tmpRet.append(tmpNode.val) + # 把左右子树放到stack2中 + if tmpNode.left: + stack2.append(tmpNode.left) + if tmpNode.right: + stack2.append(tmpNode.right) + ret.append(tmpRet) + + if stack2: + tmpRet = [] + while stack2: + # 取出stack1中的一个节点 + tmpNode = stack2.pop() + tmpRet.append(tmpNode.val) + # 把左右子树放到stack2中 + if tmpNode.right: + stack1.append(tmpNode.right) + if tmpNode.left: + stack1.append(tmpNode.left) + ret.append(tmpRet) + return ret +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/36_\346\214\211\344\271\213\345\255\227\345\275\242\351\241\272\345\272\217\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221/images/image-20200624203223700.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/36_\346\214\211\344\271\213\345\255\227\345\275\242\351\241\272\345\272\217\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221/images/image-20200624203223700.png" new file mode 100644 index 0000000000000000000000000000000000000000..22dc289d33df70e62d46eeb4acfd2b09df8cede8 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/36_\346\214\211\344\271\213\345\255\227\345\275\242\351\241\272\345\272\217\346\211\223\345\215\260\344\272\214\345\217\211\346\240\221/images/image-20200624203223700.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/37_\346\212\212\344\272\214\345\217\211\346\240\221\346\211\223\345\215\260\346\210\220\345\244\232\350\241\214/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/37_\346\212\212\344\272\214\345\217\211\346\240\221\346\211\223\345\215\260\346\210\220\345\244\232\350\241\214/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..37ee4acbdff76e3bcae02d77d0dd1448fe9ac04e --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/37_\346\212\212\344\272\214\345\217\211\346\240\221\346\211\223\345\215\260\346\210\220\345\244\232\350\241\214/README.md" @@ -0,0 +1,54 @@ +# 把二叉树打印成多行 + +## 题目 + +https://www.nowcoder.com/practice/445c44d982d04483b04a54f298796288 + +## 描述 + +从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。 + +## 思路 + +本题的思路,和上一题是一样的,也是使用两个队列来进行存储,然后交替换行,需要注意的是,这里用的是队列,上一题之字形的用的是栈 + +## 代码 + +``` +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + # 返回二维列表[[1,2],[4,5]] + def Print(self, pRoot): + if pRoot == None: + return [] + queue1 = [pRoot] + queue2 = [] + ret = [] + while queue1 or queue2: + if queue1: + tmpRet = [] + while queue1: + tmpNode = queue1.pop(0) + tmpRet.append(tmpNode.val) + if tmpNode.left: + queue2.append(tmpNode.left) + if tmpNode.right: + queue2.append(tmpNode.right) + ret.append(tmpRet) + if queue2: + tmpRet = [] + while queue2: + tmpNode = queue2.pop(0) + tmpRet.append(tmpNode.val) + if tmpNode.left: + queue1.append(tmpNode.left) + if tmpNode.right: + queue1.append(tmpNode.right) + ret.append(tmpRet) + return ret +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/38_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\347\254\254K\344\270\252\350\212\202\347\202\271/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/38_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\347\254\254K\344\270\252\350\212\202\347\202\271/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..250a3bdfac9321be9433af59340698ad6299f290 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/38_\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\347\232\204\347\254\254K\344\270\252\350\212\202\347\202\271/README.md" @@ -0,0 +1,34 @@ +# 二叉搜索树的第K个节点 + +## 题目 + +https://www.nowcoder.com/practice/ef068f602dde4d28aab2b210e859150a + +## 描述 + +给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。 + +## 思考 + +首先需要知道,二叉排序树的中序遍历,即为有序的,所以我们查找第K小的节点,只需要将二叉树进行中序排列输出,那么取得 k-1个数,即为结果 + +## 代码 + +``` +class Solution: + # 返回对应节点TreeNode + def KthNode(self, pRoot, k): + retList = [] + def preOrder(pRoot): + if pRoot == None: + return None + preOrder(pRoot.left) + retList.append(pRoot) + preOrder(pRoot.right) + + preOrder(pRoot) + if len(retList) < k or k < 1: + return None + return retList[k-1] +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/39_\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\240\221/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/39_\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\240\221/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..51a3d7b5e3035925646d3394b35fc0b57a0beff9 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/39_\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\240\221/README.md" @@ -0,0 +1,58 @@ +# 序列化二叉树 + +## 题目 + +https://www.nowcoder.com/practice/cf7e25aa97c04cc1a68c8f040e71fb84 + +## 描述 + +请实现两个函数,分别用来序列化和反序列化二叉树 + +二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。 + +二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。 + +例如,我们可以把一个只有根节点为1的二叉树序列化为"1,",然后通过自己的函数来解析回这个二叉树 + +## 思考 + +![image-20200624222528995](images/image-20200624222528995.png) + +## 代码 + +``` +class Solution: + # 序列化 + def Serialize(self, root): + retList = [] + def preOrder(root): + if root == None: + # 找到为空的节点,插入 # + retList.append("#") + return + + # 否者插入该节点 + retList.append(str(root.val)) + preOrder(root.left) + preOrder(root.right) + preOrder(root) + return ' '.join(retList) + + # 反序列化 + def Deserialize(self, s): + retList = s.split(" ") + def dePreOrder(): + if retList == None: + return None + rootVal = retList.pop(0) + if rootVal == "#": + return None + node = TreeNode(int(rootVal)) + leftNode = dePreOrder() + rightNode = dePreOrder() + node.left = leftNode + node.right = rightNode + return node + return dePreOrder() +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/39_\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\240\221/images/image-20200624222528995.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/39_\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\240\221/images/image-20200624222528995.png" new file mode 100644 index 0000000000000000000000000000000000000000..6b6d064dc42472495c6cb541718beb0c022859c8 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/39_\345\272\217\345\210\227\345\214\226\344\272\214\345\217\211\346\240\221/images/image-20200624222528995.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/3_\346\211\276\345\207\272\344\270\221\346\225\260/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/3_\346\211\276\345\207\272\344\270\221\346\225\260/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..49f3c14af099b22dff9ad271f737a37d38ccdbfb --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/3_\346\211\276\345\207\272\344\270\221\346\225\260/README.md" @@ -0,0 +1,94 @@ +# 找出丑数 + +## 题目 + +把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。 + +## 思路1 + +死循环,找丑数判断一个数是不是丑数,先循环除以2,直到不能整除,循环除以3 直到不能整除,循环除以5 直到不能整除。这时如果剩余的值是1 我们就说它是丑数,其他情况就都不是丑数 + +```python +class Solution: + def GetUglyNumber_Solution(self, index): + # write code here + if index < 1: + return None + #死循环,找丑数 + #判断一个数是不是丑数,先循环除以2,直到不能整除, + #循环除以3 直到不能整除,循环除以5 直到不能整除 + #这时如果剩余的值是1 我们就说它是丑数 + #其他情况就都不是丑数 + def isUglyNumber(num): + while num % 2 == 0: + num = num //2 + while num % 3 == 0: + num = num //3 + while num % 5 == 0: + num = num //5 + if num == 1: + return True + else: + return False + count = 0 + num = 1 + while True: + if isUglyNumber(num): + count += 1 + if count == index: + return num + num += 1 +``` + +## 思路2 + +我们可以保存已经找到的丑数,然后 用空间环时间 来 找出丑数。 + +如何用空间换时间? + +我们找一种,只需要计算丑数的办法,根据上面丑数的定义,我们可以知道,丑数应该是另一个丑数 乘以 2,3,或者5 的结果(1除外)。因此我们 可以创建一个 列表,里面的数字是排好序的 丑数,每个丑数都是前面的丑数乘以2,3,或者5得到的。 + +那么我们就可以在一个列表中,给它第一个 丑数的值,然后根据 它 得到剩下的 丑数的值,第一个丑数为1,那么我们在这个列表的起始位置 设置三个指针,这三个指针代表的值 分别为2,3,5.又由于这个列表中的所有的丑数 是有序的,从小到大排列的,那么我们在每次 给一个丑数 乘以 2,3,5 以后要与前面的丑数比较大小,然后在根据大小值 来放入列表中。由于一开始第一个丑数是1,那么 1 * 2 得到的是2,1*3 得到的是3,1 乘以5 得到的是5,那么三个数中比较大小,最小的是 1 乘以2,那么 肯定第一个先放置的是2,然后是 2 乘以2 和 1乘3,1乘5 比较大小,最小的是3 那么就放置 3,下一个 是 2 乘以3 是6,6 与 5 和4 比较大小 最小的是4,以此类推,那么现在的到的丑数的顺序就是1,2,3,4.。。。。。 + +![image-20200527225225898](images/image-20200527225225898.png) + +代码如下 + +``` +class Solution(object): + def nthUglyNumber(self, index): + #首先判断 要找的 丑数 是不是第0个 或者是负数,如果是的话,那么就返回0 + if index <= 0: + return 0 + #然后判断要找的丑数 是不是第一个,如果是第一个,那么就返回1. + if index == 1: + return 1 + #在丑数 这个列表中 给出第一个丑数是1 + numbers = [1] + #在列表的 一开始 设置三个 指针,也就是 三个指针的 索引位置是0, + two, three, five = 0, 0, 0 + #丑数的个数 起始为 1 + count = 1 + #循环 当丑数的个数不等于我们要找到 那第 index 个 丑数时,就循环,等于的时候就跳出循环。 + while count != index : + #给列表中的 2,3,5 这三个指针所在位置的 丑数 分别 乘以2,3,5 + n2, n3, n5 = numbers[two] * 2, numbers[three] * 3, numbers[five] * 5 + #比较这三个丑数的大小 + minValue = min(n2, n3, n5) + #在丑数列表中,把三个中最小的那个 放进去。 + numbers.append(minValue) + #每放进去一个,丑数的数量就加1 + count += 1 + #这个是指针移位的,如果说我们比较出来的 三个数中最小的丑数是 2 指针的话,那么2 指针就往前移动一位 + if minValue == n2: + two += 1 + #如果是 3 那个指针的话,那么3 这个指针就移一位。 + if minValue == n3: + three += 1 + #如果是 5 那个指针的话,那么5这个指针就移一位。 + if minValue == n5: + five += 1 + #最后输出这个丑数列表中的 最后一位,那么就是我们的计数的丑数的个数 -1,就是最后一个丑数的索引值。 + return numbers[count-1] +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/3_\346\211\276\345\207\272\344\270\221\346\225\260/images/image-20200527225225898.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/3_\346\211\276\345\207\272\344\270\221\346\225\260/images/image-20200527225225898.png" new file mode 100644 index 0000000000000000000000000000000000000000..fad5c15adeb87e9adb43047db797aed3d0fde66a Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/3_\346\211\276\345\207\272\344\270\221\346\225\260/images/image-20200527225225898.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/40_\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/40_\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..0476d747126e58691a75e3a432733ee048fc05cd --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/40_\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/README.md" @@ -0,0 +1,50 @@ +# 连续子数组的最大和 + +## 题目 + +https://www.nowcoder.com/practice/459bd355da1549fa8a49e350bf3df484 + +## 描述 + +HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1) + +## 代码 + +时间复杂度:O(n^2) + +``` +class Solution: + def FindGreatestSumOfSubArray(self, array): + # write code here + maxSum = None + for i in range(len(array)): + sum = 0 + for j in range(i, len(array)): + sum += array[j] + if sum > maxSum: + maxSum = sum + return maxSum +``` + +## 代码2 + +时间复杂度:O(n) + +``` +class Solution: + def FindGreatestSumOfSubArray(self, array): + # write code here + maxNum = None + tmpNum = 0 + for i in array: + if maxNum == None: + maxNum = i + if tmpNum + i < i: + tmpNum = i + else: + tmpNum += i + if maxNum < tmpNum: + maxNum = tmpNum + return maxNum +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/41_\347\237\251\345\275\242\350\246\206\347\233\226/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/41_\347\237\251\345\275\242\350\246\206\347\233\226/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..686fa6f6de7b9ab038e14281cb84ed10139f808c --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/41_\347\237\251\345\275\242\350\246\206\347\233\226/README.md" @@ -0,0 +1,48 @@ +# 矩形覆盖 + +## 来源 + +https://www.nowcoder.com/practice/72a5a919508a4251859fb2cfb987a0e6 + +## 描述 + +我们可以用2 X 1 的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? + +比如n=3时,2*3的矩形块有3种覆盖方法: + +![image-20200625090357495](images/image-20200625090357495.png) + +## 思考 + +相当于转变成了斐波那契数列,得到通式 + +``` +f(n) = f(n-1) + f(n-2) + +n = 1: 1 +n = 2: 3 +``` + + + +## 代码 + +``` +class Solution: + def rectCover(self, number): + # write code here + if number == 0: + return 0 + if number == 1: + return 1 + if number == 2: + return 2 + + a = 1 + b = 2 + for i in range(3, number + 1): + b = a + b + a = b - a + return b +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/41_\347\237\251\345\275\242\350\246\206\347\233\226/images/image-20200625090357495.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/41_\347\237\251\345\275\242\350\246\206\347\233\226/images/image-20200625090357495.png" new file mode 100644 index 0000000000000000000000000000000000000000..a88075631e8804ef583f920ff985529882204e46 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/41_\347\237\251\345\275\242\350\246\206\347\233\226/images/image-20200625090357495.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/42_\346\216\222\345\272\217\347\256\227\346\263\225-\345\206\222\346\263\241\346\217\222\345\205\245\351\200\211\346\213\251/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/42_\346\216\222\345\272\217\347\256\227\346\263\225-\345\206\222\346\263\241\346\217\222\345\205\245\351\200\211\346\213\251/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..6d35141f1709f47e16e7fda6e9a23e1d876ca3c5 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/42_\346\216\222\345\272\217\347\256\227\346\263\225-\345\206\222\346\263\241\346\217\222\345\205\245\351\200\211\346\213\251/README.md" @@ -0,0 +1,59 @@ +# 排序算法-冒泡插入选择 + +## 冒泡排序 + +```python +# 冒泡排序 +class Solution: + def bubbleSort(self, array): + for i in range(len(array)): + flag = False + for j in range(len(array) - 1 - i): + if array[j] > array[j+1]: + temp = array[j+1] + array[j+1] = array[j] + array[j] = temp + flag = True + if not flag: + break + return array + +if __name__ == '__main__': + print(Solution().bubbleSort([1,5,4,3,2])) +``` + +## 选择排序 + +``` +# 插入排序 +class Solution: + def insertSort(self, array): + for i in range(len(array)): + minIndex = i + for j in range(i, len(array)): + if array[minIndex] > array[j]: + minIndex = j + temp = array[minIndex] + array[minIndex] = array[i] + array[i] = temp + return array +if __name__ == '__main__': + print(Solution().insertSort([1,8,3,2,6,9])) +``` + +## 插入排序 + +``` +# 插入排序 +class Solution: + def insertSort(self, alist): + n = len(alist) + for j in range(0, n): + for i in range(j, 0, -1): + if alist[i] < alist[i - 1]: + alist[i], alist[i - 1] = alist[i - 1], alist[i] + else: + break + return alist +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/43_\345\270\214\345\260\224\346\216\222\345\272\217/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/43_\345\270\214\345\260\224\346\216\222\345\272\217/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..f44eb1b096564b38d99af11dedda074591f43854 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/43_\345\270\214\345\260\224\346\216\222\345\272\217/README.md" @@ -0,0 +1,78 @@ +# 希尔排序 + +## 思想 + +希尔排序的是基于插入排序的基础上来做的,我们都知道插入排序需要比较的次数比较多,那么希尔排序就是利用的一个间隔,用于降低比较后,元素移动的次数。 + +[希尔排序的图解](http://moguit.cn/#/info?blogUid=51efadc72d2f4d66a412fd8ef1a30fdc) + +## Python 代码 + +``` +# 希尔排序 +class Solution: + def shellSort(self, arrlist): + arrayLen = len(arrlist) + h = 1 + # 工业界认定的求 增量的方法 + while h < arrayLen/3: + h = h*3 + 1 + # 插入排序的方法,判断是不是后面一个比前面的要小 + # 如果是则交换 + while h >= 1: + for i in range(h, arrayLen): + j = i + while j >= h and arrlist[j] < arrlist[j - h]: + arrlist[j], arrlist[j-h] = arrlist[j-h], arrlist[j] + j-=h + # 除以3 + h = h//3 + return arrlist + +if __name__ == '__main__': + print(Solution().shellSort([1,8,3,2,6,9])) +``` + +## Java代码 + +``` +package com.moxi.interview.study.nowCode; + +/** + * 希尔排序 + * + * @author: 陌溪 + * @create: 2020-06-25-10:43 + */ +public class ShellSort_1 { + public static int[] shellSort(int[] arrList) { + int arrLen = arrList.length; + int h = 1; + while (h > arrLen /3){ + h = h*3 + 1; + } + + while(h >=1) { + for (int i = h; i < arrLen; i++) { + int j = i; + while(j >=h && arrList[j] < arrList[j - h]) { + int temp = arrList[j]; + arrList[j] = arrList[j-h]; + arrList[j-h] = temp; + j -= h; + } + } + h /= 3; + } + return arrList; + } + public static void main(String[] args) { + int [] arrList = new int[]{1,8,3,2,6,9}; + int [] resultList = shellSort(arrList); + for (int a=0; a> 1 + # 递归左边部分 + sortedLeft = self.MergeSort(arrayList[:middleIndex]) + # 递归右边部分 + sortedRight = self.MergeSort(arrayList[middleIndex:]) + # 合并代码 + return self.MergeCore(sortedLeft, sortedRight) + + def MergeCore(self, leftList, rightList): + # leftIndex = 0 + # rightIndex = 0 + # # 由于多次用,length 我们自己保存 + # leftLen = len(leftList) + # rightLen = len(rightList) + retList = [] + + while leftList != [] and rightList != []: + leftValue = leftList[0] + rightValue = rightList[0] + if leftValue >= rightValue: + retList.append(rightValue) + del rightList[0] + else: + retList.append(leftValue) + del leftList[0] + + # 归并排序后,然后 + if leftList != []: + for i in leftList: + retList.append(i) + if rightList != []: + for i in rightList: + retList.append(i) + return retList + +if __name__ == '__main__': + print(Solution().MergeSort([1,8,7,5,4,2])) +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/44_\345\275\222\345\271\266\346\216\222\345\272\217/images/1551078679377.gif" "b/\346\225\260\346\215\256\347\273\223\346\236\204/44_\345\275\222\345\271\266\346\216\222\345\272\217/images/1551078679377.gif" new file mode 100644 index 0000000000000000000000000000000000000000..a29ca19d027d9a924c7cc0fa6c56e3165a3f6784 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/44_\345\275\222\345\271\266\346\216\222\345\272\217/images/1551078679377.gif" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/45_\345\277\253\351\200\237\346\216\222\345\272\217/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/45_\345\277\253\351\200\237\346\216\222\345\272\217/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..e6aae2ad6addb39d73b58d554fd936ff1697caae --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/45_\345\277\253\351\200\237\346\216\222\345\272\217/README.md" @@ -0,0 +1,58 @@ +# 快速排序 + +## 概念 + +快速排序也是分治的思想,但是它于归并算法更加好,是因为归并算法会用到辅助数组,其空间复杂度为O(n),而快速排序不需要用到新的数组空间,它的空间复杂度是O(1) + +快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下: + +- 从数列中挑出一个元素,称为 “基准”(**pivot**); +- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作; +- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。 + +![img](images/1551078742204.gif) + +## 代码 + +``` +def quick_sort(li, start, end): + # 分治 一分为二 + # start=end ,证明要处理的数据只有一个 + # start>end ,证明右边没有数据 + if start >= end: + return + # 定义两个游标,分别指向0和末尾位置 + left = start + right = end + # 把0位置的数据,认为是中间值 + mid = li[left] + while left < right: + # 让右边游标往左移动,目的是找到小于mid的值,放到left游标位置 + while left < right and li[right] >= mid: + right -= 1 + print("left 1", li) + li[left] = li[right] + print("left 2", li) + # 让左边游标往右移动,目的是找到大于mid的值,放到right游标位置 + while left < right and li[left] < mid: + left += 1 + li[right] = li[left] + print("right ", li) + # while结束后,把mid放到中间位置,left=right + li[left] = mid + # 递归处理左边的数据 + quick_sort(li, start, left-1) + # 递归处理右边的数据 + quick_sort(li, left+1, end) + +if __name__ == '__main__': + l = [1,5,4,6,2,8] + # l = 3 [2,1,5,6,5,4] + # [2, 1, 5, 6, 5, 4] + quick_sort(l,0,len(l)-1) + print(l) + # 稳定性:不稳定 + # 最优时间复杂度:O(nlogn) + # 最坏时间复杂度:O(n^2) +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/45_\345\277\253\351\200\237\346\216\222\345\272\217/images/1551078742204.gif" "b/\346\225\260\346\215\256\347\273\223\346\236\204/45_\345\277\253\351\200\237\346\216\222\345\272\217/images/1551078742204.gif" new file mode 100644 index 0000000000000000000000000000000000000000..ad88d35762a3747aa0de1db844ff128859734a77 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/45_\345\277\253\351\200\237\346\216\222\345\272\217/images/1551078742204.gif" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/4_\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/4_\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..c13092191081052f94ed0f55069e6e21983dd8a2 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/4_\344\272\214\347\273\264\346\225\260\347\273\204\344\270\255\347\232\204\346\237\245\346\211\276/README.md" @@ -0,0 +1,81 @@ +# 二维数组中的查找 + +## 题目描述 + +在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 + + + +## 暴力算法 + +下面是这样一个规律的二维数组 + +``` +1 2 3 4 +2 3 4 5 +4 6 7 10 +9 11 13 15 +``` + +我们对每个数字进行遍历 + +``` +class Solution: + def Find(self, target, array): + for i in range(len(array)): + for j in range(len(array)): + if target == array[i][j]: + return True + return False +``` + + + +## 标准解法 + +上面我们可以看到,题目是给定递增的顺序的,而我们使用暴力算法的时候,没有应用到它的有序的特征。 + +``` +1 2 3 4 +2 3 4 5 +4 6 7 10 +9 11 13 15 +``` + +我们在回到刚刚的规律这块,我们能够发现,给定一个 target,我们可以比较这个数的最后一列 + +``` +4 +5 +10 +15 +``` + +如果这个数在比 某一个数小,那么它肯定处于该行中,进行查找。例如我们现在要查找 `7` + +``` +首先比较的是 4,然后发现 4 < 7 ,因此肯定不在第一行 +然后比较 5 , 5 < 7,那么也不在第二行 +然后比较 10, 10 > 7,因此可能就在这一行,那么就开始在这一行进行遍历,最终找到了7 +``` + + + +代码为: + +``` +class Solution: + # array 二维列表 + def Find(self, target, array): + # 判断二维数组是否非空 + if any(array) == 0: + return False + for i in range(len(array)): + # 判断最后一位是否比target更大 + if array[i][len(array) - 1] >= target: + for j in range(len(array)): + if target == array[i][j]: + return True + return False +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/5_\346\233\277\346\215\242\347\251\272\346\240\274/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/5_\346\233\277\346\215\242\347\251\272\346\240\274/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..7fcc5aa03361a834b330ae3541bf1cc3cc73ef75 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/5_\346\233\277\346\215\242\347\251\272\346\240\274/README.md" @@ -0,0 +1,41 @@ +# 替换空格 + +## 题目描述 + +请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 + + + +## 调用方法实现 + +``` +class Solution: + # s 源字符串 + def replaceSpace(self, s): + return s.replace(' ', '%20') +``` + + + +## 自己写方法实现Replace + +我们将字符串存储在数组中,然后循环比较每个字符的值,当遇到空格的时候,替换即可 + +``` +class Solution: + def replaceSpace2(self, s): + strLen = len(s) + aaa = [] + for i in range(0, strLen): + if s[i] == " ": + aaa.append("%") + aaa.append("2") + aaa.append("0") + else: + aaa.append(s[i]) + return ''.join(aaa) + +if __name__ == '__main__': + print(Solution().replaceSpace2('We Are Happy')) +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/6_\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\344\270\200\344\270\252\351\230\237\345\210\227/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/6_\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\344\270\200\344\270\252\351\230\237\345\210\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..dfa697e6ae76e3c504e3a290c1275a54ac09a2bd --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/6_\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\344\270\200\344\270\252\351\230\237\345\210\227/README.md" @@ -0,0 +1,47 @@ +# 两个栈实现一个队列 + +## 题目描述 + +用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。 + + + +## 思考 + +栈:先进后出 + +队列:先进先出. + +![image-20200423094525763](images/image-20200423094525763.png) + +我们需要使用一个栈用于接收数据,并且一个栈用于输出数据 + + + +## 代码 + +``` +class Solution: + def __init__(self): + # 接收栈 + self.acceptStack = [] + # 输出栈 + self.outputStack = [] + + def push(self, node): + # 把节点放到栈中 + self.acceptStack.append(node) + + def pop(self): + # 从接收栈中获取元素,把它放入到 输出栈中 + if self.outputStack == []: + while self.acceptStack: + self.outputStack.append(self.acceptStack.pop()) + + # 判断输出栈中是否有元素,有,则输出最后一个 + if self.outputStack != []: + return self.outputStack.pop() + else: + return None +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/6_\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\344\270\200\344\270\252\351\230\237\345\210\227/images/image-20200423094525763.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/6_\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\344\270\200\344\270\252\351\230\237\345\210\227/images/image-20200423094525763.png" new file mode 100644 index 0000000000000000000000000000000000000000..da10cfd5797ada8d6a5d9243001c862217c3280a Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/6_\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\344\270\200\344\270\252\351\230\237\345\210\227/images/image-20200423094525763.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/7_\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/7_\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..9a23876aff08eacd21ad9dca2bf1e7f6dbdbe6fd --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/7_\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227/README.md" @@ -0,0 +1,101 @@ +# 旋转数组的最小数字 + +## 题目描述 + +来源:https://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba + +把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。 + +## 暴力破解 + +第一种方法就是遍历全部的元素,然后找出最小的,时间复杂度为:`O(n)` + +``` +class Solution: + def minNumberInRotateArray(self, rotateArray): + minNum = 0 + # 第一种方法,就是遍历所以的元素,找出最小的 + for i in range(0, len(rotateArray)): + minNum = minNum if minNum < rotateArray[i] and minNum != 0 else rotateArray[i] + return minNum +``` + + + +## 方式2 + +上面的暴力破解方法,没有用到题目的特性,就是非递减排序的数组,这个时候我们就可以使用二分查找法,来找出最小的元素。 + +![image-20200423120520734](images/image-20200423120520734.png) + +首先这个数组局部有序的,假设我们查询一个数,如找出最小是1 + +``` +第一次比较的数为: 5,通过 3 < 5, 2 < 5, |5 - 3| < |5 - 2| ,所以从右边找 +第二次比较: 5 > 1, 2 > 1,这个时候,它两边的数都比它小,说明它就是最小值。 +``` + +![image-20200423121048934](images/image-20200423121048934.png) + +这个时候,我们就需要将原来的 二分查找法变换一下 + +``` +|a[middle] - left| < |a[middle] - right| +如果成立,就往右边查找 +如果不成立,那就左边查找 + +如果 middle < left,middle < right时,那么就说明这个数是最小值 +即比两边的数都更小 +``` + +给定一个二分查找法的代码 + +``` +class Solution: + + # 二分查找法 + # 有序的数组中使用 + def bSearch(self, array, target): + left = 0 + right = len(array) - 1 + while left < right: + # 右移1位,相当于除以2 + mid = (left + right) >> 1 + if target == mid: + return mid + if target > mid: + left = mid + 1 + else: + right = mid - 1 + return None + +if __name__ == '__main__': + print(Solution().bSearch([1,2,3,4,5,6,7,8,9,10], 8)) +``` + +下面我们需要改进一下代码,让其能够找出我们的最小值。 + +``` +# -*- coding:utf-8 -*- +class Solution: + # 二分查找法 + # 有序的数组中使用 + def minNumberInRotateArray(self, rotateArray): + if not rotateArray: + return None + left = 0 + right = len(rotateArray) - 1 + while left <= right: + middle = (left + right) >> 1 + # middle 比两边的都小,说明是最小值 + if rotateArray[middle] < rotateArray[middle - 1]: + return rotateArray[middle] + elif rotateArray[middle] < rotateArray[right]: + right = middle - 1 + else: + left = middle + 1 + return 0 +``` + + + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/7_\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227/images/image-20200423120520734.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/7_\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227/images/image-20200423120520734.png" new file mode 100644 index 0000000000000000000000000000000000000000..87dfbbefa76d79ed56b8d7f20591c4b29e261f7c Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/7_\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227/images/image-20200423120520734.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/7_\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227/images/image-20200423121048934.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/7_\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227/images/image-20200423121048934.png" new file mode 100644 index 0000000000000000000000000000000000000000..765056930da5e80ef89d4ae2b8d5eadfd9901321 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/7_\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227/images/image-20200423121048934.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/8_\350\260\203\346\225\264\346\225\260\347\273\204\351\241\272\345\272\217\344\275\277\345\245\207\346\225\260\344\275\215\344\272\216\345\201\266\346\225\260\345\211\215\351\235\242/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/8_\350\260\203\346\225\264\346\225\260\347\273\204\351\241\272\345\272\217\344\275\277\345\245\207\346\225\260\344\275\215\344\272\216\345\201\266\346\225\260\345\211\215\351\235\242/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..6acc6fc859563d758e442777ea1d688a760b9298 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/8_\350\260\203\346\225\264\346\225\260\347\273\204\351\241\272\345\272\217\344\275\277\345\245\207\346\225\260\344\275\215\344\272\216\345\201\266\346\225\260\345\211\215\351\235\242/README.md" @@ -0,0 +1,36 @@ +# 调整数组顺序使奇数位于偶数前面 + +## 题目描述 + +来源:https://www.nowcoder.com/practice/beb5aa231adc45b2a5dcc5b62c93f593 + +输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。 + +## 思考 + +我们要做的就是下面的这种效果,把奇数提取出来,放在一个数组中,然后在把偶数放在另外一个数组中,最后将两个数组合并 + +![image-20200424093736886](images/image-20200424093736886.png) + +## 代码 + +``` +# 调整数组顺序使奇数位于偶数前面 +# 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分, +# 所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变 +class Solution: + def reOrderArray(self, array): + ret = [] + ret2 = [] + for i in range(0, len(array)): + # 判断是否偶数 + if array[i] % 2 == 0: + ret2.append(array[i]) + else: + ret.append(array[i]) + return ret + ret2 +if __name__ == '__main__': + print(Solution().reOrderArray([3,4,5,2,3,6,7,8])) +``` + +假设不用辅助数组来排序 \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/8_\350\260\203\346\225\264\346\225\260\347\273\204\351\241\272\345\272\217\344\275\277\345\245\207\346\225\260\344\275\215\344\272\216\345\201\266\346\225\260\345\211\215\351\235\242/images/image-20200424093736886.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/8_\350\260\203\346\225\264\346\225\260\347\273\204\351\241\272\345\272\217\344\275\277\345\245\207\346\225\260\344\275\215\344\272\216\345\201\266\346\225\260\345\211\215\351\235\242/images/image-20200424093736886.png" new file mode 100644 index 0000000000000000000000000000000000000000..fbce09015fdc77651a67ed957a635c41299396a5 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/8_\350\260\203\346\225\264\346\225\260\347\273\204\351\241\272\345\272\217\344\275\277\345\245\207\346\225\260\344\275\215\344\272\216\345\201\266\346\225\260\345\211\215\351\235\242/images/image-20200424093736886.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/9_\345\214\205\345\220\253min\345\207\275\346\225\260\347\232\204\346\240\210/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/9_\345\214\205\345\220\253min\345\207\275\346\225\260\347\232\204\346\240\210/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..acdd6e63c1918ff7165ac2ae2eb7a13ed9234c46 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/9_\345\214\205\345\220\253min\345\207\275\346\225\260\347\232\204\346\240\210/README.md" @@ -0,0 +1,79 @@ +# 包含min函数的栈 + +## 题目描述 + +定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。 + +注意:保证测试中不会当栈为空的时候,对栈调用pop()或者min()或者top()方法。 + +## 思路 + +我们需要维护一个最小值的数组,这个数组存储每次push元素时候的最小值 + +``` + # 压栈 + def push(self, node): + self.stack.append(node) + + # 维护当前最小的数组 + if self.minValue: + if self.minValue[-1] > node: + self.minValue.append(node) + else: + self.minValue.append(self.minValue[-1]) + else: + self.minValue.append(node) +``` + +从上面的代码能看出,我们只需要比较 当前 最小值数组的,最小值和当前插入值比较,如果比最小值比当前的小,那么就还是插入本身,否则插入的是我们新的节点。 + +![image-20200424101759236](images/image-20200424101759236.png) + + + +## 代码 + +``` +# 包含min函数的栈 +# 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。 +# 注意:保证测试中不会当栈为空的时候,对栈调用pop()或者min()或者top()方法。 +class Solution: + + # 初始化 + def __init__(self): + self.stack = [] + # 存储最小元素 + self.minValue = [] + + # 压栈 + def push(self, node): + self.stack.append(node) + + # 维护当前最小的数组 + if self.minValue: + if self.minValue[-1] > node: + self.minValue.append(node) + else: + self.minValue.append(self.minValue[-1]) + else: + self.minValue.append(node) + + # 出栈 + def pop(self): + if self.stack == []: + return None + self.minValue.pop() + return self.stack.pop() + + # 获取栈顶 + def top(self): + if self.stack == []: + return None + return self.stack[-1] + + def min(self): + if self.minValue == []: + return None + return self.minValue[-1] +``` + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/9_\345\214\205\345\220\253min\345\207\275\346\225\260\347\232\204\346\240\210/images/image-20200424101759236.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/9_\345\214\205\345\220\253min\345\207\275\346\225\260\347\232\204\346\240\210/images/image-20200424101759236.png" new file mode 100644 index 0000000000000000000000000000000000000000..8c3d5889c63d2aaca13c46dc3312def6f2da5e13 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/9_\345\214\205\345\220\253min\345\207\275\346\225\260\347\232\204\346\240\210/images/image-20200424101759236.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/KMP\347\256\227\346\263\225/README.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/KMP\347\256\227\346\263\225/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..3bccfe986e88a83865239e5733cdd70d228f81e1 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/KMP\347\256\227\346\263\225/README.md" @@ -0,0 +1,19 @@ +# KMP算法 + +## 字符串匹配问题 + +字符串匹配问题场景 + +- 有一个字符串str1 = "abcdefg" 和 str2 = "def" +- 现在要判断str1 是否含有str2,如果存在,就返回第一次出现的位置,如果没有,则返回-1 + + + +### 暴力匹配算法 + +如果用暴力匹配的思路,并假设现在str1 匹配到i位置,字符串str2匹配到j位置,则有: + +- 如果当前字符串匹配成功(即 str1[i] == str2[j]) , 则 i++,j++,继续匹配下一个字符 +- 如果匹配失败(即 str1[i] != str2[j]),令 i = i - ( j - 1),j = 0。相当于每次匹配失败时,i回溯,j被置为0. +- 用暴力方法解决的话,就会有大量的回溯,每次只移动一位,若匹配不成功,移动到下一位接着判断,浪费了大量的时间。 +- \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/.gitignore" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/.gitignore" new file mode 100644 index 0000000000000000000000000000000000000000..0e40fe8f57160b43f9ea8e200b1a5d9f91f4aed9 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/.gitignore" @@ -0,0 +1,3 @@ + +# Default ignored files +/workspace.xml \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/NowCode.iml" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/NowCode.iml" new file mode 100644 index 0000000000000000000000000000000000000000..f3d7bc9c9d036a32dfe9c30113dafdf14174715b --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/NowCode.iml" @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/inspectionProfiles/profiles_settings.xml" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/inspectionProfiles/profiles_settings.xml" new file mode 100644 index 0000000000000000000000000000000000000000..105ce2da2d6447d11dfe32bfb846c3d5b199fc99 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/inspectionProfiles/profiles_settings.xml" @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/misc.xml" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/misc.xml" new file mode 100644 index 0000000000000000000000000000000000000000..865611434f0cce78ec2223c6c4d52a717e8ec1c1 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/misc.xml" @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/modules.xml" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/modules.xml" new file mode 100644 index 0000000000000000000000000000000000000000..cea95e260eb9e3d032968667ed4ac46a3ba6ec0e --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/modules.xml" @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/vcs.xml" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/vcs.xml" new file mode 100644 index 0000000000000000000000000000000000000000..b2bdec2d71b6a5ce4ae49efc37516809c50e4d5e --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/.idea/vcs.xml" @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/10_IsPopOrder.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/10_IsPopOrder.py" new file mode 100644 index 0000000000000000000000000000000000000000..fbc24b51387fbc0c726904d5e6703f596d110ad9 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/10_IsPopOrder.py" @@ -0,0 +1,24 @@ +# 栈的压入弹出 +# 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。 +# 假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序, +# 序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的) +class Solution: + + def IsPopOrder(self, pushV, popV): + # 首先我们需要有一个栈 + if pushV == [] or len(pushV) != len(popV): + return None + stack = [] + index = 0 + for item in pushV: + # 压栈 + stack.append(item) + # 判断是否需要弹出,也就是插入的值,等于popV的第一个。这里需要循环判断 + while stack != [] and stack[-1] == popV[index]: + stack.pop() + index += 1 + # 判断 stack 中是否有元素,如果有,代表着False + return len(stack) == 0 + +if __name__ == '__main__': + print(Solution().IsPopOrder([1,2,3,4,5],[4,5,3,2,1])) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/11_PrintListFromTailToHead.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/11_PrintListFromTailToHead.py" new file mode 100644 index 0000000000000000000000000000000000000000..7022c06f8d43d5c3c5176308f9ab5efd2575229b --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/11_PrintListFromTailToHead.py" @@ -0,0 +1,33 @@ +# 从头到尾打印链表 +# 输入一个链表,按链表从尾到头的顺序返回一个ArrayList。 + +# 链表结构 +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +# 打印链表 +def printChain(head): + node = head + while node: + print(node.val) + node = node.next + +class Solution: + # 返回从尾部到头部的列表值序列,例如[1,2,3] + def printListFromTailToHead(self, listNode): + node = listNode + list = [] + while node: + list.insert(0, node.val) + node = node.next + return list +if __name__ == '__main__': + # 创建链表 + l1 = ListNode(1) + l2 = ListNode(2) + l3 = ListNode(3) + l1.next = l2 + l2.next = l3 + Solution().printListFromTailToHead(l1) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/12_FindKthToTail.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/12_FindKthToTail.py" new file mode 100644 index 0000000000000000000000000000000000000000..417fc976e5fb277b2cbdaf4bddd58babbd7ec570 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/12_FindKthToTail.py" @@ -0,0 +1,63 @@ +# 链表中倒数第K个节点 +# 输入一个链表,输出该链表中倒数第k个结点。 + +# 链表结构 +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +# 打印链表 +def printChain(head): + node = head + while node: + print(node.val) + node = node.next + +class Solution: + def FindKthToTail(self, head, k): + if k <= 0 or head == []: + return None + node = head + list = [] + while node: + list.append(node) + node = node.next + # K比链表长度大 + if k > len(list): + return None + return list[len(list) - k] + + + def FindKthToTail2(self, head, k): + if k <= 0 or head == []: + return None + list = [] + first = head + second = head + # 先让第一个节点走 K步 + for i in range(0, k): + if first == None: + return None + first = first.next + + # 然后两个节点在继续走,当first走到头的时候,second就是倒数第K个节点 + while first: + first = first.next + second = second.next + return second + +if __name__ == '__main__': + # 创建链表 + l1 = ListNode(1) + l2 = ListNode(2) + l3 = ListNode(3) + l4 = ListNode(4) + l5 = ListNode(5) + + l1.next = l2 + l2.next = l3 + l3.next = l4 + l4.next = l5 + + print(Solution().FindKthToTail2(l1, 1)) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/13_ReverseList.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/13_ReverseList.py" new file mode 100644 index 0000000000000000000000000000000000000000..60e74bcdc55588d426ab312e0951edefd81ebe2d --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/13_ReverseList.py" @@ -0,0 +1,53 @@ +# 反转链表 +# 输入一个链表,反转链表后,输出新链表的表头。 + +# 链表结构 +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +# 打印链表 +def printChain(head): + node = head + while node: + print(node.val) + node = node.next + +class Solution: + def ReverseList(self, pHead): + if pHead == None: + return None + if pHead.next == None: + return pHead + + leftPointer = pHead + middlePointer = pHead.next + rightPointer = pHead.next.next + leftPointer.next = None + + while rightPointer != None: + middlePointer.next = leftPointer + + leftPointer = middlePointer + middlePointer = rightPointer + rightPointer = rightPointer.next + + middlePointer.next = leftPointer + + return middlePointer + +if __name__ == '__main__': + # 创建链表 + l1 = ListNode(1) + l2 = ListNode(2) + l3 = ListNode(3) + l4 = ListNode(4) + l5 = ListNode(5) + + l1.next = l2 + l2.next = l3 + l3.next = l4 + l4.next = l5 + + print(Solution().ReverseList(l1)) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/14_MergeLinkList.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/14_MergeLinkList.py" new file mode 100644 index 0000000000000000000000000000000000000000..a60df6e851f27f00ee8ef400dbfb4af8c6d9774f --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/14_MergeLinkList.py" @@ -0,0 +1,71 @@ +# 合并两个链表 +# 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。 + +# 链表结构 +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +# 打印链表 +def printChain(head): + node = head + while node: + print(node.val) + node = node.next + +class Solution: + # 返回合并后列表 + def Merge(self, pHead1, pHead2): + + if pHead1 == None: + return pHead2 + if pHead2 == None: + return pHead1 + + # 得到最小的一个头结点 + newHead = pHead1 if pHead1.val < pHead2.val else pHead2 + # 链表1上的指针 和 链表2上的指针 + pTmp1 = pHead1 + pTmp2 = pHead2 + if newHead == pTmp1: + pTmp1 = pTmp1.next + if newHead == pTmp2: + pTmp2 = pTmp2.next + + # 前面的指针 + previousPointer = newHead + + # 链表1 和 链表2 都不为空的时候,开始合并 + while pTmp1 and pTmp2: + # 找出最小值,放在previousPointer指针后面 + if pTmp1.val < pTmp2.val: + previousPointer.next = pTmp1 + previousPointer = pTmp1 + pTmp1 = pTmp1.next + else: + previousPointer.next = pTmp2 + previousPointer = pTmp2 + pTmp2 = pTmp2.next + + if pTmp1 == None: + previousPointer.next = pTmp2 + if pTmp2 == None: + previousPointer.next = pTmp1 + + return newHead + +if __name__ == '__main__': + # 创建链表 + l1 = ListNode(1) + l2 = ListNode(2) + l3 = ListNode(3) + l4 = ListNode(4) + l5 = ListNode(5) + + l1.next = l2 + l2.next = l3 + l3.next = l4 + l4.next = l5 + + print(Solution().ReverseList(l1)) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/15_LinkListClone.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/15_LinkListClone.py" new file mode 100644 index 0000000000000000000000000000000000000000..962ea6c43b056af2afbacf0af6471b9b315994ff --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/15_LinkListClone.py" @@ -0,0 +1,50 @@ +# 复杂链表的复制 +# 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点), +# 请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空) + +# 链表结构 +class RandomListNode: + def __init__(self, x): + self.label = x + self.next = None + self.random = None + + +class Solution: + # 返回合并后列表 + def Clone(self, pHead): + if pHead == None: + return None + pTmp = pHead + # 复制一个一样的node,并且添加到之前的链表的每一个node后面 + while pTmp: + # 创建一个和原来一样的node + node = RandomListNode(pTmp.laebl) + node.next = pTmp.next + # 将原来的指向刚刚创建的节点 + pTmp.next = node + # 同时移动被复制的节点 + pTmp = node.next + + # 实现新建node的random的指向 + pTmp = pHead + while pHead: + # 将复制节点的random,指向 它Random的next + if pTmp.random: + pHead.next.random = pTmp.random.next + pTmp = pTmp.next.next + + # 断开原来的node 和 新 node 之间的连接 + pTmp = pHead + newHead = pHead.next + pNewTmp = pHead.next + while pTmp: + pTmp.next = pTmp.next.next + if pNewTmp.next: + pNewTmp.next = pNewTmp.next.next + pTmp = pTmp.next + pNewTmp = pNewTmp.next + return newHead + +if __name__ == '__main__': + print() diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/16_FindFirstCommonNode.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/16_FindFirstCommonNode.py" new file mode 100644 index 0000000000000000000000000000000000000000..e5a36e0147df5dbc6f2cc497ee2bbfccca7dcc8b --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/16_FindFirstCommonNode.py" @@ -0,0 +1,62 @@ +# 两个链表的公共节点 +# 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点), +# 请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空) +class Solution: + + # 第一个参数给比较短的链表,第二个参数给长链表的值 + # def findEqual(self,): + + def FindFirstCommonNode(self, pHead1, pHead2): + + # 假设输入的两个链表,是同一个链表 + if pHead1 == pHead2: + return pHead1 + + pTmp1 = pHead1 + pTmp2 = pHead2 + + # 我们通过循环,让其中一个节点走到最后 + while pTmp1 and pTmp2: + pTmp1 = pTmp1.next + pTmp2 = pTmp2.next + + + # 判断哪个链表先走到最后 + # 假设pTmp1,还没有走完,说明pTmp2是更短的 + if pTmp1: + k = 0 + # 寻找链表长度之间的差值 + while pTmp1: + pTmp1 = pTmp1.next + k += 1 + # 我们让pTmp1先跳N步 + pTmp2 = pHead2 + pTmp1 = pHead1 + for i in range(k): + pTmp1 = pTmp1.next + + # 当找到节点相等的时候,也就是说明该节点是公共节点 + while pTmp1 != pTmp2: + pTmp1 = pTmp1.next + pTmp2 = pTmp2.next + return pTmp1 + + # 假设pTmp2,还没有走完,说明pTmp1是更短的 + if pTmp2: + k = 0 + while pTmp2: + pTmp2 = pTmp2.next + k += 1 + # 我们让pTmp2先跳N步 + pTmp2 = pHead2 + pTmp1 = pHead1 + for i in range(k): + pTmp2 = pTmp2.next + + while pTmp1 != pTmp2: + pTmp1 = pTmp1.next + pTmp2 = pTmp2.next + return pTmp1 + +if __name__ == '__main__': + print() diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/17_LastRemaining.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/17_LastRemaining.py" new file mode 100644 index 0000000000000000000000000000000000000000..78d15f6c114a59cbb3548a048a20f6be38104c18 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/17_LastRemaining.py" @@ -0,0 +1,49 @@ +# 孩子们的游戏(圆圈中最后剩下的数) +# 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老, +# 自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m, +# 让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物, +# 并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友, +# 可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢? +# (注:小朋友的编号是从0到n-1) +# 如果没有小朋友,请返回-1 +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +class Solution: + def LastRemaining_Solution(self, n, m): + if n == 0 or m == 0: + return -1 + + # 构建一个循环链表 + head = ListNode(0) + tempHead = head + for i in range(1, n): + node = ListNode(i) + head.next = node + head = head.next + + head.next = tempHead + head = tempHead + while head: + # 我们找到小朋友 + leftHead = None + for i in range(m-1): + leftHead = head + head = head.next + + leftHead.next = head.next + head = head.next + + # bakTmp = leftHead.next + # + # # while bakTmp.next != head: + # # bakTmp = bakTmp.next + + # 表示循环链表中,只剩下一个小朋友了 + if head == head.next: + return head.val + +if __name__ == '__main__': + print(Solution().LastRemaining_Solution(5, 2)) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/18_EntryNodeOfLoop.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/18_EntryNodeOfLoop.py" new file mode 100644 index 0000000000000000000000000000000000000000..9a375f8e1230cf9bf39d48b481d4c941ef805666 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/18_EntryNodeOfLoop.py" @@ -0,0 +1,49 @@ +# 链表中环的入口结点 +# 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +class Solution: + def EntryNodeOfLoop(self, pHead): + # 首先需要定义两个指针,其中一个快,跳两步,一个慢跳一步。 + # 循环跳 + # 要么是快的指针 为 none(没有环),要么是快慢指针相等(有环)。 + if pHead == None: + return None + # 定义两个指针,一个快的一个慢的。 + fastPointer = pHead + slowPointer = pHead + # 当快指针存在时,而且快指针的结点指向的下一个也存在 + while fastPointer and fastPointer.next: + # 那么让快指针走两步 + fastPointer = fastPointer.next.next + # 让慢指针走一步 + slowPointer = slowPointer.next + # 如果慢指针等于快指针时,那么就说明这个链表中有环。有环的话那么就跳出,break + if fastPointer == slowPointer: + break + # 如果说两个指针没有相等的时候,快指针就已经走到链表的尽头了,说明这个链表没有环。那么就返回None。 + if fastPointer == None or fastPointer.next == None: + return None + + # 如果slow 走了 l 的长度 那么 fast 就走了 2l 的长度 + # 假设 从开始到入口点的长度是 s;slow 在环里面走的长度是 d + + # 那么 L = s + d + # 假设 环内 slow 没走的 长度 是 m; fast 走的长度是多少 + # fast 走的长度 就是 ( m + d ) * n + d + s = 2 L + # 带入 ( m + d ) * n + d + s = 2 (s + d ) + # s = m + (n-1)(m+d) + # 有环的话,那么就让快指针从头开始走,这次一次走一步, + fastPointer = pHead + # 此时慢指针还在环里走着,没有走到结点 + while fastPointer != slowPointer: + fastPointer = fastPointer.next + slowPointer = slowPointer.next + # 当两个指针相等时,就会相遇,这时返回一个指针的值,就为 入口结点处。 + return fastPointer + +if __name__ == '__main__': + print(Solution().LastRemaining_Solution(5, 2)) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/19_NumberOf1.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/19_NumberOf1.py" new file mode 100644 index 0000000000000000000000000000000000000000..3a4df30f5a84290823afe0b987766024a054a963 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/19_NumberOf1.py" @@ -0,0 +1,25 @@ +# 二进制中1的个数 +# 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示 + +class Solution: + def NumberOf1(self, n): + # 这一步是求补码的 + n = n & 0xFFFFFFFF + count = 0 + for c in str(bin(n)): + if c == "1": + count +=1 + return count + + def NumberOf2(self, n): + # 这一步是求补码的 + n = n & 0xFFFFFFFF + count = 0 + for i in range(32): + mask = 1 << i + if n & mask != 0: + count += 1 + return count + +if __name__ == '__main__': + print(Solution().NumberOf1(-2)) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/1_Fibonacci.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/1_Fibonacci.py" new file mode 100644 index 0000000000000000000000000000000000000000..5f0f97a100fd226464d5d70b55ec7d7787fa7cbc --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/1_Fibonacci.py" @@ -0,0 +1,35 @@ +# 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0) n<=39 +class Solution: + + # 递归实现 + def Fibonacci(self, n): + if n == 0: + return 0; + if n == 1: + return 1; + if n > 0: + return self.Fibonacci(n - 1) + self.Fibonacci(n -2); + else: + return None + + # 非递归实现 + # 当 n = 2的时候, h = f(1) + f(0) = 1 + 0 = 1 + # 当 n = 3的时候, h = f(2) + f(1) = 1 + 1 = 2 + # 当 n = 4的时候, h = f(3) + f(2) = 3 + 1 = 4 + def Fibonacci2(self, n): + if n == 0: + return 0; + if n == 1: + return 1; + + ret = 0 + a = 1 + b = 0 + for i in range(0, n-1): + ret = a + b + b = a + a = ret + return ret + +if __name__ == '__main__': + print(Solution().Fibonacci2(10)) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/20_Add.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/20_Add.py" new file mode 100644 index 0000000000000000000000000000000000000000..6e8f324aa951aaa8eff9dc112b164e5464b7177b --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/20_Add.py" @@ -0,0 +1,34 @@ +# 链表中环的入口结点 +# 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null +# -*- coding:utf-8 -*- +class Solution: + def Add(self, num1, num2): + # 第一种代码:循环。简洁但是原理相同,那么我们以下面第二段代码为例;来解析。 + # while (num2): + # num1, num2 = (num1 ^ num2) & 0xFFFFFFFF, ((num1 & num2) << 1) & 0xFFFFFFFF + # return num1 if num1 <= 0x7FFFFFFF else ~(num1 ^ 0xFFFFFFFF) + + # 第二种代码: + # 首先两个数做 一个 异或 运算^ 那就是 在不进位的情况下,让两个相加 求和。 + xorNum = num1 ^ num2 + # 让两个数 做 位与 操作,然后再向 左 移 一位,得到它 向前进位的值。 + andNum = (num1 & num2) << 1 + # 判断,当 进位 的值不等于0 的时候,说明 一直有进位,也就是 过程没有结束。 + while andNum != 0: + # 那么我们就继续上面的操作。但是这次的 数值 改为上次的两个结果, + # 一个 是异或的结果,一个是 与 操作 & 以后 左移一位的 结果。 + tmp1 = xorNum ^ andNum + tmp2 = (xorNum & andNum) << 1 + # 因为如果这个数为负数的话,那么负数 左移 一位与正数 不同,负数 是数值变小,正数 数值变大 + # 如果是正数的话那么这一步就 不变,如果是负数的话,这一步就对负数来起作用。 + # 对于python来说 负数的 二进制 可能会有无数个1,我们用这个方法让它变成一个可数的数字长度。 + tmp1 = tmp1 & 0xffffffff + + xorNum = tmp1 + andNum = tmp2 + # 一个负整数(或原码)与其补数(或补码)相加,和为模。 0xffffffff + # ~(xorNum ^ 0xFFFFFFFF) 这个是 异或数 与 模 来 异或,最后 按位 取反 来求得 负数的补码。 + return xorNum if xorNum <= 0x7ffffff else ~(xorNum ^ 0xFFFFFFFF) + +if __name__ == '__main__': + print(Solution().NumberOf1(-2)) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/21_MoreThanHalfNum.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/21_MoreThanHalfNum.py" new file mode 100644 index 0000000000000000000000000000000000000000..d6c79824cff6ccebc5a30e6bfef56920987c4d6c --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/21_MoreThanHalfNum.py" @@ -0,0 +1,19 @@ +# 数组中出现次数超过一半的数字 +# 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 +# -*- coding:utf-8 -*- +class Solution: + def MoreThanHalfNum_Solution(self, numbers): + numsCount = {} + numLen = len(numbers) + for num in numbers: + if num in numsCount: + numsCount[num] += 1 + else: + numsCount[num] = 1 + # 找出超过一半的数 + if numsCount[num] > numLen >> 1: + return num + return 0 + +if __name__ == '__main__': + print(Solution().MoreThanHalfNum_Solution({1,2,3,2,2,2,5,4,2})) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/22_NumberOfBetween1AndN_Solution.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/22_NumberOfBetween1AndN_Solution.py" new file mode 100644 index 0000000000000000000000000000000000000000..f326a707e5de0cc1f371a4bfdb7a9906b615ed2f --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/22_NumberOfBetween1AndN_Solution.py" @@ -0,0 +1,48 @@ +# 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数) +class Solution: + def NumberOf1Between1AndN_Solution(self, n): + # 循环的出口是 highValue = 0 + + # 我们从最低位开始一个位一个位的来寻找 1 的可能出现的 情况次数。 + + # 一开始 精准度为1.高位低位中位 先赋值为1. + preceise = 1 + # 高位数 + highValue = 1 + # 低位数 + lowValue = 1 + # 中位数 + midValue = 1 + + # 计数 后面的位数。 + count = 0 + # 计数 1 的次数和 + sumNum = 0 + # 循环的 出口是我们找不到最高位了,那么这个时候就说明,我们遍历到了 这个数字的最高位。 + while highValue != 0: + # 高位 先将这个数 除以10 得到高位 + highValue = n // (preceise * 10) + # 中位 先将这个数 与 10 取余。 + midValue = (n // preceise) % 10 + # 低位 先将这个数 除以 1 那么低位就是个位后面的,没有就是0. + lowValue = n % preceise + # 每遍历一次 向右移一位,那么就是说 精准度要乘以10. + preceise *= 10 + # 如果这个数是0 的话, + + if midValue == 0: + # 那么它就是高位的值,乘以 10^后面的位数 次方,但是这个时候 对于中位 来说 它是个位,后面没有位,所以是0, + num = (highValue) * pow(10, count) + # 如果这个数 大于1 的话, + elif midValue > 1: + # 那么它 就是 最高位加1 乘以 10^后面的位数 次方, + num = (highValue + 1) * pow(10, count) + else: + # 否则的话 它就是等于1 的情况了,对于等于1 的1情况,又是比较特殊的情况,它需要 最高位 * 它10 的后面位数个数的次方,然后要加上我们低位 的数值再加 1, 原因在上面的分析中已经给出。 + num = highValue * pow(10, count) + (lowValue + 1) + # 最后 我们1 出现的 次数 就是这 三个 num 的和,。 + sumNum += num + # 没循环一次,这个三个就往左移一次吗,那么这个时候它们 后面的位数也就会 多一位。 + count += 1 + # 最后返回这个 次数和。 + return sumNum \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/23_FindNumsAppearOnce.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/23_FindNumsAppearOnce.py" new file mode 100644 index 0000000000000000000000000000000000000000..ac7078e9228aebc170d47c0604f6588ab2cf54a1 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/23_FindNumsAppearOnce.py" @@ -0,0 +1,19 @@ +# 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 +class Solution: + # 返回[a,b] 其中ab是出现一次的两个数字 + def FindNumsAppearOnce(self, array): + dict = {} + for i in range(len(array)): + if dict.get(array[i]) != None: + del dict[array[i]] + else: + dict[array[i]] = 1 + if len(dict) == 0: + return None + list = [] + for key in dict: + list.append(key) + return list[0], list[1] +if __name__ == '__main__': + array = [2,4,3,6,3,2,5,5] + print(Solution().FindNumsAppearOnce(array)) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/24_Tree.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/24_Tree.py" new file mode 100644 index 0000000000000000000000000000000000000000..4fa54aeb6d9604adc90b5374b1e8fdd6c5fbd4f7 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/24_Tree.py" @@ -0,0 +1,112 @@ +class TreeNode(object): + def __init__(self, x): + self.val = x + self.left = None + self.right = None + +########## 递归遍历 ############### + +# 递归先序遍历 +def preOrderRecusive(root): + if root == None: + return None + print(root.val, end=" ") + preOrderRecusive(root.left) + preOrderRecusive(root.right) + +# 递归中序遍历 +def midOrderRecusive(root): + if root == None: + return None + midOrderRecusive(root.left) + print(root.val, end=" ") + midOrderRecusive(root.right) + +# 递归后序遍历 +def latOrderRecusive(root): + if root == None: + return None + latOrderRecusive(root.left) + latOrderRecusive(root.right) + print(root.val, end=" ") + +########## 非递归遍历 ############### + +# 非递归先序遍历 +def preOrder(root): + if root == None: + return None + stack = [] + tempNode = root + while tempNode != None or stack: + print(tempNode.val, end=" ") + stack.append(tempNode) + tempNode = tempNode.left + while tempNode == None and stack != []: + tempNode = stack.pop() + tempNode = tempNode.right + +# 非递归中序遍历 +def midOrder(root): + if root == None: + return None + stack = [] + tempNode = root + while tempNode != None or stack: + stack.append(tempNode) + tempNode = tempNode.left + while tempNode == None and stack != []: + tempNode = stack.pop() + print(tempNode.val, end=" ") + tempNode = tempNode.right + +# 非递归后序遍历 +def latOrder(root): + if root == None: + return None + stack = [] + tempNode = root + while tempNode != None or stack: + stack.append(tempNode) + tempNode = tempNode.left + while tempNode == None and stack != []: + # 后序遍历,pop的方式有变化,不能在右子树不为空的时候pop + node = stack[-1] # 因此这里不出列 + tempNode = node.right + # 当右节点没有的时候,才能够pop + if node.right == None: + print(node.val, end=" ") + node = stack.pop() + # 判断pop的节点,是否是上一个节点 + while stack and node == stack[-1].right: + node = stack.pop() + print(node.val, end=" ") + +if __name__ == '__main__': + t1 = TreeNode(1) + t2 = TreeNode(2) + t3 = TreeNode(3) + t4 = TreeNode(4) + t5 = TreeNode(5) + t6 = TreeNode(6) + t7 = TreeNode(7) + t8 = TreeNode(8) + t1.left = t2 + t1.right = t3 + t2.left = t4 + t2.right = t5 + t3.left = t6 + t3.right = t7 + t6.right = t8 + + preOrderRecusive(t1) + print() + midOrderRecusive(t1) + print() + latOrderRecusive(t1) + print() + preOrder(t1) + print() + midOrder(t1) + print() + latOrder(t1) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/25_reConstructBinaryTree.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/25_reConstructBinaryTree.py" new file mode 100644 index 0000000000000000000000000000000000000000..12d6b984e1e3f03d2df3e5735db6cd4d9ea80dfa --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/25_reConstructBinaryTree.py" @@ -0,0 +1,37 @@ +# 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 +# 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。 +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + # 返回构造的TreeNode根节点 + def reConstructBinaryTree(self, pre, tin): + # 取出pre的值 + if not pre or not tin: + return None + if len(pre) != len(tin): + return None + root = pre[0] + # 新建立节点 + rootNode = TreeNode(root) + # 找出这个节点,在中序遍历对应的角标 + pos = tin.index(root) + # 取出中序遍历 左子树 + tinLeft = tin[:pos] + # 取出中序遍历 右子树 + tinRight = tin[pos+1:] + # 取出先序遍历的 左子树 + preLeft = pre[1:pos+1] + # 取出先序遍历的 右子树 + preRight = pre[pos+1:] + + leftNode = self.reConstructBinaryTree(preLeft, tinLeft) + rightNode = self.reConstructBinaryTree(preRight, tinRight) + + if leftNode: + rootNode.left = leftNode + if rightNode: + rootNode.right = rightNode + return rootNode \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/26_HasSubtree.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/26_HasSubtree.py" new file mode 100644 index 0000000000000000000000000000000000000000..c9c10da47c89069f495366cefa41240d9b25f0ec --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/26_HasSubtree.py" @@ -0,0 +1,37 @@ +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + def HasSubtree(self, pRoot1, pRoot2): + if pRoot1 == None or pRoot2 == None: + return None + + def hasEqual(pRoot1, pRoot2): + if pRoot2 == None: + return True + if pRoot1 == None: + return None + if pRoot1.val == pRoot2.val: + if pRoot2.left == None: + leftEqual = True + else: + leftEqual = hasEqual(pRoot1.left, pRoot2.left) + if pRoot2.right == None: + rightEqual = True + else: + rightEqual = hasEqual(pRoot1.right, pRoot2.right) + # 左边相等和右边相等的时候,才返回 + return leftEqual and rightEqual + return False + + ret = hasEqual(pRoot1, pRoot2) + if ret: + return True + + ret = self.HasSubtree(pRoot1.left, pRoot2) + if ret: + return True + ret = self.HasSubtree(pRoot1.right, pRoot2) + return ret \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/27_Mirror.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/27_Mirror.py" new file mode 100644 index 0000000000000000000000000000000000000000..09570e5839cc1becf0d2682e7b9992df7d5ff0b4 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/27_Mirror.py" @@ -0,0 +1,29 @@ +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + # 返回镜像树的根节点 + # def Mirror(self, root): + # if root == None: + # return None + # # 处理左子树 + # temp = root.left + # root.left = root.right + # root.right = temp + # self.Mirror(root.left) + # self.Mirror(root.right) + + def Mirror(self, root): + if root == None: + return None + stack = [root] + while stack: + node = stack.pop() + if node.left: + stack.append(node.left) + if node.right: + stack.append(node.right) + node.right,node.left = node.left, node.right + return root diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/28_PrintFromTopToBottom.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/28_PrintFromTopToBottom.py" new file mode 100644 index 0000000000000000000000000000000000000000..81487862441bb05c07439c3cf5d40be4b41ae1b2 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/28_PrintFromTopToBottom.py" @@ -0,0 +1,23 @@ +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + # 返回从上到下每个节点值列表,例:[1,2,3] + def PrintFromTopToBottom(self, root): + if root == None: + return [] + # 将输入的节点存入support中 + support = [root] + ret = [] + while support: + tempNode = support[0] + ret.append(tempNode.val) + if tempNode.left: + support.append(tempNode.left) + if tempNode.right: + support.append(tempNode.right) + # 删除已经输出的节点 + del support[0] + return ret \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/29_VerifySquenceOfBST.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/29_VerifySquenceOfBST.py" new file mode 100644 index 0000000000000000000000000000000000000000..1c73dd669e3d5d8f2a77870c748f6bd2534d6e15 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/29_VerifySquenceOfBST.py" @@ -0,0 +1,31 @@ +# 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。 +class Solution: + def VerifySquenceOfBST(self, sequence): + if sequence == []: + return False + + # 找ROOT节点,也就是最后一个 + root = sequence[-1] + # 删除队列中的末尾节点 + del sequence[-1] + # 寻找出划分的节点 + index = None + for i in range(len(sequence)): + # 只寻找一次,就不进入了 + if index == None and sequence[i] > root: + index = i + # 当我们找到一个大的数,然后往后又找到一个更小的数,那么就无法组成二叉搜索树 + if index != None and sequence[i] < root: + return False + + if sequence[:index] == []: + left = True + else: + # 寻找左子树和右子树 + left = self.VerifySquenceOfBST(sequence[:index]) + if sequence[index:] == []: + right = True + else: + right = self.VerifySquenceOfBST(sequence[index:]) + # 返回结果 + return left and right \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/2_JumpFloor.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/2_JumpFloor.py" new file mode 100644 index 0000000000000000000000000000000000000000..169ef182db4f1837c8a7b339f045c8c55f3024d4 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/2_JumpFloor.py" @@ -0,0 +1,21 @@ +# 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果) +class Solution: + def JumpFloor(self, n): + if n == 0: + return 0; + if n == 1: + return 1; + if n == 2: + return 2; + + ret = 0 + a = 1 + b = 2 + for i in range(3, n + 1): + ret = a + b + a = b + b = ret + return ret + +if __name__ == '__main__': + print(Solution().JumpFloor(10)) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/2_JumpFloorII.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/2_JumpFloorII.py" new file mode 100644 index 0000000000000000000000000000000000000000..75ca76383fd89f274a123b3b6cc9cf92af30b1e0 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/2_JumpFloorII.py" @@ -0,0 +1,15 @@ +# 变态跳台阶 +# 一只青蛙一次可以跳上1级台阶,也可以跳上2级,也可以跳n阶。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果) +class Solution: + def JumpFloorII(self, n): + if n == 1: + return 1; + ret = 0 + a = 1 + for i in range(2, n + 1): + ret = 2 * a + a = ret + return ret + +if __name__ == '__main__': + print(Solution().JumpFloorII(10)) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/30_FindPath.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/30_FindPath.py" new file mode 100644 index 0000000000000000000000000000000000000000..924693c316f9126e77295beecf47dd259a5a145e --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/30_FindPath.py" @@ -0,0 +1,42 @@ +# 输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。 +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None + +import copy +class Solution: + # 返回二维列表,内部每个列表表示找到的路径 + def FindPath(self, root, expectNumber): + if root == None: + return None + ret = [] + # 用于存放路径 + supportArrayList = [[root.val]] + # 存放中间节点,把root节点放入 + support = [root] + # 广度优先遍历 + while support: + temp = support[0] + tempArrayList = supportArrayList[0] + # 判断是否是叶子节点 + if temp.left == None and temp.right == None: + # 判断路径中的值,是否等于expectNum,往该条数组中插入 + if sum(tempArrayList) == expectNumber: + ret.insert(0, tempArrayList) + + if temp.left: + support.append(temp.left) + newTempArrayList = copy.copy(tempArrayList) + newTempArrayList.append(temp.left.val) + supportArrayList.append(newTempArrayList) + if temp.right: + support.append(temp.right) + newTempArrayList = copy.copy(tempArrayList) + newTempArrayList.append(temp.right.val) + supportArrayList.append(newTempArrayList) + + del support[0] + del tempArrayList[0] + return ret \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/31_Convert.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/31_Convert.py" new file mode 100644 index 0000000000000000000000000000000000000000..5818d39b83fdc03fbd2553bcf2b90578fdf65701 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/31_Convert.py" @@ -0,0 +1,34 @@ +# 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + def Convert(self, pRootOfTree): + def find_right(node): + while node.right: + node = node.right + return node + + if pRootOfTree == None: + return None + + leftNode = self.Convert(pRootOfTree.left) + rightNode = self.Convert(pRootOfTree.right) + retNode = leftNode + if leftNode: + leftNode = find_right(leftNode) + retNode = leftNode + else: + retNode = pRootOfTree + + pRootOfTree.left = leftNode + pRootOfTree.right = rightNode + + if leftNode != None: + leftNode.right = pRootOfTree + if rightNode != None: + rightNode.left = pRootOfTree + + return retNode \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/32_GetMiddleValue.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/32_GetMiddleValue.py" new file mode 100644 index 0000000000000000000000000000000000000000..740fb1112e1e005d26ba2743fb3a1521a392094c --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/32_GetMiddleValue.py" @@ -0,0 +1,32 @@ +# -*- coding:utf-8 -*- +array = [] +class Solution: + + def Insert(self, num): + global array + # write code here + array.append(num) + def GetMedian(self): + # write code here + global array + if array == []: + return None + for i in range(len(array)): + flag = False + for j in range(len(array) - 1 - i): + if array[j] > array[j+1]: + temp = array[j+1] + array[j+1] = array[j] + array[j] = temp + flag = True + if not flag: + break + mid = len(array) /2 + return array[mid] +if __name__ == '__main__': + Solution().Insert(1) + Solution().Insert(5) + Solution().Insert(4) + Solution().Insert(3) + Solution().Insert(2) + Solution().GetMedian() \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/33_GetNext.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/33_GetNext.py" new file mode 100644 index 0000000000000000000000000000000000000000..4e86156768a32715c6de2ba4302f6c1012d4472b --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/33_GetNext.py" @@ -0,0 +1,25 @@ +# 二叉树的下一个节点 +class TreeLinkNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None + self.next = None +class Solution: + def GetNext(self, pNode): + # 寻找右子树,如果存在就一直找右子树的最左边就是下一个节点 + if pNode.right: + tmpNode = pNode.right + while tmpNode.left: + tmpNode = tmpNode.left + return tmpNode + else: + tmpNode = pNode + # 寻找父节点 没有右子树,就寻找它的父节点,一直找到它是父节点的左子树,打印父节点 + while tmpNode.next: + # 判断父节点的左子树,是否是该节点,如果是直接返回父节点 + if tmpNode.next.left == tmpNode: + return tmpNode.next + tmpNode = tmpNode.next + return None + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/35_isSymmetrical.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/35_isSymmetrical.py" new file mode 100644 index 0000000000000000000000000000000000000000..fd02d0442ece6685668f87b88ab6c29867a5eb62 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/35_isSymmetrical.py" @@ -0,0 +1,23 @@ +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + def isSymmetrical(self, pRoot): + + if pRoot == None: + return True + + def isMirror(left, right): + if left == None and right == None: + return True + elif left == None or right == None: + return False + if left.val != right.val: + return False + ret1 = isMirror(left.left, right.right) + ret2 = isMirror(left.right, right.left) + return ret1 and ret2 + + return isMirror(pRoot.left, pRoot.right) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/36_Print.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/36_Print.py" new file mode 100644 index 0000000000000000000000000000000000000000..da9de3d87675c98391740d8e0d5fb3d9b01f1436 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/36_Print.py" @@ -0,0 +1,43 @@ +# 按之字形顺序打印二叉树 +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + def Print(self, pRoot): + if pRoot == None: + return [] + # write code here + stack1 = [pRoot] + stack2 = [] + # 存储打印 + ret = [] + # 当1和2中有空时 + while stack1 or stack2: + if stack1: + tmpRet = [] + while stack1: + # 取出stack1中的一个节点 + tmpNode = stack1.pop() + tmpRet.append(tmpNode.val) + # 把左右子树放到stack2中 + if tmpNode.left: + stack2.append(tmpNode.left) + if tmpNode.right: + stack2.append(tmpNode.right) + ret.append(tmpRet) + + if stack2: + tmpRet = [] + while stack2: + # 取出stack1中的一个节点 + tmpNode = stack2.pop() + tmpRet.append(tmpNode.val) + # 把左右子树放到stack2中 + if tmpNode.right: + stack1.append(tmpNode.right) + if tmpNode.left: + stack1.append(tmpNode.left) + ret.append(tmpRet) + return ret \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/37_Print.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/37_Print.py" new file mode 100644 index 0000000000000000000000000000000000000000..4ff048f6366944e28bb0e1aee471e8cd65282915 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/37_Print.py" @@ -0,0 +1,37 @@ +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + # 返回二维列表[[1,2],[4,5]] + def Print(self, pRoot): + if pRoot == None: + return [] + queue1 = [pRoot] + queue2 = [] + ret = [] + while queue1 or queue2: + if queue1: + tmpRet = [] + while queue1: + tmpNode = queue1.pop(0) + tmpRet.append(tmpNode.val) + if tmpNode.left: + queue2.append(tmpNode.left) + if tmpNode.right: + queue2.append(tmpNode.right) + ret.append(tmpRet) + if queue2: + tmpRet = [] + while queue2: + tmpNode = queue2.pop(0) + tmpRet.append(tmpNode.val) + if tmpNode.left: + queue1.append(tmpNode.left) + if tmpNode.right: + queue1.append(tmpNode.right) + ret.append(tmpRet) + return ret + + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/38_KthNode.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/38_KthNode.py" new file mode 100644 index 0000000000000000000000000000000000000000..80e831d4cf8585f37a6856df4ce25b40118cdfe5 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/38_KthNode.py" @@ -0,0 +1,16 @@ +# 二叉排序树的第K小的节点 +class Solution: + # 返回对应节点TreeNode + def KthNode(self, pRoot, k): + retList = [] + def preOrder(pRoot): + if pRoot == None: + return None + preOrder(pRoot.left) + retList.append(pRoot) + preOrder(pRoot.right) + + preOrder(pRoot) + if len(retList) < k or k < 1: + return None + return retList[k-1] \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/39_SerializeTree.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/39_SerializeTree.py" new file mode 100644 index 0000000000000000000000000000000000000000..386e69f5e949eb087735241f5f4fe22cd7a13ada --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/39_SerializeTree.py" @@ -0,0 +1,38 @@ +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + # 序列化 + def Serialize(self, root): + retList = [] + def preOrder(root): + if root == None: + # 找到为空的节点,插入 # + retList.append("#") + return None + + # 否者插入该节点 + retList.append(str(root.val)) + preOrder(root.left) + preOrder(root.right) + preOrder(root) + return ' '.join(retList) + + # 反序列化 + def Deserialize(self, s): + retList = s.split(" ") + if retList == None: + return None + def dePreOrder(): + rootVal = retList.pop(0) + if rootVal == "#": + return None + node = TreeNode(rootVal) + leftNode = dePreOrder() + rightNode = dePreOrder() + node.left = leftNode + node.right = rightNode + return node + return dePreOrder() \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/3_GetUglyNumber.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/3_GetUglyNumber.py" new file mode 100644 index 0000000000000000000000000000000000000000..e03410332ea79f8573c10e1ce69192904e8f82ec --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/3_GetUglyNumber.py" @@ -0,0 +1,29 @@ +class Solution: + def GetUglyNumber_Solution(self, index): + # write code here + if index < 1: + return None + #死循环,找丑数 + #判断一个数是不是丑数,先循环除以2,直到不能整除, + #循环除以3 直到不能整除,循环除以5 直到不能整除 + #这时如果剩余的值是1 我们就说它是丑数 + #其他情况就都不是丑数 + def isUglyNumber(num): + while num % 2 == 0: + num = num //2 + while num % 3 == 0: + num = num //3 + while num % 5 == 0: + num = num //5 + if num == 1: + return True + else: + return False + count = 0 + num = 1 + while True: + if isUglyNumber(num): + count += 1 + if count == index: + return num + num += 1 \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/40_FindGreatestSumOfSubArray.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/40_FindGreatestSumOfSubArray.py" new file mode 100644 index 0000000000000000000000000000000000000000..a8d14ed3770850d56bade081199175db8e7d653b --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/40_FindGreatestSumOfSubArray.py" @@ -0,0 +1,30 @@ +# 连续子数组的最大和 +class Solution: + # def FindGreatestSumOfSubArray(self, array): + # # write code here + # maxSum = -99999 + # for i in range(len(array)): + # sum = 0 + # for j in range(i, len(array)): + # sum += array[j] + # if sum > maxSum: + # maxSum = sum + # return maxSum + + def FindGreatestSumOfSubArray(self, array): + # write code here + maxNum = None + tmpNum = 0 + for i in array: + if maxNum == None: + maxNum = i + if tmpNum + i < i: + tmpNum = i + else: + tmpNum += i + if maxNum < tmpNum: + maxNum = tmpNum + return maxNum + +if __name__ == '__main__': + print(Solution().FindGreatestSumOfSubArray([1,-2,3,10,-4,7,2,-5])) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/41_rectCover.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/41_rectCover.py" new file mode 100644 index 0000000000000000000000000000000000000000..7daf21b74d8b5eb42cd09299049750ed974bcb1b --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/41_rectCover.py" @@ -0,0 +1,17 @@ +# 矩形覆盖 +class Solution: + def rectCover(self, number): + # write code here + if number == 0: + return 0 + if number == 1: + return 1 + if number == 2: + return 2 + + a = 1 + b = 2 + for i in range(3, number + 1): + b = a + b + a = b - a + return b \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/4_ArrayFind.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/4_ArrayFind.py" new file mode 100644 index 0000000000000000000000000000000000000000..a2735ccc132c17ed4b8add37b0258524cfaec42c --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/4_ArrayFind.py" @@ -0,0 +1,25 @@ +# 二维数组查找 +# 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序, +# 每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 +class Solution: + # 暴力算法 + def Find(self, target, array): + for i in range(len(array)): + for j in range(len(array)): + if target == array[i][j]: + return True + return False + + def Find2(self, target, array): + if any(array) == 0: + return False + for i in range(len(array)): + # 判断最后一位是否比target更大 + if array[i][len(array) - 1] >= target: + for j in range(len(array)): + if target == array[i][j]: + return True + return False + +if __name__ == '__main__': + print(Solution().Find(10)) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/5_ReplaceSpace.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/5_ReplaceSpace.py" new file mode 100644 index 0000000000000000000000000000000000000000..db68614f2cc9f1f2f998d1580306625cae561358 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/5_ReplaceSpace.py" @@ -0,0 +1,21 @@ +# 替换空格 +# 请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 +class Solution: + # s 源字符串 + def replaceSpace(self, s): + return s.replace(' ', '%20') + + def replaceSpace2(self, s): + strLen = len(s) + aaa = [] + for i in range(0, strLen): + if s[i] == " ": + aaa.append("%") + aaa.append("2") + aaa.append("0") + else: + aaa.append(s[i]) + return ''.join(aaa) + +if __name__ == '__main__': + print(Solution().replaceSpace2('We Are Happy')) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/6_TwoArrayImplementStack.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/6_TwoArrayImplementStack.py" new file mode 100644 index 0000000000000000000000000000000000000000..c3b2d81bc9cc301d5fa679f72347ac5e447ffe22 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/6_TwoArrayImplementStack.py" @@ -0,0 +1,27 @@ +# 两个栈实现一个队列 +# 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。 +class Solution: + def __init__(self): + # 接收栈 + self.acceptStack = [] + # 输出栈 + self.outputStack = [] + + def push(self, node): + # 把节点放到栈中 + self.acceptStack.append(node) + + def pop(self): + # 从接收栈中获取元素,把它放入到 输出栈中 + if self.outputStack == []: + while self.acceptStack: + self.outputStack.append(self.acceptStack.pop()) + + # 判断输出栈中是否有元素,有,则输出最后一个 + if self.outputStack != []: + return self.outputStack.pop() + else: + return None + +if __name__ == '__main__': + print() \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/7_MinNumberInRotateArray.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/7_MinNumberInRotateArray.py" new file mode 100644 index 0000000000000000000000000000000000000000..cf9168449a611e8e07e378a29e409892aa547aad --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/7_MinNumberInRotateArray.py" @@ -0,0 +1,66 @@ +# 旋转数组的最小数字 +# 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 +# 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 +# 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 +# NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。 +class Solution: + def minNumberInRotateArray(self, rotateArray): + minNum = 0 + # 第一种方法,就是遍历所以的元素,找出最小的 + for i in range(0, len(rotateArray)): + minNum = minNum if minNum < rotateArray[i] and minNum != 0 else rotateArray[i] + return minNum + + # 二分查找法 + # 有序的数组中使用 + def bSearch(self, array, target): + left = 0 + right = len(array) - 1 + while left < right: + # 右移1位,相当于除以2 + mid = (left + right) >> 1 + if target == mid: + return mid + if target > mid: + left = mid + 1 + else: + right = mid - 1 + return None + + # 有序的数组中使用 + def minNumberInRotateArray2(self, rotateArray): + if not rotateArray: + return None + left = 0 + right = len(rotateArray) - 1 + while left <= right: + middle = (left + right) >> 1 + # middle 比两边的都小,说明是最小值 + if rotateArray[middle] < rotateArray[middle - 1]: + return rotateArray[middle] + elif rotateArray[middle] < rotateArray[right]: + right = middle - 1 + else: + left = middle + 1 + return 0 + + # 二分查找法(以下代码错误) + # 有序的数组中使用 + def minNumberInRotateArray3(self, rotateArray): + if not rotateArray: + return None + left = 0 + right = len(rotateArray) - 1 + while left < right: + middle = (left + right) >> 1 + # middle 比两边的都小,说明是最小值 + if rotateArray[middle] < rotateArray[middle - 1]: + return rotateArray[middle] + elif abs(rotateArray[left] - rotateArray[middle]) < abs(rotateArray[right] - rotateArray[middle]): + left = middle + 1 + elif abs(rotateArray[left] - rotateArray[middle]) > abs(rotateArray[right] - rotateArray[middle]): + right = middle - 1 + return 0 + +if __name__ == '__main__': + print(Solution().minNumberInRotateArray2([3,4,5,2,3,6,7,8])) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/8_reOrderArray.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/8_reOrderArray.py" new file mode 100644 index 0000000000000000000000000000000000000000..0ae0243b11b002411cd272e144fb0689be85e2b0 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/8_reOrderArray.py" @@ -0,0 +1,16 @@ +# 调整数组顺序使奇数位于偶数前面 +# 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分, +# 所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变 +class Solution: + def reOrderArray(self, array): + ret = [] + ret2 = [] + for i in range(0, len(array)): + # 判断是否偶数 + if array[i] % 2 == 0: + ret2.append(array[i]) + else: + ret.append(array[i]) + return ret + ret2 +if __name__ == '__main__': + print(Solution().reOrderArray([3,4,5,2,3,6,7,8])) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/9_containMainStack.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/9_containMainStack.py" new file mode 100644 index 0000000000000000000000000000000000000000..25fa71298ed08370743b9c74c8c2fbcd590dfa64 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/9_containMainStack.py" @@ -0,0 +1,44 @@ +# 包含min函数的栈 +# 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。 +# 注意:保证测试中不会当栈为空的时候,对栈调用pop()或者min()或者top()方法。 +class Solution: + + # 初始化 + def __init__(self): + self.stack = [] + # 存储最小元素 + self.minValue = [] + + # 压栈 + def push(self, node): + self.stack.append(node) + + # 维护当前最小的数组 + if self.minValue: + if self.minValue[-1] > node: + self.minValue.append(node) + else: + self.minValue.append(self.minValue[-1]) + else: + self.minValue.append(node) + + # 出栈 + def pop(self): + if self.stack == []: + return None + self.minValue.pop() + return self.stack.pop() + + # 获取栈顶 + def top(self): + if self.stack == []: + return None + return self.stack[-1] + + def min(self): + if self.minValue == []: + return None + return self.minValue[-1] + +if __name__ == '__main__': + print(Solution().reOrderArray([3,4,5,2,3,6,7,8])) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A0_inserttSort.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A0_inserttSort.py" new file mode 100644 index 0000000000000000000000000000000000000000..5ee3b522c33c47adae3349d6dc20b5937bfd76a3 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A0_inserttSort.py" @@ -0,0 +1,15 @@ +# 插入排序 +class Solution: + def insertSort(self, alist): + n = len(alist) + for j in range(0, n): + for i in range(j, 0, -1): + if alist[i] < alist[i - 1]: + alist[i], alist[i - 1] = alist[i - 1], alist[i] + else: + break + return alist + + +if __name__ == '__main__': + print(Solution().insertSort([1,8,3,2,6,9])) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A1_binarySearch.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A1_binarySearch.py" new file mode 100644 index 0000000000000000000000000000000000000000..9d33dc448d7cc9b2f2a7de036230732b0eafc4df --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A1_binarySearch.py" @@ -0,0 +1,18 @@ +# 二分查找 +class Solution: + def binarySearch(self, array, key): + left = 0 + right = len(array) + + while(left < right): + middle = int((right + left) / 2) + if array[middle] == key: + return middle + elif array[middle] > key: + right = middle - 1 + else: + left = middle + 1 + return -1 + +if __name__ == '__main__': + print(Solution().binarySearch([1,3,5,6,8,9], 10)) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A2_bubbleSort.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A2_bubbleSort.py" new file mode 100644 index 0000000000000000000000000000000000000000..ba10d4bcd765e2ee87338ad8d03c4b14cc28beab --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A2_bubbleSort.py" @@ -0,0 +1,17 @@ +# 冒泡排序 +class Solution: + def bubbleSort(self, array): + for i in range(len(array)): + flag = False + for j in range(len(array) - 1 - i): + if array[j] > array[j+1]: + temp = array[j+1] + array[j+1] = array[j] + array[j] = temp + flag = True + if not flag: + break + return array + +if __name__ == '__main__': + print(Solution().bubbleSort([1,5,4,3,2])) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A4_quickSort.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A4_quickSort.py" new file mode 100644 index 0000000000000000000000000000000000000000..1beb693e07738700e446074dc20c47c71910a7aa --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A4_quickSort.py" @@ -0,0 +1,39 @@ +def quick_sort(li, start, end): + # 分治 一分为二 + # start=end ,证明要处理的数据只有一个 + # start>end ,证明右边没有数据 + if start >= end: + return + # 定义两个游标,分别指向0和末尾位置 + left = start + right = end + # 把0位置的数据,认为是中间值 + mid = li[left] + while left < right: + # 让右边游标往左移动,目的是找到小于mid的值,放到left游标位置 + while left < right and li[right] >= mid: + right -= 1 + print("left 1", li) + li[left] = li[right] + print("left 2", li) + # 让左边游标往右移动,目的是找到大于mid的值,放到right游标位置 + while left < right and li[left] < mid: + left += 1 + li[right] = li[left] + print("right ", li) + # while结束后,把mid放到中间位置,left=right + li[left] = mid + # 递归处理左边的数据 + quick_sort(li, start, left-1) + # 递归处理右边的数据 + quick_sort(li, left+1, end) + +if __name__ == '__main__': + l = [1,5,4,6,2,8] + # l = 3 [2,1,5,6,5,4] + # [2, 1, 5, 6, 5, 4] + quick_sort(l,0,len(l)-1) + print(l) + # 稳定性:不稳定 + # 最优时间复杂度:O(nlogn) + # 最坏时间复杂度:O(n^2) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A5_shellSort.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A5_shellSort.py" new file mode 100644 index 0000000000000000000000000000000000000000..955ac3233edf52a81298c548aa0dc7109173cfa0 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A5_shellSort.py" @@ -0,0 +1,22 @@ +# 希尔排序 +class Solution: + def shellSort(self, arrlist): + arrayLen = len(arrlist) + h = 1 + # 工业界认定的求 增量的方法 + while h < arrayLen/3: + h = h*3 + 1 + # 插入排序的方法,判断是不是后面一个比前面的要小 + # 如果是则交换 + while h >= 1: + for i in range(h, arrayLen): + j = i + while j >= h and arrlist[j] < arrlist[j - h]: + arrlist[j], arrlist[j-h] = arrlist[j-h], arrlist[j] + j-=h + # 除以3 + h = h//3 + return arrlist + +if __name__ == '__main__': + print(Solution().shellSort([1,8,3,2,6,9])) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A6_MergeSort.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A6_MergeSort.py" new file mode 100644 index 0000000000000000000000000000000000000000..f765cdbd227216e7dd17abf9d23ba3bd33f18871 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/A6_MergeSort.py" @@ -0,0 +1,48 @@ +# 归并排序 +class Solution: + def MergeSort(self, arrayList): + arrayLen = len(arrayList) + # 判断输入参数的正确性 + if arrayLen < 1: + return [] + # 归并的出口是当分解到长度为1的时候 + if arrayLen == 1: + return arrayList + # 获取中间索引值 + middleIndex = arrayLen >> 1 + # 递归左边部分 + sortedLeft = self.MergeSort(arrayList[:middleIndex]) + # 递归右边部分 + sortedRight = self.MergeSort(arrayList[middleIndex:]) + # 合并代码 + return self.MergeCore(sortedLeft, sortedRight) + + def MergeCore(self, leftList, rightList): + # leftIndex = 0 + # rightIndex = 0 + # # 由于多次用,length 我们自己保存 + # leftLen = len(leftList) + # rightLen = len(rightList) + retList = [] + + while leftList != [] and rightList != []: + leftValue = leftList[0] + rightValue = rightList[0] + if leftValue >= rightValue: + retList.append(rightValue) + del rightList[0] + else: + retList.append(leftValue) + del leftList[0] + + # 归并排序后,然后 + if leftList != []: + for i in leftList: + retList.append(i) + if rightList != []: + for i in rightList: + retList.append(i) + return retList + +if __name__ == '__main__': + print(Solution().MergeSort([1,8,7,5,4,2])) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/GetLeastNumbers_Solution.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/GetLeastNumbers_Solution.py" new file mode 100644 index 0000000000000000000000000000000000000000..cc2bbb05d2be0c35c8a106b6a8edfe966597ceba --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/GetLeastNumbers_Solution.py" @@ -0,0 +1,17 @@ +class Solution: + def GetLeastNumbers_Solution(self, tinput, k): + array = [] + if k > len(tinput): + return array + for i in range(k): + array.append(99) + for key in tinput: + for index in range(len(array)): + if key < array[index]: + array.insert(index, key) + break + if len(array) > k: + del array[-1] + return array +if __name__ == '__main__': + print(Solution().GetLeastNumbers_Solution([4,5,1,6,2,7,3,8], 4)) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/KthNode.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/KthNode.py" new file mode 100644 index 0000000000000000000000000000000000000000..d4b45ba5322b0e01cce89b30ff6dd3533ec9e6d0 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/KthNode.py" @@ -0,0 +1,20 @@ +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None +class Solution: + # 返回对应节点TreeNode + def KthNode(self, pRoot, k): + retList = [] + def preOrder(pRoot): + if pRoot == None: + return None + preOrder(pRoot.left) + retList.append(pRoot) + preOrder(pRoot.right) + + preOrder(pRoot) + if len(retList) < k or k < 1: + return None + return retList[k-1] \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/LeetCode/189_rotate.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/LeetCode/189_rotate.py" new file mode 100644 index 0000000000000000000000000000000000000000..84cc37221bfb6199768d4d7d4f353c5cc3e51543 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/LeetCode/189_rotate.py" @@ -0,0 +1,23 @@ +class Solution(object): + # def rotate(self, nums, k): + # arrLen = len(nums) + # if k == arrLen: + # return nums + # arr=[0 for i in range(arrLen)] + # for index in range(arrLen): + # newIndex = (index + k) % arrLen + # arr[newIndex] = nums[index] + # return arr + + def rotate(self, nums, k): + arrLen = len(nums) + if k == arrLen: + return nums + + k = k % arrLen + + for index in range(k): + nums.insert(0, nums.pop()) + return nums +if __name__ == '__main__': + print(Solution().rotate([1,2,3,4,5,6,7], 3)) \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/Merge.py" "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/Merge.py" new file mode 100644 index 0000000000000000000000000000000000000000..68d8f277526f8c85298609b971512a0ed7dffb6f --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/NowCode/Merge.py" @@ -0,0 +1,26 @@ +class Solution(object): + def getIndex(self, line): + lineLen = len(line) + left = 0 + right = lineLen - 1 + + while left <= right: + mid = (left + right) // 2 + if line[mid] < 0 and ((mid != 0 and line[mid -1] >= 0) or (mid == 0)): + return lineLen - mid + elif line[mid] < 0: + right = mid -1 + else: + left = mid + 1 + return 0 + + + def countNegatives(self, grid): + count = 0 + for i in range(len(grid)): + count += self.getIndex(grid[i]) + return count + +if __name__ == '__main__': + print(Solution().countNegatives([[4,3,2,-1],[3,2,1,-1],[1,1,-1,-2],[-1,-1,-2,-3]])) + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\270\215\347\224\250\345\212\240\345\207\217\346\263\225\347\256\227\345\222\214\350\277\220\347\256\227.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\270\215\347\224\250\345\212\240\345\207\217\346\263\225\347\256\227\345\222\214\350\277\220\347\256\227.png" new file mode 100644 index 0000000000000000000000000000000000000000..16c8ae6f46fd15d0678cda30b183b4160119f9f4 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\270\215\347\224\250\345\212\240\345\207\217\346\263\225\347\256\227\345\222\214\350\277\220\347\256\227.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\344\270\200\344\270\252\351\230\237\345\210\227.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\344\270\200\344\270\252\351\230\237\345\210\227.png" new file mode 100644 index 0000000000000000000000000000000000000000..f05089d99fa4749d42f9f9af93e8cad79bfbb5cc Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\270\244\344\270\252\346\240\210\345\256\236\347\216\260\344\270\200\344\270\252\351\230\237\345\210\227.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\270\244\344\270\252\351\223\276\350\241\250.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\270\244\344\270\252\351\223\276\350\241\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..e85087ba5026d4b53a0f8ad89cf911635cf422e3 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\270\244\344\270\252\351\223\276\350\241\250.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\270\244\344\270\252\351\223\276\350\241\250\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\232\204\347\273\223\347\202\271.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\270\244\344\270\252\351\223\276\350\241\250\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\232\204\347\273\223\347\202\271.png" new file mode 100644 index 0000000000000000000000000000000000000000..c909d13245c7665c157ae371c53420c45d2b2cf0 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\270\244\344\270\252\351\223\276\350\241\250\347\254\254\344\270\200\344\270\252\345\205\254\345\205\261\347\232\204\347\273\223\347\202\271.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\272\214\345\217\211\346\240\221.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\272\214\345\217\211\346\240\221.png" new file mode 100644 index 0000000000000000000000000000000000000000..d3e9caf03ecffa16e6730bc0f37352eddee0a572 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\272\214\345\217\211\346\240\221.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..5353eb6ba1a6fac05ac8d1ed7c9df5c8b4899b32 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\344\273\216\345\260\276\345\210\260\345\244\264\346\211\223\345\215\260\351\223\276\350\241\250.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\211\221\346\214\207offer1-24\351\242\230 .md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\211\221\346\214\207offer1-24\351\242\230 .md" new file mode 100644 index 0000000000000000000000000000000000000000..088ef640c1730cb9b00f6aa126c0507ad6a30b30 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\211\221\346\214\207offer1-24\351\242\230 .md" @@ -0,0 +1,1767 @@ +#### 队列 + +**队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。** + +对列的添加 insert append + +队列的取值 列表[-1] 列表[0] + +队列的删除 pop() pop(0) + +___ + + + +#### 栈 + +**栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。** + +只允许在栈的栈顶来操作。 + +添加元素用append(push),称作是进栈,入栈或者压栈 + +取值列表[-1],因为它只能从栈顶来取值,相当于取列表的最后一个值,所以用索引-1. + +删除元素pop()从后端开始删除。称作是出栈或者退栈。 + +___ + + + +## 1. 两个栈实现一个队列:[^本题考点 队列 栈] + +**用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。** + +……解析: + +定义一个类,首先这个类要具备两个属性,一个是压栈,一个是出栈。 + +因为要两个栈来实现一个队列:进行插入操作的端称为队尾,进行删除操作的端称为队头。 + +那么如何用:两个栈实现一个队列? + +栈: 先进后出 + +队列:先进先出 + +![](两个栈实现一个队列.png) + +#### 如图所示: + +队列从一头添加数据,从一头删除数据。 + +所以我们需要让两个栈 + +一个栈实现添加数据 + +​ 即:`self.acceptStack=[] `它拥有一个` push `的方法,用来作为队列的一端的添加数据 功能 用append来实现 + +​ `self.acceptStack.append(node)` + +另一个栈实现删除数据: + +​ 即:`self.outputStack = [] `它拥有pop 的方法,用来作为队列的另一端的删除数据的功能 用pop 来实现 + +​ 但是我们要实现的是队列的先进先出,也就意味着 如果说我们添加数据的栈中添加了一个数据,那么我们另一个删除数据的栈中,也要相应的删除这个数据,所以说这两个栈中的数据的顺序是相反的。 + +以上的需求我们通过,删除`acceptStack`栈中的数据,在`outputStack`中添加这个数据,那么先在`acceptStack`中删除的数据,就会进入到`outputStack`的栈底,后在`acceptStack`中删除的数据,会后进入`outputStack`,那么它就会先出来。 + +那么两个栈,这样来合作,就会实现队列的先进先出,如图:1 是先进的(栈1) 那么1 就会先出来(栈2)。 + +进而实现了 题目的需求。 + +在pop 的方法中,如果说 `self.outputStack `是空 没有数据,那么 就给它 while 循环我们的 作为添加数据的栈 + +`acceptStack`,删除这个栈中的内容,它会弹出,然后把它添加到 `栈2 outputStack` 中,它就会有数据,有数据的话就返回 (如果 调用了 删除 数据的这个方法的话)。如果说 做了循环,我们的`栈2 outputStack` 中还没有数据,就明 `acceptStack `中,没有数据压入,也就说明这个 队列 没有添加数据,也就不会有删除的数据,所以返回一个None。 + +___ + + + +```python +class Solution: + def init(self): + #添加数据栈 + self.acceptStack=[] + #删除数据栈 + self.outputStack = [] + def push(self, node): + #向添加数据的栈中添加数据 + self.acceptStack.append(node) + def pop(self): + #判断删除数据的栈中是否有数据,没有的话,就添加数据,添加数据时,要添加栈1 中删除的数据 + if not self.outputStack: + while self.acceptStack: + self.outputStack.append(self.acceptStack.pop()) + #如果有数据的话,就返回 + if self.outputStack: + return self.outputStack.pop() + #如果没有数据,说明没有数据添加进去,也就不需要删除数据,所以返回none + else: + return None +``` + +### 二分查找法 + +##### **分析查找:首先快速的查找方法 有二分查找法,那么什么是二分查找法?** + +``` +二分查找法什么情况下用。有序的数组中。首先 肯定是在有序的 数组中的!!!!! +``` + +算法:二分法查找适用于数据量较大时,但是数据需要先排好顺序。主要思想是:(设查找的数组区间为array[low, high]) + +(1)确定该区间的中间位置K(2)将查找的值T与array[k]比较。若相等,查找成功返回此位置;否则确定新的查找区域,继续二分查找。区域确定如下:a.array[k]>T 由数组的有序性可知array[k,k+1,……,high]>T;故新的区间为array[low,……,K-1]b.array[k] 10 = 2 + #1100 = 12 => 110 = 6 + #一下用了 向右 移一位, 那么上面是解释,它就相当于 除以2 。 + mid = (left + right) >> 1 + #如果中间的数等于我们要找的数,那么就返回。 + if array[mid] == target: + return mid + #如果说中间的数 < 目标的数,那么就说明,我们要找的数在右侧,所以左侧取值的索引需要改变为中间的索引+1; + elif array[mid]< target: + left = mid + 1 + #如果说中间的数 > 目标的数,那么就说明,我们要找的数在左侧,所以左侧取值的索引需要改变为中间的索引-1; 因为越往左索引值越小 + else: + right = mid-1 + + return None +``` + +把数组内的数据一分为二,然后计算出中间数据的 索引值。 + +数组中 最左侧的 索引为 0 ;最右侧的索引为 len(array)-1,数组的长度 减 1 就是 最后一个数的索引。 + +先判断中间索引的所对应的数组中的数值,是否与我们要查找的数字 target 相等,如果相等那么就返回,如果不相等,那么就继续判断。如果说我们找到的 array[mid] 小于 target 这个数; 那么 就说明 我们要查找的数在右侧的一半数据中,那么这个时候我们就需要改变我们左边的索引值,不在从0 开始,而是从我们中间 mid 的下一个开始,left = mid + 1,继续查找。如果说我们找到的 array[mid] 大于 target 这个数 ,那么就说明我们要查找的数据在左侧,这个时候就需要改变右侧的索引,为 right = mid-1,越往左侧走,索引值越小。直到找的的数 与target 相等为止。 + +以上为二分法的原理。 + +___ + + + + + +## 2. 旋转数组的最小数字 [^本题考点 查找] + +**把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。** + +```python +class Solution: + def minNumberInRotateArray(self, rotateArray): + #最小值 一定比前面的要小 + # 二分法查找数据 找左右的方法是: + #右边的值大于中值,就说明最小值在左边 + if not rotateArray: + return 0 + left = 0 + right = len(rotateArray) - 1 + while left <= right: + mid = (left + right) >> 1 + #如果说中间的数的上一个数 > 中间数,那么就说明,我们要找的数就是这个中间的数,返回这个数。 + if rotateArray[mid - 1] > rotateArray[mid]: + return rotateArray[mid] + #如果说中间的数 < 中间数的上一个数,那么就说明,我们要找的数在二分法的左侧,所以右侧取值的索引需要改变为中间的索引-1;因为越往左索引值越小 + elif rotateArray[mid] < rotateArray[right]: + right = mid - 1 + #否则就说明,我们要找的数在二分法的右侧,所以左侧取值的索引需要改变为中间的索引+1;因为越往右索引值越小 + else: + left = mid + 1 + return 0 +``` + +___ + + + +##### 什么叫做数组? + +*所谓数组,是有序的元素序列。 [1] 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按无序的形式组织起来的一种形式。 [1] 这些无序排列的同类数据元素的集合称为数组。* + +例如: + +int (32 位) int int 这三个就会组成一个数组,类型相同的变量。 +a(0) a(1) a(2) + +数组与python中的 列表比较相似, 用索引去查找。 +数组的长度是固定的,在初始化时就指定长度。列表是可以动态增加的。 +数组还和元组比较像,元组是初始化后,长度指定了就不可以变。 +但是元组在初始化时给的值,确定了以后就不可以变了。 +所以可以理解为数组与list 列表很相似。 + +___ + + + +## 3.在二维数组中的查找[^本题考点 *查找*] + +**在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。** + +```python +class Solution: + # array 二维列表 + def Find(self, target, array): + # write code here + # 1 2 3 4 + # 3 4 5 6 + # 4 6 8 10 + # 9 11 13 15 + #时间复杂度 o(n**n) + + # for i in range(len(array)): + # for j in range(len(array[i])): + # if target == array[i][j]: + # return True + # return False + + #时间复杂度 + #O(n) + #这个二维数组的长度是多少,也就是说这个数组有几行; + row_count = len(array) + i = 0 + #这个数组列数的索引值,就是我们数组取第一个数的个数,也就是有几列 + column_count = len(array[0]) + #给j 一个值,就是数组列数的值-1,即为j 的最大值。 + j = len(array[0])-1 + #循环,当i 小于我们行数的时候,并且j 也没有取到 0 那么就进入循环,去查找数据。 + #我们要取到每行的最后一个数,即对应的那一列的第一个数,来与我们的目标数来对比,这个数是这一行的最大数,是这一列的最小数。 + while i < row_count and j >= 0: + #根据两个索引下标可以取到 对应的在数组中的值 + value = array[i][j] + #如果说取到的值,刚好等于目标值,那么就说明我们找到了它,直接返回就好。 + if value == target: + return True + #如果说取到的值 > 我们的目标值。那就说明它不在它所在的那一列里,因为这个数是那一列的最小值,这个时候就需要改变我们列的索引值,给它减-1,找前一列的数做比较 + elif target < value: + j -= 1 + #如果说取到的值 < 我们的目标值。那就说明它不在它所在的那一行里,因为这个数是那一行的最大值,这个时候就需要改变我们行的索引值,给它加+1,找下一行的数做比较 + else: + i += 1 + return False +``` + +___ + + + +## 4.包含min 函数的栈[^本题考点 *栈*] + +**定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。** + +原理:用空间换时间,用时间换空间;增加空间来减少时间的消耗 + +```python +#第一种方法:考虑两个栈的长度相同,添加一个,另一个栈也会删除一个 + +class Solution: + #给这个类一个初始的属性,有一个栈,另外有一个最小值的列表栈 + def __init__(self): + self.stack = [] + self.minValue = [] + #给栈中推进去数值,推进去元素node,添加函数 + def push(self, node): + self.stack.append(node) + #如果最小值列表里有值 + if self.minValue: + #如果最小值列表里的最后一个值 大于 node 这个值,说明node这个值小, + # 那么就放进最小值列表中; + if self.minValue[-1] > node: + self.minValue.append(node) + #如果列表里面的最后一个值,小于node值,那么就说明node这个值大;那么就添加上次添加进来的那个小的值,与栈中的数据长度保持一致; + else: + self.minValue.append(self.minValue[-1]) + #如果最小值列表里面没有值,就在最小值列表里添加node + else: + self.minValue.append(node) + #给栈中做删除操作 + def pop(self): + #如果说栈中是空值得话那么就返回none,说明没有在栈中压值进来,没有最小值 + if self.stack == []: + return None + #栈的长度与最小值的栈的长度要相同,所以最小值列表也需要删除一个 + self.minValue.pop() + #有值得话,就需要删除一个,删除做pop 操作;返回我们删除的那个数 + return self.stack.pop() + #栈顶 + def top(self): + #如果栈里没有数值的话,就返回一个空 + if not self.stack: + return None + #否则栈里有数,那么就返回栈顶的那个数 + return self.stack[-1] + #取出最小值,那么就是我们minvalue 中的最后一个值为最小值 + def min(self): + #如果为空的话,就说明没有值,返回none + if self.minValue == []: + return None + return self.minValue[-1] + + + #第二种方法:不考虑两个栈的长度必须要保持一致,那么在栈删除值的时候,判断一下删除的值,是不是与装最小值的栈里的最后一个最小值相同,如果相同就删掉,如果不同,就不删除。 + + +class Solution: + def __init__(self): + self.stack = [] + self.minValue = [] + def push(self, node): + # write code here + self.stack.append(node) + if self.minValue: + #如果最小值列表里的最后一个值 大于 node 这个值,说明node这个值小, + # 那么就放进最小值列表中; + if self.minValue[-1] > node: + self.minValue.append(node) + #最后一个值不大于node这个值得话;不做操作,不需要把它两个做的长度一致 + else: + self.minValue.append(node) + def pop(self): + if self.stack == []: + return None + # write code here + #删除的时候,做个判断,它是不是与栈里面的最后一个值,与我们最小值栈里的最后一个值相等,那么就删除双方的这个值 + if self.stack[-1] == self.minValue[-1]: + self.minValue.pop() + return self.stack.pop() + #如果不等的话,就只要删除栈 里最后一个值就可以 + else: + return self.stack.pop() + def top(self): + if self.stack == []: + return None + return self.stack[-1] + # write code here + def min(self): + if self.minValue == []: + return None + return self.minValue[-1] +``` + +## 5.替换空格[^本题考点 *字符串*] + +**请实现一个函数,将一个字符串中的每个空格替换成`“%20”`。例如,当字符串为`We Are Happy`.则经过替换之后的字符串为`We%20Are%20Happy`。** + +```python +# -*- coding:utf-8 -*- +class Solution: + # s 源字符串 + def replaceSpace(self, s): + #第一种:python中自带的一个替换的函数 + # return s.replace(' ','%20') + #第二种遍历来替换字符串中的空格 + strlen = len(s) + #借助第三方的列表来实现时间的节省。 + aaa = [] + for i in range(strlen): + #如果是空格的话那就替换为%20. + if s[i] == " ": + #if s[i] isspace: + aaa.append("%") + aaa.append("2") + aaa.append("0") + else: + aaa.append(s[i]) + return "".join(aaa) +``` + +___ + +## 6.斐波那契数列 + +**大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39** + +```python +#第一种方法:下面是使用了for循环, + +class Solution: + def Fibonacci(self, n): + + # 如果是按照递归来写的话, 时间复杂度就是随着n的变化 增长率是 2^n + + ''' 递归实现 + # n = 0 f(0) = 0 + if n == 0: + return 0 + # n = 1 f(1) = 1 + if n == 1: + return 1 + # if n > 1 f(n) = f(n-1) + f(n-2) + if n > 1: + num = self.Fibonacci(n-1) + self.Fibonacci(n-2) + return num + + return None + ''' + + # n = 0 f(0) = 0 + if n == 0: + return 0 + # n = 1 f(1) = 1 + if n == 1: + return 1 + + a = 1 + b = 0 + # if n > 1 f(n) = f(n-1) + f(n-2) + # h = a + b + # 当 n = 2 h = 0 + 1 + ret = 0 + #三个变量,互相转换 来实现 + for i in range(0, n - 1): + ret = a + b + b = a + a = ret + return ret +#第二种方法:相对来说比较简便,简单来讲,就是取出这个列表的最后两项求和,就是列表的第三项,时间复杂度比较小,空间复杂度为 n + + class Solution: + def Fibonacci(self, n): + #初始列表值 为 0 1 第三项为 0+1 = 1; + res = [0, 1, 1] + #临界条件为:第 n 项,所以就是 这个 列表的长度要小于等于 n;大于 n 就应该跳出这个循环。 + while len(res) <= n: + #取出列表的最后两项,然后求和,并添加到列表中。 + res.append(res[-1] + res[-2]) + return res[n] + + + +``` + +___ + +## 7.青蛙跳台阶 + +**一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。** + +![](青蛙跳台阶.png) + +```python +""" +1 (1) +2 (11,2) +3 (12,21,111) +4 (1111,22,112,121,211) +5 (11111,221,212,122,1121,2111,1112,1211) +6 (111111,222,2211,1122,2112,1221,2121,1212,21111,12111,11211,11121,11112,) +""" + +class Solution: + def jumpFloor(self, number): + # write code here + + #第一种方法: + res = [1, 1, 2] + while len(res) <= number: + res.append(res[-1] + res[-2]) + return res[number] + + + a = 1 + b = 1 + for i in range(0,number): + a,b = b,a+b + return a + + + if number < 1: + return 0 + if number ==1: + return 1 + if number == 2: + return 2 + ret = 0 + a = 1 + b = 2 + for i in range(3,number+1): + ret = a+b + a = b + b = ret + return ret +``` +--- + +## 8.变态跳台阶 + +**一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。** + +```python +""" +1 (1) +2 (11,2) +3 (111,21,3,12) +4 (1111,22,13,31,211,112,121,4) + +n 2^(n-1) +f(n) = f(n-1) + f(n-2) + .... + f(1) +f(n-1) = f(n-2) + .... + f(1) +f(n) = 2f(n-1) n > 1 + +f(1) = 1 n = 1 + +""" + +# -*- coding:utf-8 -*- +class Solution: + def jumpFloorII(self, number): + # write code here + #第一种方法: + # return pow(2,number-1) + + #第二种方法: + # return 2 ** (number - 1) + + #第三种方法: + if number == 0: + return 0 + if number ==1 : + return 1 + a = 1 + ret = 1 + for i in range(2,number+1): + a,ret = ret,2*ret + return ret +``` + +___ + +## 9. 调整数组顺序使奇数位于偶数前面 [^本题知识点 *数组*] + +**输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。** + +```python +class Solution: + def reOrderArray(self, array): + # write code here + #时间复杂度是o(n) + #空间复杂度o(n) + # ret = [] + # for i in array: + # if i % 2 == 1: + # ret.append(i) + # for i in array: + # if i % 2 == 0: + # ret.append(i) + # return ret + #用了冒泡排序的原理,判断奇偶数,如果一个是偶数而且下一个是奇数,那么两个就互换位置。 + for i in range(len(array)): + for j in range(len(array) - i - 1): + if array[j] % 2 == 0 and array[j + 1] % 2 == 1: + array[j], array[j + 1] = array[j + 1], array[j] + return array +``` + +___ + + + +### 知识点:冒泡排序法 + +```python +def bubbleSort(array): + + #一共 需要 n 次 的循环,每一个都要找到没排好序的最大值。 + for i in range(len(array)): + #将没有排好序的数组 找最大值,并一直将最大值换到最顶端。 + for j in range(len(array)-i-1): + #判断如果说一个数大于它下面的一个数,那么就两个数的位置互换。 + if array[j] > array[j+1]: + array[j],array[j+1] = array[j+1],array[j] + return array +``` + +___ + +## 10.栈的压入,弹出序列 [^本题考点 *栈*] + +**输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)** + +```python +class Solution: + def IsPopOrder(self, pushV, popV): + # write code here + #首先要先有一个栈,列表 + #按照 pushV 的方式去压入栈, + # 弹出的时候是需要循环判断是否需要弹出 + #判断是否需要弹出的时机,刚刚压入过后就判断 + #判断需要弹出的情况的条件,压入栈的顶部和弹出栈的顶部数据相等 + + #先判断pushV 这个栈里是否为空,如果是空的话返回none,或者说这两个序列的长度不相同。那也返回none。 + + if pushV == [] or len(pushV ) != len(popV): + return None + #首先有个栈 + stack = [] + #定义一个变量,它作为弹出序列的索引存在。 + index = 0 + #遍历 pushV 的这个列表里的元素,并把它每个都添加进stack 这个列表中 + for item in pushV: + stack.append(item) + #做判断 1,stack 里有元素 并且 stack里的最后一个元素 等于 popV 这个序列里 第一个元素,那么就进去这个循环,然后把stack里的这个元素删掉,这样下次还会添加新的元素,然后再和 popV 里的下一个元素 做判断,所以这个时候 index 这个索引值就要发生变化了,这个时候比较的是 它的下一个值。往右移动一位。 + while stack and stack[-1] == popV[index]: + stack.pop() + index += 1 + """ + if stack == []: + return True + else: + return False + + """ + #最后 直到 把 pushV 里的元素都遍历完,然后stack内的元素都比较完,并都删除完,就返回True,如果说 它不为空:说明 pushV 里有的元素 是popV 中所没有的,这个时候就说明他们不相等,那么这个情况,就需要返回 False。 + #以下代码与以上代码 共同实现的相同的功能,但是下面的代码相对来说等 “装B” 一点。节省代码空间。 + return True if stack == [] else False +``` + +___ + +#### `知识点`链表: + +链表是一种物理[存储单元](https://baike.baidu.com/item/%E5%AD%98%E5%82%A8%E5%8D%95%E5%85%83/8727749)上非连续、非顺序的[存储结构](https://baike.baidu.com/item/%E5%AD%98%E5%82%A8%E7%BB%93%E6%9E%84/350782),[数据元素](https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE%E5%85%83%E7%B4%A0/715313)的逻辑顺序是通过链表中的[指针](https://baike.baidu.com/item/%E6%8C%87%E9%92%88/2878304)链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储[数据元素](https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE%E5%85%83%E7%B4%A0)的数据域,另一个是存储下一个结点地址的[指针](https://baike.baidu.com/item/%E6%8C%87%E9%92%88/2878304)域。 相比于[线性表](https://baike.baidu.com/item/%E7%BA%BF%E6%80%A7%E8%A1%A8/3228081)[顺序结构](https://baike.baidu.com/item/%E9%A1%BA%E5%BA%8F%E7%BB%93%E6%9E%84/9845234),操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。 + +![](链表.png) + + + +数组 就是连续的 同一个类型的 元素,而且必须是固定的长度。 + +如果我们想要非固定的长度来存储数据。这个时候就出现了链表。 + + + +___ + + + +## 11. 从栈尾到栈头打印链表 [^本题知识点 *链表*] + +**输入一个链表,按链表值从尾到头的顺序返回一个`ArrayList`。** + +```python +# -*- coding:utf-8 -*- +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + # 返回从尾部到头部的列表值序列,例如[1,2,3] + def printListFromTailToHead(self, listNode): + # write code here + # pointer 指针 temporary临时数据;node 结点 + #给一个 arraylist 空列表,然后向这个里面压入数据,来输出 这个链表值 的一个从尾到头 的顺序值。 + ret = [] + #把 listNode 这个链表 传给一个 变量 + pTemp = listNode + #当这个变量 存在时 有值时: + while pTemp: + #使用 insert 的原因是:insert 可以在指定位置之前插入元素,列表.insert(索引,值) + #在空列表中起始位置,插入 pTemp的第一个值,然后 给pTemp 赋值 为 pTemp.next (下一个值) + ret.insert(0, pTemp.val) + #更改 指针,使指针指向下一个 元素 + pTemp = pTemp.next + #最后返回我们 这个 插入值的 列表 + return ret +``` + +![](从尾到头打印链表.png) + +如图所示:打印出 3 2 1 即为我们的目标。 + +___ + +## 12.链表中的倒数第k个结点[^本题考点 *链表*] + +**输入一个链表,输出该链表中倒数第k个结点。** + +```python +# -*- coding:utf-8 -*- +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def FindKthToTail(self, head, k): + + # write code here + # k 如果 比我们的链表的长度还要大的话,我们直接返回None + # k 如果小于链表的长度,我们可以定义两个变量,这两个变量中间间隔k + #用两个指针做一个尺子,然后让尺子在跳跳,然后就会找到 第k 个结点 + + + #起始位置 第一个和第二个指针 都是从头开始的。 + firstPoint = head + secondPoint = head + + #首先让一个指针先开始移动,那么就是遍历我们的k 值,让我们的 第一个指针移动 k 步。 + for i in range(k): + #如果第一个指针为空的话,那么说明我们的k值为空,那么我们的这个链表就为空。 + if firstPoint == None: + return None + #第一个指针 移动一步 + firstPoint = firstPoint.next + #当 第一个指针不为空的时候, + while firstPoint != None: + #移动尺子,移动距离为 k 的长度, 直到 第一个指针点 为空的时候 ,就到了 这个链表的结尾,此时就返回 第二个指针 那么就为 倒数第 k 个结点。 + firstPoint = firstPoint.next + secondPoint = secondPoint.next + + return secondPoint +``` + +![](链表中倒数的第k个结点.png) + +___ + + + +如上图所示:分析过程,可以为两个结点的指针长度,也可以为三个结点的指针长度,也可以为k个结点的指针长度。 + +## 13.反转链表[^本题考点 *链表*] + +**输入一个链表,反转链表后,输出新链表的表头。** + +```python +#第一种方法: +""" + pHead始终指向要反转的结点 +last 指向反转后的首结点 +每反转一个结点, +把pHead结点的下一个结点指向last, +last指向pHead成为反转后首结点, +再把pHead向前移动一个结点直至None结束 + +""" + + + +# -*- coding:utf-8 -*- +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None +class Solution: + # 返回ListNode + def ReverseList(self, pHead): + #首先判断这个链表里是否只有一个结点,只有一个结点那么它就不需要发生变化,它第一个结点指向的指针就为 none + # 这个时候就直接返回这个 pHead + if not pHead or not pHead.next: + return pHead + #首先要明白 反转过后,第一个数值的指针的结点指向的是none 也就是一个指向反转后的首结点 为none + last = None + + #当 要反转的结点 pHead 存在的时候 + while pHead: + #先找到第一个元素的结点指向的元素,赋值给一个临时变量 + temp = pHead.next + """ + 本来一个元素的结点 是要指向它的下一个 元素的 . + 反转后 就是 这个元素 要指向它的 上一个 元素 . + + """ + #然后第一次循环 把这第一个元素的结点 改为 none last 第一个值 是 none (此时还没有发生改变的last) + # 之后循环 就是 每 反转一个结点 把pHead结点的下一个结点指向last, + pHead.next = last + #下一步 是把 pHead 这个 元素的 赋值给last + # last指向pHead成为反转后首结点, + last = pHead + # 再把pHead向前移动一个结点直至None结束 + pHead = temp + + return last + + +""" +反转需要两步 ,第一步找到它的 结点,第二步改变结点就可以了; +之后需要 把结点 赋值为 这个元素的 本身 ; + +循环: + 找到 元素结点指向的元素, +目标是 让元素结点指向的元素 改为 自己本身。 + +""" + +#第二种方法: + +""" +1 将现有的头换成尾,尾部的next为空 +2 将从第二个node开始,循环将next指向前一个 +3 需要一直有一个指针指向还没有反转的链表的头部 + +""" +class Solution2: + # 返回ListNode + def ReverseList(self, pHead): + #判断是否为空值,没有元素 + if pHead == None: + return None + #判断是否只有一个元素 + if pHead.next == None: + return pHead + #左边指针为 头 第一个 指针 + leftPointer = pHead + #中间 的指针 为 第二个指针 + midPointer = pHead.next + #右边的指针 为 指向 中间 指针后的 所有的元素 + rightPointer = midPointer.next + #左边的指针为 起始 的 元素, 反转后 它的next 为 None; + leftPointer.next = None + #循环,当我的右边的结点指向的 元素 一直存在的时候,那么就会一直循环,一直来反转结点。 + while rightPointer: + #中间指针指向的为上一个 元素 即 leftPointer + midPointer.next = leftPointer + #三个指针开始往右移。每次移一个。 + #左边指针 往右移一个 就是中间指针的位置 + leftPointer = midPointer + #中间指针 往 右 移 一个,就时 右边指针的位置 + midPointer = rightPointer + #右边指针往右移 一个 ,就时 右边指针的下一个。 + rightPointer = rightPointer.next + #当右指针 指向的为 空的时候 就会跳出循环,那么此时的最后一次循环的 中间的指针的 指向的 是此时的左 指针。 + midPointer.next = leftPointer + #最后返回中间的 这个指针,就是 最后一个 反转的指针的第一个,表头。 + return midPointer +``` + + + +如图所示: + +![](反转链表.png) + +___ + +## 14.复杂链表的复制 + +**输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)** + +![](复杂链表的复制.png) + +___ + +```python +#第一种方法: + +# -*- coding:utf-8 -*- +# class RandomListNode: +# def __init__(self, x): +# self.label = x +# self.next = None +# self.random = None +class Solution: + # 返回 RandomListNode + def Clone(self, pHead): + # write code here + + #判断当pHead 为空值的时候 返回的是none + + if pHead == None: + return None + # 复制一个一样的node, 并且添加到之前的链表的每一个node后面 + pTmp = pHead + while pTmp: + #把第一个 A 的值 赋给 node 为A‘ + node = RandomListNode(pTmp.label) + #此时 node A' 的结点指向的是 原来A 的结点指向的 值 + node.next = pTmp.next + #将原来A 的结点指向的值 改为 A’ + pTmp.next = node + #将 我们要操作的指针 向后移动 操作下一个 需要复制的元素,即为 A‘ 结点 指向的元素 + pTmp = node.next + # 实现新建的node的random的指向 + pTmp = pHead + while pTmp: + #如果现在操作的这个指针的元素,存在一个 random 的结点 + if pTmp.random: + #那么 这个A 的结点指向的(A’)的random结点指向的 值 为 A 的random的结点指向的值,指向的结点(也就是它的下一个值)上图更清楚明白。 + pTmp.next.random = pTmp.random.next + #建好 这个元素的 random 的值,然后移动 指针 到下一个元素,来 建立 下一个 复制的元素的random 结点的指向。 + #当前元素 下一个的下一个 是复制的元素 是需要添加random 指向的元素。 + pTmp = pTmp.next.next + # 断开原来的node 和 新的node 之间的链接 + #最后 为断开 链接 的操作 + pTmp = pHead + #复制的新链表的表头A’ 为 旧链表 A 的结点指向的 下一个值A‘ + newHead = pHead.next + #复制的新链表的第一个值A’ 为 旧链表 A 的结点指向的 下一个值A‘ + pNewTmp = pHead.next + + while pTmp: + #print(pTmp.label) + #将旧链表 A 的指向结点 改为 A‘ 的指向的下一个 的B。 + pTmp.next = pTmp.next.next + #如果新的 链表 的元素有指向的下一个的指针 + if pNewTmp.next: + #那么就把 这个元素的A’ 的结点指向 改为 A‘ 下一个 B 的下一个 的B’ + pNewTmp.next = pNewTmp.next.next + #然后再 将 新链表的指针移 位,来断开下一个 链接,也就是 指针改为了 B‘ + pNewTmp = pNewTmp.next + #上面新链表的元素指针改好了,再更改 下一个旧链表的 元素 也就是 上三行代码 之前改好的 A 的结点指向的B + pTmp = pTmp.next + #如此循环下去,改变所有的 新链表,旧链表的指向。 + #最后返回这个复制好的新链表。 + return newHead + + + #第二种方法: + import copy + chead=copy.deepcopy(pHead) + return chead +``` + +___ + +## 15.两个链表之间的第一个公共结点 + +**输入两个链表,找出它们的第一个公共结点** + +如图: + +![](两个链表第一个公共的结点.png) + +___ + + + +```python +# -*- coding:utf-8 -*- +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None +class Solution: + def FindFirstCommonNode(self, pHead1, pHead2): + # write code here + pTmp1 = pHead1 + pTmp2 = pHead2 + #当链表1 和链表2 同时存在的时候 + while pTmp1 and pTmp2: + #当两个链表移动到值相同的时候,这个位置就是结点,直接返回pTmp1或pTmp2 + if pTmp1 == pTmp2: + return pTmp1 + #移动指针的位置,两个同时移动, + pTmp1 = pTmp1.next + pTmp2 = pTmp2.next + + #第一个参数给比较短的那个链表的值 + #第二个参数给比较长的链表的值 + #第三个参数是比较短的那个链表头 + #第四个参数是比较长的那个链表头 + + def findEqual(longPointer, shorPointer, longHead, shortHead): + k = 0 + # 寻找出链表长度之间的差值,让长的链表继续走,直到链表走完为止,走了多少步,就说明,两个链表之间的差值是多少。 + while longPointer: + longPointer = longPointer.next + k += 1 + #然后: + # 先让长的那个去走k步 + longPointer = longHead + shortPointer = shortHead + for i in range(k): + longPointer = longPointer.next + #长的走k步之后,再让两个链表一起移动,直到两个链表移动的位置的值相等为止,那么这个点就是 两个链表的第一个公共结点。 + while longPointer != shortPointer: + longPointer = longPointer.next + shortPointer = shortPointer.next + return shortPointer + #如果两个链表不一样的长度,那么假设是 第一个链表长度长,第二个链表已经走完了,结束了,那么第一个链表还没有走完,那么就调用我们封装好的函数,或者是看下面注释的代码。 + if pTmp1: + return findEqual(pTmp1,pTmp2,pHead1,pHead2) + # k = 0 + # #寻找出链表长度之间的差值 + # while pTmp1: + # pTmp1 = pTmp1.next + # k += 1 + # #先让长的那个去走k步 + # pTmp2 = pHead2 + # pTmp1 = pHead1 + # for i in range(k): + # pTmp1=pTmp1.next + #长的走k步之后,再让两个链表一起移动,直到两个链表移动的位置的值相等为止,那么这个点就是 两个链表的第一个公共结点。 + # while pTmp1 != pTmp2: + # pTmp1 = pTmp1.next + # pTmp2 = pTmp2.next + # return pTmp1 + + if pTmp2: + return findEqual(pTmp1, pTmp2, pHead1, pHead2) + # k = 0 + # # 寻找出链表长度之间的差值 + # while pTmp2: + # pTmp2 = pTmp2.next + # k += 1 + # # 先让长的那个去走k步 + # pTmp2 = pHead2 + # pTmp1 = pHead1 + # for i in range(k): + # pTmp2 = pTmp2.next + #长的走k步之后,再让两个链表一起移动,直到两个链表移动的位置的值相等为止,那么这个点就是 两个链表的第一个公共结点。 + # while pTmp1 != pTmp2: + # pTmp1 = pTmp1.next + # pTmp2 = pTmp2.next + # return pTmp2 + + +``` + +___ + +## 16.合并两个排序的链表 [^本题考点 链表] + +**输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。** + +如图:为两个递增的链表 + +![](两个链表.png) + +如下图,合并成一个单调不减链表 + +![](合成一个链表.png) + +___ + +```python +#第一种方法: + +""" + +比较两个链表的首结点,哪个小的的结点则合并到第三个链表尾结点,并向前移动一个结点。 +步骤一结果会有一个链表先遍历结束,或者没有 +第三个链表尾结点指向剩余未遍历结束的链表 +返回第三个链表首结点 + +""" +# -*- coding:utf-8 -*- +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + # 返回合并后列表 + def Merge(self, pHead1, pHead2): + # write code here + head = ListNode(0) + tmp = head + while pHead1 is not None and pHead2 is not None: + if pHead1.val <= pHead2.val: + tmp.next = pHead1 + pHead1 = pHead1.next + else: + tmp.next = pHead2 + pHead2 = pHead2.next + tmp = tmp.next + if pHead1 is None: + tmp.next = pHead2 + elif pHead2 is None: + tmp.next = pHead1 + return head.next + +#第二种方法: +class Solution: + # 返回合并后列表 + def Merge(self, pHead1, pHead2): + # write code here + #首先判断两个链表是不是为空。 + if pHead1 == None: + return pHead2 + if pHead2 == None: + return pHead1 + #比较两个链表当前指针的元素值的大小。小的那一方为新的一个表头。 + newHead = pHead1 if pHead1.val < pHead2.val else pHead2 + + pTmp1 = pHead1 + pTmp2 = pHead2 + #判断 如果新表头 是 表1 的头的话 那么 新表头 + if newHead == pTmp1: + pTmp1 = pTmp1.next + else: + pTmp2 = pTmp2.next + # + previousPointer = newHead + + while pTmp1 and pTmp2: + if pTmp1.val < pTmp2.val: + previousPointer.next = pTmp1 + previousPointer = pTmp1 + pTmp1 = pTmp1.next + else: + previousPointer.next = pTmp2 + previousPointer = pTmp2 + pTmp2 = pTmp2.next + + if pTmp1 == None: + + previousPointer.next = pTmp2 + else: + previousPointer.next = pTmp1 + + return newHead +``` + +___ + + + +## 17.圆圈中最后剩下的数 [^本题考点 *模拟*] + +**每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)** + +![](小朋友的游戏.png) + +___ + +思路分析: + +这个题一开始小朋友们每个人自己的编号是确定的,就相当于我们列表里面的索引是确定的一样,然后让编号为0。 + +链表1:也就是 列表里面的第一个数开始报数,上图第一个链表蓝色的0,开始报数。报到 m-1 的数的 i小朋友 出列,圈里就少了一个数。定义为 f(n). + +链表2:这个时候 从 m-1 的下一个 m 开始 下一轮的循环,开始报数,也就是上图第二个链表的蓝色框。再次报到 m-1 的时候,这个ii小朋友会站出来。(但是这个时候 我们链表的 循环顺序 (m-(m-2)) 发生了变化,不再是从第一个数 【链表的表头 开始循环,而是m 这个数作为起始位置的】,与之前第一个 链表循环的时候的 顺序(0-n)不同了【起始位置为链表的表头】。此时表里少了一个小朋友。这个是题意,让我们这样来找的小朋友。所以定义为 f `(n-1). + +这样的话,就出现了 上图中的 链表2 ,链表3. 这样的不同的情况,这两个 找出来的第 m-1 个 小朋友 是同一个小朋友,但是 两个顺序却不相同。 + +链表3:这个图 是 以 m 为起始位置 来寻找第 m-1 个值的,它 就是 f(n-1) + + 如果说我们想由 链表3 得到 链表2 的话,那么 我们就需要把作为起始位置的m(下标为0) 移动到 下标为(m) 的位置,那么就是下标值 + m 。如图,我们需要移动的是 每个数值所对应的 下标 index值。让 m 在一个链表中作为起始位置来开始 报数 找 第 m - 1 个iii小朋友。 + +但是又由于 我们这样直接加上一个m 以后,这个 index 值有可能会大于 这个链表的长度,如果大于这个链表的长度的话,那么就是说移动到了这个链表的前一部分,所以要对我们的 这个数 对 链表的长的的一个取余: + +(iii+m)%n 我们一共是 n 个值,从0-(n-1); + +f(n-1) = iii + +所以 f(n) = f `(n-1) = (iii+m)%n + +所以 f(n) = (f(n-1)+m) + +那么这个通项表达式我们就找到了,再去编写代码。 + +```python +# -*- coding:utf-8 -*- +class Solution: + def LastRemaining_Solution(self, n, m): + # write code here + #通过推导公式可得 f(n) = (f(n-1)+m)%n + #首先判断,当我们这个链表里没有小朋友的时候,或者找到的小朋友报的数小于1 的时候,这个时候返回一个-1,题中表示 如果测试的是0个小朋友,数0个站出来,那么返回的值应为-1. + if n < 1 or m < 1: + return -1 + #只有一个人的时候,说明要找的就是这一个人。那么就返回下标0 编号。 + if n==1: + return 0 + value = 0 + #时间复杂度 o(n) + #从 2 开始 一直到 n 个小朋友 来循环,n 个数,所以为 n+1 + for index in range(2,n+1): + #现在数到的 m-1 这个值 的索引。对应上上面的公式。 + currentValue = (value+m) % index + #把找到的这个下标值 赋值给 value + value = currentValue + #返回编号 + return value +``` + +___ + +## 18.链表中环的入口点 [^本题知识点 链表] + +**给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。** + +![](链表中环的入口结点.png) + +```python +# -*- coding:utf-8 -*- +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None +class Solution: + def EntryNodeOfLoop(self, pHead): + # write code here + #首先需要定义两个指针,其中一个快,跳两步,一个慢跳一步。 + #循环跳 + #要么是快的指针 为 none(没有环),要么是快慢指针相等(有环)。 + if pHead == None: + return None + #定义两个指针,一个快的一个慢的。 + fastPointer = pHead + slowPointer = pHead + #当快指针存在时,而且快指针的结点指向的下一个也存在 + while fastPointer and fastPointer.next : + #那么让快指针走两步 + fastPointer = fastPointer.next.next + #让慢指针走一步 + slowPointer = slowPointer.next + #如果慢指针等于快指针时,那么就说明这个链表中有环。有环的话那么就跳出,break + if fastPointer == slowPointer: + break + #如果说两个指针没有相等的时候,快指针就已经走到链表的尽头了,说明这个链表没有环。那么就返回None。 + if fastPointer == None or fastPointer.next == None: + return None + #如果slow 走了 l 的长度 那么 fast 就走了 2l 的长度 + #假设 从开始到入口点的长度是 s;slow 在环里面走的长度是 d + + # 那么 L = s + d + #假设 环内 slow 没走的 长度 是 m; fast 走的长度是多少 + # fast 走的长度 就是 ( m + d ) * n + d + s = 2 L + #带入 ( m + d ) * n + d + s = 2 (s + d ) + # s = m + (n-1)(m+d) + #有环的话,那么就让快指针从头开始走,这次一次走一步, + fastPointer = pHead + #此时慢指针还在环里走着,没有走到结点 + while fastPointer != slowPointer: + fastPointer = fastPointer.next + slowPointer = slowPointer.next + #当两个指针相等时,就会相遇,这时返回一个指针的值,就为 入口结点处。 + return fastPointer +``` + + + +定义: + +假设 slow 走了 L 步,那么 fast 就走了 2L 步。 + + 我们 链表的头部 到 链表的环的入口结点处 的距离是 S + +那么 从入口结点 到 我们 快慢指针相遇的地点 的距离 为 d。 + +链表的环中,慢指针走过的距离是d,那么没走过的距离是M。 + +我们不确定的是快指针在链表的环里走过了多少圈来与慢指针相遇,因此 将这个参数设置为n。 + +那么 L = s + d + +2L = 2(s+d) = n*(m + d) + d + s + +由上面公式 推导出 n(m+d) = s + d + +得到:s = n(m+d) -d; + +s = nm + (n-1)(d) +s = m + (n-1)(m+d) + +___ + +## 19.二进制中的1的个数 + +**输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示** + +#### `知识点:` + +#### 补码 + +特性: + +1、一个负整数(或原码)与其补数(或补码)相加,和为模。 + +2、对一个整数的补码再求补码,等于该整数自身。 + +3、补码的正零与负零表示方法相同 + +#### 按位取反 ~ + +~,用法只有一个那就是按位取反,需要注意的是: + +- ~的按位取反,包括符号位 +- 正数各位取反变为负数,显示时转化为其补码 +- 负数本身需要先转换为补码(符号位不变,各位取反再加 1),再对其补码进行各位去反 + +##### 1. ~5 + +5 的二进制为 0101, + +~5 + +- (1)各位取反,1010 +- (2)变为负数,转化为其补码形式(符号位保持不变),各位取反 1(1101),再加1(1110),也即 -6 + +```python +>> ~5 +>> -6 +``` + +##### 2. ~(-5) + +-5 因为是负数,存储时存储的是其补码: + +- -5 的补码是:1011, +- ~(-5)将其各位取反(包括符号位),也即 0100(4) + +```python +>> ~(-5) +>> 4 +``` + +___ + + + +```python +# -*- coding:utf-8 -*- +#第一种: +class Solution: + def NumberOf1(self, n): + # write code here + #补码:正数不变,负数是它的正数的反码 + 1 + # -2 补码: -2 的 1 0000.。。000010, + # 1 1111.。。111101 + 1 + #-2 的补码就是 1 1111.。。111110 + #把输入的正数n转化为二进制的数,并把0b 替换掉,计算1的数量,如果输入的值不是正数的话 + #一个负整数(或原码)与其补数(或补码)相加,和为模。2 的32 次方 是模。 + #那么就是 2 的32 次方 然后 + n 这是在取一个负数的补码 就相当于 n & 0xffffffff + #然后计算 这个数里面 1 的 数量 + return bin(n).replace("0b", "").count("1") if n >= 0 else bin(2 ** 32 + n).replace("0b", "").count("1") + + +#第二种: +# -*- coding:utf-8 -*- +class Solution2: + def NumberOf1(self, n): + # write code here + # 1 出现的次数为0 次 + count = 0 + #判断 这个数 n 是不是负数,如果是负数的话 求其补码: + if n < 0: + n = n & 0xffffffff + #如果这个数不是0 的话,那么它在二进制的表示中至少有一位是1,所以一开始我们赋值 count +=1. + while n: + count += 1 + #把一个整数先减去1,再和原整数做与运算,会把该整数最右边的1 变从成0,那么一个二进制中有多少个1,就可以进行多少次这样的操作。 + n = (n - 1) & n + return count + """ + 例如:一个二进制1100, 它的第二位 是从最右边数起的一个1,减去一个1后,第二位变成0,它后面的两位0变成1,而前面的1保持不变,因此结果是1011. + 那把 这个整数 和它 减去1 的结果 做一个按位 与运算,相当于 把 最右边的 1 变成 0,。 + 1011 和 1100 做 按位与 运算 1100 & 1011 结果为 1000,那么刚好是我们 要得到 将最右边的1 变成0 的结果 1000. + + """ +``` + +___ + +## 20.不用加减乘除做加法[^本题考点 *按位运算*] + +**写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。** + +![](不用加减法算和运算.png) + + + +分析: + +对于数字运算,如果说四则运算不能用的话,那么我们只能用位运算来做了。 + +我们以 5 + 17 为例 结果为 22,那么 22 的计算结果,我们可以分为三步 来进行: + +​ 第一步: 只做各位相加不进位 也就是说 没一位上的数字 相应的来相加 但是不进位,那么 5 + 7 为 12 + +​ 个位数 5 和 7 相加 不进位 是2 十位是0 和1 相加 为 1 + +​ 第二步: 5 + 7 中有进位,进位值 是10 ; + +​ 第三步: 把前面两个结果 加起来: 12 + 10 = 22 + +以上为我们用十进制计算的 策略,那么 我们用于位运算中是不是也合适,我们来举个栗子: + +还是以 5 + 17 为例,那么 5 的二进制是101 ; 17 的二进制是 10001; + +第一步:各位相加 但不进位: 101 + 10001 = 10110 不进位的话 结果为 10100 (最后一位两个数都是1,相加的结果需要进位,但是这一位不进位,意味着结果仍然是0) + +第二步: 记下进位,它只在最后一位相加时产生了一个进位。 + +第三步: 把前面两个结果相加,得到的结果是 10110. + +**那么现在我们把前面的 二进制的加法用位运算来替代的话** + +第一步的 求 和 运算就是 不考虑 进位的话,对每一位来相加,0 和0 1 和1 的结果都是0,0+1,或者1+0 的结果 都是1;那么我们会看出它与我们学过的异或运算相同,就是相同为假,不同为真,所以叫 异 或 XOR 。 + +第二步: 对0 加 0、1加0、0加1 而言,都不会产生进位,只有1+1 的时候,会产生一个进位。此时 我们可以想象成两个数 先做了一个 位 与 & 运算,然后再向 左移 一位。只有两个数是1 的时候,位与 & 得到的结果是 1,其余的都是0。 + +第三步:把前面两个步骤的结果再相加,然后在继续判断是否有进位,直到没有进位为止,那么此时的相加的过程,依然是重复前面的两步,直到不产生进位为止。 + + + +```python +# -*- coding:utf-8 -*- +class Solution: + def Add(self, num1, num2): + #第一种代码:循环。简洁但是原理相同,那么我们以下面第二段代码为例;来解析。 + # while (num2): + # num1, num2 = (num1 ^ num2) & 0xFFFFFFFF, ((num1 & num2) << 1) & 0xFFFFFFFF + # return num1 if num1 <= 0x7FFFFFFF else ~(num1 ^ 0xFFFFFFFF) + + #第二种代码: + #首先两个数做 一个 异或 运算^ 那就是 在不进位的情况下,让两个相加 求和。 + xorNum = num1 ^ num2 + #让两个数 做 位与 操作,然后再向 左 移 一位,得到它 向前进位的值。 + andNum = (num1 & num2) << 1 + #判断,当 进位 的值不等于0 的时候,说明 一直有进位,也就是 过程没有结束。 + while andNum != 0: + #那么我们就继续上面的操作。但是这次的 数值 改为上次的两个结果, + #一个 是异或的结果,一个是 与 操作 & 以后 左移一位的 结果。 + tmp1 = xorNum ^ andNum + tmp2 = (xorNum & andNum) << 1 + #因为如果这个数为负数的话,那么负数 左移 一位与正数 不同,负数 是数值变小,正数 数值变大 + #如果是正数的话那么这一步就 不变,如果是负数的话,这一步就对负数来起作用。 + #对于python来说 负数的 二进制 可能会有无数个1,我们用这个方法让它变成一个可数的数字长度。 + tmp1 = tmp1 & 0xffffffff + + xorNum = tmp1 + andNum = tmp2 + #一个负整数(或原码)与其补数(或补码)相加,和为模。 0xffffffff + # ~(xorNum ^ 0xFFFFFFFF) 这个是 异或数 与 模 来 异或,最后 按位 取反 来求得 负数的补码。 + return xorNum if xorNum <= 0x7ffffff else ~(xorNum ^ 0xFFFFFFFF) +``` + +## 21.数组中出现次数超过一半的数字[^本题考点 数组] + +**数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。** + + 思路:抵消掉 遇到不相同的数字就相互抵消掉,最终剩下的数字就可能是出现次数大于数组长度一半的数字。 + 首先我们来遍历数字,遍历的时候需要记录上次出现的数字是什么,进而判断 下次出现的数字是否与现在这个数字相等,如果不相等的话,那么就把两个数字抵消掉,到最后没有抵消掉的数字,就可能是出现的次数大于数组长度的一半。 + + +我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,另一个是次数;当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1,如果下一个数字和我们之前保存的数字不同,则凑数减1.如果次数为0 ,我们需要保存下一次出现的次数,然后把次数设置为1. + + + + + +```python +# -*- coding:utf-8 -*- +class Solution: + def MoreThanHalfNum_Solution(self, numbers): + # write code here + #dict [key] = count + #o(n) 空间复杂度为O(n) + #第一种思路:建 一个字典,把数字作为键,数字出现的次数作为值,然后 遍历这个数组中的数,如果这个数作为键出现过,那么就让他的值加1,如果没有就把它添加到字典中。 + numsCount = {} + numLen = len(numbers) + for num in numbers: + if num in numsCount: + numsCount[num] += 1 + else: + numsCount[num] = 1 + #如果说字典中某个键 大于 我们这个数组长度的一半,那么就返回这个键, 数组长度的一半 可以用 >> 1右移以为来实现,右移以为相当于 是除以2. + if numsCount[num] > (numLen >> 1): + return num + return 0 + + #想要空间复杂度为O(1),时间复杂度为o(n) +#第二种: + #定义变量 上次出现的数字为0 + last = 0 + #上次出现的数字的数量为0 + lastCount = 0 + #遍历数组中的数字 + for num in numbers: + #如果说这个数字出现的次数为0了。 + if lastCount == 0: + #那么就把上次出现的数字,变为需要保存的那个数字。 + last = num + #并把次数设置为1 次,出现了这一次。 + lastCount = 1 + else: + #否则就判断,这个数字是不是与上次出现的次数相同,如果相同的话,那么我们这个数字出现的次数就加1. + if num == last: + lastCount += 1 + #如果不同的话,那么我们就让这两个数字抵消掉,那么这个数字出现的次数需要减 1; + else: + lastCount -= 1 + #如果最后遍历完事之后 这个记录数字出现次数的 值为0 的话,那么就说明我们的这个数组里面的数刚好可以两两抵消掉 + if lastCount == 0: + return 0 + #否则的话,就说明 数组里面 留下了没有抵消掉的数 + else: + #这种情况是last可能是大于一半的数字 + #这个时候把 记录数字次数的变量 计数 为0 + lastCount = 0 + #遍历数组中的数 + for num in numbers: + #如果这个数与我们记录的数相等的话 + if num == last: + #让这个计数加1 + lastCount += 1 + #最后判断一下,这个数的计数次数,是不是大于 我们数组长度的一半,如果是的话,就返回这个数,如果不是就返回0. + if lastCount > (len(numbers)>> 1): + return last + return 0 +``` + +___ + +## 22.数组中只出现一次的数字[^数组] + +**一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。** + +思路:其他数字出现的次数都是偶数次,那么我们就可以用到异或的一个性质,那就是 任何一个数字异或它自己都等于0.,也就是说如果我们 从头到尾 异或 数组中的每个数字,那么最终的结果刚好是那个 只出现一次的数字,因为那些成对出现的数字都已经全部抵消掉了。 + +```python +# -*- coding:utf-8 -*- +class Solution: + # 返回[a,b] 其中ab是出现一次的两个数字 + def FindNumsAppearOnce(self, array): + # write code here + #如果两个数相同那么两个数的异或操作为0 + #数组的长度如果小于2,那么就就不会有数字出现了偶数次。 + if len(array) < 2: + return None + + #变量赋值 两个数的异或为none + twoNumXor = None + #遍历 数组中的数字 + for num in array: + #判断 如果 两个数的数字异或的结果为0 的话, + if twoNumXor == None: + #那么 此时就让 两个数异或中的一个数 为此时遍历出来的那个数。 + twoNumXor = num + #如果数 这个数不为 空 的话 + else: + #那么就让这个 两个数异或的结果的值 (或者当 异或的值为空的时候,我们赋给的值 与 此时遍历数组中的数得到的 num 来异或。 + twoNumXor = twoNumXor ^ num + #变量 计数 为 0 + count = 0 + #当异或的 结果 为偶数时 + while twoNumXor % 2 == 0 : + #那么我们就给它 除以2 ,每除一次2 就记录一次,直到 结果不为 奇数 为止。 + twoNumXor = twoNumXor >> 1 # 右移以为 相当于 除以2 + count += 1 + #以上是用来计数 判断 这个 二进制数中 第一个1 是在哪一位上。 + + #我们在这个结果中 找到 第一个为1 的位的位置,记为 第 n 位,那么 现在我们以第n 位 是不是 1 + + mask = 1 << count #向左 移 位 count 位。 + + #为标准 把原 数组中的数字分成两个子数组,第一个数组中每个数字的第n 位 都是1,而 第 二个子 数组中的 每个数字的第 n 位 都是 0.由于我们的分配的标准是 数字中的某一位是0 还是1 ,那么数字相同的数肯定被分到了 同一组,那么每个 子数组中 都会包含一个 只 出现一次的数字,而 其他数字都出现了两次,这个时候,分别把 子数组中的 所有的数 异或,那么 最后的结果 就是 那个 出现一次的数。 + + firstNum = None + secondNum = None + + for num in array: + if mask & num == 0: + if firstNum == None: + firstNum = num + else: + firstNum = firstNum ^ num + else: + if secondNum == None: + secondNum = num + else: + secondNum = secondNum ^ num + + return firstNum,secondNum +``` + +___ + +## 23.整数中1出现的次数[^本题考点 数组] + +**求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。** + + ![](整数中1出现的次数.png) + +___ + +如上图所示,如果那个数 是我们 的 1-n 中 n 这个数,那么这个数就是一个特别大的数,不能遍历 计算每个数字的1 的个数, 那就只能去寻找1在数字中出现的规律来。 + +那么我们可以把 这个数字中 ,分段来 看 1 在这个数字片段中可能出现的情况都有多少。 + +**若 以上 栗子 中的 十万位上的 0 那一位 为 数字1 的话,有多少种 可能? ** + +​ 首先 直接 为1 的话,这个数就会大于 我们的n 这个数,所以 它需要 向前一位借 一位,来计算 可能出现的 情况 有多少种,那么就是 一共 有 + +`0-3458` 个数 那么就一共是 3459 中可能性。 + +​ **那么十万位 后面 出现1 的情况有多少种 可能性 ?** + +​ 0 后面一共有5 位,每 一 位 的数字 可能的情况 是 0-9 共 十 个数字,也就是说 后面 为的可能性是 `10^5`. + +那么就是说对于 十万位数字是0 来说,一共有3459*(10^5 )种 可能。 + +​ **接下来我们在考虑一个 数字 那就是 万 位 上的数字,8,如果8 这一位为1 的话,有多少种可能性?** + +如果8 为1 的话,那么就是我们前面的数字 有 1-34590,共`34591`种情况,后面 是一共 4 位,那么就有 `10^4 `种情况。 + +那么就是说对于 万位数字是0 来说,一共有34591*(10^4) 种 可能。 + +​ **我们再考虑另一个特殊的,那就是我们的百位上的 1 那一位,除了现在的n 的百位上是1,那么其他 这个一位为1 的情况,一共有多少种可能?** + +如果说1 这个数字不变的话,那么1前面 的位数 可能为1 的可能性就是 0-3459082,后面的两位的 可能性为 0-90,不能大于90,如果大于的话,需要 跟 百位来借 一位了,我们先考虑这种不借位的可能性,那就是 + +3459083*91,如果借位的话,那么前面就是 0-3459081,后面就10^2-91 为9 种 情况,那么最后 一共有 + +3459083 x 91+3459082 x 9,最后推导为 3459082 x 91 + 91 + 3459082 x 9,最后为 3459082 *10^2 +91种 可能性。 + +分析了三种特殊的情况,那么我们可以用递归的方式来找,只不过因为递归的话 时间复杂度比较高,那么我们可以写一个 与递归等价的 while 循环来实现,递归和 while 循环是可以互相转换的。 + + + +```python +class Solution: + def NumberOf1Between1AndN_Solution(self, n): + # write code here + #循环的出口是 highValue = 0 + #我们从最低位开始一个位一个位的来寻找 1 的可能出现的 情况次数。 + # 一开始 精准度为1.高位低位中位 先赋值为1. + preceise = 1 + highValue = 1 + lowValue = 1 + midValue =1 + #计数 后面的位数。 + count = 0 + #计数 1 的次数和 + sumNum = 0 + #循环的 出口是我们找不到最高位了,那么这个时候就说明,我们遍历到了 这个数字的最高位。 + while highValue != 0: + #高位 先将这个数 除以10 得到高位 + highValue = n // (preceise * 10) + #中位 先将这个数 与 10 取余。 + midValue = (n // preceise)%10 + #低位 先将这个数 除以 1 那么低位就是个位后面的,没有就是0. + lowValue = n % preceise + #每遍历一次 向右移一位,那么就是说 精准度要乘以10. + preceise *= 10 + #如果这个数是0 的话, + + if midValue == 0: + #那么它就是高位的值,乘以 10^后面的位数 次方,但是这个时候 对于中位 来说 它是个位,后面没有位,所以是0, + num = (highValue)* pow(10,count) + #如果这个数 大于1 的话, + elif midValue > 1: + #那么它 就是 最高位加1 乘以 10^后面的位数 次方, + num = (highValue+1)*pow(10,count) + else: + #否则的话 它就是等于1 的情况了,对于等于1 的1情况,又是比较特殊的情况,它需要 最高位 * 它10 的后面位数个数的次方,然后要加上我们低位 的数值再加 1, 原因在上面的分析中已经给出。 + num = highValue*pow(10,count)+(lowValue+1) + #最后 我们1 出现的 次数 就是这 三个 num 的和,。 + sumNum += num + #没循环一次,这个三个就往左移一次吗,那么这个时候它们 后面的位数也就会 多一位。 + count += 1 + #最后返回这个 次数和。 + return sumNum +``` + +___ + +## 24.丑数 + +**把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。** + +思路分析 第一种方法:所谓的一个数n 的因子,是指 n 能被m 整除,也就是 n%m == 0; 根据丑数 的定义,丑数只能被 2,3,5 整除,也就是说,如果一个数能被2 整除,能被3 整除,能被5 整除,如果最后的到的数是1.那么这个数就是丑数,否则就不是。 先搞清楚丑数的定义是什么? + +因此按照这个思路我们就可以 写出下面的 代码。但是 这个代码 是逐个判断的每个整数是不是丑数的解法,它直观,但是不够高效,最大的问题是 一个不是丑数的数,我必须要计算 而且判断它是不是丑数。 + +```python +class Solution: + def GetUglyNumber_Solution(self, index): + # write code here + if index < 1: + return None + #死循环,找丑数 + #判断一个数是不是丑数,先循环除以2,直到不能整除, + #循环除以3 直到不能整除,循环除以5 直到不能整除 + #这时如果剩余的值是1 我们就说它是丑数 + #其他情况就都不是丑数 + def isUglyNumber(num): + while num % 2 == 0: + num = num //2 + while num % 3 == 0: + num = num //3 + while num % 5 == 0: + num = num //5 + if num == 1: + return True + else: + return False + count = 0 + num = 1 + while True: + if isUglyNumber(num): + count += 1 + if count == index: + return num + num += 1 +``` + +第二种方法分析: + +我们可以保存已经找到的丑数,然后 用空间环时间 来 找出丑数。 + +如何用空间换时间? + +我们找一种,只需要计算丑数的办法,根据上面丑数的定义,我们可以知道,丑数应该是另一个丑数 乘以 2,3,或者5 的结果(1除外)。因此我们 可以创建一个 列表,里面的数字是排好序的 丑数,每个丑数都是前面的丑数乘以2,3,或者5得到的。 + + + +那么我们就可以在一个列表中,给它第一个 丑数的值,然后根据 它 得到剩下的 丑数的值,第一个丑数为1,那么我们在这个列表的起始位置 设置三个指针,这三个指针代表的值 分别为2,3,5.又由于这个列表中的所有的丑数 是有序的,从小到大排列的,那么我们在每次 给一个丑数 乘以 2,3,5 以后要与前面的丑数比较大小,然后在根据大小值 来放入列表中。由于一开始第一个丑数是1,那么 1 * 2 得到的是2,1*3 得到的是3,1 乘以5 得到的是5,那么三个数中比较大小,最小的是 1 乘以2,那么 肯定第一个先放置的是2,然后是 2 乘以2 和 1乘3,1乘5 比较大小,最小的是3 那么就放置 3,下一个 是 2 乘以3 是6,6 与 5 和4 比较大小 最小的是4,以此类推,那么现在的到的丑数的顺序就是1,2,3,4.。。。。。 + + + +```python + + +class Solution(object): + def nthUglyNumber(self, index): + #首先判断 要找的 丑数 是不是第0个 或者是负数,如果是的话,那么就返回0 + if index <= 0: + return 0 + #然后判断要找的丑数 是不是第一个,如果是第一个,那么就返回1. + if index == 1: + return 1 + #在丑数 这个列表中 给出第一个丑数是1 + numbers = [1] + #在列表的 一开始 设置三个 指针,也就是 三个指针的 索引位置是0, + two, three, five = 0, 0, 0 + #丑数的个数 起始为 1 + count = 1 + #循环 当丑数的个数不等于我们要找到 那第 index 个 丑数时,就循环,等于的时候就跳出循环。 + while count != index : + #给列表中的 2,3,5 这三个指针所在位置的 丑数 分别 乘以2,3,5 + n2, n3, n5 = numbers[two] * 2, numbers[three] * 3, numbers[five] * 5 + #比较这三个丑数的大小 + minValue = min(n2, n3, n5) + #在丑数列表中,把三个中最小的那个 放进去。 + numbers.append(minValue) + #每放进去一个,丑数的数量就加1 + count += 1 + #这个是指针移位的,如果说我们比较出来的 三个数中最小的丑数是 2 指针的话,那么2 指针就往前移动一位 + if minValue == n2: + two += 1 + #如果是 3 那个指针的话,那么3 这个指针就移一位。 + if minValue == n3: + three += 1 + #如果是 5 那个指针的话,那么5这个指针就移一位。 + if minValue == n5: + five += 1 + #最后输出这个丑数列表中的 最后一位,那么就是我们的计数的丑数的个数 -1,就是最后一个丑数的索引值。 + return numbers[count-1] +``` + +___ + diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\211\221\346\214\207offer25-50\351\242\230.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\211\221\346\214\207offer25-50\351\242\230.md" new file mode 100644 index 0000000000000000000000000000000000000000..31fd9b8ba3b0f6b63211e22478d2cb6e2544c255 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\211\221\346\214\207offer25-50\351\242\230.md" @@ -0,0 +1,563 @@ +#### 树的知识点: + +##### 什么叫做树? + +**树状图**是一种[数据结构](https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1450),它是由n(n>=0)个有限结点组成一个具有层次关系的[集合](https://baike.baidu.com/item/%E9%9B%86%E5%90%88)。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点: + +每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点外,每个子结点可以分为多个不相交的子树; + +叶节点没有子节点,根节点没有父节点。 + +##### 什么是二叉树? + +每个节点最多含有两个子树的树称为二叉树。下图就是一个二叉树。 + +在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。 + +一棵深度为k,且有2^k-1个节点的二叉树,称为满二叉树。这种树的特点是每一层上的节点数都是最大节点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树。具有n个节点的完全二叉树的深度为floor(log2n)+1。深度为k的完全二叉树,至少有2k-1个节点,至多有2k-1个节点 + + + +![](C:\Users\Administrator\Desktop\剑指offer\二叉树.png) + +##### 二叉树的遍历: + +遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,[树的遍历](https://baike.baidu.com/item/%E6%A0%91%E7%9A%84%E9%81%8D%E5%8E%86)实质上是将二叉树的各个结点转换成为一个线性序列来表示。 + +设L、D、R分别表示遍历左子树、访问根结点和遍历右子树, 则对一棵二叉树的遍历有三种情况:DLR(称为先根次序遍历),LDR(称为中根次序遍历),LRD (称为后根次序遍历)。 + +```python +class treeNode(object): + def __init__(self,x): + self.val = x + self.left = None + self.right = None + +#1. 深度优先 +#2. 广度优先 +#对于深度优先来说: +""" + +1 先序遍历 先打印根 1,2,4,5,3,6,8,7 +2 中序遍历 先打印左侧的叶子节点 4,再输出 中节点 2 ; 4 2 5 1 6 8 3 7 +3 先序遍历 输出顺序 4 5 2 8 6 7 3 1 + +注意: 先序 中序 后序 都是对应于根节点来说的,左右节点都是先左后右 + +""" +#递归 +def preOrderRecusive(root): + if root == None: + return None + + print(root.val) + preOrderRecusive(root.left) + preOrderRecusive(root.right) + +def midOrderRecusive(root): + if root == None: + return None + midOrderRecusive(root.left) + print(root.val) + midOrderRecusive(root.right) + + +def laterOrderRecusive(root): + if root == None: + return None + laterOrderRecusive(root.left) + laterOrderRecusive(root.right) + print(root.val) + +#非递归的形式 去遍历数 +#递归和循环是可以互相转换的 + +""" + +1 先根遍历 先访问根节点,再访问左子节点,最后访问右子节点 +2 中根遍历 先访问左子节点,再访问根节点,最后访问右子节点 +3 后跟遍历 先访问左子节点,再访问右子节点,最后访问根节点。 + +""" + +def preOrder(root): + if root == None: + return None + + stack = [] + tmpNode = root + while tmpNode or stack : + while tmpNode: + print(tmpNode.val) + stack.append(tmpNode) + tmpNode = tmpNode.left + node = stack.pop() + tmpNode = node.right + +def midOrder(root): + if root == None: + return None + + stack = [] + tmpNode = root + while tmpNode or stack : + while tmpNode: + + stack.append(tmpNode) + tmpNode = tmpNode.left + node = stack.pop() + print(node.val) + tmpNode = node.right + +def laterOrder(root): + if root == None: + return None + + stack = [] + tmpNode = root + while tmpNode or stack : + while tmpNode: + stack.append(tmpNode) + tmpNode = tmpNode.left + node = stack[-1] + tmpNode = node.right + if node.right == None: + node = stack.pop() + print(node.val) + while stack and node == stack[-1].right: + node = stack.pop() + print(node.val) +``` + +## 25.重建二叉树 + +**输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。** + +```python +# -*- coding:utf-8 -*- +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +class Solution: + # 返回构造的TreeNode根节点 + def reConstructBinaryTree(self, pre, tin): + # write code here + if not pre or not tin: + return None + if len(pre) != len(tin): + return None + # 取出pre 的第一个值 就是根节点 + root = pre[0] + rootNode = TreeNode(root) + # 找到在 tin 中序遍历中的根节点 所在的索引位置 + pos = tin.index(root) + # 中序遍历的 列表的左右节点 分开 切片 成两个列表 + tinLeft = tin[0:pos] + tinRight = tin[pos + 1:] + # 前序遍历的 列表的左右节点 分开 切片 成两个列表 + preLeft = pre[1:pos + 1] + preRight = pre[pos + 1:] + + leftNode = self.reConstructBinaryTree(preLeft, tinLeft) + rightNode = self.reConstructBinaryTree(preRight, tinRight) + + rootNode.left = leftNode + rootNode.right = rightNode + return rootNode +``` + +___ + + + +## 26.树的子结构 + +**输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)** + +```python +# -*- coding:utf-8 -*- +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +class Solution: + def HasSubtree(self, pRoot1, pRoot2): + # write code here + if pRoot2 == None or pRoot1 == None: + return False + + def hasEqual(pRoot1, pRoot2): + if pRoot2 == None: + return True + if pRoot1 == None: + return False + if pRoot1.val == pRoot2.val: + if pRoot2.left == None: + leftEqual = True + else: + leftEqual = hasEqual(pRoot1.left, pRoot2.left) + if pRoot2.right == None: + rightEqual = True + else: + rightEqual = hasEqual(pRoot1.right, pRoot2.right) + return leftEqual and rightEqual + return False + + if pRoot1.val == pRoot2.val: + ret = hasEqual(pRoot1, pRoot2) + if ret: + return True + + ret = self.HasSubtree(pRoot1.left, pRoot2) + if ret: + return True + + ret = self.HasSubtree(pRoot1.right, pRoot2) + return ret + + +""" + +对于Python这道题,有些地方需要仔细考虑的。 + +先说下算法实现思路:对于两棵二叉树来说,要判断B是不是A的子结构,首先第一步在树A中查找与B根节点的值一样的节点。 + +通常对于查找树中某一个节点,我们都是采用递归的方法来遍历整棵树。 + +第二步就是判断树A中以R为根节点的子树是不是和树B具有相同的结构。 + +这里同样利用到了递归的方法,如果节点R的值和树的根节点不相同,则以R为根节点的子树和树B肯定不具有相同的节点; + +如果它们值是相同的,则递归的判断各自的左右节点的值是不是相同。 + +递归的终止条件是我们达到了树A或者树B的叶节点。 + +有地方要重点注意,DoesTree1haveTree2()函数中的两个 if 判断语句 不能颠倒顺序 。 +因为如果颠倒了顺序,会先判断pRoot1 是否为None, 其实这个时候,pRoot1 的节点已经遍历完成确认相等了,但是这个时候会返回 False,判断错误。 + +有同学不相信的,可以去试试换个顺序,肯定不能AC。同时这个也是《剑指offer》书上没有写的,希望能引起大家的注意。 + +""" +# -*- coding:utf-8 -*- +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +class Solution2: + def HasSubtree(self, pRoot1, pRoot2): + # write code here + result = False + if pRoot1 != None and pRoot2 != None: + if pRoot1.val == pRoot2.val: + result = self.DoesTree1haveTree2(pRoot1, pRoot2) + if not result: + result = self.HasSubtree(pRoot1.left, pRoot2) + if not result: + result = self.HasSubtree(pRoot1.right, pRoot2) + return result + # 用于递归判断树的每个节点是否相同 + # 需要注意的地方是: 前两个if语句不可以颠倒顺序 + # 如果颠倒顺序, 会先判断pRoot1是否为None, 其实这个时候pRoot2的结点已经遍历完成确定相等了, 但是返回了False, 判断错误 + def DoesTree1haveTree2(self, pRoot1, pRoot2): + if pRoot2 == None: + return True + if pRoot1 == None: + return False + if pRoot1.val != pRoot2.val: + return False + return self.DoesTree1haveTree2(pRoot1.left, pRoot2.left) and self.DoesTree1haveTree2(pRoot1.right, pRoot2.right) +``` + +___ + +## 27.二叉树的镜像 + +**操作给定的二叉树,将其变换为源二叉树的镜像。** + +##### `输入描述:` + +```python +二叉树的镜像定义:源二叉树 + 8 + / \ + 6 10 + / \ / \ + 5 7 9 11 + 镜像二叉树 + 8 + / \ + 10 6 + / \ / \ + 11 9 7 5 +``` + +___ + + + +```python +# -*- coding:utf-8 -*- +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +class Solution: + # 返回镜像树的根节点 + def Mirror(self, root): + # write code here + if root == None: + return None + #处理根节点 + root.left,root.right = root.right,root.left + self.Mirror(root.left) + self.Mirror(root.right) +``` + +___ + +## 28.从上往下打印二叉树 + +**从上往下打印出二叉树的每个节点,同层节点从左至右打印。** + +```python +# -*- coding:utf-8 -*- +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +class Solution: + # 返回从上到下每个节点值列表,例:[1,2,3] + def PrintFromTopToBottom(self, root): + # write code here + if root == None: + return [] + treeNodeTmp = [root] + ret = [] + while treeNodeTmp: + tmpNode = treeNodeTmp[0] + ret.append(tmpNode.val) + if tmpNode.left: + treeNodeTmp.append(tmpNode.left) + if tmpNode.right: + treeNodeTmp.append(tmpNode.right) + del treeNodeTmp[0] + return ret +``` + +___ + +## 29.二叉搜索树的后序遍历序列 + +**输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。** + +```python +""" +python:后序遍历 的序列中,最后一个数字是树的根节点 ,数组中前面的数字可以分为两部分:第一部分是左子树节点 的值,都比根节点的值小;第二部分 是右子树 节点的值,都比 根 节点 的值大,后面用递归分别判断前后两部分 是否 符合以上原则 + +""" + + +class Solution: + def VerifySquenceOfBST(self, sequence): + # write code here + if sequence==None or len(sequence)==0: + return False + length=len(sequence) + root=sequence[length-1] + # 在二叉搜索 树中 左子树节点小于根节点 + for i in range(length): + if sequence[i]>root: + break + # 二叉搜索树中右子树的节点都大于根节点 + for j in range(i,length): + if sequence[j]0: + left=self.VerifySquenceOfBST(sequence[0:i]) + # 判断 右子树是否为二叉树 + right=True + if i rootNum: + index = i + if index != None and sequence[i] < rootNum: + return False + if sequence[:index] == []: + leftRet = True + else: + leftRet = self.VerifySquenceOfBST(sequence[:index]) + if sequence[index:] == []: + rightRet = True + else: + rightRet = self.VerifySquenceOfBST(sequence[index:]) + + return leftRet and rightRet +``` + +___ + + + +## 30.二叉树中和为某一值的路径 + +**输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)** + +```python +""" +递归先序遍历树, 把结点加入路径。 +若该结点是叶子结点则比较当前路径和是否等于期待和。 +弹出结点,每一轮递归返回到父结点时,当前路径也应该回退一个结点 + +""" +# -*- coding:utf-8 -*- +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +import copy + + +class Solution: + # 返回二维列表,内部每个列表表示找到的路径 + def FindPath(self, root, expectNumber): + # write code here + if root == None: + return [] + + ret = [] + support = [root] + supportArrayList = [[root.val]] + + while support: + tmpNode = support[0] + tmpArrayList = supportArrayList[0] + if tmpNode.left == None and tmpNode.right == None: + if sum(tmpArrayList) == expectNumber: + ret.insert(0, tmpArrayList) + + if tmpNode.left: + support.append(tmpNode.left) + newTmpArrayList = copy.copy(tmpArrayList) + newTmpArrayList.append(tmpNode.left.val) + supportArrayList.append(newTmpArrayList) + if tmpNode.right: + support.append(tmpNode.right) + newTmpArrayList = copy.copy(tmpArrayList) + newTmpArrayList.append(tmpNode.right.val) + supportArrayList.append(newTmpArrayList) + + del supportArrayList[0] + del support[0] + + return ret + + + +# -*- coding:utf-8 -*- +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +class Solution2: + # 返回二维列表,内部每个列表表示找到的路径 + def FindPath(self, root, expectNumber): + # write code here + if not root: + return [] + + result = [] + + def FindPathMain(root, path, currentSum): + currentSum += root.val + + path.append(root) + isLeaf = root.left == None and root.right == None + + if currentSum == expectNumber and isLeaf: + onePath = [] + for node in path: + onePath.append(node.val) + result.append(onePath) + + if currentSum < expectNumber: + if root.left: + FindPathMain(root.left, path, currentSum) + if root.right: + FindPathMain(root.right, path, currentSum) + + path.pop() + + FindPathMain(root, [], 0) + + return result +``` + +___ + + + +## 31.二叉搜索树与双向链表 + +**输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。** + +```python +# -*- coding:utf-8 -*- +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +class Solution: + def Convert(self, pRootOfTree): + # write code here + if pRootOfTree == None: + return None + + def find_right(node): + while node.right: + node = node.right + return node + + leftNode = self.Convert(pRootOfTree.left) + rightNode = self.Convert(pRootOfTree.right) + + retNode = leftNode + + if leftNode: + leftNode = find_right(leftNode) + else: + retNode = pRootOfTree + + pRootOfTree.left = leftNode + pRootOfTree.right = rightNode + + if leftNode != None: + leftNode.right = pRootOfTree + if rightNode != None: + rightNode.left = pRootOfTree + + return retNode +``` \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\217\215\350\275\254\351\223\276\350\241\250.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\217\215\350\275\254\351\223\276\350\241\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..ef7b6318f65585bb697e22c587968d4d49081d78 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\217\215\350\275\254\351\223\276\350\241\250.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\220\210\346\210\220\344\270\200\344\270\252\351\223\276\350\241\250.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\220\210\346\210\220\344\270\200\344\270\252\351\223\276\350\241\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..4bb734313364b0a1a9b28ba30a9ecff70a85bba8 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\220\210\346\210\220\344\270\200\344\270\252\351\223\276\350\241\250.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260.png" new file mode 100644 index 0000000000000000000000000000000000000000..7837ac182ce861e2b5e047a842071008f98c0c69 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\234\206\345\234\210\344\270\255\346\234\200\345\220\216\345\211\251\344\270\213\347\232\204\346\225\260.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266.png" new file mode 100644 index 0000000000000000000000000000000000000000..c6342cd41d7887aab70a6a695a2926e0d3f209c0 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\244\215\346\235\202\351\223\276\350\241\250\347\232\204\345\244\215\345\210\266.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\260\217\346\234\213\345\217\213\347\232\204\346\270\270\346\210\217.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\260\217\346\234\213\345\217\213\347\232\204\346\270\270\346\210\217.png" new file mode 100644 index 0000000000000000000000000000000000000000..22617a7fdcf84dfe66beba30e53a52174601e14a Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\260\217\346\234\213\345\217\213\347\232\204\346\270\270\346\210\217.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\260\217\346\234\213\345\217\213\347\232\204\346\270\270\346\210\217\345\205\254\345\274\217.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\260\217\346\234\213\345\217\213\347\232\204\346\270\270\346\210\217\345\205\254\345\274\217.png" new file mode 100644 index 0000000000000000000000000000000000000000..414e0f77b3b4d1171f268b5456a18899aa9b77b7 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\345\260\217\346\234\213\345\217\213\347\232\204\346\270\270\346\210\217\345\205\254\345\274\217.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.png" new file mode 100644 index 0000000000000000000000000000000000000000..c61cc64225b95fbea89efca9fd8ec31ebdc73877 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\346\225\264\346\225\260\344\270\2551\345\207\272\347\216\260\347\232\204\346\254\241\346\225\260.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\346\234\200\345\244\247\345\240\206\346\234\200\345\260\217\345\240\206.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\346\234\200\345\244\247\345\240\206\346\234\200\345\260\217\345\240\206.png" new file mode 100644 index 0000000000000000000000000000000000000000..9c6e27cea19ea64c89c9af6d5e13d3ea425926de Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\346\234\200\345\244\247\345\240\206\346\234\200\345\260\217\345\240\206.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\350\241\245\347\240\201.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\350\241\245\347\240\201.md" new file mode 100644 index 0000000000000000000000000000000000000000..8d8e9385c1d30847952c6787b6334b9787ccf085 --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\350\241\245\347\240\201.md" @@ -0,0 +1,43 @@ +#### 补码 + +特性: + +1、一个负整数(或原码)与其补数(或补码)相加,和为模。 + +2、对一个整数的补码再求补码,等于该整数自身。 + +3、补码的正零与负零表示方法相同 + +#### 按位取反 ~ + +~,用法只有一个那就是按位取反,需要注意的是: + +- ~的按位取反,包括符号位 +- 正数各位取反变为负数,显示时转化为其补码 +- 负数本身需要先转换为补码(符号位不变,各位取反再加 1),再对其补码进行各位去反 + +##### 1. ~5 + +5 的二进制为 0101, + +~5 + +- (1)各位取反,1010 +- (2)变为负数,转化为其补码形式(符号位保持不变),各位取反 1(1101),再加1(1110),也即 -6 + +``` +>> ~5 +>> -6 +``` + +##### 2. ~(-5) + +-5 因为是负数,存储时存储的是其补码: + +- -5 的补码是:1011, +- ~(-5)将其各位取反(包括符号位),也即 0100(4) + +``` +>> ~(-5) +>> 4 +``` \ No newline at end of file diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\351\223\276\350\241\250.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\351\223\276\350\241\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..e4293487692c3238109b9d36019ae7af5342073d Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\351\223\276\350\241\250.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\232\204\347\254\254k\344\270\252\347\273\223\347\202\271.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\232\204\347\254\254k\344\270\252\347\273\223\347\202\271.png" new file mode 100644 index 0000000000000000000000000000000000000000..89092d89d9dd0f945fd576b65f20235c17974b5a Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\351\223\276\350\241\250\344\270\255\345\200\222\346\225\260\347\232\204\347\254\254k\344\270\252\347\273\223\347\202\271.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271.png" new file mode 100644 index 0000000000000000000000000000000000000000..7eaed4e2ec15ccd9225a3c860321704cc53f40d0 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\351\223\276\350\241\250\344\270\255\347\216\257\347\232\204\345\205\245\345\217\243\347\273\223\347\202\271.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266.png" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266.png" new file mode 100644 index 0000000000000000000000000000000000000000..08802248642c69c73748a045fd195579c72edbd7 Binary files /dev/null and "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\211\221\346\214\207offer/\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266.png" differ diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\212\250\346\200\201\350\247\204\345\210\222\347\256\227\346\263\225/READMNE.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\212\250\346\200\201\350\247\204\345\210\222\347\256\227\346\263\225/READMNE.md" new file mode 100644 index 0000000000000000000000000000000000000000..7149a6225b6abb80c74b85c1637f874602d3d4ae --- /dev/null +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\212\250\346\200\201\350\247\204\345\210\222\347\256\227\346\263\225/READMNE.md" @@ -0,0 +1,197 @@ +# 动态规划问题 + +## 应用场景 + +背包问题:有个背包,初始容量为4磅,现有如下物品 + +0 - 1背包问题,转入的商品不能重复 + +| 物品 | 重量 | 价格 | +| ---- | ---- | ---- | +| 吉他 | 1 | 1500 | +| 音箱 | 4 | 3000 | +| 电脑 | 3 | 2000 | + +1)要求达到的目标为装入的背包的总价值最大,并且重量不能超过 + +2)要求装入物品不能重复 + + + +## 动态规划算法 + +### 概念 + +- 动态规划(DynamicProgramming)算法的核心思想是:将大问题划分成小问题进行解决,从而一步步获取最优解的处理算法 +- 动态规划算法与分治法类似,其基本思想也是将带求解问题,分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解 +- 与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的,(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步求解) +- 动态规划可以通过填表的方式来逐步推进,得到最优解 + +### 求解 0-1背包问题 + +- 背包问题主要指一个给定容量的背包、若干具有一定价值和重量的物品,如何选择物品放入背包使得物品价值最大,其中又分为01背包和完全背包(完全背包指的是:每个物品都是无限件可用) +- 这里的问题属于01背包问题,即每个物品最多放一个,而无限背包可以转回成01背包问题 + +### 主要思想 + +算法的主要思想,利用动态规划来解决,每次遍历到第i个物品,根据 w[i] 和 v[i] 来确定是否需要将该物品放入背包中,即对于给定的n个物品,设v[i] 、w[i]分别为第i个物品的价值和重量,C为背包的容量。再令v[i] [j] 表示前i个物品中能够装入容量为j的背包中的最大价值,则我们有下面的结果。 + +- v[i] [0] = v[0] [j] = 0 +- 当w[i] > j 时:v[i] [j] = v[i - 1] [j] +- 当 j >= w[i]时:v[i] [j] = max {v[i - 1] [j] , v[i - 1] [j - w[i]] + v[i]} + +### 思路推导图 + +使用填表法 + +解决类似的问题可以分解成一个个的小问题进行解决,假设存在背包容量大小为1,2,3,4 的各种容量的背包(分配容量的规则为最小重量的整数倍) + +- 假设现在只有吉他(G),这时候不管背包容量有多大,只能放一个吉他 1500(G) +- 假设现在有 吉他 和 音箱S,那么在 0 - 3 磅的时候,只能放吉他,当为4磅的时候,能放入音箱 +- + +| 物品 | 0磅 | 1磅 | 2磅 | 3磅 | 4磅 | +| ------------------------ | ---- | ------- | ------- | --------- | ------------ | +| | 0 | 0 | 0 | 0 | 0 | +| 吉他G(重量1, 价值1500) | 0 | 1500(G) | 1500(G) | 1500(G) | 1500(G) | +| 音箱S(重量4, 价值3000) | 0 | 1500(G) | 1500(G) | 1500(G) | 3000(S) | +| 电脑L(重量3, 价值2000) | 0 | 1500(G) | 1500(G) | 2000(L) | 3500(G,L) | + +这个时候,就得到了公式 + +- v[i] [0] = v[0] [j] = 0 + - 表示第一行和第一列为0 +- 当w[i] > j 时:v[i] [j] = v[i - 1] [j] + - 当我们装入新增的商品,它的容量大于当前背包的容量时,就直接使用上一个单元格的装入策略 +- 当 j >= w[i]时:v[i] [j] = max {v[i - 1] [j] , v[i] + v[i - 1] [j - w[i]] } + - 当准备新增的商品的容量小于等于当前背包的容量,装入的方式,应该是求一个最大值 + - v[i-1] [j]:表示上一个单元格的装入的最大值 + - v[i]:表示当前商品的价值 + - v[i -1] [j - w[i]]:装入i-1商品,到剩余空间的最大值 + + + +验证公式1 + +- v[i] [j] = 1500 +- i = 1, j = 1 +- w[i] = w[1] = 1 +- j >= w[i] ,满足第三个条件 +- v[i] [j] = max { v[0] [1], val[1]+ v[0] [0] } = max { 0 , 1500 + 0} = 1500 + + + +验证公式2 + +- v[3] [4] = 3500 +- i = 3, j = 4 +- w[i] = w[3] = 3 +- j = 4 >= w[i] , max { v[2] [4], v[3] + v[2] [1] } = max {3000 , 2000 + 1500 } = 3500 + + + +## 代码实现 + +``` +/** + * 动态规划 + * 解决 0-1背包问题 + * + * @author: 陌溪 + * @create: 2020-04-18-15:00 + */ +public class DynamicProgramming { + public static void main(String[] args) { + // 物品的重量 + int w [] = {1, 4, 3}; + + // 物品的价值 + int val [] = {1500, 3000, 2000}; + + // 背包的容量 + int m = 4; + + // 物品的个数 + int n = val.length; + + // 创建二维数组 v[i][j] 表示在前i个物品中,可以装入容量为j的背包中的商品最大值 + int [][] v = new int[n+1][m+1]; + + // 为了记录放入商品的情况,我们定义一个二维数组 + int [][] path = new int[n+1][m+1]; + + // 初始化第一行 和 第一列,这里在本程序中可以不去处理,因为数组默认就是0 + for(int i = 0; i j) { + v[i][j] = v[i-1][j]; + } else { + // 因为我们的i从1开始的,因此公式需要调整成 i -> i-1 +// v[i][j] = Math.max(v[i-1][j], val[i-1] + v[i-1][j - w[i -1]]); + + // 为了记录商品存放的背包的情况,我们不能直接的使用上面的公式,需要使用if else来体现公式 + if(v[i-1][j] < (val[i-1] + v[i-1][j - w[i -1]])) { + v[i][j] = (val[i-1] + v[i-1][j - w[i -1]]); + // 把当前的情况记录到path + path[i][j] = 1; + } else { + v[i][j] = v[i-1][j]; + } + } + } + } + + // 输出一下 + for(int i = 0; i< v.length; i++) { + for(int j = 0; j 0 && j>0) { + if(path[i][j] == 1) { + System.out.print(i + " "); + j -= w[i-1]; + } + // 找到一个 i需要减1 + i --; + } + } +} +``` + +输出结果 + +``` +0 0 0 0 0 +0 1500 1500 1500 1500 +0 1500 1500 1500 3000 +0 1500 1500 2000 3500 +3 1 +``` + diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/CatBoost\347\232\204\345\256\211\350\243\205\345\222\214\344\275\277\347\224\250/README.md" "b/\346\234\272\345\231\250\345\255\246\344\271\240/CatBoost\347\232\204\345\256\211\350\243\205\345\222\214\344\275\277\347\224\250/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..6b7a29aeca04dfdaeadef8a9645937089b0283dc --- /dev/null +++ "b/\346\234\272\345\231\250\345\255\246\344\271\240/CatBoost\347\232\204\345\256\211\350\243\205\345\222\214\344\275\277\347\224\250/README.md" @@ -0,0 +1,84 @@ +# CatBoost的安装和使用 + +## 前言 + +CatBoost算法也是GBDT家族中的一种,是由俄罗斯大兄弟于2017年发表出来的[论文](https://arxiv.org/pdf/1706.09516.pdf),它具备如下的优点: + +- 它自动采用特殊的方式处理**类别型特征(categorical features)**。首先对categorical features做一些统计,计算某个类别特征(category)出现的频率,之后加上超参数,生成新的数值型特征(numerical features)。这也是我在这里介绍这个算法最大的motivtion,有了catboost,再也**不用手动处理类别型特征了。** +- catboost还使用了**组合类别特征**,可以利用到特征之间的联系,这极大的**丰富了特征维度**。 +- catboost的基模型采用的是**对称树**,同时计算leaf-value方式和传统的boosting算法也不一样,传统的boosting算法计算的是平均数,而catboost在这方面做了优化采用了其他的算法,这些改进都能**防止模型过拟合**。 + +## 安装 + +下面我们使用conda进行安装,首先需要删除之前的 `.condarc` 文件,一般在 `C:\Users\Administrator` 目录 + +![image-20200520181910922](images/image-20200520181910922.png) + +然后需要配置国内镜像源 + +``` +conda config --add channels https://mirrors.ustc.edu.cn/anaconda/pkgs/free/ +conda config --add channels https://mirrors.ustc.edu.cn/anaconda/cloud/conda-forge/ +conda config --add channels https://mirrors.ustc.edu.cn/anaconda/cloud/msys2/ +conda config --set show_channel_urls yes +``` + +配置成功后,在Anaconda import中使用conda命令进行安装 + +``` +conda install catboost +``` + +## 使用 + +具体使用,我以一个辍学预测二分类问题案例来进行说明,首先我们引入包 + +```python +from catboost import CatBoostClassifier +import pandas as pd +import numpy as np +``` + +然后在导入我们的数据集 + +```python +subset_train = pd.read_csv('./GaussianNB/train.csv') +subset_test = pd.read_csv('./GaussianNB/test.csv') +x_train = subset_train.drop(["enrollment_id","result"],axis=1) +y_train = subset_train['result'] +x_test = subset_test.drop(["enrollment_id","result"],axis=1) +y_test = subset_test['result'] +``` + +配置我们的CatBoost分类器 + +``` +categorical_features_indices = np.where(x_train.dtypes != np.float)[0] +model = CatBoostClassifier(iterations=100, depth=5,cat_features=categorical_features_indices,learning_rate=0.5, loss_function='Logloss', + logging_level='Verbose') +``` + +开始模型的训练 + +``` +model.fit(x_train,y_train,eval_set=(x_test, y_test),plot=True) +``` + +预测数据的输出,同时输出到指定的目录下 + +``` +pred = (model.predict(x_test)).tolist() ## predicting the output on the test data +catBoost_result = pd.DataFrame(pred) +catBoost_result.to_csv('./GaussianNB/result/catBoostResult.csv', index = False) +catBoost_result.shape +``` + +进行模型精度评判 + +``` +noOfEnrollments = 24108 +# 求出模型的百分精度 +comp = [1 if pred[i] == int(y_test[i]) else 0 for i in range(noOfEnrollments)] +sum(comp)/len(y_test) * 100 +``` + diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/CatBoost\347\232\204\345\256\211\350\243\205\345\222\214\344\275\277\347\224\250/images/image-20200520181910922.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/CatBoost\347\232\204\345\256\211\350\243\205\345\222\214\344\275\277\347\224\250/images/image-20200520181910922.png" new file mode 100644 index 0000000000000000000000000000000000000000..8bd645d7ffee5ac7ec9ddc1917eeda90b1a4740a Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/CatBoost\347\232\204\345\256\211\350\243\205\345\222\214\344\275\277\347\224\250/images/image-20200520181910922.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\344\275\277\347\224\250SMOTE\347\256\227\346\263\225\350\277\233\350\241\214\344\270\212\351\207\207\346\240\267/README.md" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\344\275\277\347\224\250SMOTE\347\256\227\346\263\225\350\277\233\350\241\214\344\270\212\351\207\207\346\240\267/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..c7851b54beab0e0ff8eafa401379adcdd9cf608f --- /dev/null +++ "b/\346\234\272\345\231\250\345\255\246\344\271\240/\344\275\277\347\224\250SMOTE\347\256\227\346\263\225\350\277\233\350\241\214\344\270\212\351\207\207\346\240\267/README.md" @@ -0,0 +1,88 @@ +# 使用SMOTE算法进行过采样 + +## 前言 + +SMOTE算法的思想是合成新的少数类样本,合成的策略是对每个少数类样本a,从它的最近邻中随机选一个样本b,然后在a、b之间的连线上随机选一点作为新合成的少数类样本 + +通过研究,我发现Github有人已经实现了一个 [KmeansSmote算法](https://github.com/felix-last/kmeans_smote)平衡数据集,Kmeans的作用主要是聚类算法,然后在结合SMOTE过采样,以重新平衡数据集。 + +从官网上的简介说到,K-Means Smote算法是一种针对类不平衡数据的过采样方法。它通过在输入空间的安全和关键区域生成少数类样本来辅助分类。该方法避免了产生噪声,有效地克服了类间和类内的不平衡。 + +## 安装 + +安装的前提是确保下面的依赖已经安装成功 + +``` +imbalanced-learn (>=0.4.0, <0.5) +numpy (numpy>=1.13, <1.16) +scikit-learn (>=0.19.0, <0.21) +``` + +首先需要使用pip命令进行安装 + +``` +pip install kmeans-smote +``` + +## 使用 + +目前我的数据集中存在不平衡的问题,如果所示,我们首先将数据集中的标签进行统计 + +``` +import numpy as np +import pandas as pd +from kmeans_smote import KMeansSMOTE +import matplotlib.pyplot as plt + +# 导入测试集和 +train = pd.read_csv('./GaussianNB/train.csv',header=0) +test = pd.read_csv('./GaussianNB/test.csv',header=0) + +# 画出正负样本的比值 +def drawDropout(x): + plt.hist(x,bins=5,rwidth=0.8) + my_x_ticks = np.arange(0, 2, 1) + plt.xticks(my_x_ticks) + plt.xlabel('isDropout') + plt.ylabel('student') + plt.show() + +y = train["result"] +X = train.drop(["enrollment_id","result"],axis=1) +drawDropout(y) +``` + +能够看到,大概存在1:4的关系,貌似也不是很不平衡,我们就看看效果如何 + +![image-20200527221056845](images/image-20200527221056845.png) + +开始使用Kmeans-Smote算法进行平衡 + +``` +[print('Class {} has {} instances'.format(label, count)) + for label, count in zip(*np.unique(y, return_counts=True))] + +kmeans_smote = KMeansSMOTE( + kmeans_args={ + 'n_clusters': 100 + }, + smote_args={ + 'k_neighbors': 10 + } +) +X_resampled, y_resampled = kmeans_smote.fit_sample(X, y) + +[print('Class {} has {} instances after oversampling'.format(label, count)) + for label, count in zip(*np.unique(y_resampled, return_counts=True))] +``` + +输出的结果如下所示,原来的是 1 :4 的关系,经过平衡后,我们合成了少数类样本,然后达到1:1的效果 + +``` +Class 0 has 19917 instances +Class 1 has 76517 instances +Class 0 has 76517 instances after oversampling +Class 1 has 76517 instances after oversampling +``` + +![image-20200527221259769](images/image-20200527221259769.png) \ No newline at end of file diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\344\275\277\347\224\250SMOTE\347\256\227\346\263\225\350\277\233\350\241\214\344\270\212\351\207\207\346\240\267/images/image-20200527221056845.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\344\275\277\347\224\250SMOTE\347\256\227\346\263\225\350\277\233\350\241\214\344\270\212\351\207\207\346\240\267/images/image-20200527221056845.png" new file mode 100644 index 0000000000000000000000000000000000000000..5463d02a003f65a5e787c054915c01dcd71425ee Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\344\275\277\347\224\250SMOTE\347\256\227\346\263\225\350\277\233\350\241\214\344\270\212\351\207\207\346\240\267/images/image-20200527221056845.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\344\275\277\347\224\250SMOTE\347\256\227\346\263\225\350\277\233\350\241\214\344\270\212\351\207\207\346\240\267/images/image-20200527221259769.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\344\275\277\347\224\250SMOTE\347\256\227\346\263\225\350\277\233\350\241\214\344\270\212\351\207\207\346\240\267/images/image-20200527221259769.png" new file mode 100644 index 0000000000000000000000000000000000000000..a1dbe5042009695a1936c63e906d6341a972fb5d Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\344\275\277\347\224\250SMOTE\347\256\227\346\263\225\350\277\233\350\241\214\344\270\212\351\207\207\346\240\267/images/image-20200527221259769.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/README.md" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..ef1ffdc78d78f5b93ea020d2260bd2de1ee15f64 --- /dev/null +++ "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/README.md" @@ -0,0 +1,207 @@ +# 决策树和分类树 + +## 决策树的直观理解 + +![image-20200427180341047](images/image-20200427180341047.png) + +## 分类树之信息熵 + +### 信息熵 + +信息熵是用阿里衡量信息不确定性的指标,不确定性是一个时间出现不同结果的可能性,计算方式如下所示: +$$ +H(X)=-\sum_{i=1}^{n} P(X=i) \log _{2} P(X=i) +$$ +其中:P(X=i) 为随机变量X取值为i的概率。 + +下面以抛硬币为例,得到两个不同的熵值 + +![image-20200427180723072](images/image-20200427180723072.png) + +从上可知,不确定性越大的时候,得到的熵也越高,如百分50概率的时候,我们得到熵为1,而当正面为0.99的时候,熵值为0.08 + + + +### 条件熵 + +在给定随机变量Y的条件下,随机变量X的不确定性,也就是对条件概率求信息熵 +$$ +H(X | Y=v)=-\sum_{i=1}^{n} P(X=i | Y=v) \log _{2} P(X=i | Y=v) +$$ + +### 信息增益 + +熵 减去 条件熵 得到的就是信息增益,代表了在一个条件下,信息不确定性减少的程度。 +$$ +I(X, Y)=H(X)-H(X | Y) +$$ +![image-20200427181614925](images/image-20200427181614925.png) + + + +### 举例 + +假设高尔夫球场拥有不同天气下某个客户的打高尔夫球的历史记录如右图所示我们无法单纯的通过Yes和No的历史频率判断用户明天会不会打高尔夫因此我们需要借助天气信息减少不确定性 + +![image-20200427182516870](images/image-20200427182516870.png) + +首先是构建根节点,我们先看下 Play Golf的熵: + +![image-20200427182636732](images/image-20200427182636732.png) + +在14条历史数据中,打球的概率为0.64,不打球的概率为0.36,熵值为0.94。接下来我们寻找睛朗与否,湿度,风力和温度四种状况与是否打高尔夫相关性最高的一个,进行决策树的构建。 + +#### 晴朗程度Outlook的条件熵与信息增益: + +![image-20200427183010140](images/image-20200427183010140.png) + +使用Outlook的条件熵 0.36 * 0.971 + 0.29 * 0 + 0.36 * 0.971 = 0.69 + +信息增益:0.940 - 0.69 = 0.25 (最佳分割特征) + +#### 温度Temp的条件熵与信息增益 + +![image-20200427184708081](images/image-20200427184708081.png) + +#### 风力Wind的条件熵与信息增益 + +![image-20200427184842977](images/image-20200427184842977.png) + + + +#### 总结 + +![image-20200427184859431](images/image-20200427184859431.png) + +这个时候,我们需要选择信息增益最大的,也就是 Outlook作为 最佳分隔特征 + +#### 构建步骤 + +**根节点分隔结果** + +![image-20200427185008572](images/image-20200427185008572.png) + +**根节点和OverCast节点分隔结果:** + +![image-20200427185057844](images/image-20200427185057844.png) + +**Sunny节点分隔结果:** + +![image-20200427185122531](images/image-20200427185122531.png) + +**Rainy节点分隔结果:** + +![image-20200427185218192](images/image-20200427185218192.png) + +#### 最终结果 + +![image-20200427185320167](images/image-20200427185320167.png) + +#### 使用决策树进行预测 + +![image-20200427185413042](images/image-20200427185413042.png) + + + +## 分类树之基尼指数 + +基尼指数(Gn不纯度)**表示在样本集合中一个随机选中的样本被分错的概率** + +注意:Gini指数越小表示集合中被选中的样本被分错的概率越小,也就是说集合的纯度越高,反之,集合越不纯。当集合中所有样本为个类时,基尼指数为0基尼指数的计算方法: +$$ +\operatorname{Gini}(\mathrm{p})=\sum_{k=1}^{K} p_{k}\left(1-p_{k}\right)=1-\sum_{k=1}^{K} p_{k}^{2} +$$ +其中,pk表示选中的样本属于第K个类别的概率 + +### 案例 + +#### 根据天气计算基尼指数 + +根据天气状况预测是否打高尔夫球,首先计算根节点的基尼指数 + +![image-20200427185944222](images/image-20200427185944222.png) + + + +#### 根据晴朗程度计算基尼指数 + +晴朗程度Outlook的基尼指数 + +![image-20200427190109182](images/image-20200427190109182.png) + + + +#### 根据温度的基尼指数 + +![image-20200427190148092](images/image-20200427190148092.png) + + + +#### 湿度的基尼指数 + +![image-20200427190230060](images/image-20200427190230060.png) + + + +#### 风力的基尼指数 + +![image-20200427190250190](images/image-20200427190250190.png) + + + +### 最佳分割点 + +使用基尼指数来分割的树叫CART树,CART树是二叉树,对于一个具有多个取值(超过2个)的特征,需要计算以每一个取值作为划分点,对样本D划分之后子集的纯度Gn(DAi),然后从所有的可能划分的Gin(DA)中找出Gin指数最小的划分,这个划分的划分点,便是使用特征A对样本集合D进行划分的最佳划分点。 + +- 使用 Outlook分隔的Gini增益:0.117(最佳分隔特征) +- 使用Temp分隔的Gin增益:0.0185 +- 使用 Humidity.分隔的Gin增益:00916 +- 使用Wnd分隔的Gin增益:0.0304 + +Outlook是最优的分割特征,揭下来计算 rainy, overcast和suny的基尼指数,选择最小的作为分割节点即可 + + + +## 回归树 + +回归树( regression tree),就是用决策树模型做回归问题,每片叶子都输出一个预测值。预测值一般是叶子节点所含训练集元素输出的均值 + +![image-20200427190718363](images/image-20200427190718363.png) + +回归树的分支标准:标准方差( Standard deviation)。回归树使用某特征将原集合分为多个子集,用标准方差衡量子集中的元素是否相近越小表示越相近。首先计算根节点的标准方差 + +![image-20200427190859086](images/image-20200427190859086.png) + + + +### 分支 + +使用标准方差来确定分支,以计算 Outlook分支后的标准差为例: + +![image-20200427191416114](images/image-20200427191416114.png) + +同理可计算其他特征的标准方差,并得到方差的减小值: + +![image-20200427191527882](images/image-20200427191527882.png) + +标准差降低最多的特征是 Outlook,利用其进行分支 + +![image-20200427191649388](images/image-20200427191649388.png) + +接下来,重复这个过程,使用标准方差降低最多的特征进行分支直到满足某个停止条件,如:1.当某个分支的变化系数小于某个值(10%),2.当前节点包含的元素个数小于某个值(3) + +使用“ outlook“分支以后,值为“ Overcast”的分支的变化系数( coefficient of variation)太小(8%)小于我们设置的最小值(10%,停止继续在“ Overcast 对应的分支上继续分支,生成亠个叶子节点 + +![image-20200427191727409](images/image-20200427191727409.png) + +![image-20200427191750710](images/image-20200427191750710.png) + +Sunny分支 + +使用“ Windy”分支后,两个子分支包含的元素个数小于我们设定的值(3),可以停止继续分支 + +![image-20200427191848412](images/image-20200427191848412.png) + +![image-20200427191913939](images/image-20200427191913939.png) + +![image-20200427191922628](images/image-20200427191922628.png) \ No newline at end of file diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427180341047.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427180341047.png" new file mode 100644 index 0000000000000000000000000000000000000000..6a33fba4ed63edf44bc68397a8d5cbb6056be7a7 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427180341047.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427180723072.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427180723072.png" new file mode 100644 index 0000000000000000000000000000000000000000..3d77a39587ae59aef7ca9561d87092154acac870 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427180723072.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427181614925.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427181614925.png" new file mode 100644 index 0000000000000000000000000000000000000000..53908f4e310c20e64961d9421525fe56d358545a Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427181614925.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427182516870.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427182516870.png" new file mode 100644 index 0000000000000000000000000000000000000000..5b6cc7d29d9ac4de6db339da79642b4e75adccac Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427182516870.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427182636732.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427182636732.png" new file mode 100644 index 0000000000000000000000000000000000000000..74f9ceeb51739d03f6cdec0076eb75c9cd7b6c9a Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427182636732.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427183010140.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427183010140.png" new file mode 100644 index 0000000000000000000000000000000000000000..760385e6dfa18632f50456a57566bbaa4f6c81ec Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427183010140.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427184708081.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427184708081.png" new file mode 100644 index 0000000000000000000000000000000000000000..df45f774d264c82ca5be0ea39548617782c5ab62 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427184708081.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427184842977.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427184842977.png" new file mode 100644 index 0000000000000000000000000000000000000000..b2dc5c882872b7728c93af6492f86da8eef60642 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427184842977.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427184859431.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427184859431.png" new file mode 100644 index 0000000000000000000000000000000000000000..59f3f94019d79b8bb7f3d219324355c7922f820f Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427184859431.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185008572.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185008572.png" new file mode 100644 index 0000000000000000000000000000000000000000..04182fcf65637ddc037b152fbbd4752a6eced759 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185008572.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185057844.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185057844.png" new file mode 100644 index 0000000000000000000000000000000000000000..b9019bbef44c2cb05e07ed08d0eed6845a79665d Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185057844.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185122531.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185122531.png" new file mode 100644 index 0000000000000000000000000000000000000000..4412aaa026f096ca2889957d86873acd77d6f187 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185122531.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185218192.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185218192.png" new file mode 100644 index 0000000000000000000000000000000000000000..fec0226d607cbaafa231cf8b8fef2a6536a04de5 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185218192.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185320167.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185320167.png" new file mode 100644 index 0000000000000000000000000000000000000000..46f9f40c295b43f102fcc00f214fa09ca42dbde4 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185320167.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185413042.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185413042.png" new file mode 100644 index 0000000000000000000000000000000000000000..7c84610981d1346e0d1a69ff1dee9db5bbc19d3e Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185413042.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185944222.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185944222.png" new file mode 100644 index 0000000000000000000000000000000000000000..1e8d7613df9e74c57229c65676e3e34e275da522 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427185944222.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190109182.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190109182.png" new file mode 100644 index 0000000000000000000000000000000000000000..9eb9f5510388094365b6db7127baf0e97cc25585 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190109182.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190148092.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190148092.png" new file mode 100644 index 0000000000000000000000000000000000000000..8dbaa53cb8552fd636721013af85a90d16fb130c Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190148092.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190230060.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190230060.png" new file mode 100644 index 0000000000000000000000000000000000000000..e85cefea756a30805dc94c9819d70b381cdb1e76 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190230060.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190250190.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190250190.png" new file mode 100644 index 0000000000000000000000000000000000000000..45ae881f39bfaf04154cd05e37682cf09e1f42e8 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190250190.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190718363.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190718363.png" new file mode 100644 index 0000000000000000000000000000000000000000..c3492f95d90f4d7cf7c886db332650956e4a97a7 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190718363.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190859086.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190859086.png" new file mode 100644 index 0000000000000000000000000000000000000000..270452a452c01a1d6a737ea1c8329d9aa9ad5068 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427190859086.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191416114.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191416114.png" new file mode 100644 index 0000000000000000000000000000000000000000..6377d6e5d0343ce5419f224cfee39676162b64cc Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191416114.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191527882.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191527882.png" new file mode 100644 index 0000000000000000000000000000000000000000..13f37dab7140899aa13c5b679f776814ab0396c8 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191527882.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191649388.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191649388.png" new file mode 100644 index 0000000000000000000000000000000000000000..f54827b8241ba3868d79384047f1ab1e6d8d1bd6 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191649388.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191727409.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191727409.png" new file mode 100644 index 0000000000000000000000000000000000000000..e84fec76c517de1b99087c279fd638f7a0307b50 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191727409.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191750710.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191750710.png" new file mode 100644 index 0000000000000000000000000000000000000000..6c68ebb9e4288fb9da864d832584e15d1ee018ee Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191750710.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191848412.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191848412.png" new file mode 100644 index 0000000000000000000000000000000000000000..a7ff3f246508cb9865420c6d79d6328d4b052b38 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191848412.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191913939.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191913939.png" new file mode 100644 index 0000000000000000000000000000000000000000..fea8b7e25a591590acf5e43da3adf427e1a872cf Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191913939.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191922628.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191922628.png" new file mode 100644 index 0000000000000000000000000000000000000000..a065a7342356e6dccba7e60dd0ebdcd5d1daf589 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/1_\345\206\263\347\255\226\346\240\221/images/image-20200427191922628.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/README.md" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..7c3430bd72e30ce4f95c2f7b595b2e740c874be9 --- /dev/null +++ "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/README.md" @@ -0,0 +1,653 @@ +# 集成学习简介 + +集成学习是通过构建并组合多个学习器来完成学习任务的算法,集成学习常见的有两类 + +- Bagging:基学习器之间无强依赖关系,可同时生成的并行化方法 +- Boosting:基学习器之间存在强烈的依赖关系,必须串行生成基分类器的方法 + - Adaboost:对样本进行加权的过程,然后来进行基学习器的训练,集成后得到最终的学习器 + - GBDT:梯度提升算法 + - XGBoost: + - LightGBM + +![image-20200428102348559](images/image-20200428102348559.png) + +## Bagging算法 + +Bagging(Bootstrap Aggregating)方法: + +![image-20200428102845090](images/image-20200428102845090.png) + +训练完成后,我们进行预测 + +![image-20200428102940361](images/image-20200428102940361.png) + +如果是预测问题,我们只需要通过Average求平均 + +如果是分类问题,我们需要进行投票表决 + + + +## Boosting算法 + +Boosting方法是将“弱学习算法”提升为“强学习算法”的过程,通过反复学习得到一系列弱分类器(决策树和逻辑回归),组合这些弱分类器得到一个强分类器。 Boosting算法要涉及到两个部分,加法模型和前向分步算法 + +![image-20200428110627474](images/image-20200428110627474.png) + +### 加法模型 + +加法模型就是说强分类器由一系列弱分类器线性相加而成。一般组合形式如下 +$$ +F_{M}(x ; P)=\sum_{m=1}^{n} \beta_{m} h\left(x ; a_{m}\right) +$$ +其中,h(x;am)是弱分类器,am是弱分类器学习到的最优参数,m是弱学习在强分类器中所占比重,P是所有Lm和βm的组合。这些弱分类器线性相加组成强分类器前向分步是在训练过程中,下一轮迭代产生的分类器是在上一轮的基础上训练得来的。即 + +### 前向步骤 + +前向步骤是在训练过程中,下一轮迭代产生的分类器是在上一步的基础上训练得来的。即 +$$ +F_{m}(x)=F_{m-1}(x)+\beta_{m} h_{m}\left(x ; a_{m}\right) +$$ + + +## 随机森林 + +随机森林 = Bagging + 决策树 + +同时训练多个决策树,预测时综合考虑多个结果进行预测,例如取多个节点的均值(回归),或者是众数(分类)。 + +### 优势 + +- 消除了决策树容易过拟合的缺点 +- 减小了预测的方差,预测值不会因训练数据的小变化而剧烈变化 + +![image-20200428115107690](images/image-20200428115107690.png) + +### 随机性 + +随机森林的随机性体现在以下两点 + +- 从原来的训练数据集随机(带放回bootstrap)取一个子集作为森林中某一个决策树的训练数据集 +- 每一个选择分叉的特征时,限定为在随机选择的特征的子集中寻找一个特征。 + +![image-20200428115411734](images/image-20200428115411734.png) + + + +### 实例 + +通过案例来看下随机森林的应用 现有某公司的员工离职数据,我们通过构建决策树和随机森林,来预测某一员工是否会离职。并找出影响员工离职的重要特征 + +见代码:DecisionTree.RandomForest.ipynb + + + +## Adaboost + +提升树中的算法,Adaboost是在样本上做文章的,在每次训练完基学习器之后,来调整样本的分布,在最后集成的时候,也是需要在不同的分类器前面添加权重参数。 + +### 思想 + +Adaboost的思想是将关注点放在被错误分类的样本上,减小上一轮被正确分类的样本权值提高被错误分类的样本权值 + +Adaboost采用加权投票的方法分类误差小的弱分类器的权重大,而分类误差大的弱分类器的权重小。 + +![image-20200428124635998](images/image-20200428124635998.png) + +例如上图所示,在第一步的时候,我们进行分类,同时有分类正确的,和分类错误的。 + +![image-20200428124817590](images/image-20200428124817590.png) + +在第二步的时候,我们需要将分类正确的样本权重缩小,通知增大分类错误的权重,然后再次进行分类,这样下次分类的时候,就会更加关注与上次分错的样本,从而得到下面的分类结果 + +![image-20200428124823061](images/image-20200428124823061.png) + + + +然后我们再次调整分错样本的权值 + +![image-20200428124953733](images/image-20200428124953733.png) + +最终我们将前面的弱分类器进行集成,得到我们最终的分类结果 + +![image-20200428125021604](images/image-20200428125021604.png) + +### 算法流程 + +假设输入训练数据为: +$$ +T=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right),\left(x_{N}, y_{N}\right)\right\} +$$ +其中:x∈X≤Rn,y∈Y=-1,1,迭代次数即弱分类器个数为M + +初始化训练样本的权值分布为: +$$ +D_{1}=\left(w_{1,1}, w_{1,2}, \ldots, w_{1, i}\right), w_{1, i}=\frac{1}{N}, i=1,2, \ldots, N +$$ + + +![image-20200428125528569](images/image-20200428125528569.png) + +上述的更新权重的过程就是:如果我们分类正确了,那么就需要缩小权重,如果分类错误,那么就需要放大权重,然后不断循环,最后得到M个弱分类器 + +最终得到的分类器为: +$$ +F(x)=\operatorname{sign}\left(\sum_{i=1}^{N} \alpha_{m} G_{m}(x)\right) +$$ +在整个过程中,令人困惑的是:分类器的权重的确定 + +假设经过m-1轮迭代,得到弱分类器Fm-1(x),根据前向分布,有 +$$ +F_{m}(x)=F_{m-1}(x)+\alpha_{m} G_{m}(x) +$$ +AdaBoost的损失函数是指数损失,则有: +$$ +\text {Loss}=\sum_{i=1}^{N} \exp \left(-y_{i} F_{m}\left(x_{i}\right)\right)=\sum_{i=1}^{N} \exp \left(-y_{i}\left(\boldsymbol{F}_{m-1}\left(x_{i}\right)+\alpha_{m} G_{m}\left(x_{i}\right)\right)\right) +$$ +![image-20200428145723489](images/image-20200428145723489.png) + +![image-20200428145930172](images/image-20200428145930172.png) + +![image-20200428150240554](images/image-20200428150240554.png) + +Adaboost可以看成是加法模型、损失函数为指数损失函数、学习算法为前向分布算法时的二分类学习方法,接下来我们使用SkLearn中的AdaBoost的接口进行实践 + +``` +AdaBoostClassifier(base_estimator=None, $n_{-}$ estimators $=50$ learning_rate $=1.0,$ algorithm='SAMME.R', random_state=None) +``` + +base_estimator:代表基学习器是什么 + +### Adaboost实践 + +参考代码:adaboost.ipynb + + + +## GBDT + +BDT:提升树 + +GBDT:梯度提升树 + +### BDT + +我们首先看一下简单的提升树(Boosting Decision Tree),提升树是以CART决策树为基学习器的集成学习方法。 + +![image-20200428153045454](images/image-20200428153045454.png) + +我们通过不同的训练数据,来训练弱学习器,最后通过不同的学习器,组合成为强学习器 + +提升树实际上就是加法模型和前向分布算法,将其表示为: + +![image-20200428153350966](images/image-20200428153350966.png) + +x是参数 0m 是参数 + +在前向分布算法第m步时,给定当前的模型 fm - 1 ( x ) ,求解: + +![image-20200428153730182](images/image-20200428153730182.png) + +得到第m棵决策树T(x, 0m) ,不同问题的提升树的区别在于损失函数的不同,如分类用指数损失函数,回归用平方误差损失函数。 + +当提升树采用平方损失函数时,第m次迭代时表示为: + +![image-20200428153949765](images/image-20200428153949765.png) + +称r为残差,所以第m棵决策树(x,⊙m)是对该残差的拟合。要注意的是提升树算法中的基学习器CART树是回归树。 + +>残差在数理统计中是指实际观察值与估计值([拟合值](https://baike.baidu.com/item/拟合值/9461734))之间的差。 + +![image-20200428154411161](images/image-20200428154411161.png) + +### GBDT + +GBDT全称为: Gradient Boosting Decision Tree,即梯度提升决策树,理解为 梯度提升 + 决策树。 Friedman提出了利用最速下降的近似方法,利用损失函数的负梯度拟合基学习器 + +![image-20200428154633244](images/image-20200428154633244.png) + +怎么理解这个近似,我们通过平方损失函数来给大家介绍 + +![image-20200428154751350](images/image-20200428154751350.png) + +![image-20200428154930163](images/image-20200428154930163.png) + +GBDT的梯度提升流程如下所示: + +![image-20200428155742442](images/image-20200428155742442.png) + +GBDT与提升树的区别是残差使用梯度代替,而且每个基学习器有对应的参数权重。 + +GBDT使用梯度提升的决策树(CART),CART树回归将空间划分为K个不相交的区域,并确定每个区域的输出CK,数学表达式如下: + +![image-20200428160111309](images/image-20200428160111309.png) + +### GBDT完成回归任务 + +![image-20200428160954632](images/image-20200428160954632.png) + +### 使用GBDT完成分类任务 + +![image-20200428161136964](images/image-20200428161136964.png) + +![image-20200428161352770](images/image-20200428161352770.png) + + + +## XGBoost + +ⅹGBoost是GBDT的一种,也是加法模型和前向优化算法在监督学习中,可以分为:模型,参数,目标函数和学习方法 + +- 模型:给定输入X后预测输出y的方法,比如说回归,分类,排序等 +- 参数:模型中的参数,比如线性回归中的权重和偏置 +- 目标函数:即损失函数,包含正则化项 +- 学习方法:给定目标函数后求解模型和参数的方法,比如 +- 梯度下降法,数学推导等 + +这四方面的内容也指导着 XGBoost系统的设计。 + +### 模型形式 + +假设要判断一个人是否喜欢电脑游戏,输入年龄、性别、职业等特征,可以得到如下的回归树: + +![image-20200428162009041](images/image-20200428162009041.png) + +在叶子节点上会有一个分数,利用这个分数我们可以回归,或者映射成概率进行分类等。 + +但是一颗CART树的拟合能力有限,我们可以进行集成学习,比如用两棵树进行预测,结果是两个树的和: + +![image-20200428162142920](images/image-20200428162142920.png) + +用多棵树进行预测的方法就是随机森林或提升树。 + +给定数据集: +$$ +D=\left(X_{i}, y_{i}\right)\left(|\mathrm{D}|=\mathrm{n}, x_{i} \in R^{m}, y_{i} \in R\right) +$$ +XGBoost利用前向分布算法,学习到包含K棵树的加法模型: +$$ +\hat{y}_{i}=\sum_{t=1}^{K} f_{t}\left(x_{i}\right), \quad f_{t} \in \mathcal{F} +$$ +其中有K棵树,f是回归树,而F对应回归树组成的函数空间,那怎么得到这些树,也就是树的结构和叶子节点的预测结果? + +### 目标函数 + +定义目标函数,包含正则项: +$$ +\operatorname{Obj}(\Theta)=\sum_{i=1}^{N} l\left(y_{i}, \hat{y}_{i}\right)+\sum_{j=1}^{t} \Omega\left(f_{j}\right), \quad f_{j} \in \mathcal{F} +$$ +如何优化这个目标函数呢?因为f是决策树,而不是数值型的向量,我们不能使用梯度下降的算法进行优化。 + +XGBoost是前向分布算法,我们通过贪心算法寻找局部最优解: +$$ +\hat{y}_{i}^{(t)}=\sum_{j=1}^{t} f_{j}\left(x_{i}\right)=\hat{y}_{i}^{(t-1)}+f_{t}\left(x_{i}\right) +$$ +每一次迭代我们寻找使损失函数降低最大的 f(CART树),因此目标函数可改写成 +$$ +\begin{aligned} +O b j^{(t)} &=\sum_{i=1}^{N} l\left(y_{i}, \hat{y}_{i}^{(t)}\right)+\sum_{j=1}^{t} \Omega\left(f_{j}\right) \\ +&=\sum_{i=1}^{N} l\left(y_{i}, \hat{y}_{i}^{(t-1)}+f_{t}\left(\mathbf{x}_{\mathbf{i}}\right)\right)+\Omega\left(f_{t}\right)+\text {constant(在t轮时,前t-1次迭代正则项看作是常数)} \\ +&=\sum_{i=1}^{N} l\left(y_{i}, \hat{y}_{i}^{(t-1)}+f_{t}\left(\mathbf{x}_{\mathbf{i}}\right)\right)+\Omega\left(f_{t}\right) +\end{aligned} +$$ +接下来,我们采用泰勒展开对目标参数进行近似: +$$ +\begin{aligned} +O b j^{(t)} &=\sum_{i=1}^{N} l\left(y_{i}, \hat{y}_{i}^{(t)}\right)+\sum_{j=1}^{t} \Omega\left(f_{j}\right) \\ +&=\sum_{i=1}^{N} l\left(y_{i}, \hat{y}_{i}^{(t-1)}+f_{t}\left(\mathbf{x}_{\mathbf{i}}\right)\right)+\Omega\left(f_{t}\right)+\text {constant} \\ +&=\sum_{i=1}^{N} l\left(y_{i}, \hat{y}_{i}^{(t-1)}+f_{t}\left(\mathbf{x}_{\mathbf{i}}\right)\right)+\Omega\left(f_{t}\right) +\end{aligned} +$$ +移除对第t轮迭代来说的常数项 l(yi, yi(t -1 ))得到: +$$ +O b j^{(t)}=\sum_{i=1}^{N}\left(g_{i} f_{t}\left(\mathbf{x}_{\mathbf{i}}\right)+\frac{1}{2} h_{i} f_{t}^{2}\left(\mathbf{x}_{\mathbf{i}}\right)\right)+\Omega\left(f_{t}\right) +$$ +所以目标函数只依赖于每条数据在误差函数上的一阶倒数和二阶导数 + +#### 泰勒公式 + +泰勒公式( Taylor‘s formula)是一个用函数在某点的信息描述其附近取值的公式,对于一般的函数,泰勒公式的系数的选择依赖于函数在一点的各阶导数值。函数f(x)在x0处的基本形式如下 +$$ +\begin{aligned} +f(x) &=\sum_{n=0}^{\infty} \frac{f^{(n)}\left(x_{0}\right)}{n !}\left(x-x_{0}\right)^{n} \\ +&=f\left(x_{0}\right)+f^{1}\left(x_{0}\right)\left(x-x_{0}\right)+\frac{f^{2}\left(x_{0}\right)}{2}\left(x-x_{0}\right)^{2}+\cdots+\frac{f^{(n)}\left(x_{0}\right)}{n !}\left(x-x_{0}\right)^{n} +\end{aligned} +$$ +还有一种常见的写法为,假设x+1=x+△x,将f(x+1)在x处 的泰勒展开为 +$$ +f\left(x^{t+1}\right)=f\left(x^{t}\right)+f^{1}\left(x^{t}\right) \Delta x+\frac{f^{2}\left(x^{t}\right)}{2} \Delta x^{2}+\cdots +$$ + +#### 正则项 + +树的复杂度可以用树的深度,内部节点个数,叶子节点个数来衡量,XGBoost中正则项用来衡量树的复杂度:树的叶子节点个数T和每棵树的叶子节点输出分数W的平方和(相当于L2正则化) + +![image-20200428170701662](images/image-20200428170701662.png) + +XGBoost的目标函数改写成: + +![image-20200428171422148](images/image-20200428171422148.png) + +上式中第一部分是对样本的累加,而后面的部分是正则项,是对叶节点的累加 + +定义Q函数将输入X映射到某个叶子节点上,则有: + +![image-20200428172404486](images/image-20200428172404486.png) + +定义每个叶子节点 j 上的样本集合为 Ij = {i | q(xi) = j },则目标函数可以改写成: +$$ +\begin{aligned} +O b j^{(t)} &=\sum_{i=1}^{N}\left(g_{i} f_{t}\left(\mathbf{x}_{\mathbf{i}}\right)+\frac{1}{2} h_{i} f_{t}^{2}\left(\mathbf{x}_{\mathbf{i}}\right)\right)+\gamma T+\frac{1}{2} \lambda \sum_{j=1}^{T} w_{j}^{2} \\ +&=\sum_{i=1}^{N}\left(g_{i} w_{q\left(\mathbf{x}_{i}\right)}+\frac{1}{2} h_{i} w_{q\left(\mathbf{x}_{i}\right)}^{2}\right)+\gamma T+\frac{1}{2} \lambda \sum_{j=1}^{T} w_{j}^{2} \\ +&=\sum_{j=1}^{T}\left(\sum_{i \in I_{j}} g_{i} w_{j}+\frac{1}{2} \sum_{i \in I_{j}} h_{i} w_{j}^{2}\right)+\gamma T+\frac{1}{2} \lambda \sum_{j=1}^{T} w_{j}^{2} \\ +&=\sum_{j=1}^{T}\left(G_{j} w_{j}+\frac{1}{2}\left(\boldsymbol{H}_{j}+\lambda\right) w_{j}^{2}\right)+\gamma T +\end{aligned} +$$ +这个就是目标函数的最终结果 + +接下来我们进行目标函数的优化,即计算第t轮时使用目标函数最小的叶节点的输出分数W,直接对W求导,使得导数为0,得: +$$ +w_{j}=-\frac{G_{j}}{H_{j}+\lambda} +$$ +将其带入损失函数中: +$$ +\begin{aligned} +O b j^{(t)} &=\sum_{j=1}^{T}\left(G_{j} w_{j}+\frac{1}{2}\left(H_{j}+\lambda\right) w_{j}^{2}\right)+\gamma T \\ +&=\sum_{j=1}^{T}\left(-\frac{G_{j}^{2}}{H_{j}+\lambda}+\frac{1}{2} \frac{G_{j}^{2}}{H_{j}+\lambda}\right)+\gamma T \\ +&=-\frac{1}{2} \sum_{j=1}^{T}\left(\frac{G_{j}^{2}}{H_{j}+\lambda}\right)+\gamma T +\end{aligned} +$$ +上式越小越好,即目标函数越小 + +![image-20200428173858739](images/image-20200428173858739.png) + +### 学习策略 - 确定树结构 + +采用贪心算法,每次尝试分裂一个叶节点,计算分裂后的增益,选择增益最大的。类似于在ID3中的信息增益,和CART树中的基尼指数,那XGBoost中怎么计算增益呢?损失函数是: +$$ +O b j^{(t)}=-\frac{1}{2} \sum_{j=1}^{T}\left(\frac{G_{j}^{2}}{H_{j}+\lambda}\right)+\gamma T +$$ +其中红色部分衡量了叶子节点对总体损失的贡献,目标函数越小越好,则红色部分就越大越好,在XGBoost中增益计算方法是: + +![image-20200428174423188](images/image-20200428174423188.png) + +Gain值越大,说明分裂后能使目标函数减少的越多,也就是越好。 + +#### 精确 贪心算法 + +就像CART树一样,枚举所有的特征和特征值,计算树的分裂方式 + +![image-20200428175646019](images/image-20200428175646019.png) + +假设枚举年龄特征 xj,考虑划分点 a,计算枚举 xj < a 和 a <= xj的导数和: + +![image-20200428175903891](images/image-20200428175903891.png) + +对于一个特征,对特征取值排完序后,枚举所有的分裂点a,只要从左到右扫描就可以枚举出所有分割的梯度GL和GR,计算增益。假设树的高度为H,特征数d,则复杂度为O( Hanlon)。其中,排序为0(logn),每个特征都要排序乘以d,每一层都要这样一遍,所以乘以高度H。 + +#### 近似算法 + +当数据量庞大,无法全部存入内存中时,精确算法很慢,因此引入近似算法。根据特征k的分布确定L个候选切分点Sk={Sk1,Sk2,…Sk } 然后根据候选切分点把相应的样本放入对应的桶中,对每个桶的GH进行累加,在候选切分点集合上进行精确贪心査找。算法描述如 + +![image-20200428180101868](images/image-20200428180101868.png) + +根据分位数给出相应的候选切分点,简单例子如下所示: + +![image-20200428180335131](images/image-20200428180335131.png) + +何时选取划分点?全局策略(Global)和局部策略(Local) + +- 全局策略:学习每棵树前,提出候选的切分点,当切分点树足够多的时候,和精确的贪心算法性能相当 +- 局部策略:树节点分裂时,重新提出候选切入点,切分点个数不需要这么多,性能与贪心算法相差不多。 + +![image-20200428180600154](images/image-20200428180600154.png) + +XGBoost中没有采用简单的分位数方法,而是提出了以二阶梯度h为权重的分位数算法(Weighted Quantile Sketch),对特征K构造multi-set的数据集: +$$ +D_{k}=\left(x_{1 k}, h_{1}\right),\left(x_{2 k}, h_{2}\right), \ldots,\left(x_{n k}, h_{n}\right) +$$ +其中,X表示样本的特征k的取值,而h是对应的二阶梯度 定义一个 rank function,表示第k个特征小于z的样本比例: +$$ +r_{k}(z)=\frac{1}{\sum_{(x, h) \in D_{k}} h} \sum_{(x, h) \in D_{k}, x 0,【0.1, 0.3】-> 1。并根据特征所在的bin对其进行梯度累加和个数统计,然后根据直方图,寻找最优的切分点 + +![image-20200428212605067](images/image-20200428212605067.png) + +直方图构建算法: + +![image-20200428212801755](images/image-20200428212801755.png) + +#### 如何分桶 + +数值型特征和类别特征采用的方法是不同的 + +**数值型特征** + +- 对特征值去重后进行排序(从大到小),并统计每个值的counts +- 取max_bin和distinct_value.size()中较小的值作为bins_num +- 计算bins中的平均样本个数 mean_bin_size,若某个distinct_value的count大于mean_bin_size,则该特征作为bins的上界,小于该特征值的第一个distinct value作为下界,若某个distinct_value的count小于mean_bin_size,则要进行累计后在分组。 + + **类别型特征** + +- 首先对特征取值按出现的次数排序(大到小) +- 取前min(max_bin,distinct_values_int.size() )中 的每个特征做第3步,忽略一些出现次数很少的特征取值 +- 用bin_2_categorical_bin_2_categorical_(vector类型)和categorical_2_bin_categorical_2_bin 将特征取值和bin一一对应起来,这样就可以方便进行两者之间的切换了。 + +#### 构建直方图 + +给定一个特征值,我们可以转换为对应的bin了,就要构建直方图了,直方图累加了一阶梯度和二阶梯度,并统计了取值的个数 + +![image-20200428215026626](images/image-20200428215026626.png) + +#### 直方图作差 + +一个叶子节点的直方图可以由它的父亲节点的直方图与其兄弟节点的直方图做差得到,使用这个方法,构建完一个叶子节点的直方图后,就可以用较小的代价得到兄弟节点的直方图,相当于速度提升了一倍 + +![image-20200428215203659](images/image-20200428215203659.png) + +#### 寻找最优的切分点 + +最优的切分点 + +- 遍历所有的bin +- 以当前的bin作为分割点,累加左边的bins至当前bin的地图和Sl及样本数量nl,并利用直方图做差求得右边的梯度和样本数量 +- 带入公司计算增益loss +- 在遍历过程中取得最大的增益,以此时的特征和bin的特征值作为分裂节点的特征及取值。 + +![image-20200428215608063](images/image-20200428215608063.png) + +#### 直方图算法的优点 + +- 减少内存占用 +- 缓存命中率提高,直方图中梯度的存放是连续的 +- 计算效率提高,相对于XGBoost中预排序每个特征遍历数据,复杂度为O(Feature * data),而直方图算法之需要遍历每个特征的直方图即可,复杂度为O(Feature * bins) +- 在进行数据并行时,可大幅度降低通信代价 + +### 直方图算法的改进 + +直方图算法仍有优化的空间,建立直方图的复杂度为O(feature * data),如果能降低特征数或者降低样本数,训练的时间会大大减少,加入特征存在冗余时,可以使用PCA等算法降维,但特征通常是精心设计的,去除他们中的任何一个可能会影响训练精度,因此LightGBM提出了GOSS算法和EFB算法。 + +### GOSS算法 + +样本的梯度越小,样本的训练误差就越小,表示样本已训练的很好,直接的做法就是丢掉这部分样本,然而丢掉会影响数据的分布,因此在LightGBM中采取了one-side采样的方式来适配,GOSS采样策略,它保留所有的大梯度样本,对小梯度样本进行随机采样。 + +![image-20200428222041079](images/image-20200428222041079.png) + +原始直方图算法下,在第j个特征,值为d处进行分裂带来的增益可以定义为: +$$ +\begin{aligned} +V_{j | O}(d) &=\frac{1}{n_{O}}\left(\frac{\left(\sum_{x_{i} \in A_{l}} g_{i}+\frac{1-a}{b} \sum_{x_{i} \in B l} g_{i}\right)^{2}}{n_{l}^{j}(d)}+\frac{\left(\sum_{x_{i} \in A_{r}} g_{i}+\frac{1-a}{b} \sum_{x_{i} \in B_{l}} g_{r}\right)^{2}}{n_{r}^{j}(d)}\right) \\ +\text { 其中 } A_{l} &=x_{i} \in A: x_{i j} \leq d, A_{r}=x_{i} \in A: x_{i j}>d \\ +B_{l}=x_{i} & \in B: x_{i j} \leq d, B_{r}=x_{i} \in B: x_{i j}>d +\end{aligned} +$$ +注意:A表示大梯度样本集,而B表示小梯度样本中随机采样的结果。 + +### EFB算法 + +高维数据通常是稀疏的,而且许多特征是互斥的,即两个或多个特征列不会同时为非0,LightGBM根据这一特点提出了EFB算法,将互斥特征进行合并,能够合并的特征为#bundle,从而将特征的维度降下来,响应的,构建histogram锁耗费的时间复杂度也从O(data * feature)变成了O(data * bundle),其中feature << bundle,方法说起来很简单,但是实现起来有两大难点 + +- 哪些特征可以合并为一个bundle?:Greedy bundle +- 如果将特征合并为bundle,实现降维:Merge Exclusive Features + +Greedy bundle的原理与图着色相同,给定一个图G,定点为V,表示特征,边为E,表示特征之间的互斥关系,接着采用贪心算法对图进行着色,一次来生成Bundle。 + +![image-20200428232020666](images/image-20200428232020666.png) + +MEF(Merge Exclusive Features)将bundle中的特征合并为新的特征,合并的关键是原有的不同特征值在构建后的bundle中仍能够识别,由于急于histogram的方法存储的是离散的bin而不是连续的数值,因此可以通过添加偏移的方法将不同的特征的bin值设定为不同的区间。 + +![image-20200428232607192](images/image-20200428232607192.png) + + + +### 树的生长策略 + +在XGBoost中,树是按层生长的,同一层的所有节点都做分裂,最后剪枝,他不加区分的对待同一层的叶子,带来了很多没必要的开销,因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。 + +![image-20200428233314626](images/image-20200428233314626.png) + +LightGBM的生长策略是leaf-wise,以降低模型损失最大化为目的,对当前所有叶子节点中切分增益最大的leaf节点进行切分,leaf-wise的缺点是生成比价深的决策树,为了防止过拟合,可以在模型中设置决策树的深度。 + +![image-20200428233608994](images/image-20200428233608994.png) + + + +### 系统设计 + +LightGBM具有支持高效并行的特点,原生支持并行学习,目前支持 + +- 特征并行 +- 数据并行 +- Voting(投票)并行(数据并行的一种) + +### 特征并行 + +特征并行是并行化决策树中寻找最优划分点的过程,特征并行是将对特征进行划分,每个worker找到局部的最佳切入点,使用点对点通信找到全局的最佳切入点 + +![image-20200428233940790](images/image-20200428233940790.png) + +#### 传统算法 + +不同的worker存储不同的特征集,在找到全局的最佳划分点后,具有该划分点的worker进行节点分裂,然后广播切分后的左右子树数据结果,其它worker收到结果后也进行划分。 + +#### LightGBM中的算法 + +每个worker中保存了所有的特征集,在找到全局的最佳划分点后,每个worker可自行进行划分,不在进行广播划分结果,减小了网络的通信量,但存储代价变高。 + + + +### 数据并行 + +数据并行的目标是并行化整个决策学习的过程,每个worker中拥有部分数据,独立的构建局部直方图,合并后得到全局直方图,在全局直方图中寻找最优切分点进行分裂。 + +![image-20200428234328151](images/image-20200428234328151.png) + +### Voting Parallel 投票并行 + +LightGBM采用一种称为PV-Tree的算法进行投票并行,其实这本质上也是数据并行的一种,PV-Tree和普通的决策树差不多,只是在寻找最优切分点上有所不同 + +![image-20200428234448970](images/image-20200428234448970.png) + +每个worker拥有部分数据,独自构建直方图并找到 top-k最优的划分特征,中心worker聚合得到最优的2K个全局划分特征,再向每个worker收集top-2k特征的直方图,并进行合并得到最优划分,广播给所有worker进行本地划分。 + +![image-20200428235129193](images/image-20200428235129193.png) + +### 实践 + +使用XGBoost设置树的深度,在LightGBM中是叶子节点的个数 + +![image-20200428235648153](images/image-20200428235648153.png) + +![image-20200428235723087](images/image-20200428235723087.png) + +![image-20200428235803136](images/image-20200428235803136.png) + +![img](images/9J%474I3L_2JSY[W%LA6G2G.png) \ No newline at end of file diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/9J%474I3L_2JSY[W%LA6G2G.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/9J%474I3L_2JSY[W%LA6G2G.png" new file mode 100644 index 0000000000000000000000000000000000000000..5033e1e643ce1a30b5a15c34c1c2d4c30a507d35 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/9J%474I3L_2JSY[W%LA6G2G.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428102348559.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428102348559.png" new file mode 100644 index 0000000000000000000000000000000000000000..298150c277b450144df9999b0b8f1b83bd92f7c0 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428102348559.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428102845090.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428102845090.png" new file mode 100644 index 0000000000000000000000000000000000000000..38853d014edc3a8b7423e7d8cdaee88d4fefc1fd Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428102845090.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428102940361.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428102940361.png" new file mode 100644 index 0000000000000000000000000000000000000000..49dea2c9455df05e785da0860ebe51c9b6c152b0 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428102940361.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428110627474.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428110627474.png" new file mode 100644 index 0000000000000000000000000000000000000000..cdf8af5b0ef1ee8174c02b15dfda93db00e229b6 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428110627474.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428115107690.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428115107690.png" new file mode 100644 index 0000000000000000000000000000000000000000..7ccfe0c73e4bb0b15d4e3496667fe74973812062 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428115107690.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428115411734.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428115411734.png" new file mode 100644 index 0000000000000000000000000000000000000000..206233deabe99bd6c3a572e7de9e82004e8d16e7 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428115411734.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428124635998.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428124635998.png" new file mode 100644 index 0000000000000000000000000000000000000000..0cb74cf937c218b166a626a411733c282b9e005f Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428124635998.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428124817590.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428124817590.png" new file mode 100644 index 0000000000000000000000000000000000000000..a17c21195ec1ea6cbebd9ea4c8fed78a257193eb Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428124817590.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428124823061.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428124823061.png" new file mode 100644 index 0000000000000000000000000000000000000000..e2f49488d3cadfd8f9aade3370d6c8278de14a10 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428124823061.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428124953733.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428124953733.png" new file mode 100644 index 0000000000000000000000000000000000000000..d7e8b1f044c28f6b0e6c424a5ee7b5eabcb544f1 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428124953733.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428125021604.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428125021604.png" new file mode 100644 index 0000000000000000000000000000000000000000..2f0d4f3e0dda25a25aaf5af69200eac9a1b9d84c Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428125021604.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428125528569.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428125528569.png" new file mode 100644 index 0000000000000000000000000000000000000000..2cf7af831c880eb30a490e96acad03b4cf532d31 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428125528569.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428145723489.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428145723489.png" new file mode 100644 index 0000000000000000000000000000000000000000..d5b77d7ae18d69fba890166213473067811d7b75 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428145723489.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428145930172.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428145930172.png" new file mode 100644 index 0000000000000000000000000000000000000000..dca6ee0039b12471bc500a37d40eee64b4b01714 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428145930172.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428150240554.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428150240554.png" new file mode 100644 index 0000000000000000000000000000000000000000..0636d2becdabf5a0d6c83fe23dbf27cc394980cc Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428150240554.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428153045454.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428153045454.png" new file mode 100644 index 0000000000000000000000000000000000000000..64399312830080c1cb1c0cf58c2e4e6d4b569eba Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428153045454.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428153350966.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428153350966.png" new file mode 100644 index 0000000000000000000000000000000000000000..08123b30e84ffeb987a86486641bf929630ab170 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428153350966.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428153730182.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428153730182.png" new file mode 100644 index 0000000000000000000000000000000000000000..c03db85f3f9b9590fe66026cf33e2bcbfb3a7468 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428153730182.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428153949765.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428153949765.png" new file mode 100644 index 0000000000000000000000000000000000000000..571100f4fb47e00bd4c2e441cc3c0ae4ecd7efd2 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428153949765.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428154411161.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428154411161.png" new file mode 100644 index 0000000000000000000000000000000000000000..f97a8063f8fb702fdfd3272ba4ad1d736f36e337 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428154411161.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428154633244.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428154633244.png" new file mode 100644 index 0000000000000000000000000000000000000000..eb907a1087a67ccff454c0b6e91b7623565b227d Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428154633244.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428154751350.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428154751350.png" new file mode 100644 index 0000000000000000000000000000000000000000..540326b1a2ddabd3f8d88d3fb00fb8d6bef8d01e Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428154751350.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428154930163.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428154930163.png" new file mode 100644 index 0000000000000000000000000000000000000000..5dcdb3f2378869dad91713a0be4b87404bf725aa Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428154930163.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428155742442.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428155742442.png" new file mode 100644 index 0000000000000000000000000000000000000000..d93cad54bc734a726ccc5838b0d8a270e072f093 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428155742442.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428160111309.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428160111309.png" new file mode 100644 index 0000000000000000000000000000000000000000..dfcd6165eac1ea48145157d7752ced696d5915bf Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428160111309.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428160954632.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428160954632.png" new file mode 100644 index 0000000000000000000000000000000000000000..3260e4020253f9a5ea8209d42c882390c3219ab4 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428160954632.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428161136964.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428161136964.png" new file mode 100644 index 0000000000000000000000000000000000000000..bcc6f688612cc5d0fff062e71f2dad4f22c888e3 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428161136964.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428161352770.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428161352770.png" new file mode 100644 index 0000000000000000000000000000000000000000..168d82eb7b7e4272b74c8c6cbee5b52241684145 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428161352770.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428162009041.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428162009041.png" new file mode 100644 index 0000000000000000000000000000000000000000..f6019363aaa64a37c7e76d55a07b86d760242582 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428162009041.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428162142920.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428162142920.png" new file mode 100644 index 0000000000000000000000000000000000000000..915087bae783ec9b4f3b7fe65999f29e10311293 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428162142920.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428170701662.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428170701662.png" new file mode 100644 index 0000000000000000000000000000000000000000..18c1a103a73af5690b884948b1d4e700dde325ea Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428170701662.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428171422148.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428171422148.png" new file mode 100644 index 0000000000000000000000000000000000000000..9322464044e0e36c05e57405393eeb0fe5dfecda Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428171422148.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428172404486.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428172404486.png" new file mode 100644 index 0000000000000000000000000000000000000000..c99a9821d66f46d189ed93b55d1b612c14e9b99f Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428172404486.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428173858739.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428173858739.png" new file mode 100644 index 0000000000000000000000000000000000000000..02ce134bd63c946d6207c15be0e37ae47f311a62 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428173858739.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428174423188.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428174423188.png" new file mode 100644 index 0000000000000000000000000000000000000000..c1c8bd346871ee16e6b3ff579279543550162f02 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428174423188.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428175646019.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428175646019.png" new file mode 100644 index 0000000000000000000000000000000000000000..abb663d1499952b97dbeabe67c99665d65942b06 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428175646019.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428175903891.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428175903891.png" new file mode 100644 index 0000000000000000000000000000000000000000..aeddc0ac8459a22b3902e88dc6743f8fa82b6078 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428175903891.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428180101868.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428180101868.png" new file mode 100644 index 0000000000000000000000000000000000000000..983c9e82e5dde0a751ae9400ccd53b12d81cc47a Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428180101868.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428180335131.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428180335131.png" new file mode 100644 index 0000000000000000000000000000000000000000..e0362637421a830997240bd330af616942cc367d Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428180335131.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428180600154.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428180600154.png" new file mode 100644 index 0000000000000000000000000000000000000000..79ec1c148b4353c27ce91e61656239d224b84aeb Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428180600154.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428181004950.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428181004950.png" new file mode 100644 index 0000000000000000000000000000000000000000..558f5c2b7c2f821b6ea43ea385e028b4e72cfa44 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428181004950.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428181136752.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428181136752.png" new file mode 100644 index 0000000000000000000000000000000000000000..7bf4b4cd12198825c701e36c4d91666ce35a66fa Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428181136752.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428181457335.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428181457335.png" new file mode 100644 index 0000000000000000000000000000000000000000..1f0660c9ef48481527ef9538306fc6b9491d382e Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428181457335.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428200820520.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428200820520.png" new file mode 100644 index 0000000000000000000000000000000000000000..e7b19be2a7734fe26ae81d2beadd8a1bb3eba3ab Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428200820520.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428201054648.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428201054648.png" new file mode 100644 index 0000000000000000000000000000000000000000..ac3d23e75bf512ac7c02f30730ac1d1e72a48673 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428201054648.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428201242146.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428201242146.png" new file mode 100644 index 0000000000000000000000000000000000000000..b55e5271a9287247778bfd71ab23ecb47f1cf087 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428201242146.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428211350887.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428211350887.png" new file mode 100644 index 0000000000000000000000000000000000000000..bcb7c3b98d69e27e89202947e0d47f87429a8f8d Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428211350887.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428211725599.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428211725599.png" new file mode 100644 index 0000000000000000000000000000000000000000..ca4436bb0bb645e0a26d77d688fd12f38da7872d Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428211725599.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428212334135.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428212334135.png" new file mode 100644 index 0000000000000000000000000000000000000000..ff3fc064a4d42567f4fb181f03ecb00480eb2268 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428212334135.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428212605067.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428212605067.png" new file mode 100644 index 0000000000000000000000000000000000000000..3c139eb44aa585f87c92e480e925c686e76936f0 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428212605067.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428212801755.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428212801755.png" new file mode 100644 index 0000000000000000000000000000000000000000..1993ee2f58aa997334a12fa91eb2e2ab97fca89f Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428212801755.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428215026626.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428215026626.png" new file mode 100644 index 0000000000000000000000000000000000000000..7b90722dee5474d005337c2b12709b8de9397cb0 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428215026626.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428215203659.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428215203659.png" new file mode 100644 index 0000000000000000000000000000000000000000..d30525f2d6d8844cb9a5b7c7dcea179fe223df62 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428215203659.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428215608063.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428215608063.png" new file mode 100644 index 0000000000000000000000000000000000000000..c596900d95b42f4f5d27b55e4f244e8c10248101 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428215608063.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428222041079.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428222041079.png" new file mode 100644 index 0000000000000000000000000000000000000000..f147987a8a83c997c827d5ab084bc32a80bc1404 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428222041079.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428232020666.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428232020666.png" new file mode 100644 index 0000000000000000000000000000000000000000..6adaa99d5514e7ff79dc6a885e4608ccb6181159 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428232020666.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428232607192.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428232607192.png" new file mode 100644 index 0000000000000000000000000000000000000000..aa158e46d5c45325c76f4955aaa19503828452cf Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428232607192.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428233314626.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428233314626.png" new file mode 100644 index 0000000000000000000000000000000000000000..09b983898f82223d6a21f4b91b7382ef7a7ec3f2 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428233314626.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428233608994.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428233608994.png" new file mode 100644 index 0000000000000000000000000000000000000000..81396e2cb9bb761da200c185a0b42f1c181f9d97 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428233608994.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428233940790.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428233940790.png" new file mode 100644 index 0000000000000000000000000000000000000000..0c538999f4df5a015d10b62fbb29eb96c6ccb162 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428233940790.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428234328151.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428234328151.png" new file mode 100644 index 0000000000000000000000000000000000000000..6becab339760e04cef50ab90f7087fdd8e47988d Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428234328151.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428234448970.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428234448970.png" new file mode 100644 index 0000000000000000000000000000000000000000..914f31fd799ed1540bfae8c34ea9f731dbfe3d8f Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428234448970.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428235129193.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428235129193.png" new file mode 100644 index 0000000000000000000000000000000000000000..7068d484a0de6eed0f913422b4f8492cfff531fe Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428235129193.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428235648153.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428235648153.png" new file mode 100644 index 0000000000000000000000000000000000000000..b4d635d5fd9b382558ee3246cb3212c45d659f2c Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428235648153.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428235723087.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428235723087.png" new file mode 100644 index 0000000000000000000000000000000000000000..1c347219b41e11c0e4b4367ad3174ea3548a1da0 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428235723087.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428235803136.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428235803136.png" new file mode 100644 index 0000000000000000000000000000000000000000..5bc4e3572d6b5e2092d2af22bd68b0f4153a1bbf Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/2_\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200428235803136.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/README.md" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..75122392df9f5959d228bc7b9e5772884f9772fe --- /dev/null +++ "b/\346\234\272\345\231\250\345\255\246\344\271\240/\346\267\261\345\205\245\347\220\206\350\247\243\351\233\206\346\210\220\345\255\246\344\271\240XGBoost\345\217\212LightGBM/README.md" @@ -0,0 +1,17 @@ +## 主要内容 + +来源:https://www.bilibili.com/video/BV1Ca4y1t7DS?p=1 + +- 决策树 + - 分类树 + - 回归树 +- 集成学习 + - Bagging:随机森林 + - Boosting:Adaboost、GBDT、XGBoost、LightGBM + + + +数据挖掘竞赛利器:Stacking 和Blending方式 + +https://blog.csdn.net/maqunfi/article/details/82220115 + diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/README.md" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..bda593c91b145de1f82308fdf596e7e479f4d812 --- /dev/null +++ "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/README.md" @@ -0,0 +1,3 @@ +StackNet: + +https://blog.csdn.net/qq_18124075/article/details/80545842 \ No newline at end of file diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Stacking/README.md" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Stacking/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..e5a5c00557c27bb6634010779f61225b092bc2bd --- /dev/null +++ "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Stacking/README.md" @@ -0,0 +1,119 @@ +# Stacking + +## 原理 + +stacking 就是当用初始训练数据学习出若干个基学习器后,将这几个学习器的预测结果作为新的训练集,来学习一个新的学习器。 + +![image-20200430150603850](images/image-20200430150603850.png) + + + +## Stacking分类应用 + +这里我们用二分类的例子做介绍。 例如我们用 RandomForestClassifier, ExtraTreesClassifier, GradientBoostingClassifier 作为第一层学习器(当然这里我们可以添加更多的分类器,也可以用不同的特征组合但是同样的学习方法作为基分类器): + +```python +clfs = [ + RandomForestClassifier(n_estimators = n_trees, criterion = 'gini'), + ExtraTreesClassifier(n_estimators = n_trees * 2, criterion = 'gini'), + GradientBoostingClassifier(n_estimators = n_trees), + ] +``` + +接着要训练第一层学习器,并得到第二层学习器所需要的数据,这里会用到 k 折交叉验证。我们首先会将数据集进行一个划分,比如使用80%的训练数据来训练,20%的数据用来测试, + +``` +dev_cutoff = len(Y) * 4/5 + X_dev = X[:dev_cutoff] + Y_dev = Y[:dev_cutoff] + X_test = X[dev_cutoff:] + Y_test = Y[dev_cutoff:] +``` + +然后对训练数据通过交叉验证训练 clf,并得到第二层的训练数据 blend_train,同时,在每个基分类器的每一折交叉验证中,我们都会对测试数据进行一次预测,以得到我们blend_test,二者的定义如下: + +```python +blend_train = np.zeros((X_dev.shape[0], len(clfs))) # Number of training data x Number of classifiers +blend_test = np.zeros((X_test.shape[0], len(clfs))) # Number of testing data x Number of classifiers +``` + +按照上面说的,blend_train基于下面的方法得到,注意,下图是对于一个分类器来说的,所以每个分类器得到的blend_train的行数与用于训练的数据一样多,所以blend_train的shape为X_dev.shape[0]*len(clfs),即训练集长度 * 基分类器个数: + +![image-20200430150946784](images/image-20200430150946784.png) + +而对于第二轮的测试集blend_test来说,由于每次交叉验证的过程中都要进行一次预测,假设我们是5折交叉验证,那么对于每个分类器来说,得到的blend_test的shape是测试集行数 * 交叉验证折数,此时的做法是,对axis=1方向取平均值,以得到测试集行数 * 1 的测试数据,所以总的blend_test就是测试集行数 * 基分类器个数,可以跟blend_train保持一致: + +![image-20200430151036967](images/image-20200430151036967.png) + +得到blend_train 和 blend_test的代码如下: + +```python +for j, clf in enumerate(clfs): + print 'Training classifier [%s]' % (j) + blend_test_j = np.zeros((X_test.shape[0], len(skf))) # Number of testing data x Number of folds , we will take the mean of the predictions later + for i, (train_index, cv_index) in enumerate(skf): + print 'Fold [%s]' % (i) + + # This is the training and validation set + X_train = X_dev[train_index] + Y_train = Y_dev[train_index] + X_cv = X_dev[cv_index] + Y_cv = Y_dev[cv_index] + + clf.fit(X_train, Y_train) + + # This output will be the basis for our blended classifier to train against, + # which is also the output of our classifiers + blend_train[cv_index, j] = clf.predict(X_cv) + blend_test_j[:, i] = clf.predict(X_test) + # Take the mean of the predictions of the cross validation set + blend_test[:, j] = blend_test_j.mean(1) + +``` + +接着我们就可以用 blend_train, Y_dev 去训练第二层的学习器 LogisticRegression(当然也可以是别的分类器,比如lightGBM,XGBoost): + +``` + bclf = LogisticRegression() +bclf.fit(blend_train, Y_dev) +``` + +最后,基于我们训练的二级分类器,我们可以预测测试集 blend_test,并得到 score: + +``` +Y_test_predict = bclf.predict(blend_test) +score = metrics.accuracy_score(Y_test, Y_test_predict) +print 'Accuracy = %s' % (score) +``` + +如果是多分类怎么办呢,我们这里就不能用predict方法啦,我么要用的是predict_proba方法,得到基分类器对每个类的预测概率代入二级分类器中训练,修改的部分代码如下: + +```python +blend_train = np.zeros((np.array(X_dev.values.tolist()).shape[0], num_classes*len(clfs)),dtype=np.float32) # Number of training data x Number of classifiers +blend_test = np.zeros((np.array(X_test.values.tolist()).shape[0], num_classes*len(clfs)),dtype=np.float32) # Number of testing data x Number of classifiers + + # For each classifier, we train the number of fold times (=len(skf)) + for j, clf in enumerate(clfs): + for i, (train_index, cv_index) in enumerate(skf): + print('Fold [%s]' % (i)) + + # This is the training and validation set + X_train = X_dev[train_index] + Y_train = Y_dev[train_index] + X_cv = X_dev[cv_index] + + X_train = np.concatenate((X_train, ret_x),axis=0) + Y_train = np.concatenate((Y_train, ret_y),axis=0) + clf.fit(X_train, Y_train) + blend_train[cv_index, j*num_classes:(j+1)*num_classes] = clf.predict_proba(X_cv) + blend_test[:, j*num_classes:(j+1)*num_classes] += clf.predict_proba(X_test) +blend_test = blend_test / float(n_folds) +``` + +上面的代码修改的主要就是blend_train和blend_test的shape,可以看到,对于多分类问题来说,二者的第二维的shape不再是基分类器的数量,而是class的数量*基分类器的数量,这是大家要注意的,否则可能不会得到我们想要的结果。 + +## 参考 + +https://www.jianshu.com/p/3d2bd58908d0 + +https://blog.csdn.net/u012526003/article/details/79109418 \ No newline at end of file diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Stacking/images/image-20200430150603850.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Stacking/images/image-20200430150603850.png" new file mode 100644 index 0000000000000000000000000000000000000000..bbbf47b7e8b65a27d037fb2278c39e2df59bc63f Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Stacking/images/image-20200430150603850.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Stacking/images/image-20200430150946784.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Stacking/images/image-20200430150946784.png" new file mode 100644 index 0000000000000000000000000000000000000000..9f94ad3a74449bd9f4ffec73e815f20409f54e2d Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Stacking/images/image-20200430150946784.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Stacking/images/image-20200430151036967.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Stacking/images/image-20200430151036967.png" new file mode 100644 index 0000000000000000000000000000000000000000..02a6603ec4d2e95c1f0fe0265971e9deaead9a7f Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Stacking/images/image-20200430151036967.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/README.md" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..80736c8a59e10474dac565639c133bf7d8067e46 --- /dev/null +++ "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/README.md" @@ -0,0 +1,68 @@ +# 模型融合方法 + +youtube视频介绍模型融合: + +https://www.youtube.com/watch?v=BS4SY3HhVDI&t=4320s + +Kaggle比赛上的,介绍模型组合 + +https://www.kaggle.com/arthurtok/introduction-to-ensembling-stacking-in-python + +## BasicModel:Start From simple + +- 让你的第一个模型开始工作 + - 交叉验证:通常为5 - 10倍 + - 了解模型评估指标估计器的 + - 初始超参数调优 + - 提交:观看CV评分和公共排名 + +- 尝试不同的算法 +- 基线作为一个单一的模型 + +## Alogorithms + +![image-20200509164810523](images/image-20200509164810523.png) + +## Cross-validation + +交叉验证 + +![image-20200509165602740](images/image-20200509165602740.png) + + + +不平衡的数据集 + +![image-20200509170021718](images/image-20200509170021718.png) + + + +## Model Evaluation + +取决于不同的比赛 + +回归问题 + +- Mean absolute error(MAE) +- Root mean squared error(RMSE) + +分类问题 + +- Logarithmic loss(log-loss)or multiclass log-loss +- Mean consequential error(MCE) +- Area under curve(AUC) +- Hamming loss + +![image-20200509170428165](images/image-20200509170428165.png) + + + +## Hyper-parameter Optimization + +- Grid search + - Brute force + - Expensive computation + - Less efficient +- Random Search + +![image-20200509171212009](images/image-20200509171212009.png) \ No newline at end of file diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509164810523.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509164810523.png" new file mode 100644 index 0000000000000000000000000000000000000000..a44d1ac9521984976dd63718a7c3c9a86caaf04b Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509164810523.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509165602740.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509165602740.png" new file mode 100644 index 0000000000000000000000000000000000000000..6cd297c74a3e6c536297444b77cd7168c456a5d6 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509165602740.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509170021718.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509170021718.png" new file mode 100644 index 0000000000000000000000000000000000000000..ecb8c0de3628c49c73b4efc45a0e02ee65e21eae Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509170021718.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509170428165.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509170428165.png" new file mode 100644 index 0000000000000000000000000000000000000000..ab6b5c551908d4ae3cd6473efe7eff68b7512bc5 Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509170428165.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509171212009.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509171212009.png" new file mode 100644 index 0000000000000000000000000000000000000000..17f193c0549b887555292ce3eb20bd6b4f6a4f5e Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/Youtube\351\233\206\346\210\220\345\255\246\344\271\240/images/image-20200509171212009.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/README.md" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..0f59a24df2b4957983b7c024398c4e3084c0b702 --- /dev/null +++ "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/README.md" @@ -0,0 +1,40 @@ +# 模型融合 + +来源:https://www.bilibili.com/video/BV13K4y1k7Vy + +模型融合的主要目的是降低偏差和方差 + +![image-20200501101658533](images/image-20200501101658533.png) + +## 集成学习 + +### 各类模型和实现 + +- Bagging + - 随机森林:(效率很高,在头部的时候可以使用) +- Boosting + - AdaBoost + - GBDT:(使用了残差) + - XGBoost + - LightGBM + - CatBoost:(主要用于分类) +- Stacking + - Stacking +- Blending:(和Stacking类似,建议在数据量比较大的时候使用) + - Blending + +### Voting + +投票机制 + +![image-20200501095513508](images/image-20200501095513508.png) + +### Blending + +![image-20200501095550657](images/image-20200501095550657.png) + +## Stacking + +这个时候需要使用强模型,在做Stacking模型 + +![image-20200501095646554](images/image-20200501095646554.png) \ No newline at end of file diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/images/image-20200501095513508.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/images/image-20200501095513508.png" new file mode 100644 index 0000000000000000000000000000000000000000..7b3e7e2508f642e866e100462f86296d62a5d97a Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/images/image-20200501095513508.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/images/image-20200501095550657.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/images/image-20200501095550657.png" new file mode 100644 index 0000000000000000000000000000000000000000..0b9b6df730b4ae6c3b07ede7d80958d56a4c7bdb Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/images/image-20200501095550657.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/images/image-20200501095646554.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/images/image-20200501095646554.png" new file mode 100644 index 0000000000000000000000000000000000000000..619fdc014233d225f454135949e22200c2cee83b Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/images/image-20200501095646554.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/images/image-20200501101658533.png" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/images/image-20200501101658533.png" new file mode 100644 index 0000000000000000000000000000000000000000..13cc436b9c9d8efe3b91a9decee297f82670bf8e Binary files /dev/null and "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\346\250\241\345\236\213\350\236\215\345\220\210/images/image-20200501101658533.png" differ diff --git "a/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\351\207\221\350\236\215\351\243\216\346\216\247\351\227\256\351\242\230\346\241\210\344\276\213/README.md" "b/\346\234\272\345\231\250\345\255\246\344\271\240/\351\233\206\346\210\220\345\255\246\344\271\240/\351\207\221\350\236\215\351\243\216\346\216\247\351\227\256\351\242\230\346\241\210\344\276\213/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/README.md" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..da4fadb730fff024af2e5d998643a343a5db235f --- /dev/null +++ "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/README.md" @@ -0,0 +1,524 @@ +# 使用Docker快速搭建蘑菇博客(Eureka版) + +最近几天一直在研究怎么样才能够快速搭建蘑菇博客项目,对了,我的服务器是阿里云购买的云服务器ECS,配置是 1核2G ,学生优惠价,100多一年。。。 嗯,这应该是搭建蘑菇博客的最低配置了,内存少于2G的话,可能会启动不起来,本来2G也是不够用的,我是把所有的微服务和solr都放到一个tomcat中,才勉强跑起来的。 目前为了更加方便大家的部署,我已经修改成jar包的方式进行部署启动了,tomcat仅用于作为solr启动的web容器。 + +如果你的服务器内存也是2G的话,请务必先配置一下交换内存:[CentOS如何增加虚拟内存](http://www.moguit.cn/#/info?blogUid=36ee5efa56314807a9b6f1c1db508871) + +如果你也拥有对应的域名并且备案了的话,可以给蘑菇博客配置域名的方式访问:[蘑菇博客配置域名解析](http://moguit.cn/#/info?blogUid=06565868c0e86fe8125a9d55430cd266) + +如果你的服务器带宽只有1M,可以使用免费的百度云加速,加快页面渲染速度:[如何使用百度云加速提升网站访问速度](http://www.moguit.cn/#/info?blogUid=af053959672343f8a139ec27fd534c6c) + +> tip:特别注意,因为镜像中的代码可能不是最新版本,因此推荐在按照本篇博客,安装好docker环境后,需要在参考下面蘑菇博客部署阿里云这篇博客,重新将前后端代码都重新部署一遍,同时也记得把doc中的两个SQL文件也重新导入,确保服务器为最新代码 + +如果你之前安装好了蘑菇博客的docker环境,修改的博客的源码,想要重新发布到自己服务器上:[蘑菇博客如何部署到阿里云服务器](http://moguit.cn/#/info?blogUid=89defe3f4a3f317cba9aa0cdb9ff879e) + +因为配置那些环境比较麻烦,(主要包括Nginx,Solr,Redis,Tomcat,Mysql,RabbitMQ)当然如果小伙伴喜欢自己配置的话,也可以不使用我搭建好的镜像,可以参考下面几篇博客哦,希望你也能够配置成功的~!(想直接通过Docker部署的,可以忽略下面几步..) + +1、[CentOS下如何安装Nginx](http://www.moguit.cn/#/info?blogUid=e8d3e38ba35b4765ae128256eb44e341) + +2、[CentOS下Rdeis的安装和部署](http://www.moguit.cn/#/info?blogUid=d0e2c4337d7a4a85b176834c8c674fdf) + +3、[CentOS下Solr的安装和部署](http://www.moguit.cn/#/info?blogUid=7c7404c456904be5b7736238f28d2515) + +4、[CentOS下Mariadb的安装和部署](http://www.moguit.cn/#/info?blogUid=d5b6dff48e5d42b1afcbf6ab591bdab1) + +5、[CentOS下RabbitMQ的安装和部署](http://www.moguit.cn/#/info?blogUid=2af543cdbd4342e1812e72687aac4580) + +6、[CentOS下ElasticSearch的安装和部署](http://moguit.cn/#/info?blogUid=ee342088a5d0f5b96bcb4582d9b563aa) + +好了。下面我介绍的是用Docker快速搭建蘑菇博客。话不多说,下面我就直接进入正题。 + +## 注册Docker账号 + +首先大家先去DockerHub注册账号,用于拉取Docker镜像和存储镜像 + +注意:注册DockerHub的目的,是为了能够方便以后大家把自己的镜像上传上去,如果DockerHub无法访问,或者不想上传镜像的话,可以忽略这一步,同时在3步 也忽略 docker login,直接进行Docker pull 拉取我的镜像即可 + +DockerHub官网:[点我传送](https://hub.docker.com/) + +关于更多docker命令和介绍,可以看这篇博客:[Docker常用命令](http://www.moguit.cn/#/info?blogUid=8974a6ce5bae4bf68f1aa37f07c96d0f) + +## Docker安装和启动 + +注册成功后,进入我们的CentOS系统中(如果是Ubuntu的话,可能安装docker的方式不同,请自行百度安装) + +下面介绍的是使用yum方式安装docker + +### 配置docker的阿里云yum源 + +``` +cat >>/etc/yum.repos.d/docker.repo< tip:因为镜像中的代码可能不是最新版本,因此推荐在按照本篇博客,安装好docker环境后,需要在参考下面蘑菇博客部署阿里云这篇博客,重新将前后端代码都重新部署一遍,同时也记得把doc中的两个SQL文件也重新导入,确保服务器为最新代码~ + +### mogu_picture修改配置 + +首先我们在启动startup.sh脚本前,先修改对应目录下 config文件夹的application.yml配置文件,直接修改可能会里面是乱码,可以先把它取出来,到window下修改,然后在放入 + +``` +# 进入picture目录下 +cd /home/mogu_blog/mogu_picture/config +# 编辑配置 +vim application.yml +``` + +然后找到下面的内容,把对应的ip地址改成自己云服务器的即可 + +``` +#Data image url +file: + upload: + path: /home/mogu_blog/mogu_data/ +``` + +修改完成后,我们回到上级目录,执行启动脚本 + +``` +# 返回上一级 +cd .. +# 启动项目 +./startup.sh +``` + +### mogu_web修改配置 + +同理,找到mogu_web下的config文件,我们需要将下面的域名,改成自己的IP地址 + +``` +#Data image url +data: + # 门户页面 + webSite: + url: http://101.132.122.175:9527/#/ + # mogu_web网址,用于第三方登录回调 + web: + url: http://101.132.122.175:8603 + # 静态资源映射,通过nginx + image: + url: http://101.132.122.175:8600/ +``` + +同时在配置文件的最下面,还需要修改第三方注册需要的 clientId 和 ClientSecret:如果不清楚如何获取的小伙伴,可以查看我的这篇博客,在后面部分对ID的获取有相关介绍:[SpringBoot+Vue如何集成第三方登录JustAuth](http://moguit.cn/#/info?blogUid=8cbadb54967257f12d6cc7eb1a58a361) + +```yml +# 第三方登录 +justAuth: + clientId: + gitee: XXXXXXXXXXXXXXXXXXXXXX + github: XXXXXXXXXXXXXXXXXXXXXX + clientSecret: + gitee: XXXXXXXXXXXXXXXXXXXXXX + github: XXXXXXXXXXXXXXXXXXXXXX +``` + +### mogu_sms修改配置 + +在mogu_sms中,主要修改的就是邮箱的配置,我们将发送邮件的信息改成自己的 + +```yml +#mail +mail: + username: XXXXXXX@163.com + password: XXXXXXX #授权码开启SMTP服务里设置 +``` + +注意,上面的password是授权码,授权码不是密码,以163邮箱为例,我们需要开启SMTP服务,然后设置授权码 + +![image-20200722090457339](images/image-20200722090457339.png) + + + +修改完成后,我们启动对应的项目即可,最终我们需要启动的项目有: mogu_eureka,mogu_picture, mogu_sms, mogu_admin, mogu_web + +**tip:(用于以后使用图形化客户端进行连接)** + +mysql的账号和密码是 root mogu2018 + +redis的密码是 mogu2018 + +## 验证是否后台是否启动成功 + +等服务器都启动完成后,下面我们验证一下后台是否正常启动,访问下列的地址: + +``` +http://your_ip:8761 +``` + +首次登录会出现登录框:用户名:user 密码:password123 + +如果我们看到下面四个服务都注册到eureka中,那说明启动成功 + +![image-20200209130259959](images/image-20200209130259959.png) + +我们在通过访问下列swagger接口,测试接口是否正常 + +``` +http://your_ip:8601/swagger-ui.html +http://your_ip:8603/swagger-ui.html +``` + +如果能够进入下面页面的话,说明后台是没有问题的了,下面我们可以验证一下接口 + +![image-20200209130313977](images/image-20200209130313977.png) + +验证登录 + +![image-20200209130324333](images/image-20200209130324333.png) + +登录功能正常使用,我们把token复制到来,然后在swagger页面的右上角,有一个authorize的按钮,点击后,将token粘贴进去,即可操作全部接口进行测试了~ + +![image-20200209130336478](images/image-20200209130336478.png) + +## 修改前端项目配置 + +我们现在需要修改两个地方的配置,分别是:vue_mogu_admin 和 vue_mogu_web + +下面我们到 vue_mogu_web/config/目录下,修改prod.env.js文件 + +![image-20200209130347971](images/image-20200209130347971.png) + +把里面的ip地址换成你主机的地址即可 + +``` +WEB_API: '"http://your_ip:8603"', +PICTURE_HOST: '"http://your_ip:8600"', +``` + +同理,在修改 vue_mogu_admin下的地址,把里面的ip地址,换成你服务器的ip即可 + +![image-20200209130403916](images/image-20200209130403916.png) + +修改完成后prod.js后,我们还需要修改ckeditor图片上传的接口 + +在 vue_mogu_admin/static/ckeditor/config.js,修改下面的内容,这个只需要在admin项目才需要修改,web中没有使用ckeditor + +```javascript +//开启工具栏“图像”中文件上传功能,后面的url为待会要上传action要指向的的action或servlet +config.filebrowserImageUploadUrl = "http://your_ip:8602/ckeditor/imgUpload?"; + +//开启插入\编辑超链接中文件上传功能,后面的url为待会要上传action要指向的的action或servlet +config.filebrowserUploadUrl = 'http://your_ip:8602/ckeditor/fileUpload'; +``` + +修改完成后,需要进行重新编译~ 打包~ 部署~ + +我们首先在 vue_mogu_admin 目录下,执行下列命令进行打包(打包过程中.....可能会遇到一些语法规范错误,请无视~) + +``` +# 安装依赖 +npm install --registry=https://registry.npm.taobao.org + +# 打包 +npm run build +``` + +打包完成后,会生成一个dist目录,我们将整个dist目录,压缩成 zip格式 + +![image-20200209130425874](images/image-20200209130425874.png) + +然后使用xftp工具,丢入到我们的前端目录下,目录在 /home/mogu_blog/vue_mogu_admin + +![image-20200209130438506](images/image-20200209130438506.png) + +注意:如果该文件夹下存在 dist文件夹,我们需要将其删除,然后在解压 + +然后使用下面命令进行解压 + +``` +unzip dist.zip +``` + +同理的操作,在执行一下上述操作,将vue_mogu_web项目也进行打包,部署到 /home/mogu_blog/vue_mogu_web目录下即可 + + + +## 访问蘑菇博客项目 + +### 访问前端项目 + +例如: 192.168.1.101:9527 + +![image-20200209130524162](images/image-20200209130524162.png) + +### 访问后端项目 + + ip地址:9528 用户名和密码是: admin mogu2018 + +![image-20200209130547785](images/image-20200209130547785.png) + +## 总结: + +好了,到目前为止,蘑菇博客已经搭建完成。当然小伙伴并不是拉取来就能直接用的, 如果ip地址不一样的话,是不能直接使用的,后面的话,需要拉取源码后,修改对应的配置信息后,然后在打包部署,才能够使用的。 \ No newline at end of file diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209122416398.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209122416398.png" new file mode 100644 index 0000000000000000000000000000000000000000..b49bf4d9c8a38de1031dccff7883c8318d61b139 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209122416398.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209122441971.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209122441971.png" new file mode 100644 index 0000000000000000000000000000000000000000..6b64b2594d4ccaeaafa896d41a767001c5029de0 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209122441971.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125847329.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125847329.png" new file mode 100644 index 0000000000000000000000000000000000000000..31500486ee678d0eb1a45c918314cd4851e109e3 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125847329.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125905430.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125905430.png" new file mode 100644 index 0000000000000000000000000000000000000000..4edcd2e6507c2a383d231d24d482aad153c827d1 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125905430.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125919324.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125919324.png" new file mode 100644 index 0000000000000000000000000000000000000000..872eafffa5f754e5dba5c7f0bc5ed38e6e4dbddb Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125919324.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125938397.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125938397.png" new file mode 100644 index 0000000000000000000000000000000000000000..2d275e508fcbf82aa61512711a82ba4cbfcac257 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125938397.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125953803.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125953803.png" new file mode 100644 index 0000000000000000000000000000000000000000..c86f00a4257be3bf2e4491daae1b8133772cbf5d Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209125953803.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130011043.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130011043.png" new file mode 100644 index 0000000000000000000000000000000000000000..e215106839678cf3e592c787ea64c3cd23643ad1 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130011043.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130023427.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130023427.png" new file mode 100644 index 0000000000000000000000000000000000000000..3adb6d9b27420909c447c662a4ce69d442858392 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130023427.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130036402.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130036402.png" new file mode 100644 index 0000000000000000000000000000000000000000..aa4460652f9af62cbfac7e6f589555d23b14c3f2 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130036402.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130104979.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130104979.png" new file mode 100644 index 0000000000000000000000000000000000000000..8fc4c44becfd39c12cc97b132725f417600a3a58 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130104979.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130124155.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130124155.png" new file mode 100644 index 0000000000000000000000000000000000000000..afa5ed95e0dd7c47e9674a539f8668a7a0656cd4 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130124155.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130139403.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130139403.png" new file mode 100644 index 0000000000000000000000000000000000000000..407e6ddce526fd2965e5789b9c382c0742719339 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130139403.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130156442.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130156442.png" new file mode 100644 index 0000000000000000000000000000000000000000..cfc79fa27049bf8800b4618bd0f2c2c77f733acc Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130156442.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130210835.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130210835.png" new file mode 100644 index 0000000000000000000000000000000000000000..33af97a708722520a8834c99e93c60b26d26ddbe Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130210835.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130224724.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130224724.png" new file mode 100644 index 0000000000000000000000000000000000000000..8ce106e58c384617f4329a55c446dcbdf6b33ba2 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130224724.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130259959.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130259959.png" new file mode 100644 index 0000000000000000000000000000000000000000..17888b30d60c888ce7381188c35536039b251639 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130259959.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130313977.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130313977.png" new file mode 100644 index 0000000000000000000000000000000000000000..cacbd7f45fcf1d72aa24abcdc5fb1bbc2beaba2a Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130313977.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130324333.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130324333.png" new file mode 100644 index 0000000000000000000000000000000000000000..d54bf37df807106db04ca4b2cae815da0008b08a Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130324333.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130336478.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130336478.png" new file mode 100644 index 0000000000000000000000000000000000000000..321c0a8f2ac2c0fe23d33d7f9d27027616e5a02d Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130336478.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130347971.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130347971.png" new file mode 100644 index 0000000000000000000000000000000000000000..1891933d2d852ad0b77be6f31ce0c36259cfe2f3 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130347971.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130403916.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130403916.png" new file mode 100644 index 0000000000000000000000000000000000000000..23fb7f1de5ff65633d6603a88913ac4f0f82f2b3 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130403916.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130425874.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130425874.png" new file mode 100644 index 0000000000000000000000000000000000000000..09d1d7dc050b1c01ac654d93f2186a3361abe07b Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130425874.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130438506.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130438506.png" new file mode 100644 index 0000000000000000000000000000000000000000..eb6f59026d5bfee99b6a78fcac06c942cfd6371a Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130438506.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130524162.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130524162.png" new file mode 100644 index 0000000000000000000000000000000000000000..ec7f855b5a176830574457fc577bad8bb0929fc9 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130524162.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130547785.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130547785.png" new file mode 100644 index 0000000000000000000000000000000000000000..da5a179af653ac229128b3d8faa979471f204550 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200209130547785.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200722090457339.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200722090457339.png" new file mode 100644 index 0000000000000000000000000000000000000000..b56c34b8dad565e4bc447c4282b4c4c450150326 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200722090457339.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903163514966.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903163514966.png" new file mode 100644 index 0000000000000000000000000000000000000000..d62bfd4508e83023f0b62290c70f9a9e873bf1dc Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903163514966.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903164316451.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903164316451.png" new file mode 100644 index 0000000000000000000000000000000000000000..b299dd85ae1e062ba5a53f200223edfabc241d09 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903164316451.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903164514073.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903164514073.png" new file mode 100644 index 0000000000000000000000000000000000000000..71ff0bd7876daea1faf128272140a69922ba2e15 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903164514073.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903165638594.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903165638594.png" new file mode 100644 index 0000000000000000000000000000000000000000..c3a6afeb73f0beea71f4b51ad30424475ada58f2 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903165638594.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903165911938.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903165911938.png" new file mode 100644 index 0000000000000000000000000000000000000000..3a463141b44a009b72ef11b52b6e34959f0fa2b1 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903165911938.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903165947652.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903165947652.png" new file mode 100644 index 0000000000000000000000000000000000000000..98ecea39a893a2e42650c002e92e708f5fb3fe97 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903165947652.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903170244575.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903170244575.png" new file mode 100644 index 0000000000000000000000000000000000000000..816e0094f317b9107d2dd2c723010ab55a015d31 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Eureka\347\211\210)/images/image-20200903170244575.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/README.md" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..0d321520cecdf42fdccfafc2755eae746d182622 --- /dev/null +++ "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/README.md" @@ -0,0 +1,577 @@ +# 使用Docker快速搭建蘑菇博客(Nacos版) + +最近几天一直在研究怎么样才能够快速搭建蘑菇博客项目,对了,我的服务器是阿里云购买的云服务器ECS,配置是 1核2G ,学生优惠价,100多一年。。。 嗯,这应该是搭建蘑菇博客的最低配置了,内存少于2G的话,可能会启动不起来,本来2G也是不够用的,我是把所有的微服务和solr都放到一个tomcat中,才勉强跑起来的。 目前为了更加方便大家的部署,我已经修改成jar包的方式进行部署启动了,tomcat仅用于作为solr启动的web容器。 + +如果你的服务器内存也是2G的话,请务必先配置一下交换内存:[CentOS如何增加虚拟内存](http://www.moguit.cn/#/info?blogUid=36ee5efa56314807a9b6f1c1db508871) + +如果你也拥有对应的域名并且备案了的话,可以给蘑菇博客配置域名的方式访问:[蘑菇博客配置域名解析](http://moguit.cn/#/info?blogUid=06565868c0e86fe8125a9d55430cd266) + +如果你的服务器带宽只有1M,可以使用免费的百度云加速,加快页面渲染速度:[如何使用百度云加速提升网站访问速度](http://www.moguit.cn/#/info?blogUid=af053959672343f8a139ec27fd534c6c) + +> tip:特别注意,因为镜像中的代码可能不是最新版本,因此推荐在按照本篇博客,安装好docker环境后,需要在参考下面蘑菇博客部署阿里云这篇博客,重新将前后端代码都重新部署一遍,同时也记得把doc中的两个SQL文件也重新导入,确保服务器为最新代码 + +如果你之前安装好了蘑菇博客的docker环境,修改的博客的源码,想要重新发布到自己服务器上:[蘑菇博客如何部署到阿里云服务器](http://moguit.cn/#/info?blogUid=89defe3f4a3f317cba9aa0cdb9ff879e) + +因为配置那些环境比较麻烦,(主要包括Nginx,Solr,Redis,Tomcat,Mysql,RabbitMQ)当然如果小伙伴喜欢自己配置的话,也可以不使用我搭建好的镜像,可以参考下面几篇博客哦,希望你也能够配置成功的~!(想直接通过Docker部署的,可以忽略下面几步..) + +1、[CentOS下如何安装Nginx](http://www.moguit.cn/#/info?blogUid=e8d3e38ba35b4765ae128256eb44e341) + +2、[CentOS下Rdeis的安装和部署](http://www.moguit.cn/#/info?blogUid=d0e2c4337d7a4a85b176834c8c674fdf) + +3、[CentOS下Solr的安装和部署](http://www.moguit.cn/#/info?blogUid=7c7404c456904be5b7736238f28d2515)(可选) + +4、[CentOS下Mariadb的安装和部署](http://www.moguit.cn/#/info?blogUid=d5b6dff48e5d42b1afcbf6ab591bdab1) + +5、[CentOS7下RabbitMQ的安装步骤](http://www.moguit.cn/#/info?blogUid=f346267364024e78844d459be2f6f528) + +6、[CentOS下ElasticSearch的安装和部署](http://moguit.cn/#/info?blogUid=ee342088a5d0f5b96bcb4582d9b563aa)(可选) + +7、[Elasticsearch介绍和安装](http://moguit.cn/#/info?blogUid=ee342088a5d0f5b96bcb4582d9b563aa)(可选) + +8、[CentOS下安装Nacos](http://moguit.cn/#/info?blogUid=7a7ad19472d53147150eb7fdb0978bb2)(Nacos分支需要) + +9、[CentOS下安装Sentinel](http://moguit.cn/#/info?blogUid=b100fde21ac0b61414dbaa74d2db7192)(Nacos分支需要) + +好了。下面我介绍的是用Docker快速搭建蘑菇博客。话不多说,下面我就直接进入正题。 + +## 注册Docker账号 + +首先大家先去DockerHub注册账号,用于拉取Docker镜像和存储镜像 + +注意:注册DockerHub的目的,是为了能够方便以后大家把自己的镜像上传上去,如果DockerHub无法访问,或者不想上传镜像的话,可以忽略这一步,同时在3步 也忽略 docker login,直接进行Docker pull 拉取我的镜像即可 + +DockerHub官网:[点我传送](https://hub.docker.com/) + +关于更多docker命令和介绍,可以看这篇博客:[Docker常用命令](http://www.moguit.cn/#/info?blogUid=8974a6ce5bae4bf68f1aa37f07c96d0f) + +## Docker安装和启动 + +注册成功后,进入我们的CentOS系统中(如果是Ubuntu的话,可能安装docker的方式不同,请自行百度安装) + +下面介绍的是使用yum方式安装docker + +### 配置docker的阿里云yum源 + +``` +cat >>/etc/yum.repos.d/docker.repo< tip:因为镜像中的代码可能不是最新版本,因此推荐在按照本篇博客,安装好docker环境后,需要在参考下面蘑菇博客部署阿里云这篇博客,重新将前后端代码都重新部署一遍,同时也记得把doc中的三个SQL文件也重新导入,确保服务器为最新代码~ + +### mogu_web修改配置 + +我们进入到nacos配置文件管理界面,找到的 mogu_web_prod.yaml文件 + +![image-20200903164514073](images/image-20200903164514073-1599124105900.png) + +我们需要将下面的域名,改成自己的 + +``` +data: + # 门户页面 + webSite: + url: http://101.132.122.175/:9527/#/ + # 有域名可以改成如下 + # url: http://www.moguit.cn/#/ + + # mogu_web网址,用于第三方登录回调 + web: + url: http://101.132.122.175/:8603 +``` + +同时在配置文件的最下面,还需要修改第三方注册需要的 clientId 和 ClientSecret:如果不清楚如何获取的小伙伴,可以查看我的这篇博客,在后面部分对ID的获取有相关介绍:[SpringBoot+Vue如何集成第三方登录JustAuth](http://moguit.cn/#/info?blogUid=8cbadb54967257f12d6cc7eb1a58a361) + +```yml +# 第三方登录 +justAuth: + clientId: + gitee: XXXXXXXXXXXXXXXXXXXXXX + github: XXXXXXXXXXXXXXXXXXXXXX + clientSecret: + gitee: XXXXXXXXXXXXXXXXXXXXXX + github: XXXXXXXXXXXXXXXXXXXXXX +``` + +修改完成后,启动项目 + +```bash +# 进入mogu_web目录 +cd mogu_web +# 启动项目 +./startup.sh +``` + +### mogu_sms修改配置 + +我们进入到nacos配置文件管理界面,找到的 mogu_sms_prod.yaml文件 + +![image-20200903164316451](images/image-20200903164316451-1599124105900.png) + +在mogu_sms中,主要修改的就是邮箱的配置,我们将发送邮件的信息改成自己的 + +```yml +#mail +mail: + username: XXXXXXX@163.com + password: XXXXXXX #授权码开启SMTP服务里设置 +``` + +注意,上面的password是授权码,授权码不是密码,以163邮箱为例,我们需要开启SMTP服务,然后设置授权码 + +![image-20200722090457339](images/image-20200722090457339-1599124105900.png) + + + +修改完成后,我们启动对应的项目即可,最终我们需要启动的项目有: mogu_picture, mogu_sms, mogu_admin, mogu_web + +**tip:(用于以后使用图形化客户端进行连接)** + +mysql的账号和密码是 root mogu2018 + +redis的密码是 mogu2018 + +## 验证是否后台是否启动成功 + +等服务器都启动完成后,下面我们验证一下后台是否正常启动,回到我们的Nacos管理界面 + +``` +http://your_ip:8848/nacos +``` + +如果我们看到下面四个服务都注册到eureka中,那说明启动成功 + +![image-20200903165638594](images/image-20200903165638594-1599124105900.png) + +我们在通过访问下列swagger接口,测试接口是否正常 + +``` +http://your_ip:8601/swagger-ui.html +http://your_ip:8603/swagger-ui.html +``` + +如果能够进入下面页面的话,说明后台是没有问题的了,下面我们可以验证一下接口 + +![image-20200209130313977](images/image-20200209130313977-1599124105900.png) + +验证登录 + +![image-20200209130324333](images/image-20200209130324333-1599124105900.png) + +登录功能正常使用,我们把token复制到来,然后在swagger页面的右上角,有一个authorize的按钮,点击后,将token粘贴进去,即可操作全部接口进行测试了~ + +![image-20200209130336478](images/image-20200209130336478-1599124105900.png) + +## 修改前端项目配置 + +我们现在需要修改两个地方的配置,分别是:vue_mogu_admin 和 vue_mogu_web\ + +>tip:以下配置的修改,需要在我们本地的编辑器下进行修改,修改完成后在打包发送到服务器,也就是我们下载的源码目录,注意不是在linux服务器下的dist文件夹内!!! + +下面我们到 vue_mogu_web/config/目录下,修改prod.env.js文件 + +![image-20200903165911938](images/image-20200903165911938-1599124105900.png) + +把里面的ip地址换成你主机的地址即可 + +``` +//配置线上环境 +VUE_MOGU_WEB: '"http://101.132.122.175:9527"', +PICTURE_API: '"http://101.132.122.175:8602"', +WEB_API: '"http://101.132.122.175:8603"', +ELASTICSEARCH: '"http://101.132.122.175:8605"', +``` + +同理,在修改 vue_mogu_admin下的地址,把里面的ip地址,换成你服务器的ip即可 + +![image-20200903165947652](images/image-20200903165947652-1599124105900.png) + +修改完成后,需要进行重新编译~ 打包~ 部署~ + +我们首先在 vue_mogu_admin 目录下,执行下列命令进行打包(打包过程中.....可能会遇到一些语法规范错误,请无视~) + +``` +# 安装依赖 +npm install --registry=https://registry.npm.taobao.org + +# 打包 +npm run build +``` + +打包完成后,会生成一个dist目录,我们将整个dist目录,压缩成 zip格式 + +![image-20200209130425874](images/image-20200209130425874-1599124105901.png) + +然后使用xftp工具,丢入到我们的前端目录下,目录在 /home/mogu_blog/vue_mogu_admin + +![image-20200209130438506](images/image-20200209130438506-1599124105901.png) + +注意:如果该文件夹下存在 dist文件夹,我们需要将其删除,然后在解压 + +然后使用下面命令进行解压 + +``` +unzip dist.zip +``` + +同理的操作,在执行一下上述操作,将vue_mogu_web项目也进行打包,部署到 /home/mogu_blog/vue_mogu_web目录下即可 + +## 访问蘑菇博客项目 + +### 访问前端项目 + +例如: 192.168.1.101:9527 + +![image-20200209130524162](../../杂记/Docker搭建蘑菇博客/images/image-20200209130524162.png) + +tip:需要注意的是,如果图片无法正常显示,请先登录后台管理页面,然后修改对应的域名 + +关于具体的配置,参考这篇博客:[蘑菇博客配置七牛云存储](http://www.moguit.cn/#/info?blogUid=735ed389c4ad1efd321fed9ac58e646b) + +![image-20200903170244575](images/image-20200903170244575-1599124105901.png) + +### 访问后端项目 + + ip地址:9528 用户名和密码是: admin mogu2018 + +![image-20200209130547785](images/image-20200209130547785-1599124105901.png) + +## 总结: + +好了,到目前为止,蘑菇博客已经搭建完成。当然小伙伴并不是拉取来就能直接用的, 如果ip地址不一样的话,是不能直接使用的,后面的话,需要拉取源码后,修改对应的配置信息后,然后在打包部署,才能够使用的。 \ No newline at end of file diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209122416398.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209122416398.png" new file mode 100644 index 0000000000000000000000000000000000000000..b49bf4d9c8a38de1031dccff7883c8318d61b139 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209122416398.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209122441971.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209122441971.png" new file mode 100644 index 0000000000000000000000000000000000000000..6b64b2594d4ccaeaafa896d41a767001c5029de0 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209122441971.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125847329.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125847329.png" new file mode 100644 index 0000000000000000000000000000000000000000..31500486ee678d0eb1a45c918314cd4851e109e3 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125847329.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125905430.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125905430.png" new file mode 100644 index 0000000000000000000000000000000000000000..4edcd2e6507c2a383d231d24d482aad153c827d1 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125905430.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125919324.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125919324.png" new file mode 100644 index 0000000000000000000000000000000000000000..872eafffa5f754e5dba5c7f0bc5ed38e6e4dbddb Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125919324.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125938397.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125938397.png" new file mode 100644 index 0000000000000000000000000000000000000000..2d275e508fcbf82aa61512711a82ba4cbfcac257 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125938397.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125953803.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125953803.png" new file mode 100644 index 0000000000000000000000000000000000000000..c86f00a4257be3bf2e4491daae1b8133772cbf5d Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209125953803.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130011043.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130011043.png" new file mode 100644 index 0000000000000000000000000000000000000000..e215106839678cf3e592c787ea64c3cd23643ad1 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130011043.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130023427.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130023427.png" new file mode 100644 index 0000000000000000000000000000000000000000..3adb6d9b27420909c447c662a4ce69d442858392 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130023427.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130036402.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130036402.png" new file mode 100644 index 0000000000000000000000000000000000000000..aa4460652f9af62cbfac7e6f589555d23b14c3f2 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130036402.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130104979.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130104979.png" new file mode 100644 index 0000000000000000000000000000000000000000..8fc4c44becfd39c12cc97b132725f417600a3a58 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130104979.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130124155.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130124155.png" new file mode 100644 index 0000000000000000000000000000000000000000..afa5ed95e0dd7c47e9674a539f8668a7a0656cd4 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130124155.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130139403.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130139403.png" new file mode 100644 index 0000000000000000000000000000000000000000..407e6ddce526fd2965e5789b9c382c0742719339 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130139403.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130156442.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130156442.png" new file mode 100644 index 0000000000000000000000000000000000000000..cfc79fa27049bf8800b4618bd0f2c2c77f733acc Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130156442.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130210835.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130210835.png" new file mode 100644 index 0000000000000000000000000000000000000000..33af97a708722520a8834c99e93c60b26d26ddbe Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130210835.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130224724-1599124105899.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130224724-1599124105899.png" new file mode 100644 index 0000000000000000000000000000000000000000..8ce106e58c384617f4329a55c446dcbdf6b33ba2 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130224724-1599124105899.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130313977-1599124105900.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130313977-1599124105900.png" new file mode 100644 index 0000000000000000000000000000000000000000..cacbd7f45fcf1d72aa24abcdc5fb1bbc2beaba2a Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130313977-1599124105900.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130324333-1599124105900.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130324333-1599124105900.png" new file mode 100644 index 0000000000000000000000000000000000000000..d54bf37df807106db04ca4b2cae815da0008b08a Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130324333-1599124105900.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130336478-1599124105900.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130336478-1599124105900.png" new file mode 100644 index 0000000000000000000000000000000000000000..321c0a8f2ac2c0fe23d33d7f9d27027616e5a02d Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130336478-1599124105900.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130425874-1599124105901.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130425874-1599124105901.png" new file mode 100644 index 0000000000000000000000000000000000000000..09d1d7dc050b1c01ac654d93f2186a3361abe07b Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130425874-1599124105901.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130438506-1599124105901.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130438506-1599124105901.png" new file mode 100644 index 0000000000000000000000000000000000000000..eb6f59026d5bfee99b6a78fcac06c942cfd6371a Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130438506-1599124105901.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130524162-1599124105901.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130524162-1599124105901.png" new file mode 100644 index 0000000000000000000000000000000000000000..ec7f855b5a176830574457fc577bad8bb0929fc9 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130524162-1599124105901.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130547785-1599124105901.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130547785-1599124105901.png" new file mode 100644 index 0000000000000000000000000000000000000000..da5a179af653ac229128b3d8faa979471f204550 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200209130547785-1599124105901.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200722090457339-1599124105900.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200722090457339-1599124105900.png" new file mode 100644 index 0000000000000000000000000000000000000000..b56c34b8dad565e4bc447c4282b4c4c450150326 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200722090457339-1599124105900.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903160432721.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903160432721.png" new file mode 100644 index 0000000000000000000000000000000000000000..85430062a891b318856a5b4d207b527beee0fe6f Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903160432721.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903161239748.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903161239748.png" new file mode 100644 index 0000000000000000000000000000000000000000..c377c193c25f15a2844ecf92b906c86ad2ea857f Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903161239748.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903161406977.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903161406977.png" new file mode 100644 index 0000000000000000000000000000000000000000..d33556649c8048b9d200ccba109b1dd50feee6a7 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903161406977.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903161619843.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903161619843.png" new file mode 100644 index 0000000000000000000000000000000000000000..10da7d08f5412880d46f399a620195bc19fc6382 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903161619843.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903162631281.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903162631281.png" new file mode 100644 index 0000000000000000000000000000000000000000..63d50d31c6f18bbe8d3126375b5f8db6d257db22 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903162631281.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903163514966-1599124136538.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903163514966-1599124136538.png" new file mode 100644 index 0000000000000000000000000000000000000000..d62bfd4508e83023f0b62290c70f9a9e873bf1dc Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903163514966-1599124136538.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903164316451-1599124105900.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903164316451-1599124105900.png" new file mode 100644 index 0000000000000000000000000000000000000000..b299dd85ae1e062ba5a53f200223edfabc241d09 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903164316451-1599124105900.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903164514073-1599124105900.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903164514073-1599124105900.png" new file mode 100644 index 0000000000000000000000000000000000000000..71ff0bd7876daea1faf128272140a69922ba2e15 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903164514073-1599124105900.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903165638594-1599124105900.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903165638594-1599124105900.png" new file mode 100644 index 0000000000000000000000000000000000000000..c3a6afeb73f0beea71f4b51ad30424475ada58f2 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903165638594-1599124105900.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903165911938-1599124105900.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903165911938-1599124105900.png" new file mode 100644 index 0000000000000000000000000000000000000000..3a463141b44a009b72ef11b52b6e34959f0fa2b1 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903165911938-1599124105900.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903165947652-1599124105900.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903165947652-1599124105900.png" new file mode 100644 index 0000000000000000000000000000000000000000..98ecea39a893a2e42650c002e92e708f5fb3fe97 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903165947652-1599124105900.png" differ diff --git "a/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903170244575-1599124105901.png" "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903170244575-1599124105901.png" new file mode 100644 index 0000000000000000000000000000000000000000..816e0094f317b9107d2dd2c723010ab55a015d31 Binary files /dev/null and "b/\346\235\202\350\256\260/Docker\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242(Nacos\347\211\210)/images/image-20200903170244575-1599124105901.png" differ diff --git "a/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/README.md" "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..cb9d882a97c30a4200d280bc154e8b3c43487a88 --- /dev/null +++ "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/README.md" @@ -0,0 +1,52 @@ +# OCR文字识别软件 + +## 概述 + +OCR(optical character recognition)文字识别是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,然后用字符识别方法将形状翻译成计算机文字的过程;即,对文本资料进行扫描,然后对图像文件进行分析处理,获取文字及版面信息的过程。如何除错或利用辅助信息提高识别正确率,是OCR最重要的课题。衡量一个OCR系统性能好坏的主要指标有:拒识率、误识率、识别速度、用户界面的友好性,产品的稳定性,易用性及可行性等。 + +## 前言 + +前阵子沉迷于B站视频学习,然后有很多视频都是不提供课件和ppt的,如果自己需要做笔记的话,需要自己暂停视频,然后手动敲,虽然说。。这么一个动作可以加深一下学习记忆,但是也让我苦不堪言,仿佛回到了老师在黑板上写,我在下面抄写的情景,最后老师讲的啥也没听到,满满的一本子笔记就感觉自己学会了。。 + +所以为了避免这类事情的再次重演,我寻找了几款ORC文字识别工具,帮助我们能够提高生产力。 + +## 树洞OCR + +树洞 OCR 文字识别(一款跨平台的 OCR 小工具) 同时也在Github上开源了,官网地址:[点我传送](https://github.com/AnyListen/tools-ocr) + +我最开始尝试了一些,页面比较简陋,而且功能不是特别完善,截图翻译的时候比较难受,特别是在双屏的环境下 + +![image-20200528153423741](images/image-20200528153423741.png) + +## 雨梦OCR + +一款超易用文字提取&翻译软件,下载即用,免安装。目前支持,截图提取文本 | 图片导入提取 | 文本自动合并 | 文本自动翻译 | 多个OCR接口,支持多种语言提取 | 支持百度,腾讯,谷歌翻译接口 | 自定义快捷键 | 支持只截图 + +官网地址:[点我传送](http://hanxinyumeng.cn/) + +![image-20200528153835250](images/image-20200528153835250.png) + +这个比上面的树洞OCR操作起来就更友好了,因为我主要的用处是用于截屏翻译,这个在截屏翻译这块做的还可以,能满足需求,但是存在一个问题就是,雨梦OCR是收费版本的,还不是买断制,是需要1年19元的收费,但是每天会提供50次免费使用好像,如果对这个OCR使用不是特别频繁的话,是可以使用的。 + +## 天若OCR + +天若 OCR 文字识别开源版是基于 @天若幽心 [开源的代码](https://github.com/tianruoyouxin/tianruoocr_last) 进行完善制作而成,目前该大佬好像去开发上面的树洞OCR了?? + +官网地址:https://github.com/AnyListen/tianruoocr + +我们选择release发行版,进行下载 + +![image-20200528154455138](images/image-20200528154455138.png) + +下面里面的zip文件 + +![image-20200528154517106](images/image-20200528154517106.png) + +然后运行里面的exe文件即可,运行后会创建一个状态栏图标,我们按F4即可截图 + +![image-20200528154741103](images/image-20200528154741103.png) + +界面还是挺美观的,而且功能也很强大,还支持请求的接口,所以目前来说 天若OCR是首选~ + +![image-20200528154820325](images/image-20200528154820325.png) + diff --git "a/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528153423741.png" "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528153423741.png" new file mode 100644 index 0000000000000000000000000000000000000000..edbc615ce2ca3cfe3ab48cf4e0d27200783398a5 Binary files /dev/null and "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528153423741.png" differ diff --git "a/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528153835250.png" "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528153835250.png" new file mode 100644 index 0000000000000000000000000000000000000000..3b59eb31566626a874d0d4440ec3534e6d79856e Binary files /dev/null and "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528153835250.png" differ diff --git "a/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528154455138.png" "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528154455138.png" new file mode 100644 index 0000000000000000000000000000000000000000..1b96adae34b41fc1619a0185c40f22c9ab3b885d Binary files /dev/null and "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528154455138.png" differ diff --git "a/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528154517106.png" "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528154517106.png" new file mode 100644 index 0000000000000000000000000000000000000000..a0eebacef5b7f67cf2500a49ee811f0a1d1fdbeb Binary files /dev/null and "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528154517106.png" differ diff --git "a/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528154741103.png" "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528154741103.png" new file mode 100644 index 0000000000000000000000000000000000000000..5a6999d77f035311d379f3ea552f65f55dd02129 Binary files /dev/null and "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528154741103.png" differ diff --git "a/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528154820325.png" "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528154820325.png" new file mode 100644 index 0000000000000000000000000000000000000000..bc5c4a73c482f4f4557762cfda362368fc468463 Binary files /dev/null and "b/\346\235\202\350\256\260/OCR\346\226\207\345\255\227\350\257\206\345\210\253\350\275\257\344\273\266/images/image-20200528154820325.png" differ diff --git "a/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/README.md" "b/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..1955097cf6913b6352eef331680fe6cc1b96db17 --- /dev/null +++ "b/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/README.md" @@ -0,0 +1,70 @@ +# VSCode服务版搭建教程 + +## 前言 + +因为之前买了个iPad,并且也配了一个蓝牙键盘,但是受限于没有合适的编辑器,因此想把ipad作为生产工具并做不到,只是用来看直播和Bilibili还挺香的。然后最近发现vscode有 server版本,也就是服务器版本,通过在自己服务器上进行配置,然后通过浏览器来来进行访问,突然发现打开新世界的大门。 + +## 安装 + +为了考虑到以后环境的可移植性比较强,做到一次安装到处运行,因此这里我使用的是使用docker来进行安装。 + +因为最开始我已经对一个centos的镜像做了ssh远程无密登录,因此这次我就直接拉取一个包含了ssh的镜像。 + +```shell +docker pull moxi/centos_ssh +``` + +下载安装后,我们启动该容器,同时开放两个端口号,分别是 11222 和 8443端口号 + +``` +docker run --privileged -d -it -h vscodeServer --name vscodeServer -v /etc/localtime:/etc/localtime:ro -p 11222:22 -p 8443:8443 moxi/centos_ssh /usr/sbin/init +``` + +制作好容器后,我们登录进去,注意连接的端口号为11222,然后输入密码 www.moguit.cn 进入我们的centos_ssh容器。 + +进入docker容器内部后,去github上下载好[vscode server](https://github.com/cdr/code-server/releases) + +![image-20200524093951596](images/image-20200524093951596.png) + +然后再到我们的服务器中解压,使用下列命令 + +``` +tar -zxvf code-server-3.3.1-linux-x86_64.tar.gz +``` + +解压完成后,如下图所示 + +![image-20200524094032917](images/image-20200524094032917.png) + +然后进入下列目录 + +``` +cd code-server-3.3.1-linux-x86_64 +``` + +修改端口号和密码 + +``` +vi ~/.config/code-server/config.yaml +``` + +![image-20200524102156946](images/image-20200524102156946.png) + +使用命令启动,这个命令需要独占一个窗口 + +``` +./code-server --host 0.0.0.0 --port 8443 +``` + +不过上面的方式存在一个问题就是,需要独占一个窗口,如果终端关闭的话,将不能继续执行,因此我们需要使用的linux的开启一个守护进程 nohup,我们创建一个启动脚本 + +``` +#!/bin/bash +nohup ./code-server --port 8443 --host 0.0.0.0 > catalina.out 2>&1 & +``` + +启动成功后,输入 ip + 8443端口号,即可访问到vs code的浏览器版本了 + +![image-20200524102450268](images/image-20200524102450268.png) + +下面就是我通过ipad打开code server了 \ No newline at end of file diff --git "a/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/images/image-20200524093951596.png" "b/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/images/image-20200524093951596.png" new file mode 100644 index 0000000000000000000000000000000000000000..5271334a00ad1571a3bbf3246fb0c3bbe3a59130 Binary files /dev/null and "b/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/images/image-20200524093951596.png" differ diff --git "a/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/images/image-20200524094032917.png" "b/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/images/image-20200524094032917.png" new file mode 100644 index 0000000000000000000000000000000000000000..188b350677b1b6dc5837f4b572e5d0b6a8fa8c3d Binary files /dev/null and "b/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/images/image-20200524094032917.png" differ diff --git "a/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/images/image-20200524102156946.png" "b/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/images/image-20200524102156946.png" new file mode 100644 index 0000000000000000000000000000000000000000..e2ea6f75af5fa107ffc77cd30a02c9290e41ed03 Binary files /dev/null and "b/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/images/image-20200524102156946.png" differ diff --git "a/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/images/image-20200524102450268.png" "b/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/images/image-20200524102450268.png" new file mode 100644 index 0000000000000000000000000000000000000000..e7c39542d492965baa3e70eb992e9a51e0780abc Binary files /dev/null and "b/\346\235\202\350\256\260/VSCode\346\234\215\345\212\241\347\211\210\346\220\255\345\273\272\346\225\231\347\250\213/images/image-20200524102450268.png" differ diff --git "a/\346\235\202\350\256\260/Windows\345\271\263\345\217\260\347\274\226\345\206\231bat\350\204\232\346\234\254\350\256\251\345\220\216\345\217\260\345\220\257\345\212\250\345\244\232\344\270\252\347\250\213\345\272\217/README.md" "b/\346\235\202\350\256\260/Windows\345\271\263\345\217\260\347\274\226\345\206\231bat\350\204\232\346\234\254\350\256\251\345\220\216\345\217\260\345\220\257\345\212\250\345\244\232\344\270\252\347\250\213\345\272\217/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a008f15b65690bf927250268c4b413a10ea35e04 --- /dev/null +++ "b/\346\235\202\350\256\260/Windows\345\271\263\345\217\260\347\274\226\345\206\231bat\350\204\232\346\234\254\350\256\251\345\220\216\345\217\260\345\220\257\345\212\250\345\244\232\344\270\252\347\250\213\345\272\217/README.md" @@ -0,0 +1,27 @@ +前言 +-- + +最近在开发蘑菇博客的时候,需要启动的服务比较多,比如nginx,solr,redis,mysql等,我就想着在Windows平台能不能编写个脚本,让它们一键启动 + +当然小伙伴可以把它们注册成系统服务,然后设置开机自启,更加省时省力,现在做的是将他们写在bat脚本上 + +启动脚本格式 +------ + + # /b 代表后台启动 + start /b server + +编写脚本 +---- + +我们首先创建一个  startup.bat文件,然后输出下面的内容 + + start /d java -jar zipkin.jar + +这样他就会帮我们启动zipikin服务了,我们设置多个,即可完成项目的一键启动 + + start java -jar E:/Software/Zipkin/zipkin.jar + start E:/Software/nginx/nginx.exe + start E:/Software/redis/Redis-x64-3.2.100/redis-server.exe + start E:/Software/xampp/tomcat/bin/startup.bat + start E:/Software/xampp/mysql/bin/mysqld.exe \ No newline at end of file diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/README.md" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..64b1c70318e54a9a097528aed3243f9454b85a95 --- /dev/null +++ "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/README.md" @@ -0,0 +1,426 @@ +# Windows环境下搭建蘑菇博客 + +## 前言 + +码云上最近有些小伙伴们问到了蘑菇博客的详细配置信息,突然想想之前本来打算写来着,但是因为各种各样的问题搁置了,现在就在win10环境下对博客的配置进行详细的说明了。 + +> Tip: 如遇到启动失败的,请先maven clean install 后再尝试启动 + +IDE得装lombok插件:[IDEA中引入Lombok](http://moguit.cn/#/info?blogUid=4ccb7df5d537f52d954eb15f094c90a3) + +参考:[蘑菇博客如何部署到阿里云服务器](http://www.moguit.cn/#/info?blogUid=89defe3f4a3f317cba9aa0cdb9ff879e) ,在你修改蘑菇博客源码后,将项目打包部署到云服务器 + +参考:[蘑菇博客切换搜索模式](http://moguit.cn/#/info?blogUid=4042b4f4088e4e37e95d9fc75d97298b),完成蘑菇博客的搜索引擎切换,目前支持Solr、ElasticSearch、mysql的方式,一般因为服务器配置文件,选择一种搜索方式即可 + +参考:[蘑菇博客切换七牛云存储](http://moguit.cn/#/info?blogUid=735ed389c4ad1efd321fed9ac58e646b),配置文件的七牛云对象存储,及本地文件存储 + +## 视频教程 + +特别感谢 [俺是程序狮](https://space.bilibili.com/277038643) 在B站上给蘑菇博客录制的视频教程,里面介绍了windows环境下配置蘑菇博客,如果参考文档遇到了问题的话,可以参考视频进行部署(ps:视频教程基于Eureka版) + +- [项目介绍](https://www.bilibili.com/video/BV1Si4y1u7H4) +- [结构介绍与本地Nginx本地图片服务器启动](https://www.bilibili.com/video/BV1AA411e7W5) +- [mysql脚本准备](https://www.bilibili.com/video/BV1kv411v7ND) +- [后台服务启动](https://www.bilibili.com/video/BV1Nv411i7wu) +- [RabbitMQ启动](https://www.bilibili.com/video/BV1mD4y1U7GT) +- [前端项目启动](https://www.bilibili.com/video/BV1B541187Ez) + +## 配置JDK + +略 + +## 配置Maven + +maven安装成功后,记得添加阿里源,不然有些东西下载会非常慢的 + +## 配置nginx + +nginx的下载直接到nginx官网下载即可 + +下载完成后,我们需要修改nginx.conf配置文件,加入下面的内容 + +```bash +#蘑菇博客图片资源 +server { + listen 8600; + server_name localhost; + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods *; + add_header Access-Control-Allow-Headers *; + if ($request_method = 'OPTIONS') { + return 204; + } + location / { + root D:\mogu_blog\data; + index index.html index.htm; + } +} +``` + +就是将8600端口的请求映射到 D:\mogu_blog\data的目录下,如果没有这个目录的,可以提前创建好,当然不一定在D盘,可以在任意位置,其它位置修改成对应的即可。 + +不过如果需要修改的话,需要到mogu_picture项目的yml文件里也一起修改对应的配置文件,如下图的 file.upload.path 修改成自定义的即可 + +```bash +#Data image url +file: + upload: + path: D:/mogu_blog/data +``` + +## 配置redis + +去redis官网,进行下载:https://redis.io/ + +然后双击启动即可 + +![image-20200209121341204](images/image-20200209121341204.png) + +> 注意,如果使用docker的方法安装的蘑菇博客镜像,里面设置了默认的密码mogu2018,如果直接复制的本地配置,还需要修改一下默认密码 + +## 配置RabbitMq + +RabbitMQ是一款比较优秀的消息中间件,在这里主要用于同步solr索引和ElasticSearch索引,redis缓存更新,以及邮件和验证码发送等功能。 + +关于配置,参考这篇博客:[蘑菇博客配置RabbitMQ](http://www.moguit.cn/#/info?blogUid=995e0fccd2b240aabd56a10a688e42d4) + +## 配置搜索模块 + +目前蘑菇博客支持三种搜索模式的配置,分别是Solr、ElasticSearch和SQL,小伙伴可以按照自己的服务器配置进行相应的部署。 + +参考:[蘑菇博客切换搜索模式](http://moguit.cn/#/info?blogUid=4042b4f4088e4e37e95d9fc75d97298b) ,进行三种模式的切换(三种方式选择一种,默认是SQL搜索,可以配置ElasticSearch或者Solr作为全文检索) + +### **配置Solr(选择性安装)** + +关于window下配置蘑菇博客的solr,其实和我之前写的一篇博客大同小异,在这里我就不多叙述了,详情参考:[CentOS下Solr的安装和部署](http://www.moguit.cn/#/info?blogUid=7c7404c456904be5b7736238f28d2515) + +注意:需要修改schema.xml文件 + +> 最近很多小伙伴说solr不好配置,所以我特意把solr的上传到百度云和七牛云了,小伙伴只需要下载后,放到tomcat的webapps目录下,然后修改一下solrhome的配置即可 + +百度云: + +``` +链接:https://pan.baidu.com/s/1gpKs7oixT8RBn8zuDSiEGQ +提取码:ditj +``` + +备用地址: + +``` +http://picture.moguit.cn/blog/resource/java/solr.zip +``` + +下载完成后,解压 + +![image-20200209121359910](images/image-20200209121359910.png) + +然后找到 web.xml文件 + +![image-20200209121416395](images/image-20200209121416395.png) + +修改里面的地址,把路径改成你的目录即可 + +``` + + solr/home + E:\Software\xampp\tomcat\webapps\solr\solr_home + java.lang.String + +``` + +然后查看solr admin页面:http://localhost:8080/solr/#/ + +如果能正常显示,说明已经安装成功 + + + +### **配置ElasticSearch(选择性安装)** + +关于ElasticSearch的配置和相关介绍,可以参考这篇博客:[Elasticsearch介绍和安装](http://moguit.cn/#/info?blogUid=ee342088a5d0f5b96bcb4582d9b563aa) + +window也可自行百度进行安装,或者直接下载我上传的压缩包 + +``` +链接:https://pan.baidu.com/s/1X1z47Osm_MBjwSBckhUmTQ +提取码:pnfp +``` + +备用地址: + +``` +http://picture.moguit.cn/blog/resource/java/ElasticSearch.zip +``` + +下载完后,解压能看到这个目录 + +![image-20200209121433345](images/image-20200209121433345.png) + +我们首先进入elasticsearch下的config目录,修改elasticsearch.yml文件,把下面两个路径,改成你对应的目录即可 + +![image-20200209121450887](images/image-20200209121450887.png) + +**然后启动ElasticSearch:** + +![image-20200209121502904](images/image-20200209121502904.png) + +**启动Kibana:** + +![image-20200209121514369](images/image-20200209121514369.png) + +启动完成后:我们输入网址 + +``` +http://localhost:5601/ +``` + +如果能出现下面的页面,说明已经成功安装了 ElasticSearch 和 Kibana,在这里kibana只是作为ElasticSearch的图形化显示工具,相当于原来的SolrAdmin页面一样,在生产环境中,可以不部署也行 + +![image-20200209121540189](images/image-20200209121540189.png) + +## 配置Mysql + +```bash +# 使用命令把项目clone下来 +git clone https://gitee.com/moxi159753/mogu_blog_v2.git +``` + +然后找到目录下的doc文件夹,里面有个数据库脚本,里面有两个数据库,我们需要提前创建好 mogu_blog 、mogu_picture 、nacos_config这里三个数据库,然后把备份脚本导入即可。 + +![image-20200908083757671](images/image-20200908083757671.png) + +- mogu_blog.sql:代表mogu_blog数据库的文件 +- mogu_blog_update.sql:代表mogu_blog在后续开发时候更新的字段(首次无需导入) +- mogu_picture.sql:代表mogu_picture数据库文件 +- mogu_picture_update.sql:代表mogu_picture在后续开发时候更新的字段(首次不需要导入) +- nacos_config.sql:代表nacos的配置信息,用来存放每个模块的配置信息 + +首次导入数据库文件的时候,我们只需要执行mogu_blog.sql 、 mogu_picture.sql、nacos_config即可!! + +如果你在之前已经部署了本项目,那么你需要在对应的update.sql文件中,打开后,从中找到没有的字段,复制上执行即可,里面每个字段的添加,都会有对应的日期提示,如果有些字段是你clone项目后添加的,那么你就需要执行它们一遍即可 + +![image-20200908084447425](images/image-20200908084447425.png) + +同时设置数据库访问账户和密码为: admin admin + +当然不设置也没关系,就是后面修改yml文件里面的配置即可 + +## 配置zipkin链路追踪(非必须) + +Zipkin是一个开源的分布式的链路追踪系统,每个微服务都会向zipkin报告计时数据,聚合各业务系统调用延迟数据,达到链路调用监控跟踪。 + +参考博客:[使用Zipkin搭建蘑菇博客链路追踪](http://www.moguit.cn/#/info?blogUid=35bd93cabc08611c7f74ce4564753ef9) + +链路追踪服务可以选择安装,不过如果没有安装的话,在启动的时候会出现这样一个错误,不过该错误不会影响正常使用,可以忽略 + +```bash +I/O error on POSt request for "http://localhost:9411/api/v2/span" :connect timeout +``` + +## 配置Nacos注册中心和配置中心(Nacos分支需安装) + +Nacos服务注册和配置中心,如果使用的使用的是Eureka作为服务注册中心,那么直接跳过Nacos和Sentinel的安装过程。 + +参考 [【SpringCloud】使用Nacos实现服务注册发现和配置中心等功能](http://moguit.cn/#/info?blogUid=e6e619349d31dded928c9265c5a9c672),了解Nacos的使用 + +参考 [蘑菇博客Nacos部署指南](http://moxi159753.gitee.io/learningnotes/#/./杂记/蘑菇博客Nacos安装指南/README?id=蘑菇博客nacos部署指南),完成蘑菇博客中Nacos的安装和配置 + +## 配置Sentinel流量控制(非必须) + +Sentinel存在于Nacos分支下,如果你的注册中心是Eureka,那么不需要配置 + +随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 + +参考[【SpringCloud】使用Sentinel实现熔断和限流](http://moguit.cn/#/info?blogUid=408e9c889ebf96a66af2adfdc258ba5f) ,了解Sentinel以及使用 + +参考 [蘑菇博客Sentinel安装指南](http://moxi159753.gitee.io/learningnotes/#/./杂记/蘑菇博客Sentinel安装指南/README?id=蘑菇博客sentinel安装指南),完成蘑菇博客中Sentinel的配置 + +## 配置zipkin链路追踪(非必须) + +Zipkin是一个开源的分布式的链路追踪系统,每个微服务都会向zipkin报告计时数据,聚合各业务系统调用延迟数据,达到链路调用监控跟踪。 + +链路追踪服务可以选择安装,不过如果没有安装的话,在启动的时候会出现这样一个错误,不过该错误不会影响正常使用,可以忽略。 + +参考博客:[使用Zipkin搭建蘑菇博客链路追踪](http://www.moguit.cn/#/info?blogUid=35bd93cabc08611c7f74ce4564753ef9) + +## 启动后端项目 + +在全部配置完成后,就可以开始启动项目了,这里我用的编辑器是sts。目前有热心的码云朋友说IDEA不能正常启动项目,后面我经过排查,确实是存在这个文件,最近正在研究是哪块出错导致的。目前蘑菇博客的开发已经迁移到 IDEA中了,感谢[Jetbrains全家桶](https://www.jetbrains.com/?from=mogu_blog_v2)对开源的支持~。 + +首先进入项目根目录文件夹,执行下面命令 + +``` +# 下载依赖 +mvn clean install +``` + +如果下面都是success,那就说明依赖下载成功了 + +![image-20200209121557593](images/image-20200209121557593.png) + +下面就把项目导入到sts中 + +![image-20200209121611995](images/image-20200209121611995.png) + +关于项目的介绍 + +```bash +MoguBlog 是一款基于最新技术开发的多人在线、简洁的博客系统。 +mogu_admin: 提供admin端API接口服务; +mogu_web:提供web端API接口服务; +mogu_eureka: 服务发现和注册 +mogu_picture: 图片服务,用于图片上传和下载; +mogu_sms:消息服务,用于更新ElasticSearch、Solr索引、邮件和短信发送 +mogu_monitor:监控服务,集成SpringBootAdmin用于管理和监控SpringBoot应用程序 +mogu_spider:爬虫服务(目前还未完善) +mogu_spider:网关服务(目前还未完善) +mogu_zipkin:链路追踪服务,目前使用java -jar的方式启动 +mogu_search:搜索服务,ElasticSearch和Solr作为全文检索工具,支持可插拔配置,默认使用SQL搜索 +mogu_commons:公共模块,主要用于存放Entity实体类、Feign远程调用接口、以及公共config配置 +mogu_utils: 是常用工具类; +mogu_xo: 是存放 VO、Service,Dao层的 +mogu_base: 是一些Base基类 +doc: 是蘑菇博客的一些文档和数据库文件 +vue_mogu_admin:VUE的后台管理页面 +vue_mogu_web:VUE的门户网站 +uniapp_mogu_web:基于uniapp 和 colorUi 的蘑菇博客移动端门户页面(Nacos分支) +nuxt_mogu_web:Nuxt的门户网站,主要用于支持SEO搜索引擎优化(目前还未完善) +``` + + 下面进行项目启动 + +mogu_eureka -> mogu_picture -> mogu_sms -> mogu_admin -> mogu_web(上述模块是必须启动的) + +> 如果是Nacos版本:需要启动 mogu_picture -> mogu_sms -> mogu_admin -> mogu_web + +其它一些模块可以根据自己配置进行启动:如 mogu_monitor、SearchApplication、Zipkin等 + +下面是启动成功的图片 + +![image-20200209121636765](images/image-20200209121636765.png) + +启动成功后,我们应该能够查看到对应的Swagger接口文档 + +> tip:需要注意,swagger-ui在nacos版本和eureka版本使用的不一致 +> +> eureka版本:swagger-ui使用的是2.X,访问的页面是 http://localhost:8601/swagger-ui.html +> +> nacos版本:swagger-ui使用的是3.X,访问的页面是 http://localhost:8601/swagger-ui/index.html + +``` +############ admin端swagger ################## +# Eureka分支 +http://localhost:8601/swagger-ui.html +# Nacos分支 +http://localhost:8601/swagger-ui/index.html + +############ picture端swagger ################## +# Eureka分支 +http://localhost:8602/swagger-ui.html +# Nacos分支 +http://localhost:8602/swagger-ui/index.html + +############ web端swagger ################## +# Eureka分支 +http://localhost:8603/swagger-ui.html +# Nacos分支 +http://localhost:8603/swagger-ui/index.html +``` + + + +Admin端接口文档: + +![image-20200209121651260](images/image-20200209121651260.png) + +Picture端接口文档 + +![image-20200209121712009](images/image-20200209121712009.png) + +web端接口文档 + +![image-20200209121727626](images/image-20200209121727626.png) + +## 启动前端项目 + +前端项目使用的是Vue编写的,所以在这之前,需要下载好nodejs,因为nodejs里的npm模块是用于管理vue项目中的依赖,就类似于maven一样 + +node官网:https://nodejs.org/en/ + +在安装的时候,记得选择好加入到环境变量中,这样我们就能在任何使用了。 + +查看是否安装成功: npm -v + +![image-20200209121742980](images/image-20200209121742980.png) + +1) 安装 vue_mogu_admin 项目的依赖 + +进入vue_mogu_admin 文件夹内,使用下面命令进行安装 + +```bash +# 指定node-sass的国内镜像源 +npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass + +# 使用淘宝镜像源进行依赖安装,解决国内下载缓慢的问题(出现警告可以忽略) +npm install --registry=https://registry.npm.taobao.org + +# 启动项目 +npm run dev + +#打包项目(在部署的时候才需要使用) +npm run build +``` + +强烈建议不要用直接使用 cnpm 安装,会有各种诡异的 bug,可以通过重新指定 registry 来解决 npm 安装速度慢的问题。若还是不行,可使用 [yarn](https://github.com/yarnpkg/yarn) 替代 `npm`。 + +Windows 用户若安装不成功,很大概率是`node-sass`安装失败,[解决方案](https://github.com/PanJiaChen/vue-element-admin/issues/24)。 + +另外因为 `node-sass` 是依赖 `python`环境的,如果你之前没有安装和配置过的话,需要自行查看一下相关安装教程。 + +在启动项目成功后,会跳转到:localhost:9528 ,我们输入账号密码: admin, mogu2018 访问即可 + +![image-20200209121800363](images/image-20200209121800363.png) + +2) 安装 vue_mogu_web 项目的依赖, + +这个步骤其实和admin端的安装时一致的,这里就不做过多的叙述 + +```bash +# 指定node-sass的国内镜像源 +npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass + +# 使用淘宝镜像源进行依赖安装,解决国内下载缓慢的问题(出现警告可以忽略) +npm install --registry=https://registry.npm.taobao.org + +# 启动项目 +npm run dev + +#打包项目(在部署的时候才需要使用) +npm run build +``` + + + +下面是启动成功的界面,跳转到: localhost:9527 + +![image-20200209121819581](images/image-20200209121819581.png) + +tip:特别注意!!!!!首次部署完成,如果图片无法显示,那是因为本地没有对应的图片,需要做的事是查看nginx是否启动,然后就是在后台添加图片进行上传 + +![image-20200908085423131](images/image-20200908085423131.png) + +然后进行图片上传 + +![image-20200908085438033](images/image-20200908085438033.png) + +上传完毕后,再到博客管理页面,修改博客标题图,然后保存即可 + +![image-20200908085522052](images/image-20200908085522052.png) + +## 写在后面的话 + +关于我本机的配置,是使用的8G内存,项目所需的全部软件开启后,占用率大概到达了95%,所以微服务还是挺吃内存的。 + +关于服务器的配置,使用的是[1核2G的学生价格服务器](https://promotion.aliyun.com/ntms/act/campus2018.html?spm=5176.10695662.1244717.1.641e5a06KpmU4A&accounttraceid=3ac1b990a4f445859080d2555566af8fiirr?userCode=w7aungxw&tag=share_component&share_source=copy_link?userCode=w7aungxw&tag=share_component&share_source=copy_link?userCode=w7aungxw&tag=share_component&share_source=copy_link&userCode=w7aungxw&tag=share_component&share_source=copy_link&share_source=copy_link),目前来说,在增加虚拟内存后,能够正常的运行项目,内存不够的小伙伴,可以参考这篇博客。[CentOS如何增加虚拟内存?](http://www.moguit.cn/#/info?blogUid=36ee5efa56314807a9b6f1c1db508871) + +好了,关于博客的配置就到这里了,如果有问题的话,欢迎提出~ \ No newline at end of file diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121341204.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121341204.png" new file mode 100644 index 0000000000000000000000000000000000000000..b59a70219c89926f266fdda1c3bab2bed93fc27e Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121341204.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121359910.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121359910.png" new file mode 100644 index 0000000000000000000000000000000000000000..f04ee764a6ccb261ce9e6fe0c303f17b62a75fe3 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121359910.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121416395.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121416395.png" new file mode 100644 index 0000000000000000000000000000000000000000..45fc85be39eb81cf767c7af641328394026a2c28 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121416395.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121433345.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121433345.png" new file mode 100644 index 0000000000000000000000000000000000000000..e7fcb467c8330ed48065757691c1ddbf863c6cf2 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121433345.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121450887.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121450887.png" new file mode 100644 index 0000000000000000000000000000000000000000..751cc6a0e90360a1104c9ad9b4df61b70d522a2b Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121450887.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121502904.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121502904.png" new file mode 100644 index 0000000000000000000000000000000000000000..e9f991e2b4cdf37db594320aad409d1cf8d355a8 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121502904.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121514369.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121514369.png" new file mode 100644 index 0000000000000000000000000000000000000000..f8a7ac3f64ee57bde2be000a54bdefd729ca7782 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121514369.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121540189.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121540189.png" new file mode 100644 index 0000000000000000000000000000000000000000..c3726dc34095351592b2e9d9afa2a499acabb9a5 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121540189.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121557593.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121557593.png" new file mode 100644 index 0000000000000000000000000000000000000000..09a953ce2b70c55b0dd0ece55daa67d7be87242a Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121557593.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121611995.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121611995.png" new file mode 100644 index 0000000000000000000000000000000000000000..66a9a61bb74dd3394fe09208d09ce9c22f47fae2 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121611995.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121636765.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121636765.png" new file mode 100644 index 0000000000000000000000000000000000000000..c9ebe561f979dad402e3888a213293fb4d17382d Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121636765.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121651260.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121651260.png" new file mode 100644 index 0000000000000000000000000000000000000000..e62836e4cde5d721f8efedb8e6cd110697bef048 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121651260.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121712009.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121712009.png" new file mode 100644 index 0000000000000000000000000000000000000000..6314e3df571db7f11aeb6025f3ebd7bc7d9e9e6b Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121712009.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121727626.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121727626.png" new file mode 100644 index 0000000000000000000000000000000000000000..916c8f03dd8d7fdc8e5709fe816643c28a1fcf69 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121727626.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121742980.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121742980.png" new file mode 100644 index 0000000000000000000000000000000000000000..f3e1c0f1008ff15068497cb12ea445b8eace84e5 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121742980.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121800363.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121800363.png" new file mode 100644 index 0000000000000000000000000000000000000000..6c0c5883d228af74bc5468393f341d34dcbd9c05 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121800363.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121819581.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121819581.png" new file mode 100644 index 0000000000000000000000000000000000000000..4163ccd1faead15bb7f751f321955c4948e17091 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200209121819581.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908083757671.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908083757671.png" new file mode 100644 index 0000000000000000000000000000000000000000..cbbb6b376c33eeaffce745233c3bef153e2f92d5 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908083757671.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908084447425.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908084447425.png" new file mode 100644 index 0000000000000000000000000000000000000000..8f2b2353d05bd13c142e2e538dd5cd292b460459 Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908084447425.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908085423131.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908085423131.png" new file mode 100644 index 0000000000000000000000000000000000000000..ddb8f3a3744cc0466040a88d1d21ae83da1fe8cd Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908085423131.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908085438033.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908085438033.png" new file mode 100644 index 0000000000000000000000000000000000000000..ee6706152a8a981b884155a034e52685f42a791e Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908085438033.png" differ diff --git "a/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908085522052.png" "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908085522052.png" new file mode 100644 index 0000000000000000000000000000000000000000..5f6f7c4780082dd11583fea0efe1f158a28db17a Binary files /dev/null and "b/\346\235\202\350\256\260/Windows\347\216\257\345\242\203\344\270\213\346\220\255\345\273\272\350\230\221\350\217\207\345\215\232\345\256\242/images/image-20200908085522052.png" differ diff --git "a/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/README.md" "b/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..85b3e238fe93dc55aaf02becd9ebd06d92cb4dbc --- /dev/null +++ "b/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/README.md" @@ -0,0 +1,120 @@ +# 什么是CICD + +## 简介 + +CI/CD的采用,让软件的发布流程变得更加轻松~ + +![image-20200702153041136](images/image-20200702153041136.png) + +从最初的瀑布模型,到后来的敏捷开发,现在是DevOps,这是现代开发人员构建出色的产品技术路线。同时随着DevOps的兴起,出现了持续集成(Continuous Integration)、持续交付(Continuous Delivery)、持续部署(Continuous Deployment)的新方法。传统的软件开发和交付方法正在迅速变得过时。从历史上来看,在敏捷时代,大多数公司每月,每季度,每两年都会发布软件。然而,在DevOps时代,每周,每天都是常态。当SaaS正在占领世界时,您可以轻松的动态更新应用,而无需强迫客户下载新组件。很多时候,我们甚至都不会意识到正在发生变化。开发团队通过软件交付流水线(Pipeline)实现自动化,以缩短交付周期,大多数团队都有自动化流程来检查代码并部署到新环境。 + +## 瀑布模型 + +瀑布模型(Waterfall Model)是一个项目开发架构,开发过程中是通过一系列阶段顺序展开的,从系统需求分析开始,直到产品发布和维护,每个阶段都会产生循环反馈,因此,如果有信息未被覆盖或者发现了问题,那么最好返回上一阶段并进行适当的修改,项目开发进程从一个阶段流动到下一个阶段,这也是瀑布模型名称的由来。包括软件工程开发、企业项目开发、产品生产以及市场销售等构造瀑布模型。 + +![img](images/e824b899a9014c089ab337860a7b02087bf4f40d.jfif) + +### 瀑布模型的优点 + +- 为项目提供了按阶段划分的检查点 +- 当前一阶段完成后,您只需要关注后续的阶段 +- 可在迭代模型中应用瀑布模型 + - 增量迭代应用与瀑布模型,迭代1解决最大的问题,每次迭代产生一个可运行的版本,同时增加更多的功能。每次迭代必须经过质量和集成测试。 +- 它提供了一个模板,这个模板使得分析、设计、编码、测试和支持的方法可以在该模板下有一个共同的指导。 + +### 瀑布模型的缺点 + +同时因为瀑布模型强调文档的作用,并要求每个阶段都要仔细验证。但是这种模型的线性过程太过于理想化,已不再适合线代的软件开发模型,几乎被业界抛弃 + +- 每个阶段的划分完全固定,阶段之间产生大量的文档,极大的增加了工作量 +- 由于开发模型是线性的,用户只有等到整个过程的末期才能见到开发成果,从而增加了开发风险。 +- 通过过多的强制完成日期和里程碑来跟踪各个项目阶段 +- 瀑布模型的突出缺点是不适应用户需求的变化 +- 早期的错误可能要等到开发后期的测试阶段才能发现,进而带来严重的后果 + +## 敏捷开发 + +敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发,在敏捷开发中,软件项目在构建初期被切分成多个子项目,各个子项目的成果都经过测试,具备可视,可集成和可运行的特征,换而言之,就是把一个大项目分为多个相互联系,但也可以独立运行的小项目,并分别完成,再此过程中,软件一直处于可使用状态。 + +### 敏捷开发原则 + +- 快速迭代 +- 让测试人员和开发人员参与需求讨论 +- 编写可测试的需求文档 +- 多沟通,尽量减少文档 +- 做好产品原型 +- 及早考虑测试 + + + +## DevOps + +DevOps(Development 和 Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序、软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。 + +它是一种重视软件开发人员(Dev)和IT运维技术人员(Ops)之间沟通合作的文化,运动或惯例。透过自动化软件交付和架构变更的流程,来使得构建、测试、发布软件能够变得更加快捷、频繁和可靠。 + +### DevOps和敏捷开发的关系 + +首先敏捷开发是关于软件开发的过程与模式,DevOps更多是关于软件部署和运维管理,产品管理是关于产品的定义和需求规划。 + +更具体的说,DevOps是补充但不能取代敏捷。因为DevOps不会取代敏捷,它非常好的补充了敏捷开发。它通过消除资源浪费和简化部署等方式来实现这一目标,从而实现更快,更持续的生产部署。许多组织都进行敏捷开发,自动化测试和持续交付。但是运维人员可能会说 + +> 嘿嘿,你不能跨域那条线,这是我们的领土,你留在你的领地,我们照顾我们的 + +从开发和运维的关系上,可以看看传统软件开发方式和DevOps方式之间的区别 + +传统方式: + +- 在软件开发中,无论是瀑布模型还是敏捷开发,都是由开发团队来构建软件 +- 开发团队需要与运维团队进行大规模的交接,运维团队负责执行一系列部署活动,将软件代码移动至生产环境,并负责维护后续的系统稳定运行 +- 生产环境的基础设施与开发或测试不同 +- 需要有额外检查和平衡,以确保它一切功能正常。 +- 部署是由不同的人完成的,运维团队之前从未见过或听过任何此类软件。 + +但是DevOps打破了开发和部署之间的界限 + +- 如果将软件放入到容器,并把容器运送到不同的环境中会怎么样? +- 如果为每个环境简化了检查和测试以及流程,那么直接转向生成该怎么办? +- 如果自动化了所有测试用例,所有的配置管理,环境管理和发布管理,直接launch是否可以? +- 如果开发团队将代码移至生产中,并在其后续进行管理,那么运维团队与开发团队形成密切合作会怎么样? + +所以说,DevOps是敏捷开发的补充,是将运维纳入产品开发过程的思维方式,是敏捷开发方法论的升级。 + +### DevOps方法和工具链 + +![img](images/10947708-498d8b5ea9e49f80.webp) + +![img](images/10947708-1108dd5f106927bd.webp) + +## CI/CD + +### 持续集成(CI) + +将各个开发人员的工作集合在一个代码仓库中,通常每天需要进行几次,主要目的是要尽早的发现集成错误,使团队更加紧密结合,更好地写作办公。 + +通过持续集成,开发人员能够频繁将其代码集成到公共代码仓库的主分支中。开发人员能够在任何时候多次向仓库提交作品,而不是独立地开发每个功能模块并在开发周期结束时一一提交。 +这里的一个重要想法是让开发人员更快,更频繁地做到这一点,从而降低集成成本。实际情况中,开发人员在集成时经常会发现新代码和已有代码存在冲突。如果集成较早并更加频繁,那么冲突将更容易解决且执行成本更低。当然,还有一些权衡。此流程变更不提供任何额外的质量保证。实际上,许多组织发现这种集成变得更加昂贵,因为它们依赖于手动过程来确保新代码不会引入新的错误,并且不会破坏现有代码。为了减少集成任务期间的摩擦,持续集成依赖于测试套件和自动化测试执行。然而,要认识到自动化测试和持续测试是完全不同的这一点很重要,我们会在文章结尾处详细说明。 +CI 的目标是将集成简化成一个简单、易于重复的日常开发任务,这将有助于降低总体构建成本,并在周期的早期发现缺陷。要想有效地使用 CI 必须转变开发团队的习惯,要鼓励频繁迭代构建,并且在发现 bug 的早期积极解决。 + +### 持续交付(CD) + +持续交付目的是最小化部署或释放过程中固有的摩擦。它的实现通常能够将构建部署的每个步骤自动化,以便于任何时刻能够安全地完成代码的发布。 + +CD实际上是 CI 的扩展,其中软件交付流程进一步自动化,以便随时轻松地部署到生成环境中。CD 集中依赖于部署流水线,团队通过流水线自动化测试和部署过程。此流水线是一个自动化系统,可以针对构建执行一组渐进的测试套件。CD 具有高度的自动化,并且在一些云计算环境中也易于配置。在流水线的每个阶段,如果构建无法通过关键测试会向团队发出警报。否则,将继续进入下一个测试,并在连续通过测试后自动进入下一个阶段。流水线的最后一个部分会将构建部署到和生产环境等效的环境中。这是一个整体的过程,因为构建、部署和环境都是一起执行和测试的,它能让构建在实际的生产环境可部署和可验证。 +AWS上提供了现代CI / CD管道的可靠展示。亚马逊是云计算提供商之一,提供令人印象深刻的CI / CD 管道环境,并提供一个演练过程,您可以从其中选择众多开发资源,并将它们链接在一个易于配置且易于监控的管道中。 + +![在这里插入图片描述](images/20190717134736854.png) + +许多人认为持续交付的吸引力主要在于,它自动化了从提交代码到仓库,再到测试和发布产品过程的所有步骤。这是构建和测试过程细致的自动化,但是如何发布以及发布什么仍然是需要人工操作,持续部署可以改变这一点。 + +### 持续部署 + +持续部署扩展了持续交付,以便软件构建,在通过所有测试时自动部署。在这样的流程中,不需要人为决定何时及如何投入生产环境。CI/CD 系统的最后一步将在构建后的组件/包退出流水线时自动部署。此类自动部署可以配置为快速向客户分发组件、功能模块或修复补丁,并准确说明当前提供的内容。 + +采用持续部署的组织可以将新功能快速传递给用户,得到用户对于新版本的快速反馈,并且可以迅速处理任何明显的缺陷。用户对无用或者误解需求的功能的快速反馈有助于团队规划投入,避免将精力集中于不容易产生回报的地方。随着 DevOps 的发展,新的用来实现 CI/CD 流水线的自动化工具也在不断涌现。这些工具通常能与各种开发工具配合,包括像 GitHub 这样的代码仓库和 Jira 这样的 bug 跟踪工具。此外,随着 SaaS 这种交付方式变得更受欢迎,许多工具都可以在现代开发人员运行应用程序的云环境中运行,例如 GCP 和 AWS。最受欢迎的自动化工具是 Jenkins(以前的 Hudson),这是一个由数百名贡献者和商业公司 Cloudbees 支持的开源项目。Cloudbees 甚至聘请了 Jenkins 的创始人,并提供了一些 Jenkins 培训项目和附加组件。除了开源项目之外,还有一些更现代化的商业产品例如 CircleCI,Codeship 和 Shippable。这些产品各有优缺点,我鼓励开发人员在开发流程中一一尝试它们,以了解它们在您的环境中的工作方式,以及它们如何与您的工具、云平台、容器系统等协作。 + +## 参考 + +[https://baike.baidu.com/item/%E7%80%91%E5%B8%83%E6%A8%A1%E5%9E%8B/9817778?fr=aladdin](https://baike.baidu.com/item/瀑布模型/9817778?fr=aladdin) + +https://dzone.com/articles/what-is-cicd \ No newline at end of file diff --git "a/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/10947708-1108dd5f106927bd.webp" "b/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/10947708-1108dd5f106927bd.webp" new file mode 100644 index 0000000000000000000000000000000000000000..9791e453155869482ef3e3033b083c4a6a269527 Binary files /dev/null and "b/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/10947708-1108dd5f106927bd.webp" differ diff --git "a/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/10947708-498d8b5ea9e49f80.webp" "b/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/10947708-498d8b5ea9e49f80.webp" new file mode 100644 index 0000000000000000000000000000000000000000..ec1e56289457a95678872522d70f084c1742e49c Binary files /dev/null and "b/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/10947708-498d8b5ea9e49f80.webp" differ diff --git "a/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/20190717134736854.png" "b/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/20190717134736854.png" new file mode 100644 index 0000000000000000000000000000000000000000..f95c4cad59c8e2cf54d7c2df5fbc5d3b5ad8c1a3 Binary files /dev/null and "b/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/20190717134736854.png" differ diff --git "a/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/e824b899a9014c089ab337860a7b02087bf4f40d.jfif" "b/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/e824b899a9014c089ab337860a7b02087bf4f40d.jfif" new file mode 100644 index 0000000000000000000000000000000000000000..753051ea994b0e7feced24f953920c06f4a74689 Binary files /dev/null and "b/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/e824b899a9014c089ab337860a7b02087bf4f40d.jfif" differ diff --git "a/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/image-20200702153041136.png" "b/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/image-20200702153041136.png" new file mode 100644 index 0000000000000000000000000000000000000000..87c4ec7d40bbdc18ba7e9a2c8a1ca8c72deb4dac Binary files /dev/null and "b/\346\235\202\350\256\260/\344\273\200\344\271\210\346\230\257CICD/images/image-20200702153041136.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/README.md" "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..75491505af23b2fbc67898d83069ae167daa71f3 --- /dev/null +++ "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/README.md" @@ -0,0 +1,254 @@ +# 使用JustAuth集成QQ登录 + +## 前言 + +JustAuth是史上最全的整合第三方登录的开源库。目前已支持Github、Gitee、微博、钉钉、百度、Coding、腾讯云开发者平台、OSChina、支付宝、QQ、微信、淘宝、Google、Facebook、抖音、领英、小米、微软、今日头条、Teambition、StackOverflow、Pinterest、人人、华为、企业微信、酷家乐、Gitlab、美团、饿了么和推特等第三方平台的授权登录。 Login, so easy! + +官方地址:[点我传送](https://gitee.com/yadong.zhang/JustAuth) + +## 使用 + +最开始我其实使用JustAuth集成了Gitee登录和Github登录,因为首先这集成起来比较方便,只需要点击就可以申请到公钥和私钥。而且微信登录和QQ登录则比较麻烦,需要层层审核,好了话不多说,下面开始进入正题。 + +首先我们需要进入的是QQ互联的官网进行申请:[点我传送](https://connect.qq.com/devuser.html#/create/1/) + +![image-20200528082615390](images/image-20200528082615390.png) + +这里就需要填写姓名,地址,还有手持身份证拍照。。这里特别需要注意, 重点在于身份证要求清晰,直接能看到身份证号,我因为这个问题都被打回一次了。 + +在弄好了个人接入后,我们在点击顶部导航栏的应用管理,然后选中网站应用,如果没有提交审核的话,是下面这个状态,无法创建应用,上面的审核通过了,那么就可以创建我们的应用了。 + +![image-20200528082958723](images/image-20200528082958723.png) + +下面演示的是我已经创建审核通过后的,在我们创建应用的时候也有一些坑。 + +- 首先是网站的名称必须是备案域名上写的名称,比如我的域名当初备案的是 我的学习乐园,如果我写蘑菇博客就不行,已经被打回一次。 + +![image-20200528083158166](images/image-20200528083158166.png) + +下面是平台的一些信息,我们主要的就是关注的网站回调域,这里方便测试我填写的是本地的127.0.0.1的回调接口,然后就是还有上图我们看到的APPID 和 APP Key。 + +![image-20200528083358122](images/image-20200528083358122.png) + +然后在修改我们的配置文件 + +``` +# 第三方登录 +justAuth: + clientId: + qq: XXXXXXXXXXXXXXXX # APP ID + clientSecret: + qq: XXXXXXXXXXXXXXXXXX # APP Key +``` + +## 完整代码下 + +下面是蘑菇博客中,第三方登录的部分源码:[点我传送](https://gitee.com/moxi159753/mogu_blog_v2/blob/master/mogu_web/src/main/java/com/moxi/mogublog/web/restapi/AuthRestApi.java) + +``` +/** + * 第三方登录认证 + */ +@RestController +@RequestMapping("/oauth") +@Api(value = "第三方登录相关接口", tags = {"第三方登录相关接口"}) +@Slf4j +public class AuthRestApi { + @Autowired + WebUtil webUtil; + @Autowired + SystemConfigService systemConfigService; + @Autowired + FeedbackService feedbackService; + @Autowired + LinkService linkService; + @Autowired + RabbitMqUtil rabbitMqUtil; + @Autowired + private UserService userService; + @Value(value = "${justAuth.clientId.gitee}") + private String giteeClienId; + @Value(value = "${justAuth.clientSecret.gitee}") + private String giteeClientSecret; + @Value(value = "${justAuth.clientId.github}") + private String githubClienId; + @Value(value = "${justAuth.clientSecret.github}") + private String githubClientSecret; + @Value(value = "${justAuth.clientId.qq}") + private String qqClienId; + @Value(value = "${justAuth.clientSecret.qq}") + private String qqClientSecret; + @Value(value = "${data.webSite.url}") + private String webSiteUrl; + @Value(value = "${data.web.url}") + private String moguWebUrl; + @Value(value = "${BLOG.USER_TOKEN_SURVIVAL_TIME}") + private Long userTokenSurvivalTime; + @Value(value = "${PROJECT_NAME_EN}") + private String PROJECT_NAME_EN; + @Value(value = "${DEFAULE_PWD}") + private String DEFAULE_PWD; + @Autowired + private StringRedisTemplate stringRedisTemplate; + @Autowired + private PictureFeignClient pictureFeignClient; + + @ApiOperation(value = "获取认证", notes = "获取认证") + @RequestMapping("/render") + public String renderAuth(String source, HttpServletResponse response) throws IOException { + log.info("进入render:" + source); + AuthRequest authRequest = getAuthRequest(source); + String token = AuthStateUtils.createState(); + String authorizeUrl = authRequest.authorize(token); + Map map = new HashMap<>(); + map.put(SQLConf.URL, authorizeUrl); + return ResultUtil.result(SysConf.SUCCESS, map); + } + + + /** + * oauth平台中配置的授权回调地址,以本项目为例,在创建gitee授权应用时的回调地址应为:http://127.0.0.1:8603/oauth/callback/gitee + */ + @RequestMapping("/callback/{source}") + public void login(@PathVariable("source") String source, AuthCallback callback, HttpServletRequest request, HttpServletResponse httpServletResponse) throws IOException { + log.info("进入callback:" + source + " callback params:" + JSONObject.toJSONString(callback)); + AuthRequest authRequest = getAuthRequest(source); + AuthResponse response = authRequest.login(callback); + if (response.getCode() == 5000) { + // 跳转到500错误页面 + httpServletResponse.sendRedirect(webSiteUrl + "500"); + return; + } + String result = JSONObject.toJSONString(response); + Map map = JsonUtils.jsonToMap(result); + Map data = JsonUtils.jsonToMap(JsonUtils.objectToJson(map.get(SysConf.DATA))); + Map token = new HashMap<>(); + String accessToken = ""; + if (data == null || data.get(SysConf.TOKEN) == null) { + // 跳转到500错误页面 + httpServletResponse.sendRedirect(webSiteUrl + "500"); + return; + } else { + token = JsonUtils.jsonToMap(JsonUtils.objectToJson(data.get(SysConf.TOKEN))); + accessToken = token.get(SysConf.ACCESS_TOKEN).toString(); + } + + httpServletResponse.sendRedirect(webSiteUrl + "?token=" + accessToken); + } + + private void updateUserPhoto(Map data, User user) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(SQLConf.STATUS, EStatus.ENABLE); + queryWrapper.last("LIMIT 1"); + Map systemConfigMap = systemConfigService.getMap(queryWrapper); + // 获取到头像,然后上传到自己服务器 + FileVO fileVO = new FileVO(); + fileVO.setAdminUid(SysConf.DEFAULT_UID); + fileVO.setUserUid(SysConf.DEFAULT_UID); + fileVO.setProjectName(SysConf.BLOG); + fileVO.setSortName(SysConf.ADMIN); + fileVO.setSystemConfig(systemConfigMap); + List urlList = new ArrayList<>(); + urlList.add(data.get(SysConf.AVATAR).toString()); + fileVO.setUrlList(urlList); + String res = this.pictureFeignClient.uploadPicsByUrl(fileVO); + Map resultMap = JsonUtils.jsonToMap(res); + if (resultMap.get(SysConf.CODE) != null && SysConf.SUCCESS.equals(resultMap.get(SysConf.CODE).toString())) { + if (resultMap.get(SysConf.DATA) != null) { + List> listMap = (List>) resultMap.get(SysConf.DATA); + if (listMap != null && listMap.size() > 0) { + Map pictureMap = listMap.get(0); + + String localPictureBaseUrl = systemConfigMap.get(SQLConf.LOCAL_PICTURE_BASE_URL).toString(); + String qiNiuPictureBaseUrl = systemConfigMap.get(SQLConf.QI_NIU_PICTURE_BASE_URL).toString(); + String picturePriority = systemConfigMap.get(SQLConf.PICTURE_PRIORITY).toString(); + + user.setAvatar(pictureMap.get(SysConf.UID).toString()); + + // 判断图片优先展示 + if ("1".equals(picturePriority)) { + // 使用七牛云 + if (pictureMap != null && pictureMap.get(SysConf.QI_NIU_URL) != null && pictureMap.get(SysConf.UID) != null) { + user.setPhotoUrl(qiNiuPictureBaseUrl + pictureMap.get(SysConf.QI_NIU_URL).toString()); + } + } else { + // 使用自建图片服务器 + if (pictureMap != null && pictureMap.get(SysConf.PIC_URL) != null && pictureMap.get(SysConf.UID) != null) { + user.setPhotoUrl(localPictureBaseUrl + pictureMap.get(SysConf.PIC_URL).toString()); + } + } + } + } + } + } + + @RequestMapping("/revoke/{source}/{token}") + public Object revokeAuth(@PathVariable("source") String source, @PathVariable("token") String token) throws IOException { + AuthRequest authRequest = getAuthRequest(source); + return authRequest.revoke(AuthToken.builder().accessToken(token).build()); + } + + @RequestMapping("/refresh/{source}") + public Object refreshAuth(@PathVariable("source") String source, String token) { + AuthRequest authRequest = getAuthRequest(source); + return authRequest.refresh(AuthToken.builder().refreshToken(token).build()); + } + + + /** + * 鉴权 + * + * @param source + * @return + */ + private AuthRequest getAuthRequest(String source) { + AuthRequest authRequest = null; + switch (source) { + case SysConf.GITHUB: + authRequest = new AuthGithubRequest(AuthConfig.builder() + .clientId(githubClienId) + .clientSecret(githubClientSecret) + .redirectUri(moguWebUrl + "/oauth/callback/github") + .build()); + break; + case SysConf.GITEE: + authRequest = new AuthGiteeRequest(AuthConfig.builder() + .clientId(giteeClienId) + .clientSecret(giteeClientSecret) + .redirectUri(moguWebUrl + "/oauth/callback/gitee") + .build()); + break; + case SysConf.QQ: + authRequest = new AuthQqRequest(AuthConfig.builder() + .clientId(qqClienId) + .clientSecret(qqClientSecret) + .redirectUri(moguWebUrl + "/oauth/callback/qq") + .build()); + break; + default: + break; + } + if (null == authRequest) { + throw new AuthException(MessageConf.OPERATION_FAIL); + } + return authRequest; + } +} + +``` + +## 效果 + +添加完成后,我们需要在网站管理开启QQ登录功能 + +![image-20200528085800863](images/image-20200528085800863.png) + +然后点击我们的QQ登录,就会跳转到对应的QQ登录页面 + +![image-20200528085838958](images/image-20200528085838958.png) + +![image-20200528085942043](images/image-20200528085942043.png) + +点击头像登录即可,下图是登录后的结果 + +![image-20200528090023488](images/image-20200528090023488.png) \ No newline at end of file diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528082615390.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528082615390.png" new file mode 100644 index 0000000000000000000000000000000000000000..f68a15728e02745a660f6cb775f5b233e2dcaefd Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528082615390.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528082958723.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528082958723.png" new file mode 100644 index 0000000000000000000000000000000000000000..38bab45a6d71563d6c49ce1fa84c3599d1039b3f Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528082958723.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528083158166.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528083158166.png" new file mode 100644 index 0000000000000000000000000000000000000000..8e5814a4d0a83828dfd2a587911a189e5c63176e Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528083158166.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528083358122.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528083358122.png" new file mode 100644 index 0000000000000000000000000000000000000000..90703250caa47d8f06a2e7e4fd322cc1b702e609 Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528083358122.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528085800863.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528085800863.png" new file mode 100644 index 0000000000000000000000000000000000000000..3530a518ce88bd8985622bf698968a18efdc3679 Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528085800863.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528085838958.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528085838958.png" new file mode 100644 index 0000000000000000000000000000000000000000..49acaa810ead102fd7962d2d759e2630fb788827 Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528085838958.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528085942043.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528085942043.png" new file mode 100644 index 0000000000000000000000000000000000000000..8d85df85a9088784765102a83a7febaa0e49050c Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528085942043.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528090023488.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528090023488.png" new file mode 100644 index 0000000000000000000000000000000000000000..173b6743bc4624ccb823bf10f6e253aa8a8aa5db Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250JustAuth\351\233\206\346\210\220QQ\347\231\273\345\275\225/images/image-20200528090023488.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/README.md" "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..8c6b84b6c78a9d1f4abadbf60cbb56511b264430 --- /dev/null +++ "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/README.md" @@ -0,0 +1,57 @@ +# 使用ngrok进行内网穿透 + +## 前言 + +有时候我们本地开发了一个功能想要分享给其它小伙伴使用,那么就需要使用到内网穿透了,将公网的ip映射到我们的本机端口号中,然后实现内网穿透。 + +## ngrok介绍 + +下面的ngrok的相关介绍 + +- 提供免费内网穿透服务,免费服务器支持绑定自定义域名 +- 管理内网服务器,内网web进行演示 +- 快速开发微信程序和第三方支付平台调试 +- 本地WEB外网访问、本地开发微信、TCP端口转发 +- 本站新增FRP服务器,基于 [FRP](http://github.com/fatedier/frp) 实现https、udp转发 +- 无需任何配置,下载客户端之后直接一条命令让外网访问您的内网不再是距离 + +并且提供了免费的穿透服务 + +![image-20200615185416454](images/image-20200615185416454.png) + +下面我们进入到ngrok的官网:[点我传送](http://www.ngrok.cc/),然后注册账号后登陆,选择 左侧开通隧道,然后移动到下方,选择免费的服务器。 + +![image-20200615185537696](images/image-20200615185537696.png) + +然后我们就进入创建隧道的页面 + +![image-20200615185727793](images/image-20200615185727793.png) + +然后点击添加即可,在添加成功的页面,我们能够看到隧道id 和 赠送域名。我们首先复制到隧道id + +![image-20200615191735760](images/image-20200615191735760.png) + +然后下载ngrok软件:[点我传送](http://www.ngrok.cc/download.html),选中window64Bit版本下载 + +![image-20200615190058228](images/image-20200615190058228.png) + +下载解压后,我们点击bat文件运行 + +![image-20200615190201647](images/image-20200615190201647.png) + +这个时候,我们就需要在输入刚刚我们复制的隧道号,然后回车 + +![image-20200615190329039](images/image-20200615190329039.png) + +输入完成后,我们就看到已经成功映射到了我们的8603端口上了。 + +![image-20200615191411423](images/image-20200615191411423.png) + +首先我们先本地对8603端口号进行测试,输入 http://localhost:8603/swagger-ui.html + +![image-20200615191442854](images/image-20200615191442854.png) + +下面我们ngrok进行测试,在浏览器输入: http://demoweb.free.idcfengye.com/swagger-ui.html,发现能够成功进行内网穿透 + +![image-20200615191348159](images/image-20200615191348159.png) + diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615185416454.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615185416454.png" new file mode 100644 index 0000000000000000000000000000000000000000..022703a4c6dbe8bb99c2b5a97c659d01efe4dfcc Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615185416454.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615185537696.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615185537696.png" new file mode 100644 index 0000000000000000000000000000000000000000..cc2e871ffac0ee6c32db5a3c0cfb7d3f7ddd40c9 Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615185537696.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615185727793.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615185727793.png" new file mode 100644 index 0000000000000000000000000000000000000000..061bc303b3b0fbbeb60538021de505f4368a0325 Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615185727793.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615185848449.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615185848449.png" new file mode 100644 index 0000000000000000000000000000000000000000..a42d56fa83ad940e006310908068a2e95ddce353 Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615185848449.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615190058228.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615190058228.png" new file mode 100644 index 0000000000000000000000000000000000000000..f9372016d29440ad5e1c9cca57af44532ce72b48 Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615190058228.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615190201647.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615190201647.png" new file mode 100644 index 0000000000000000000000000000000000000000..3eef1fb9b22afb66511f84a68ecd176d6e53be2d Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615190201647.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615190329039.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615190329039.png" new file mode 100644 index 0000000000000000000000000000000000000000..c6310c5cf0302ed8932a128b97cee1390a3c89af Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615190329039.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615191348159.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615191348159.png" new file mode 100644 index 0000000000000000000000000000000000000000..c8ac7fd042a30b72ac5e25a319a4de2d29c7ccdb Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615191348159.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615191411423.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615191411423.png" new file mode 100644 index 0000000000000000000000000000000000000000..5b95ad37ad531fb9edfddccfc8892d604f811f5b Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615191411423.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615191442854.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615191442854.png" new file mode 100644 index 0000000000000000000000000000000000000000..aa39b66f93db7883213cc7e773e1a81fb2ba48cf Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615191442854.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615191735760.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615191735760.png" new file mode 100644 index 0000000000000000000000000000000000000000..a9ab1bb9a4a4977184fd8391f48384f46da9f65a Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250ngrok\350\277\233\350\241\214\345\206\205\347\275\221\347\251\277\351\200\217/images/image-20200615191735760.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250\345\255\246\346\240\241\351\202\256\347\256\261\347\224\263\350\257\267JetBrains\345\205\250\345\256\266\346\241\266/README.md" "b/\346\235\202\350\256\260/\344\275\277\347\224\250\345\255\246\346\240\241\351\202\256\347\256\261\347\224\263\350\257\267JetBrains\345\205\250\345\256\266\346\241\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a1e6de83ec40f754eb376851b496ad0492c65e49 --- /dev/null +++ "b/\346\235\202\350\256\260/\344\275\277\347\224\250\345\255\246\346\240\241\351\202\256\347\256\261\347\224\263\350\257\267JetBrains\345\205\250\345\256\266\346\241\266/README.md" @@ -0,0 +1,21 @@ +# 使用学校邮箱申请JetBrains全家桶 + +## 前言 + +之前通过蘑菇博客申请到了一个开源License,让我能够使用Jetbrain全家桶来搬砖,但是因为我有两台电脑,而一个开源License只能让一个账号登录,所以这次我申请到了一个学校的邮箱账号,然后再去申请一个Jetbrains的账号。 + +## 步骤1 + +首先到Jetbrains的官网上,找到[学生申请入口](https://www.jetbrains.com/pycharm/buy/?fromIDE#discounts?billing=yearly) + +![image-20200908185502429](images/image-20200908185502429.png) + +然后在填写你的信息,以及教育邮箱 + +![image-20200908190155994](images/image-20200908190155994.png) + +填写完成后,即可收到一个邮件 + +![image-20200908190218912](images/image-20200908190218912.png) + +然后同意条款后,注册一个账号和密码,即可拥有学生版的Jetbrains了~ \ No newline at end of file diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250\345\255\246\346\240\241\351\202\256\347\256\261\347\224\263\350\257\267JetBrains\345\205\250\345\256\266\346\241\266/images/image-20200908185502429.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250\345\255\246\346\240\241\351\202\256\347\256\261\347\224\263\350\257\267JetBrains\345\205\250\345\256\266\346\241\266/images/image-20200908185502429.png" new file mode 100644 index 0000000000000000000000000000000000000000..5c9bec94867706fae0d6ea8f4819683c968e4f7e Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250\345\255\246\346\240\241\351\202\256\347\256\261\347\224\263\350\257\267JetBrains\345\205\250\345\256\266\346\241\266/images/image-20200908185502429.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250\345\255\246\346\240\241\351\202\256\347\256\261\347\224\263\350\257\267JetBrains\345\205\250\345\256\266\346\241\266/images/image-20200908190155994.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250\345\255\246\346\240\241\351\202\256\347\256\261\347\224\263\350\257\267JetBrains\345\205\250\345\256\266\346\241\266/images/image-20200908190155994.png" new file mode 100644 index 0000000000000000000000000000000000000000..b55331e8e183144ce68804ebad02c8aea798ebb1 Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250\345\255\246\346\240\241\351\202\256\347\256\261\347\224\263\350\257\267JetBrains\345\205\250\345\256\266\346\241\266/images/image-20200908190155994.png" differ diff --git "a/\346\235\202\350\256\260/\344\275\277\347\224\250\345\255\246\346\240\241\351\202\256\347\256\261\347\224\263\350\257\267JetBrains\345\205\250\345\256\266\346\241\266/images/image-20200908190218912.png" "b/\346\235\202\350\256\260/\344\275\277\347\224\250\345\255\246\346\240\241\351\202\256\347\256\261\347\224\263\350\257\267JetBrains\345\205\250\345\256\266\346\241\266/images/image-20200908190218912.png" new file mode 100644 index 0000000000000000000000000000000000000000..2e3b517f57261e194690888d6dd83fa1ea2eafcc Binary files /dev/null and "b/\346\235\202\350\256\260/\344\275\277\347\224\250\345\255\246\346\240\241\351\202\256\347\256\261\347\224\263\350\257\267JetBrains\345\205\250\345\256\266\346\241\266/images/image-20200908190218912.png" differ diff --git "a/\346\235\202\350\256\260/\345\246\202\344\275\225\347\273\231\344\270\203\347\211\233\344\272\221\344\270\255\347\232\204\346\226\207\344\273\266\351\205\215\347\275\256\351\230\262\347\233\227\351\223\276/README.md" "b/\346\235\202\350\256\260/\345\246\202\344\275\225\347\273\231\344\270\203\347\211\233\344\272\221\344\270\255\347\232\204\346\226\207\344\273\266\351\205\215\347\275\256\351\230\262\347\233\227\351\223\276/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..70a8f7aadb5806134344c9432d8edff929762289 --- /dev/null +++ "b/\346\235\202\350\256\260/\345\246\202\344\275\225\347\273\231\344\270\203\347\211\233\344\272\221\344\270\255\347\232\204\346\226\207\344\273\266\351\205\215\347\275\256\351\230\262\347\233\227\351\223\276/README.md" @@ -0,0 +1,28 @@ +# 蘑菇博客的七牛云配置防盗链 + +## 前言 + +我们都知道,七牛云上的流量每个月是非常宝贵的,因为免费的流量只有10G,如果超过了流量就是需要收费的,上次我的就是因为超过了10G的流量限额,而导致欠费,因此我们需要合理的管理我们的流量,首先就是防盗链这块,因为防盗链能够有效的防止别人复制我们的文件或者图片到其它地方,从而消耗我们的流量资源。 + +## 配置 + +首先我们需要进入我们的七牛云管理页面,然后点击进入加速域名 + +如果还没有提前配置好七牛云的加速域名的,可以参考这篇博客:[蘑菇博客配置七牛云存储](http://moguit.cn/#/info?blogUid=735ed389c4ad1efd321fed9ac58e646b) + +![image-20200427232714941](images/image-20200427232714941.png) + +然后我们找到防盗链,添加我们的网站信息 + +![image-20200427233258924](images/image-20200427233258924.png) + +然后进行修改 + +![image-20200427233354440](images/image-20200427233354440.png) + +修改完成后,我们需要等待一段时间,大概是一两个小时左右,会有邮件发送到邮箱,表示修改成功 + +这个时候我们就只有在我们的白名单下面的域名才能够访问我们七牛云上的图片资源了 + +这里支持白名单和黑名单的配置,顾名思义,白名单就是指只有指定域名下的才能访问,黑名单就是那些域名不能访问。 + diff --git "a/\346\235\202\350\256\260/\345\246\202\344\275\225\347\273\231\344\270\203\347\211\233\344\272\221\344\270\255\347\232\204\346\226\207\344\273\266\351\205\215\347\275\256\351\230\262\347\233\227\351\223\276/images/image-20200427232714941.png" "b/\346\235\202\350\256\260/\345\246\202\344\275\225\347\273\231\344\270\203\347\211\233\344\272\221\344\270\255\347\232\204\346\226\207\344\273\266\351\205\215\347\275\256\351\230\262\347\233\227\351\223\276/images/image-20200427232714941.png" new file mode 100644 index 0000000000000000000000000000000000000000..007b8cda77d8d774a9a04c0b3e4a19e1348d9637 Binary files /dev/null and "b/\346\235\202\350\256\260/\345\246\202\344\275\225\347\273\231\344\270\203\347\211\233\344\272\221\344\270\255\347\232\204\346\226\207\344\273\266\351\205\215\347\275\256\351\230\262\347\233\227\351\223\276/images/image-20200427232714941.png" differ diff --git "a/\346\235\202\350\256\260/\345\246\202\344\275\225\347\273\231\344\270\203\347\211\233\344\272\221\344\270\255\347\232\204\346\226\207\344\273\266\351\205\215\347\275\256\351\230\262\347\233\227\351\223\276/images/image-20200427233258924.png" "b/\346\235\202\350\256\260/\345\246\202\344\275\225\347\273\231\344\270\203\347\211\233\344\272\221\344\270\255\347\232\204\346\226\207\344\273\266\351\205\215\347\275\256\351\230\262\347\233\227\351\223\276/images/image-20200427233258924.png" new file mode 100644 index 0000000000000000000000000000000000000000..04ac485741aa7d15f69468fed20febabc3a61264 Binary files /dev/null and "b/\346\235\202\350\256\260/\345\246\202\344\275\225\347\273\231\344\270\203\347\211\233\344\272\221\344\270\255\347\232\204\346\226\207\344\273\266\351\205\215\347\275\256\351\230\262\347\233\227\351\223\276/images/image-20200427233258924.png" differ diff --git "a/\346\235\202\350\256\260/\345\246\202\344\275\225\347\273\231\344\270\203\347\211\233\344\272\221\344\270\255\347\232\204\346\226\207\344\273\266\351\205\215\347\275\256\351\230\262\347\233\227\351\223\276/images/image-20200427233354440.png" "b/\346\235\202\350\256\260/\345\246\202\344\275\225\347\273\231\344\270\203\347\211\233\344\272\221\344\270\255\347\232\204\346\226\207\344\273\266\351\205\215\347\275\256\351\230\262\347\233\227\351\223\276/images/image-20200427233354440.png" new file mode 100644 index 0000000000000000000000000000000000000000..2b94a644300dde1899d09899dbde9408f3c562ec Binary files /dev/null and "b/\346\235\202\350\256\260/\345\246\202\344\275\225\347\273\231\344\270\203\347\211\233\344\272\221\344\270\255\347\232\204\346\226\207\344\273\266\351\205\215\347\275\256\351\230\262\347\233\227\351\223\276/images/image-20200427233354440.png" differ diff --git "a/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/README.md" "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..7681a8fd4d27ed2c7d59c699c534c8c2906a7840 --- /dev/null +++ "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/README.md" @@ -0,0 +1,42 @@ +# 将PDF转换为Kindle能识别的MOBI格式 + +## 前言 + +前阵子,移动咪咕搞了个活动,就是连续签到100天,白嫖Kindle的活动,想着先买一个用来看看书也是不错的,要是能白嫖就最好了,毕竟在码云上也有连续100多天的搬砖记录了~ + +![image-20200626103137543](images/image-20200626103137543.png) + +说干就干,花了460块,然后就下单了,希望能白嫖成功 + +![image-20200626103041017](images/image-20200626103041017.png) + +因为这阵子一直在准备面试的事情,所以打算把一些面试宝典,看看能不能放到我的kindle上,但是因为PDF放在kindle显示的不好,因此需要转换一下格式,变成MOBI格式。 + +## 书籍搜索 + +关于书籍的搜索,我是使用下面几个平台的进行搜索的。 + +### 鸠摩搜书 + +首先看看[鸠摩搜书](https://www.jiumodiary.com/)的首页:简单大方,温文尔雅,不失童话色彩。 + +![image-20200626103450965](images/image-20200626103450965.png) + +例如,我需要搜索深入理解Java虚拟机这本书,如果能搜索出MOBI格式的最好了,能够直接导入到Kindle中,否则的话需要进行格式转换,后面我会介绍一下格式转换的网站。 + +![image-20200626104332405](images/image-20200626104332405.png) + +### 书伴 + +[书伴](https://bookfere.com/)指向的是正版的亚马逊电子书,不过这里面集成了许多实用的小功能,比如提供kindle字典的下载,kindle的常用技巧:格式转换、更换字体、推送、整理电子书、插件等等。 + +## 格式转换 + +在我们下载完一些PDF后,我们就需要将其转换成MOBI格式,我是使用的这个 [网站](https://pdf2mobi.com/zh/) + +![image-20200626104012320](images/image-20200626104012320.png) + +只需要将PDF文档上传,即可转换为MOBI格式,然后导入到我们的Kindle中,实际效果像下面这样,整体来说,这就要求你找到的PDF不是扫描版本的,而是可以选中 的,如果带有目录的话是最好的,因为Kindle可以根据目录来直接跳转。 + +![image-20200626104131716](images/image-20200626104131716.png) + diff --git "a/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626103041017.png" "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626103041017.png" new file mode 100644 index 0000000000000000000000000000000000000000..74a9369e72c78502bbe5f00f6d16629936fb984c Binary files /dev/null and "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626103041017.png" differ diff --git "a/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626103137543.png" "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626103137543.png" new file mode 100644 index 0000000000000000000000000000000000000000..78cb67adbd734dcb46ed2b5e1702d6b159fa5c8a Binary files /dev/null and "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626103137543.png" differ diff --git "a/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626103450965.png" "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626103450965.png" new file mode 100644 index 0000000000000000000000000000000000000000..a870fe0ae866b19c7312c20f1bc565a281bb688f Binary files /dev/null and "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626103450965.png" differ diff --git "a/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626103535333.png" "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626103535333.png" new file mode 100644 index 0000000000000000000000000000000000000000..29108106addb41c540aeb7d0f22ad9d61f3c9368 Binary files /dev/null and "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626103535333.png" differ diff --git "a/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626104012320.png" "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626104012320.png" new file mode 100644 index 0000000000000000000000000000000000000000..eeb32e870f4724ee94f5238034e52c1579f0402d Binary files /dev/null and "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626104012320.png" differ diff --git "a/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626104131716.png" "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626104131716.png" new file mode 100644 index 0000000000000000000000000000000000000000..b24228add42f546cc398882d8adc4756fa3f0c70 Binary files /dev/null and "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626104131716.png" differ diff --git "a/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626104332405.png" "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626104332405.png" new file mode 100644 index 0000000000000000000000000000000000000000..2c56a8a6cdad1a4d0548320a8e04768cd31e5843 Binary files /dev/null and "b/\346\235\202\350\256\260/\345\260\206PDF\350\275\254\346\215\242\344\270\272Kindle\350\203\275\350\257\206\345\210\253\347\232\204MOBI\346\240\274\345\274\217/images/image-20200626104332405.png" differ diff --git "a/\346\235\202\350\256\260/\347\275\227\346\212\200K380\345\277\253\346\215\267\351\224\256/README.md" "b/\346\235\202\350\256\260/\347\275\227\346\212\200K380\345\277\253\346\215\267\351\224\256/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a5d454b1fcfea02fa31bd53abc7ecb4d30a737a7 --- /dev/null +++ "b/\346\235\202\350\256\260/\347\275\227\346\212\200K380\345\277\253\346\215\267\351\224\256/README.md" @@ -0,0 +1,51 @@ +# 罗技K380键盘快捷键 + +## 前言 + +之前给ipad购买了一个罗技K380蓝牙键盘,所以特意记录了一下快捷键的使用,方便平时的一些操作 + +## 切换输入法 + +方法1:直接按caps lock + +方法2:使用fn + 音量增加按键 ins + +方法3:使用 ctrl + 空格 + +## 切换后台应用 + +使用:alt + tab + +## 截图 + +方法1:fn + tab,tab键上有一个相机的小图标,可以快速的截图。 + +方法2:alt + shift + 3 是全屏截图 + +方法3:alt + shift + 4是部分截图,也就是需要自己编辑屏幕快照 + +## 唤醒输入框 + +在页面中按下tab键 + +## 搜索 + +alt + 空格,可以直接调出ios的搜索功能 + +## 顶部快捷键 + +- F1~F3:切换连接的蓝牙设备 +- F4:返回主屏幕,按两下调出后台 +- F5:可以在文档里,返回顶端 +- F6:在平板上直接调用虚拟输入页面,因为连接键盘的时候虚拟键盘是自动隐藏的 +- F7:返回,在应用里是直接返回到主界面,跟F4一样,如果在应用里出现一个心的窗口,比如在应用里打开搜索页面,按F7是返回应用而不是退回主屏幕,同时按两下可以调出后台 +- F8~F10:播放操作,快退,播放/暂停、快进 +- F11~ins:音量控制,静音、音量调小、音量调大 + +## 快捷键提示 + +长按 alt 按键,可以调出程序内与 alt键搭配的快捷键指南 + +## 屏幕锁屏 + +fn + L,直接锁定ipad的屏幕 \ No newline at end of file diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/README.md" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..6acc660a1c246fe7474f0e89e354f172296dfd40 --- /dev/null +++ "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/README.md" @@ -0,0 +1,70 @@ +# 蘑菇博客Nacos部署指南 + +## 前言 + +蘑菇博客这阵子将部分SpringCloud组件替换成了SpringCloudAlibaba组件,其中包括注册中心由Eureka替换成Nacos、新增了Sentinel作为熔断和限流组件 + +关于Nacos和Sentinel的使用可以参考下面两篇博客 + +- [【SpringCloud】使用Nacos实现服务注册发现以及配置中心等功能](http://moguit.cn/#/info?blogUid=e6e619349d31dded928c9265c5a9c672) +- [【SpringCloud】使用Sentinel实现熔断和限流](http://moguit.cn/#/info?blogUid=408e9c889ebf96a66af2adfdc258ba5f) + +## 安装Nacos + +首先我们到Nacos的 [Github页面](https://github.com/alibaba/nacos/releases),找到我们需要安装的版本 + +![image-20200814144224359](images/image-20200814144224359.png) + +因为我现在用的是window,所以我下载了windows版本,也就是 nacos-server.zip + +> 如果国内环境下载过慢,可以使用下面的这个地址 +> 链接:https://pan.baidu.com/s/1oTYQuqz1oMM5kTE_tl-8JQ +> 提取码:92gx + +下载完成后,我们进行解压缩,然后进入 conf目录,打开 application.properties文件 + +![image-20200814144515174](images/image-20200814144515174.png) + +打开后,我们在文件的末尾添加mysql的配置信息,注意mysql的账号和密码 + +```bash +# mysql配置 +spring.datasource.platform=mysql +db.num=1 +db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true +db.user=root +db.password=root +``` + +配置完成后,我们到项目的doc文件夹,找到数据库脚本 nacos_config.sql + +![image-20200814150620395](images/image-20200814150620395.png) + +然后创建一个数据库脚 nacos_config,将配置导入到mysql中,然后我们到nacos目录,双击startup.bat启动 + +![image-20200814150743682](images/image-20200814150743682.png) + +![image-20200814150938013](images/image-20200814150938013.png) + +项目启动成功后,我们访问 http://localhost:8848/nacos,输入下方的默认密码 + +> 账号:nacos +> +> 密码:nacos + +![image-20200814151027589](images/image-20200814151027589.png) + +然后我们点击 配置列表 -> dev,即可查看到我们的配置文件了,如果我们需要修改配置的话,只需要点击编辑 + +![image-20200814151141045](images/image-20200814151141045.png) + +到这里为止,Nacos服务注册中心就已经安装完成了,后续的操作我们可以参考下面的博客进行 + +[window环境下配置蘑菇博客环境](http://moguit.cn/#/info?blogUid=082ca226cf2e4103b0ffa6e6c13d7b14) + +> 因为我们将Eureka替换成Nacos,所以我们只需要启动服务为 +> +> mogu-sms、mogu-picture、mogu-admin、mogu-web + +![image-20200814154136820](images/image-20200814154136820.png) + diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814144224359.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814144224359.png" new file mode 100644 index 0000000000000000000000000000000000000000..8e0ecb5dd4156dccade52283c8bec0465b36bce1 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814144224359.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814144515174.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814144515174.png" new file mode 100644 index 0000000000000000000000000000000000000000..b28a76c3c7a4c3be1354f1db9edb8d83f57a8807 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814144515174.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814150620395.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814150620395.png" new file mode 100644 index 0000000000000000000000000000000000000000..05fb2a0740dce3c413b22fb9910adcf3f0b2c105 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814150620395.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814150743682.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814150743682.png" new file mode 100644 index 0000000000000000000000000000000000000000..d726f6d0fa55f0a60e6ceac927e89421c5e2d839 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814150743682.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814150938013.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814150938013.png" new file mode 100644 index 0000000000000000000000000000000000000000..5e4d20fd404df00d102dcd08bd4dceec7c5e858e Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814150938013.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814151027589.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814151027589.png" new file mode 100644 index 0000000000000000000000000000000000000000..ef17e60d27024182669866ff5375eec3157d37c5 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814151027589.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814151141045.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814151141045.png" new file mode 100644 index 0000000000000000000000000000000000000000..5cfe500c6fe3b34646c72c935cf0fd0792748796 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814151141045.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814154136820.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814154136820.png" new file mode 100644 index 0000000000000000000000000000000000000000..05863c6bc82f39f5319a58f4f12489d6cda39222 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Nacos\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814154136820.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/README.md" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..0197e6a56ff324dcdc99cfcbf80da036013c5442 --- /dev/null +++ "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/README.md" @@ -0,0 +1,165 @@ +# 蘑菇博客QQ小程序发布指南 + +## 前言 + +这阵子使用 [uniapp](https://uniapp.dcloud.io/) 和 [ColorUI](https://github.com/weilanwl/ColorUI) 搭建了蘑菇博客的移动端应用,uniapp是使用vue.js开发的前端应用框架,可以做到开发一套代码,可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台,下面演示一下uniapp打包成QQ小程序后的效果图。 + +![uniapp](images/uniapp.gif) + +## 下载HbuildX + +我们首先下载uniapp推荐的编辑器 [HbuildX](https://www.dcloud.io/hbuilderx.html) + +## 导入项目 + +下载完成后,我们将uniapp_mogu_web项目导入到我们的HbuildX编辑器中,然后点击上方的发布按钮 + +![image-20200814161009006](images/image-20200814161009006.png) + +然后选择 chrome,等待一段时间后,就会弹出页面 + +> tip:需要注意,我们启动uniapp项目的时候,必须确保我们的后台服务已经成功启动了 +> +> 同时我们还需要打开 index/ index页面 + +运行成功后的页面如下所示 + +![image-20200814161424623](images/image-20200814161424623.png) + +这个时候,我们就需要打开F12的页面,然后点击手机端,这个时候就能够看到项目已经成功运行了 + +![image-20200814161914608](images/image-20200814161914608.png) + +## QQ小程序 + +uniapp可以打包成QQ小程序、微信小程序、APP等,但是因为微信小程序需要交费 300元,本着省钱的原则,决定就发布成QQ小程序,因为小程序支持个人发布 + +### 下载QQ小程序开发者工具 + +因为uniapp需要转换成QQ小程序的代码,因此我们首先需要下载 [QQ小程序开发工具](https://q.qq.com/wiki/tools/devtool/) + +![image-20200814164442612](images/image-20200814164442612.png) + + + +### 修改配置 + +如果我们发布一个QQ小程序体验版本,这个时候就可以使用 IP+端口的方式,如下我们首先找到config文件,修改里面的配置,改成自己的线上的ip + +```js +export const appConfig = { + + tokenKey: 'Authorization', + + // 开发环境 + // WEB_API: 'http://localhost:8603', + // PICTURE_API: 'http://localhost:8602', + + // 演示环境 + WEB_API: 'http://120.78.126.96:8603', + PICTURE_API: 'http://120.78.126.96:8602', + + // 正式环境 + // WEB_API: 'https://apiweb.moguit.cn', + // PICTURE_API: 'https://apipicture.moguit.cn', +} +``` + +如果你想发布项目的话,那么就需要拥有域名 和 配置对应的https了,关于如何配置,可以参考这篇博客 + +Linux下通过nginx配置https + +### 打包 + +下载完成后,我们回到HbuildX页面,然后点击 发行 -> 小程序-QQ + +![image-20200814164605313](images/image-20200814164605313.png) + +然后填写小程序名称和小程序AppID + +![image-20200814164729544](images/image-20200814164729544.png) + +关于AppId的获取,我们需要到 https://q.qq.com/ 页面进行申请,然后完成后,我们找到AppID + +![image-20200814165006063](images/image-20200814165006063.png) + +复制到对应的AppID到我们的HbuildX中,点击发行 + +![image-20200814165139237](images/image-20200814165139237.png) + +下面就得到了我们QQ小程序开发工具,然后打开我们的上面路径中的程序 + +![image-20200814165321545](images/image-20200814165321545.png) + +打开程序后,我们选择详情,然后点击不校验域名 + +![image-20200814165614236](images/image-20200814165614236.png) + +然后在看左边的项目,就能够成功运行项目了 + +![image-20200814165649487](images/image-20200814165649487.png) + +这个时候,我们就需要点击右上角的上传 + +![image-20200814165747527](images/image-20200814165747527.png) + +然后在到我们的QQ小程序页面,找到刚刚的QQ小程序页面,选择设为体验版本,扫描即可进行体验 + +![image-20200814165838142](images/image-20200814165838142.png) + +## 发布QQ小程序 + +我们点击开发版本上的提交审核按钮,即可发布小程序。但是在发布小程序的时候,我也遇到了好几个坑,首先是第一次发布的时候 + +![image-20200814172123614](images/image-20200814172123614.png) + +也就是因为申请的是个人小程序,因此不支持打赏和评论的功能,所以为了解决这个问题,我们将增加开关语句用来控制小程序的评论和打赏模块的显示,我们到 系统配置 -> 网站配置 -> 评论&打赏 + +![image-20200814172412680](images/image-20200814172412680.png) + +然后在看我们的小程序端,这个时候就没有评论和打赏相关功能了 + +![image-20200814172448046](images/image-20200814172448046.png) + +我们对比之前的页面,发现已经将评论和打赏功能给关闭了,达到审核的要求 + +![image-20200814172640019](images/image-20200814172640019.png) + +当我修改完上述的问题后,再次提交代码 + +![image-20200814173026185](images/image-20200814173026185.png) + +提示小程序还需要支持QQ授权登录,这个时候我们就需要去申请QQ授权,我们到[QQ互联](https://connect.qq.com/) + +然后创建我们的小程序,在这之前,我们需要进行审核,按照要求完成QQ互联的审核即可 + +![image-20200814173203070](images/image-20200814173203070.png) + +然后我们点击查看按钮,点击申请unionid + +![image-20200814173328196](images/image-20200814173328196.png) + +完成这一系列的操作后,我们回到QQ小程序页面 + +![image-20200814173521763](images/image-20200814173521763.png) + +最后到我们的nacos页面,http://localhost:8848/nacos/#/login,找到 mogu-web-dev.yaml配置,然后修改 appid 和 secret,也就是上面我们复制的 + +```bash +# uniapp相关配置 +uniapp: + qq: + appid: XXXXXXXXXXXXXX # 改成自己的 + secret: XXXXXXXXXXXXXX # 改成自己的 + grant_type: authorization_code +``` + +修改完成后,我们到我们的小程序登录页面,进行QQ一键登录 + +![image-20200814173940059](images/image-20200814173940059.png) + +如果能够成功登录,代表配置已经正常 + +![image-20200814173917783](images/image-20200814173917783.png) + +这个时候我们就可以重新打包程序了,然后点击发布,最后在提交审核 \ No newline at end of file diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/01D0EEF3.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/01D0EEF3.png" new file mode 100644 index 0000000000000000000000000000000000000000..748e21aa572441d9f16bd5db6b047725bfa5ebdf Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/01D0EEF3.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814161009006.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814161009006.png" new file mode 100644 index 0000000000000000000000000000000000000000..b213aaa4930bdf5e9daeb490c7f488102aeab689 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814161009006.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814161424623.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814161424623.png" new file mode 100644 index 0000000000000000000000000000000000000000..f974bfa2af7ae94655ba2c2a6f17832d795c7b23 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814161424623.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814161914608.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814161914608.png" new file mode 100644 index 0000000000000000000000000000000000000000..4e77599a85f6042322e8933e0850ff5e1e73a3bb Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814161914608.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814164442612.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814164442612.png" new file mode 100644 index 0000000000000000000000000000000000000000..be9b0302c95cde3bf03331962cf275483daab2ab Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814164442612.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814164605313.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814164605313.png" new file mode 100644 index 0000000000000000000000000000000000000000..345fdc5cfeba5734b7b5d82e15827051b1acd30f Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814164605313.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814164729544.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814164729544.png" new file mode 100644 index 0000000000000000000000000000000000000000..341863fb4882339b04aa254a9b2a63a43304ddb5 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814164729544.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165006063.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165006063.png" new file mode 100644 index 0000000000000000000000000000000000000000..ad6deffa2493557f040361d0b1d76d60f3a4b61a Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165006063.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165139237.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165139237.png" new file mode 100644 index 0000000000000000000000000000000000000000..463654bfbc9cb4fd69a1157252741a1701a1de41 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165139237.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165321545.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165321545.png" new file mode 100644 index 0000000000000000000000000000000000000000..8a8416a5ca1255d0e3eb7cdf56df21eb2043a7fa Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165321545.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165614236.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165614236.png" new file mode 100644 index 0000000000000000000000000000000000000000..fe859172405293649c775ca655a08d1e7b7ce667 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165614236.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165649487.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165649487.png" new file mode 100644 index 0000000000000000000000000000000000000000..b0fcc615eec9d9d8172f5571d82a6371b8aaa7ca Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165649487.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165747527.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165747527.png" new file mode 100644 index 0000000000000000000000000000000000000000..2bc5a09cb19385ff5b1f8d2658cff321751b534b Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165747527.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165838142.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165838142.png" new file mode 100644 index 0000000000000000000000000000000000000000..9a8407832f4858e5f9aa7c7a99b79ff0026752d3 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814165838142.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814172123614.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814172123614.png" new file mode 100644 index 0000000000000000000000000000000000000000..5ac34b0eb713610cadc51a5dd436a256e6a5f2cc Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814172123614.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814172412680.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814172412680.png" new file mode 100644 index 0000000000000000000000000000000000000000..9feff38b723915dc0da324a19228e2333673281b Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814172412680.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814172448046.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814172448046.png" new file mode 100644 index 0000000000000000000000000000000000000000..4e479c50aef0611706d99ee8fe10648007d33bbb Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814172448046.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814172640019.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814172640019.png" new file mode 100644 index 0000000000000000000000000000000000000000..f60cff07af27ea2abd9ae611b39e7eba1caea5c0 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814172640019.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173026185.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173026185.png" new file mode 100644 index 0000000000000000000000000000000000000000..ec559e0a3097b04464bc03bc251e1a65f02e407d Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173026185.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173203070.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173203070.png" new file mode 100644 index 0000000000000000000000000000000000000000..411684bd903674fdcb634f9362174e3d9055dd70 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173203070.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173328196.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173328196.png" new file mode 100644 index 0000000000000000000000000000000000000000..c906df131cb603721aecedda94338a8ede6a767e Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173328196.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173521763.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173521763.png" new file mode 100644 index 0000000000000000000000000000000000000000..bf57a2ec48a779b449023443168653193043dc3a Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173521763.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173917783.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173917783.png" new file mode 100644 index 0000000000000000000000000000000000000000..bdb4b8f3322ec37f806faaf9c850f85b0411bc1b Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173917783.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173940059.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173940059.png" new file mode 100644 index 0000000000000000000000000000000000000000..48e45ebd7ef889c84ade0635f0c78039c3955d27 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/image-20200814173940059.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/login.html" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/login.html" new file mode 100644 index 0000000000000000000000000000000000000000..368753dc1ed2a4e62165b556302c35a1b55d7eac --- /dev/null +++ "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/login.html" @@ -0,0 +1,493 @@ + + + +登录 - 码云 Gitee.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+ + +
+ + + + + + + +
+
+
+
+
+
+ +

+

+

+云端软件开发协作平台 +

+
+
+
李铭健 骑鹅旅行 Head of PMO
码云企业不只是一个代码托管的工具,更是带着深深 Geek 文化的项目管理平台。在码云企业版上,iGola.com 的团队协作变得更加容易,整个流程管理变得更加透明流畅。
+
+ +
+ +
+
+ + + +
+
+ +
+
+ + + + +
+ + diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/uniapp.gif" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/uniapp.gif" new file mode 100644 index 0000000000000000000000000000000000000000..e376debc94a3fa82278d7698b145c77cd94e40c8 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242QQ\345\260\217\347\250\213\345\272\217\345\217\221\345\270\203\346\214\207\345\215\227/images/uniapp.gif" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/README.md" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..3eaafdcccce79e9f103bee59b67b4085a2f24f7c --- /dev/null +++ "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/README.md" @@ -0,0 +1,79 @@ +# 蘑菇博客Sentinel安装指南 + +## 前言 + +Sentinel被称为分布式系统的流量防卫兵,相当于Hystrix + +Hystrix存在的问题 + +- 需要我们程序员自己手工搭建监控平台 +- 没有一套web界面可以给我们进行更加细粒度化的配置,流量控制,速率控制,服务熔断,服务降级。。 + +这个时候Sentinel运营而生 + +- 单独一个组件,可以独立出来 +- 直接界面化的细粒度统一配置 + +更详细的介绍可以参考这篇博客,这里只是讲解一下Sentinel的安装过程 + +[【SpringCloud】使用Sentinel实现熔断和限流](http://moguit.cn/#/info?blogUid=408e9c889ebf96a66af2adfdc258ba5f) + +## 安装Sentinel + +首先我们到Sentinel的[Github官网](https://github.com/alibaba/Sentinel/releases),下载对应的jar包 + +![image-20200814152203586](images/image-20200814152203586.png) + +下载完成后,放到我们的Sentinel文件夹下 + +![image-20200814152301259](images/image-20200814152301259.png) + +我们可以通过 java -jar命令来启动,但是每次输入命令也挺麻烦的,因此我们可以制作一个bat脚本,点击启动 + +我们创建一个startup.bat脚本,然后写入以下内容,指定端口号为 8070 + +```bash +start java -jar sentinel-dashboard-1.6.3.jar --server.port=8070 +``` + +![image-20200814152808028](images/image-20200814152808028.png) + +然后我们输入URL: http://localhost:8070/,然后输入默认的账号和密码 + +> 账号:sentinel +> +> 密码:sentinel + +![image-20200814152900162](images/image-20200814152900162.png) + +进入后,因为我们的项目还没有启动,所以看不到对应的配置信息 + +![image-20200814153013010](images/image-20200814153013010.png) + +到这里为止,Sentinel流控就已经安装完成了,后续的操作我们可以参考下面的博客进行 + +[window环境下配置蘑菇博客环境](http://moguit.cn/#/info?blogUid=082ca226cf2e4103b0ffa6e6c13d7b14) + +>因为我们将Eureka替换成Nacos,所以我们只需要启动服务为 +> +>mogu-sms、mogu-picture、mogu-admin、mogu-web + +![image-20200814154038280](images/image-20200814154038280.png) + +然后在启动前端服务后,再次查看Sentinel,我们就看到了三个微服务被监控了 + +![image-20200814154404812](images/image-20200814154404812.png) + +然后我们打开 mogu-web,点击系统规则,然后新增系统规则 + +![image-20200814154515420](images/image-20200814154515420.png) + +我们设置一个入口QPS为 30,也就是每秒30个请求 + +![image-20200814155422571](images/image-20200814155422571.png) + +然后我们打开首页 http://localhost:9527/,发现能够正常的访问,但是如果我们反复的刷新该页面,当超过对应的QPS数后,就会出现500页面了 + +![image-20200814155402193](images/image-20200814155402193.png) + +到这里为止,Sentinel的安装就完成了,如果想要了解更加复杂的规则,可以参考上面提到的[那篇博客](http://moguit.cn/#/info?blogUid=408e9c889ebf96a66af2adfdc258ba5f) \ No newline at end of file diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814152203586.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814152203586.png" new file mode 100644 index 0000000000000000000000000000000000000000..11757233d21ca52a998688bf359bc0fb1853ed0a Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814152203586.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814152301259.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814152301259.png" new file mode 100644 index 0000000000000000000000000000000000000000..5170c47ddac175b88b29faa5089e49fe0f541210 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814152301259.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814152808028.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814152808028.png" new file mode 100644 index 0000000000000000000000000000000000000000..9dbd47d5127c94dd58c54af53ca7cd801cff5848 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814152808028.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814152900162.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814152900162.png" new file mode 100644 index 0000000000000000000000000000000000000000..cd9e0bc6fa5c05c4684509d8b622f41519fa67b0 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814152900162.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814153013010.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814153013010.png" new file mode 100644 index 0000000000000000000000000000000000000000..57affe648f75a262b4b207fa408577e88fa02043 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814153013010.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814154038280.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814154038280.png" new file mode 100644 index 0000000000000000000000000000000000000000..3b7ab383ed3a5bf7eeef70f2a13fdd1c536efb77 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814154038280.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814154404812.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814154404812.png" new file mode 100644 index 0000000000000000000000000000000000000000..e022de2b0a2918510540740b49fee14148e0296a Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814154404812.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814154515420.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814154515420.png" new file mode 100644 index 0000000000000000000000000000000000000000..b125469a9e7ec551d3db03279d3ed874fa810a0e Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814154515420.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814155402193.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814155402193.png" new file mode 100644 index 0000000000000000000000000000000000000000..44ba7170032404d4f6eeacefb0c0c9499b382200 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814155402193.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814155422571.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814155422571.png" new file mode 100644 index 0000000000000000000000000000000000000000..58faa2482b6537f71883efdb1d3c1826a69d219e Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242Sentinel\345\256\211\350\243\205\346\214\207\345\215\227/images/image-20200814155422571.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/README.md" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a11f79d875011a4e656bf56104889dcf5094afe4 --- /dev/null +++ "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/README.md" @@ -0,0 +1,233 @@ +# 蘑菇博客从Eureka迁移到Nacos + +## 前言 + +这阵子为了学习一下Nacos的实际使用,决定将蘑菇博客从Eureka迁移到Nacos作为服务发现组件,同时将配置文件也托管到Nacos服务器中,下面是我具体迁移过程中遇到的一些问题,做个说明方便以后查阅和解决。 + +## 下载和参考 + +- [nacos下载地址](https://github.com/alibaba/nacos/releases) +- [nacos文档](https://nacos.io) +- [使用Nacos实现服务注册发现以及服务限流等功能](http://moguit.cn/#/info?blogUid=e6e619349d31dded928c9265c5a9c672) + +## 服务发现与注册 + +### 主工程 + +在主pom.xml中添加Nacos相关依赖 + +```xml + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + 2.1.0.RELEASE + pom + import + +``` + +### 各个微服务 + +在需要注册的微服务xml文件中添加Nacos服务发现依赖 + +```xml + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + +``` + +### 注释Euerka相关依赖 + +在yml文件中添加服务发现配置,以及监控暴露。 + +``` +spring: + #nacos相关配置 + cloud: + nacos: + discovery: + server-addr: localhost:8848 + +#监控 +management: + endpoints: + web: + exposure: + include: '*' +``` + +### 替换服务发现注解 + +```java +//@EnableEurekaServer +@@EnableDiscoveryClient +``` + +## Nacos config配置 + +### 修改Nacos启动内存大小 + +进入 nacos/bin/ + +修改startup.sh中jvm的内存大小,根据自己的机器情况决定。 + +```sh +if [[ "${MODE}" == "standalone" ]]; then + JAVA_OPT="${JAVA_OPT} -Xms128m -Xmx256m -Xmn256m" + JAVA_OPT="${JAVA_OPT} -Dnacos.standalone=true" +else + if [[ "${EMBEDDED_STORAGE}" == "embedded" ]]; then + JAVA_OPT="${JAVA_OPT} -DembeddedStorage=true" + fi + JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx512m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m" + JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${BASE_DIR}/logs/java_heapdump.hprof" + JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages" +``` + +## Nacos+MySql持久化配置 + +### 启动服务器 + +### Linux/Unix/Mac + +启动命令(standalone代表着单机模式运行,非集群模式): + +``` +sh startup.sh -m standalone +``` + +如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行: + +``` +bash startup.sh -m standalone +``` + +#### Windows + +启动命令: + +``` +cmd startup.cmd +``` + +或者双击startup.cmd运行文件。找到数据库新建脚本nacos/conf/nacos-mysql.sql,创建数据库nacos_config并执行脚本 + +### issus:部分老msql版本 + +先检查一下是不是数据库被限制了索引的大小 + +``` +SHOW variables like 'innodb_large_prefix' +``` + +如果查询的值是OFF的话 执行下面命令 + +``` +SET GLOBAL INNODB_LARGE_PREFIX = ON; +``` + + +执行完了 之后 还得查看当前的innodb_file_format引擎格式类型是不是BARRACUDA执行 + +``` +SHOW variables like 'innodb_file_format' +``` + +如果不是的话则需要修改 + +``` +SET GLOBAL innodb_file_format = BARRACUDA; +``` + + 创建表的时候指定表的 row format 格式为 Dynamic 或者 Compressed,如下示例: + +```mysql +create table idx_length_test_02 + +id int auto_increment primary key, + +name varchar(255) + +) + +ROW_FORMAT=DYNAMIC default charset utf8mb4; +``` + +找到nacos/conf/application.properties, 修改添加 + +```properties +spring.datasource.platform=mysql +db.num=1 +db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true +db.user=root +db.password=root +``` + +然后重启Nacos + +## 其它需要上传application.yml的微服务 + +添加pom依赖 + +```xml + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + +``` + +修改application.yml + +```yml +spring: + profiles: + active: dev +``` + +添加bootstrap.yml + +```yaml +server: + port: 8601 + +spring: + application: + name: mogu-admin + cloud: + nacos: + discovery: + server-addr: 127.0.0.1:8848 + config: + server-addr: 127.0.0.1:8848 + #文件后缀 + file-extension: yaml + #指定分组 + group: test +``` + +## 在Nacos中添加配置 + +初始用户名密码:nacos + +点击配置列表,然后添加配置: + +![image-20200614154133644](assets/image-20200614154133644.png) + + + + + +**Data ID**格式为: + +{微服务名称}-{版本名称(spring.profiles.active)}.**yaml** + +![image-20200614153901946](assets/image-20200614153901946.png) + +例如: + +![image-20200614154418823](assets/image-20200614154418823.png) + +Group对应bootstrap.yml中的nacos.config.group + diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200610160145575.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200610160145575.png" new file mode 100644 index 0000000000000000000000000000000000000000..fb381fec8314ea47917b11552cbcb2b5620533d8 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200610160145575.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200610160312310.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200610160312310.png" new file mode 100644 index 0000000000000000000000000000000000000000..44be91edf3d61804266563c75a523a51f4860610 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200610160312310.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200614153901946.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200614153901946.png" new file mode 100644 index 0000000000000000000000000000000000000000..c16d0dfb1d785c9656442bf071557a8ba4bb0cbd Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200614153901946.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200614154133644.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200614154133644.png" new file mode 100644 index 0000000000000000000000000000000000000000..3ad89f21503567b1fa144ce2fe9c4e9e2eeaf139 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200614154133644.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200614154418823.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200614154418823.png" new file mode 100644 index 0000000000000000000000000000000000000000..a3491f6eeefe8df8288594efe0bdf46b3df38e25 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\273\216Eureka\350\277\201\347\247\273\345\210\260Nacos/assets/image-20200614154418823.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/README.md" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/README.md" similarity index 100% rename from "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/README.md" rename to "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/README.md" diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/1578295198026.gif" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/1578295198026.gif" similarity index 100% rename from "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/1578295198026.gif" rename to "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/1578295198026.gif" diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200101133018350.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200101133018350.png" similarity index 100% rename from "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200101133018350.png" rename to "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200101133018350.png" diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106105526046.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106105526046.png" similarity index 100% rename from "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106105526046.png" rename to "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106105526046.png" diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106123857563.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106123857563.png" similarity index 100% rename from "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106123857563.png" rename to "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106123857563.png" diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124131629.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124131629.png" similarity index 100% rename from "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124131629.png" rename to "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124131629.png" diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124233574.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124233574.png" similarity index 100% rename from "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124233574.png" rename to "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124233574.png" diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124354788.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124354788.png" similarity index 100% rename from "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124354788.png" rename to "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124354788.png" diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124637149.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124637149.png" similarity index 100% rename from "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124637149.png" rename to "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124637149.png" diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124848340.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124848340.png" similarity index 100% rename from "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124848340.png" rename to "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106124848340.png" diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106125010689.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106125010689.png" similarity index 100% rename from "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106125010689.png" rename to "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106125010689.png" diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106144749341.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106144749341.png" similarity index 100% rename from "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250Github Action\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106144749341.png" rename to "\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250GithubAction\345\256\214\346\210\220\346\214\201\347\273\255\351\233\206\346\210\220/images/image-20200106144749341.png" diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250SQL\350\257\255\345\217\245\350\277\233\350\241\214\346\220\234\347\264\242\345\207\272\347\232\204\345\206\205\345\256\271\345\277\275\347\225\245\345\244\247\345\260\217\345\206\231\345\271\266\346\267\273\345\212\240\351\253\230\344\272\256\346\225\210\346\236\234/README.md" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250SQL\350\257\255\345\217\245\350\277\233\350\241\214\346\220\234\347\264\242\345\207\272\347\232\204\345\206\205\345\256\271\345\277\275\347\225\245\345\244\247\345\260\217\345\206\231\345\271\266\346\267\273\345\212\240\351\253\230\344\272\256\346\225\210\346\236\234/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..abb3e4e1efb51a0de589ada610c67cf8941ae0b4 --- /dev/null +++ "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\344\275\277\347\224\250SQL\350\257\255\345\217\245\350\277\233\350\241\214\346\220\234\347\264\242\345\207\272\347\232\204\345\206\205\345\256\271\345\277\275\347\225\245\345\244\247\345\260\217\345\206\231\345\271\266\346\267\273\345\212\240\351\253\230\344\272\256\346\225\210\346\236\234/README.md" @@ -0,0 +1,112 @@ +前言 +-- + +前阵子一直在改造蘑菇博客的搜索模块,因为之前是使用的Solr搜索,每次搜索返回的时候,会自带高亮字段,后面改成SQL的方式实现搜索后,也想着能够增加高亮字段,因此就想着我们通过like关键字SQL查询出来后,能够在给关键字段添加一个标签 + + + +这样就能够让关键字能够出现想要的高亮效果了 + +但是这样存在一个问题就是,我们如何能够忽略大小写,给关键字添加高亮呢 + +实现 +-- + + 其实我们的算法实现原理是比较简单的: + +* 给定需要高亮的字段 str,以及关键字keyword +* 我们将str字段使用 str.toLowerCase() 方法,全部转换成小写,并将该字段定义为 lowerCaseStr +* 同理,也将keyword转换为小写, 定义为 lowerCaseKeyword +* 然后使用 lowerCaseStr.split(lowerCaseKeyword) 将字符串切割成多份 +* 然后我们就需要记录每个切割后的字符串的开始角标和结束角标 +* 然后通过角标,从原始的字符串中截取字符串str,存储在list中 +* 最后通过循环逐个添加关键字代码 + +完整代码 +---- + + /** + * 添加高亮 + * @param str + * @param keyword + * @return + */ + private String getHitCode(String str , String keyword) { + + if(StringUtils.isEmpty(keyword) || StringUtils.isEmpty(str)) { + return str; + } + + String lowerCaseStr = str.toLowerCase(); + String lowerKeyword = keyword.toLowerCase(); + String [] lowerCaseArray = lowerCaseStr.split(lowerKeyword); + + Boolean isEndWith = lowerCaseStr.endsWith(lowerKeyword); + + // 计算分割后的字符串位置 + Integer count = 0; + List> list = new ArrayList<>(); + List> keyList = new ArrayList<>(); + for(int a=0; a map = new HashMap<>(); + Map keyMap = new HashMap<>(); + map.put("startIndex", count); + Integer len = lowerCaseArray[a].length(); + count += len; + map.put("endIndex", count); + list.add(map); + + if(a < lowerCaseArray.length -1 || isEndWith) { + // 将keyword存储map + keyMap.put("startIndex", count); + count += keyword.length(); + keyMap.put("endIndex", count); + keyList.add(keyMap); + } + + } + + // 截取切割对象 + List arrayList = new ArrayList<>(); + for(Map item : list) { + Integer start = item.get("startIndex"); + Integer end = item.get("endIndex"); + String itemStr = str.substring(start, end); + arrayList.add(itemStr); + } + + // 截取关键字 + List keyArrayList = new ArrayList<>(); + for(Map item : keyList) { + Integer start = item.get("startIndex"); + Integer end = item.get("endIndex"); + String itemStr = str.substring(start, end); + keyArrayList.add(itemStr); + } + + String startStr = ""; + String endStr = ""; + StringBuffer sb = new StringBuffer(); + + for(int a=0; a 需要注意的是,在编写页面的时候,如果我们需要让没有权限的按钮,给隐藏起来的话,那么前端页面还需要配置一下 v-permission 指令,这里的值,对应的就是上面按钮管理里面的URL + +![image-20200520103235908](images/image-20200520103235908.png) + +最后我们就需要进入后台管理的角色管理处,给我们的超级管理员,添加刚刚我们的页面以及对应的按钮 + +![image-20200520105740289](images/image-20200520105740289.png) + +然后保存,刷新页面或者重新登录后,就能够看到我们添加后的菜单了~。 + + tip:如果出现以下问题,那么说明没有添加按钮。![image-20200520105822131](images/image-20200520105822131.png) \ No newline at end of file diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520093426190.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520093426190.png" new file mode 100644 index 0000000000000000000000000000000000000000..72feb8633ecfdbc643f931ae2fa99673fe862e9e Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520093426190.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520101824704.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520101824704.png" new file mode 100644 index 0000000000000000000000000000000000000000..7fdd0ffad57e10afa371016c4a749a2abaecc7de Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520101824704.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520101954581.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520101954581.png" new file mode 100644 index 0000000000000000000000000000000000000000..60544ff7aa5d4a1c65fd1cf9c16eba6b9f188d30 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520101954581.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520103046449.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520103046449.png" new file mode 100644 index 0000000000000000000000000000000000000000..7f0fd88218c759c64a4b0b0c4cd3617d182490c5 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520103046449.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520103235908.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520103235908.png" new file mode 100644 index 0000000000000000000000000000000000000000..a29d60c590ae681b0cbfaae1f7ef9e00f1f382a9 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520103235908.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520105740289.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520105740289.png" new file mode 100644 index 0000000000000000000000000000000000000000..ecb4aba0794077b6fdd3f4069819eb3b66965970 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520105740289.png" differ diff --git "a/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520105822131.png" "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520105822131.png" new file mode 100644 index 0000000000000000000000000000000000000000..05600c764472cf994dbc41a95c890ed46feaef19 Binary files /dev/null and "b/\346\235\202\350\256\260/\350\230\221\350\217\207\345\215\232\345\256\242\345\246\202\344\275\225\346\211\251\345\261\225\346\226\260\347\232\204\345\212\237\350\203\275\345\222\214\351\241\265\351\235\242/images/image-20200520105822131.png" differ diff --git "a/\346\235\202\350\256\260/\350\247\243\345\206\263git\351\273\230\350\256\244\344\270\215\345\214\272\345\210\206\345\244\247\345\260\217\345\206\231\347\232\204\351\227\256\351\242\230/\350\247\243\345\206\263git\351\273\230\350\256\244\344\270\215\345\214\272\345\210\206\345\244\247\345\260\217\345\206\231\347\232\204\351\227\256\351\242\230.md" "b/\346\235\202\350\256\260/\350\247\243\345\206\263git\351\273\230\350\256\244\344\270\215\345\214\272\345\210\206\345\244\247\345\260\217\345\206\231\347\232\204\351\227\256\351\242\230/\350\247\243\345\206\263git\351\273\230\350\256\244\344\270\215\345\214\272\345\210\206\345\244\247\345\260\217\345\206\231\347\232\204\351\227\256\351\242\230.md" new file mode 100644 index 0000000000000000000000000000000000000000..b69e89b786cf2ecd2feedc4df71be2856526145c --- /dev/null +++ "b/\346\235\202\350\256\260/\350\247\243\345\206\263git\351\273\230\350\256\244\344\270\215\345\214\272\345\210\206\345\244\247\345\260\217\345\206\231\347\232\204\351\227\256\351\242\230/\350\247\243\345\206\263git\351\273\230\350\256\244\344\270\215\345\214\272\345\210\206\345\244\247\345\260\217\345\206\231\347\232\204\351\227\256\351\242\230.md" @@ -0,0 +1,20 @@ +前言 +-- + +之前就一直有个疑惑,在我修改文件夹名称的时候,将大写改成小写,但是使用 tortoiseGit进行提交,但是提交记录中,不会显示我修改的文件夹 + +就像下面这样,在我修改icon文件夹后,在提交页面没有任何记录 + +![](http://image.moguit.cn/1577001595366.png) + +最开始我以为是git的一个bug,后面发现原来是因为git默认配置就是忽略文件夹的大小写,我们通过命令查看,是true,说明是忽略大小写的。 + + git config --get core.ignorecase + +我们将其修改成 false + + git config core.ignorecase false + +然后在打开提交页面,就发现能够识别git的文件大小写了 + +![](http://image.moguit.cn/1577001791360.png) \ No newline at end of file diff --git "a/\346\235\202\350\256\260/\350\256\260\344\270\200\346\254\241\350\230\221\350\217\207\345\215\232\345\256\242\345\267\256\347\202\271\350\242\253\345\210\240\345\272\223\347\232\204\347\273\217\345\216\206/README.md" "b/\346\235\202\350\256\260/\350\256\260\344\270\200\346\254\241\350\230\221\350\217\207\345\215\232\345\256\242\345\267\256\347\202\271\350\242\253\345\210\240\345\272\223\347\232\204\347\273\217\345\216\206/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..fd831ec08374b06d4d8ea62be4d8acea3960016b --- /dev/null +++ "b/\346\235\202\350\256\260/\350\256\260\344\270\200\346\254\241\350\230\221\350\217\207\345\215\232\345\256\242\345\267\256\347\202\271\350\242\253\345\210\240\345\272\223\347\232\204\347\273\217\345\216\206/README.md" @@ -0,0 +1,53 @@ +前言 +-- + +今天有个热心的小伙伴成功连接了蘑菇博客的数据库,然后增加管理员账号,在蘑菇博客后台转悠了一圈,最后进群和我反馈了这个问题,在这里首先感谢这位小伙伴的不删库之恩~  + +问题原因 +---- + +首先问题出现的原因是因为远程登录的密码使用的默认密码而造成的,也就是说使用 mysql -u root -p的密码 + +![](http://image.moguit.cn/3eb7ca28be7a4cae9ef3fb9632f7d532) + +和 sqlyog连接的密码不一样,但是都能够成功连接上服务器 + +![](http://image.moguit.cn/c1baf8e7362d4a58bbaf28cc661ed4ad) + +解决方案 +---- + +首先这个问题出现的原因,是因为远程连接的密码 和 本地连接的密码,我只改了一个而导致的 + + # 登录mysql + mysql -u root -p + + # 使用mysql数据库 + use mysql + + # 查询mysql用户 + select user, host from mysql.user; + +我们能够发现有4个用户 + +![](http://image.moguit.cn/3dacdadbcbbb4abaa467130fdc0e12dc) + +其中 host为%的表示是远程连接用户,而localhost是本地用户 + +我们要做的是删除%,也就是远程连接用户 + + # 方法1 + delete from mysql.user where user = 'root' and host = '%'; + + # 方法2 + drop user 'root'@'%'; + +或者是修改%的密码 + + # 修改密码 + GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY 'your_mysql_password' WITH GRANT OPTION; + + # 刷新 + flush privileges; + +也就是说,之前修改密码的时候,只修改了localhost的,而没有修改%的,而导致这个问题的出现,最后再次感谢那位热心的小伙伴发现这个问题~ \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/11_\346\255\273\351\224\201\347\274\226\347\240\201\345\217\212\345\277\253\351\200\237\345\256\232\344\275\215/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/11_\346\255\273\351\224\201\347\274\226\347\240\201\345\217\212\345\277\253\351\200\237\345\256\232\344\275\215/README.md" index cfffe51536ec4fff2bdf2886f216327d197def49..c994a21c531f5caed823b93e926799cc7fc8a077 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/11_\346\255\273\351\224\201\347\274\226\347\240\201\345\217\212\345\277\253\351\200\237\345\256\232\344\275\215/README.md" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/11_\346\255\273\351\224\201\347\274\226\347\240\201\345\217\212\345\277\253\351\200\237\345\256\232\344\275\215/README.md" @@ -2,7 +2,7 @@ ## 概念 -死锁是指两个或多个以上的进程在执行过程中,因争夺资源而造成一种互相等待的现象,若无外力干涉那他们都将无法推进下去,如果资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁 +死锁是指两个或多个以上的进程在执行过程中,因争夺资源而造成一种互相等待的现象,若无外力干涉那他们都将无法推进下去。如果资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。 ![image-20200318175441578](images/image-20200318175441578.png) @@ -12,6 +12,17 @@ - 进程运行推进的顺序不对 - 资源分配不当 +## 死锁产生的四个必要条件 + +- 互斥 + - 解决方法:把互斥的共享资源封装成可同时访问 +- 占有且等待 + - 解决方法:进程请求资源时,要求它不占有任何其它资源,也就是它必须一次性申请到所有的资源,这种方式会导致资源效率低。 +- 非抢占式 + - 解决方法:如果进程不能立即分配资源,要求它不占有任何其他资源,也就是只能够同时获得所有需要资源时,才执行分配操作 +- 循环等待 + - 解决方法:对资源进行排序,要求进程按顺序请求资源。 + ## 死锁代码 我们创建了一个资源类,然后让两个线程分别持有自己的锁,同时在尝试获取别人的,就会出现死锁现象 diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/12_JVM/JVM\351\235\242\350\257\225\351\242\230\346\261\207\346\200\273/5_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/12_JVM/JVM\351\235\242\350\257\225\351\242\230\346\261\207\346\200\273/5_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/README.md" index d6c95504d4f0d48e2da74cde1299395426ea9565..daf0c4a5ffcf7482c6a7a4785d2a2acc1fa9f352 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/12_JVM/JVM\351\235\242\350\257\225\351\242\230\346\261\207\346\200\273/5_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/README.md" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/12_JVM/JVM\351\235\242\350\257\225\351\242\230\346\261\207\346\200\273/5_\345\236\203\345\234\276\345\233\236\346\224\266\345\231\250/README.md" @@ -315,7 +315,15 @@ Concurrent Mark Sweep:并发标记清除,并发收集低停顿,并发指 标记清除算法无法整理空间碎片,老年代空间会随着应用时长被逐步耗尽,最后将不得不通过担保机制对堆内存进行压缩,CMS也提供了参数 -XX:CMSFullGCSBeForeCompaction(默认0,即每次都进行内存整理)来指定多少次CMS收集之后,进行一次压缩的Full GC +## 为什么新生代采用复制算法,老年代采用标整算法 +### 新生代使用复制算法 + +因为新生代对象的生存时间比较短,80%的都要回收的对象,采用标记-清除算法则内存碎片化比较严重,采用复制算法可以灵活高效,且便与整理空间。 + +### 老年代采用标记整理 + +标记整理算法主要是为了解决标记清除算法存在内存碎片的问题,又解决了复制算法两个Survivor区的问题,因为老年代的空间比较大,不可能采用复制算法,特别占用内存空间 ## 垃圾收集器如何选择 diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/1_\350\260\210\350\260\210Volatile/1_Volatile\345\222\214JMM\345\206\205\345\255\230\346\250\241\345\236\213\347\232\204\345\217\257\350\247\201\346\200\247/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/1_\350\260\210\350\260\210Volatile/1_Volatile\345\222\214JMM\345\206\205\345\255\230\346\250\241\345\236\213\347\232\204\345\217\257\350\247\201\346\200\247/README.md" index f422f5d4ae1407d6f58a806ff8f5f46432f18064..aae1a500b09b8061c7af2a5efbfc9d9c430ab1a5 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/1_\350\260\210\350\260\210Volatile/1_Volatile\345\222\214JMM\345\206\205\345\255\230\346\250\241\345\236\213\347\232\204\345\217\257\350\247\201\346\200\247/README.md" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/1_\350\260\210\350\260\210Volatile/1_Volatile\345\222\214JMM\345\206\205\345\255\230\346\250\241\345\236\213\347\232\204\345\217\257\350\247\201\346\200\247/README.md" @@ -51,6 +51,30 @@ JMM关于同步的规定: 即:JMM内存模型的可见性,指的是当主内存区域中的值被某个线程写入更改后,其它线程会马上知晓更改后的值,并重新得到更改后的值。 +## 缓存一致性 + +为什么这里主线程中某个值被更改后,其它线程能马上知晓呢?其实这里是用到了总线嗅探技术 + +在说嗅探技术之前,首先谈谈缓存一致性的问题,就是当多个处理器运算任务都涉及到同一块主内存区域的时候,将可能导致各自的缓存数据不一。 + +为了解决缓存一致性的问题,需要各个处理器访问缓存时都遵循一些协议,在读写时要根据协议进行操作,这类协议主要有MSI、MESI等等。 + +### MESI + +当CPU写数据时,如果发现操作的变量是共享变量,即在其它CPU中也存在该变量的副本,会发出信号通知其它CPU将该内存变量的缓存行设置为无效,因此当其它CPU读取这个变量的时,发现自己缓存该变量的缓存行是无效的,那么它就会从内存中重新读取。 + +### 总线嗅探 + +那么是如何发现数据是否失效呢? + +这里是用到了总线嗅探技术,就是每个处理器通过嗅探在总线上传播的数据来检查自己缓存值是否过期了,当处理器发现自己的缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置为无效状态,当处理器对这个数据进行修改操作的时候,会重新从内存中把数据读取到处理器缓存中。 + +### 总线风暴 + +总线嗅探技术有哪些缺点? + +由于Volatile的MESI缓存一致性协议,需要不断的从主内存嗅探和CAS循环,无效的交互会导致总线带宽达到峰值。因此不要大量使用volatile关键字,至于什么时候使用volatile、什么时候用锁以及Syschonized都是需要根据实际场景的。 + ## JMM的特性 JMM的三大特性,volatile只保证了两个,即可见性和有序性,不满足原子性 @@ -168,4 +192,10 @@ class MyData { ![image-20200309162314054](images/image-20200309162314054.png) -主线程也执行完毕了,说明volatile修饰的变量,是具备JVM轻量级同步机制的,能够感知其它线程的修改后的值。 \ No newline at end of file +主线程也执行完毕了,说明volatile修饰的变量,是具备JVM轻量级同步机制的,能够感知其它线程的修改后的值。 + + + +## 参考 + +https://mp.weixin.qq.com/s/Oa3tcfAFO9IgsbE22C5TEg \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/1_\350\260\210\350\260\210Volatile/3_Volatile\347\246\201\346\255\242\346\214\207\344\273\244\351\207\215\346\216\222/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/1_\350\260\210\350\260\210Volatile/3_Volatile\347\246\201\346\255\242\346\214\207\344\273\244\351\207\215\346\216\222/README.md" index 311cf706c1f1a36d359a95920513bc808d56bb09..1428c2617e5b24b41fba1deb02b2f98ab1d9c179 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/1_\350\260\210\350\260\210Volatile/3_Volatile\347\246\201\346\255\242\346\214\207\344\273\244\351\207\215\346\216\222/README.md" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/1_\350\260\210\350\260\210Volatile/3_Volatile\347\246\201\346\255\242\346\214\207\344\273\244\351\207\215\346\216\222/README.md" @@ -144,4 +144,7 @@ Volatile实现禁止指令重排优化,从而避免了多线程环境下程序 对于指令重排导致的可见性问题和有序性问题 -- 可以使用volatile关键字解决,因为volatile关键字的另一个作用就是禁止重排序优化 \ No newline at end of file +- 可以使用volatile关键字解决,因为volatile关键字的另一个作用就是禁止重排序优化 + +## 总线嗅探 + diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/1_\350\260\210\350\260\210Volatile/4_Volatile\347\232\204\345\272\224\347\224\250/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/1_\350\260\210\350\260\210Volatile/4_Volatile\347\232\204\345\272\224\347\224\250/README.md" index fada5d31108548c6a9ed2d15dcf9aa00a05c4075..8c5b69c83aeabf9a57f3610dd76c2d00fec86474 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/1_\350\260\210\350\260\210Volatile/4_Volatile\347\232\204\345\272\224\347\224\250/README.md" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/1_\350\260\210\350\260\210Volatile/4_Volatile\347\232\204\345\272\224\347\224\250/README.md" @@ -174,9 +174,12 @@ public class SingletonDemo { public static SingletonDemo getInstance() { if(instance == null) { - // 同步代码段的时候,进行检测 - synchronized (SingletonDemo.class) { - if(instance == null) { + // a 双重检查加锁多线程情况下会出现某个线程虽然这里已经为空,但是另外一个线程已经执行到d处 + synchronized (SingletonDemo.class) //b + { + //c不加volitale关键字的话有可能会出现尚未完全初始化就获取到的情况。原因是内存模型允许无序写入 + if(instance == null) { + // d 此时才开始初始化 instance = new SingletonDemo(); } } diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/2_\350\260\210\350\260\210CAS/5_CAS\345\272\225\345\261\202\345\216\237\347\220\206/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/2_\350\260\210\350\260\210CAS/5_CAS\345\272\225\345\261\202\345\216\237\347\220\206/README.md" index 0517d62a9b68c2a930ff4d1dfa9d75d1a75c6c68..b0be4d7808957683794898e035ce9a257db0cf9c 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/2_\350\260\210\350\260\210CAS/5_CAS\345\272\225\345\261\202\345\216\237\347\220\206/README.md" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/2_\350\260\210\350\260\210CAS/5_CAS\345\272\225\345\261\202\345\216\237\347\220\206/README.md" @@ -8,8 +8,6 @@ CAS的全称是Compare-And-Swap,它是CPU并发原语 CAS并发原语体现在Java语言中就是sun.misc.Unsafe类的各个方法。调用UnSafe类中的CAS方法,JVM会帮我们实现出CAS汇编指令,这是一种完全依赖于硬件的功能,通过它实现了原子操作,再次强调,由于CAS是一种系统原语,原语属于操作系统用于范畴,是由若干条指令组成,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许被中断,也就是说CAS是一条CPU的原子指令,不会造成所谓的数据不一致的问题,也就是说CAS是线程安全的。 - - ## 代码使用 首先调用AtomicInteger创建了一个实例, 并初始化为5 diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/README.md" index 3ad94b7517f803819a33e13afac48c83c41bbf0a..b91d09d92d07c6b1bc0da09a71ffb73e6afec35a 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/README.md" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/README.md" @@ -247,4 +247,115 @@ public class ABADemo { ![image-20200312200434776](images/image-20200312200434776.png) -我们能够发现,线程t3,在进行ABA操作后,版本号变更成了3,而线程t4在进行操作的时候,就出现操作失败了,因为版本号和当初拿到的不一样 \ No newline at end of file +我们能够发现,线程t3,在进行ABA操作后,版本号变更成了3,而线程t4在进行操作的时候,就出现操作失败了,因为版本号和当初拿到的不一样 + + + +## LongAdder(CAS机制优化) + +LongAdder是java8为我们提供的新的类,跟AtomicLong有相同的效果。是对CAS机制的优化 + +``` +LongAdder: +//变量声明 +public static LongAdder count = new LongAdder(); +//变量操作 +count.increment(); +//变量取值 +count +``` + +### 为什么有了AtomicLong还要新增一个LongAdder呢 + +原因是:CAS底层实现是在一个死循环中不断地尝试修改目标值,直到修改成功。如果竞争不激烈的时候,修改成功率很高,否则失败率很高。在失败的时候,这些重复的原子性操作会耗费性能。(不停的**自旋**,进入一个无限重复的循环中) + +![image-20200429085540554](images/image-20200429085540554.png) + +**核心思想:将热点数据分离。** + +比如说它可以将AtomicLong内部的内部核心数据value分离成一个数组,每个线程访问时,通过hash等算法映射到其中一个数字进行计数,而最终的计数结果则为这个数组的求和累加,其中热点数据value会被分离成多个单元的cell,每个cell独自维护内部的值。当前对象的实际值由所有的cell累计合成,这样热点就进行了有效地分离,并提高了并行度。这相当于将AtomicLong的单点的更新压力分担到各个节点上。在低并发的时候通过对base的直接更新,可以保障和AtomicLong的性能基本一致。而在高并发的时候通过分散提高了性能。 + +``` +public void increment() { + add(1L); +} +public void add(long x) { + Cell[] as; long b, v; int m; Cell a; + if ((as = cells) != null || !casBase(b = base, b + x)) { + boolean uncontended = true; + if (as == null || (m = as.length - 1) < 0 || + (a = as[getProbe() & m]) == null || + !(uncontended = a.cas(v = a.value, v + x))) + longAccumulate(x, null, uncontended); + } +} +``` + +但是这个CAS有没有问题呢?肯定是有的。比如说大量的线程同时并发修改一个AtomicInteger,可能有**很多线程会不停的自旋**,进入一个无限重复的循环中。 + +这些线程不停地获取值,然后发起CAS操作,但是发现这个值被别人改过了,于是再次进入下一个循环,获取值,发起CAS操作又失败了,再次进入下一个循环。 + +在大量线程高并发更新AtomicInteger的时候,这种问题可能会比较明显,导致大量线程空循环,自旋转,性能和效率都不是特别好。 + +于是,当当当当,Java 8推出了一个新的类,**LongAdder**,他就是尝试使用分段CAS以及自动分段迁移的方式来大幅度提升多线程高并发执行CAS操作的性能! + +![image-20200429085141487](images/image-20200429085141487.png) + +在LongAdder的底层实现中,首先有一个base值,刚开始多线程来不停的累加数值,都是对base进行累加的,比如刚开始累加成了base = 5。 + +接着如果发现并发更新的线程数量过多,在发生竞争的情况下,会有一个Cell数组用于将不同线程的操作离散到不同的节点上去 ==(会根据需要扩容,最大为CPU核)==就会开始施行**分段CAS的机制**,也就是内部会搞一个Cell数组,每个数组是一个数值分段。 + +这时,让大量的线程分别去对不同Cell内部的value值进行CAS累加操作,这样就把CAS计算压力分散到了不同的Cell分段数值中了! + +这样就可以大幅度的降低多线程并发更新同一个数值时出现的无限循环的问题,大幅度提升了多线程并发更新数值的性能和效率! + +而且他内部实现了**自动分段迁移的机制**,也就是如果某个Cell的value执行CAS失败了,那么就会自动去找另外一个Cell分段内的value值进行CAS操作。 + +这样也解决了线程空旋转、自旋不停等待执行CAS操作的问题,让一个线程过来执行CAS时可以尽快的完成这个操作。 + +最后,如果你要从LongAdder中获取当前累加的总值,就会把base值和所有Cell分段数值加起来返回给你。 + +![image-20200429085957778](images/image-20200429085957778.png) + +如上图所示,LongAdder则是内部维护多个Cell变量,每个Cell里面有一个初始值为0的long型变量,在同等并发量的情况下,争夺单个变量的线程会减少,这是变相的减少了争夺共享资源的并发量,另外多个线程在争夺同一个原子变量时候, + +如果失败并不是自旋CAS重试,而是尝试获取其他原子变量的锁,最后当获取当前值时候是把所有变量的值累加后再加上base的值返回的。 + +LongAdder维护了要给延迟初始化的原子性更新数组和一个基值变量base数组的大小保持是2的N次方大小,数组表的下标使用每个线程的hashcode值的掩码表示,数组里面的变量实体是Cell类型。 + +Cell 类型是Atomic的一个改进,用来减少缓存的争用,对于大多数原子操作字节填充是浪费的,因为原子操作都是无规律的分散在内存中进行的,多个原子性操作彼此之间是没有接触的,但是原子性数组元素彼此相邻存放将能经常共享缓存行,也就是**伪共享**。所以这在性能上是一个提升。(补充:可以看到Cell类用Contended注解修饰,这里主要是解决false sharing(伪共享的问题),不过个人认为伪共享翻译的不是很好,或者应该是错误的共享,比如两个volatile变量被分配到了同一个缓存行,但是这两个的更新在高并发下会竞争,比如线程A去更新变量a,线程B去更新变量b,但是这两个变量被分配到了同一个缓存行,因此会造成每个线程都去争抢缓存行的所有权,例如A获取了所有权然后执行更新这时由于volatile的语义会造成其刷新到主存,但是由于变量b也被缓存到同一个缓存行,因此就会造成cache miss,这样就会造成极大的性能损失) +**LongAdder的add操作图** + +![image-20200429090249633](images/image-20200429090249633.png) + +可以看到,只有从未出现过并发冲突的时候,base基数才会使用到,一旦出现了并发冲突,之后所有的操作都只针对Cell[]数组中的单元Cell。 +如果Cell[]数组未初始化,会调用父类的longAccumelate去初始化Cell[],如果Cell[]已经初始化但是冲突发生在Cell单元内,则也调用父类的longAccumelate,此时可能就需要对Cell[]扩容了。 +**另外由于Cells占用内存是相对比较大的,所以一开始并不创建,而是在需要时候再创建,也就是惰性加载,当一开始没有空间时候,所有的更新都是操作base变量。** + +![image-20200429090556928](images/image-20200429090556928.png) + +如上图代码: +例如32、64位操作系统的缓存行大小不一样,因此JAVA8中就增加了一个注`@sun.misc.Contended`解用于解决这个问题,由JVM去插入这些变量,[具体可以参考openjdk.java.net/jeps/142](http://xn--openjdk-hc5k25at0ntqhnpa7548b.java.net/jeps/142) ,但是通常来说对象是不规则的分配到内存中的,但是数组由于是连续的内存,因此可能会共享缓存行,因此这里加一个Contended注解以防cells数组发生伪共享的情况。 + +为了降低高并发下多线程对一个变量CAS争夺失败后大量线程会自旋而造成降低并发性能问题,LongAdder内部通过根据并发请求量来维护多个Cell元素(一个动态的Cell数组)来分担对单个变量进行争夺资源。 + +![image-20200429090713078](images/image-20200429090713078.png) + +可以看到LongAdder继承自Striped64类,Striped64内部维护着三个变量,LongAdder的真实值其实就是base的值与Cell数组里面所有Cell元素值的累加,base是个基础值,默认是0,cellBusy用来实现自旋锁,当创建Cell元素或者扩容Cell数组时候用来进行线程间的同步。 + +在无竞争下直接更新base,类似AtomicLong高并发下,会将每个线程的操作hash到不同的cells数组中,从而将AtomicLong中更新一个value的行为优化之后,分散到多个value中 +从而降低更新热点,而需要得到当前值的时候,直接 将所有cell中的value与base相加即可,但是跟AtomicLong(compare and change -> xadd)的CAS不同,incrementAndGet操作及其变种可以返回更新后的值,而LongAdder返回的是void。 + +由于Cell相对来说比较占内存,因此这里采用懒加载的方式,在无竞争的情况下直接更新base域,在第一次发生竞争的时候(CAS失败)就会创建一个大小为2的cells数组,每次扩容都是加倍,只到达到CPU核数。同时我们知道扩容数组等行为需要只能有一个线程同时执行,因此需要一个锁,这里通过CAS更新cellsBusy来实现一个简单的spin lock。 + +数组访问索引是通过Thread里的threadLocalRandomProbe域取模实现的,这个域是ThreadLocalRandom更新的,cells的数组大小被限制为CPU的核数,因为即使有超过核数个线程去更新,但是每个线程也只会和一个CPU绑定,更新的时候顶多会有cpu核数个线程,因此我们只需要通过hash将不同线程的更新行为离散到不同的slot即可。 +我们知道线程、线程池会被关闭或销毁,这个时候可能这个线程之前占用的slot就会变成没人用的,但我们也不能清除掉,因为一般web应用都是长时间运行的,线程通常也会动态创建、销毁,很可能一段时间后又会被其他线程占用,而对于短时间运行的,例如单元测试,清除掉有啥意义呢? + +## 参考 + +[AtomicLong与LongAdder(CAS机制的优化)](https://blog.csdn.net/eluanshi12/article/details/84871879) + +[大白话聊聊Java并发面试问题之Java 8如何优化CAS性能?](https://mp.weixin.qq.com/s/KFsqsCVgyiiTDXMR-Hu1-Q) + +https://blog.csdn.net/wolf_love666/article/details/87693771 + diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429085141487.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429085141487.png" new file mode 100644 index 0000000000000000000000000000000000000000..379092740cb5d2ea1398e4e4f01e19dde373ba06 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429085141487.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429085540554.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429085540554.png" new file mode 100644 index 0000000000000000000000000000000000000000..bf09b4858206ff0f494e471d40cac55d1ffe615f Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429085540554.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429085957778.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429085957778.png" new file mode 100644 index 0000000000000000000000000000000000000000..dc05ec1ddfde1df0d316ad62470cf60ead4e9e34 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429085957778.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429090249633.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429090249633.png" new file mode 100644 index 0000000000000000000000000000000000000000..75f1554a3f4a7206cc7f2211f2146954a7d82fe5 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429090249633.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429090556928.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429090556928.png" new file mode 100644 index 0000000000000000000000000000000000000000..8d2d59a048a6eb23b015c08a11c3dbc9aa33ac1e Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429090556928.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429090713078.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429090713078.png" new file mode 100644 index 0000000000000000000000000000000000000000..057f689be06b75815a618708855cb3ee340b4f20 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/3_\350\260\210\350\260\210\345\216\237\345\255\220\347\261\273\347\232\204ABA\351\227\256\351\242\230/6_\345\216\237\345\255\220\347\261\273AtomicInteger\347\232\204ABA\351\227\256\351\242\230/images/image-20200429090713078.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/6_Java\347\232\204\351\224\201/Synchronized\346\227\240\346\263\225\347\246\201\346\255\242\346\214\207\344\273\244\351\207\215\346\216\222\345\215\264\350\203\275\344\277\235\350\257\201\346\234\211\345\272\217\346\200\247/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/6_Java\347\232\204\351\224\201/Synchronized\346\227\240\346\263\225\347\246\201\346\255\242\346\214\207\344\273\244\351\207\215\346\216\222\345\215\264\350\203\275\344\277\235\350\257\201\346\234\211\345\272\217\346\200\247/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a730fae69f5d9ccfad9414124a683d623b221144 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/6_Java\347\232\204\351\224\201/Synchronized\346\227\240\346\263\225\347\246\201\346\255\242\346\214\207\344\273\244\351\207\215\346\216\222\345\215\264\350\203\275\344\277\235\350\257\201\346\234\211\345\272\217\346\200\247/README.md" @@ -0,0 +1,42 @@ +# 为什么Synchronized无法禁止指令重排,却能保证有序性 + +## 前言 + +首先我们要分析下这道题,这简单的一个问题,其实里面还是包含了很多信息的,要想回答好这个问题,面试者至少要知道一下概念: + +- Java内存模型 +- 并发编程有序性问题 +- 指令重排 +- synchronized锁 +- 可重入锁 +- 排它锁 +- as-if-serial语义 +- 单线程&多线程 + +## 标准解答 + +为了进一步提升计算机各方面能力,在硬件层面做了很多优化,如处理器优化和指令重排等,但是这些技术的引入就会导致有序性问题。 + +> 先解释什么是有序性问题,也知道是什么原因导致的有序性问题 + +我们也知道,最好的解决有序性问题的办法,就是禁止处理器优化和指令重排,就像volatile中使用内存屏障一样。 + +>表明你知道啥是指令重排,也知道他的实现原理 + +但是,虽然很多硬件都会为了优化做一些重排,但是在Java中,不管怎么排序,都不能影响单线程程序的执行结果。这就是as-if-serial语义,所有硬件优化的前提都是必须遵守as-if-serial语义。 + +as-if-serial语义把**单线程**程序保护了起来,遵守as-if-serial语义的编译器,runtime 和处理器共同为编写单线程程序的程序员创建了一个幻觉:单线程程序是按程序的顺序来执行的。as-if-serial语义使单线程程序员无需担心重排序会 干扰他们,也无需担心内存可见性问题。 + +> 重点!解释下什么是as-if-serial语义,因为这是这道题的第一个关键词,答上来就对了一半了 + +再说下synchronized,他是Java提供的锁,可以通过他对Java中的对象加锁,并且他是一种排他的、可重入的锁。 + +所以,当某个线程执行到一段被synchronized修饰的代码之前,会先进行加锁,执行完之后再进行解锁。在加锁之后,解锁之前,其他线程是无法再次获得锁的,只有这条加锁线程可以重复获得该锁。 + +> 介绍synchronized的原理,这是本题的第二个关键点,到这里基本就可以拿满分了。 + +synchronized通过排他锁的方式就保证了同一时间内,被synchronized修饰的代码是单线程执行的。所以呢,这就满足了as-if-serial语义的一个关键前提,那就是**单线程**,因为有as-if-serial语义保证,单线程的有序性就天然存在了。 + +## 来源 + +https://mp.weixin.qq.com/s/Pd6dOXaMQFUHfAUnOhnwtw \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/.gitignore" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/.gitignore" new file mode 100644 index 0000000000000000000000000000000000000000..df0583553f36588f85b388b0f04e0b301fed32e3 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/.gitignore" @@ -0,0 +1,32 @@ +/target/ +/temp/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +.settings + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +*.iml + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +/webapps/ + +/logs/ \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/.idea/codeStyles/codeStyleConfig.xml" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/.idea/codeStyles/codeStyleConfig.xml" new file mode 100644 index 0000000000000000000000000000000000000000..a55e7a179bde3e4e772c29c0c85e53354aa54618 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/.idea/codeStyles/codeStyleConfig.xml" @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/pom.xml" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/pom.xml" index fdb8a79e12a9df5fd8f7bc5ed20c337d565552ad..65b5c3bb14633d55098780adf67c06233406700f 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/pom.xml" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/pom.xml" @@ -23,6 +23,12 @@ 3.3.0 + + cn.hutool + hutool-all + 5.3.1 + + org.springframework spring-context diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Main.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Main.java" new file mode 100644 index 0000000000000000000000000000000000000000..6b508bd36b2b3952acb73411b3ee0171ddc37230 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Main.java" @@ -0,0 +1,28 @@ +package com.moxi.interview.study.AQS; + +/** + * @author: 陌溪 + * @create: 2020-07-17-15:56 + */ +public class Main { + public static int m = 0; + + public static void main(String[] args) throws InterruptedException { + Thread[] threads = new Thread[100]; + for (int i = 0; i < threads.length; i++) { + threads[i] = new Thread(() -> { + for (int j = 0; j < 100; j++) { + m++; + } + }); + } + for (Thread t: threads) { + t.start(); + } + // 等待所有线程结束 + for (Thread t: threads) { + t.join(); + } + System.out.println(m); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Main2.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Main2.java" new file mode 100644 index 0000000000000000000000000000000000000000..cd35eb95ef30cdde09b2a51f4c7fa33add1cb948 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Main2.java" @@ -0,0 +1,30 @@ +package com.moxi.interview.study.AQS; + +/** + * @author: 陌溪 + * @create: 2020-07-17-15:56 + */ +public class Main2 { + public static int m = 0; + + public static void main(String[] args) throws InterruptedException { + Thread[] threads = new Thread[100]; + for (int i = 0; i < threads.length; i++) { + threads[i] = new Thread(() -> { + synchronized (Main2.class) { + for (int j = 0; j < 100; j++) { + m++; + } + } + }); + } + for (Thread t: threads) { + t.start(); + } + // 等待所有线程结束 + for (Thread t: threads) { + t.join(); + } + System.out.println(m); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Main3.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Main3.java" new file mode 100644 index 0000000000000000000000000000000000000000..164d83e80d15155b0dff4a78da2d87bd7a3c6c1f --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Main3.java" @@ -0,0 +1,39 @@ +package com.moxi.interview.study.AQS; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * @author: 陌溪 + * @create: 2020-07-17-15:56 + */ +public class Main3 { + public static int m = 0; + // ReentrantLock默认是非公平锁 + public static void main(String[] args) throws InterruptedException { + Thread[] threads = new Thread[100]; + ReentrantLock lock = new ReentrantLock(); + for (int i = 0; i < threads.length; i++) { + threads[i] = new Thread(() -> { + lock.lock(); + try { + for (int j = 0; j < 100; j++) { + m++; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + }); + } + + for (Thread t: threads) { + t.start(); + } + // 等待所有线程结束 + for (Thread t: threads) { + t.join(); + } + System.out.println(m); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Main4.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Main4.java" new file mode 100644 index 0000000000000000000000000000000000000000..a7f02e4e0618d4c2b5df1fc036f2a199e72e8ce1 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Main4.java" @@ -0,0 +1,39 @@ +package com.moxi.interview.study.AQS; + +import java.util.concurrent.locks.Lock; + +/** + * @author: 陌溪 + * @create: 2020-07-17-15:56 + */ +public class Main4 { + public static int m = 0; + // ReentrantLock默认是非公平锁 + public static void main(String[] args) throws InterruptedException { + Thread[] threads = new Thread[100]; + Lock lock = new MyLock(); + for (int i = 0; i < threads.length; i++) { + threads[i] = new Thread(() -> { + lock.lock(); + try { + for (int j = 0; j < 100; j++) { + m++; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + }); + } + + for (Thread t: threads) { + t.start(); + } + // 等待所有线程结束 + for (Thread t: threads) { + t.join(); + } + System.out.println(m); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/MyLock.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/MyLock.java" new file mode 100644 index 0000000000000000000000000000000000000000..cf2b7efe6f12e189b719bc9cc0bcf602be306846 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/MyLock.java" @@ -0,0 +1,59 @@ +package com.moxi.interview.study.AQS; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; + +/** + * 自定义锁 + * + * @author: 陌溪 + * @create: 2020-07-17-17:06 + */ +public class MyLock implements Lock { + private volatile int i = 0; + @Override + public void lock() { + synchronized (this) { + // 判断是否有线程已经占用了锁 + while(i != 0) { + try { + // 如果有线程占有锁,可以直接阻塞 + this.wait(); + } catch (Exception e) { + e.printStackTrace(); + } + } + i = 1; + } + } + + @Override + public void lockInterruptibly() throws InterruptedException { + + } + + @Override + public boolean tryLock() { + return false; + } + + @Override + public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { + return false; + } + + @Override + public void unlock() { + synchronized (this) { + i = 0; + // 唤醒所有线程 + this.notifyAll(); + } + } + + @Override + public Condition newCondition() { + return null; + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/MyLock2.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/MyLock2.java" new file mode 100644 index 0000000000000000000000000000000000000000..0e360d0e9382a4f841712914c5a1591d9eb19675 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/MyLock2.java" @@ -0,0 +1,97 @@ +package com.moxi.interview.study.AQS; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.AbstractQueuedSynchronizer; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; + +/** + * 自定义锁 + * + * @author: 陌溪 + * @create: 2020-07-17-17:06 + */ +public class MyLock2 implements Lock { + private volatile int i = 0; + @Override + public void lock() { + synchronized (this) { + // 判断是否有线程已经占用了锁 + while(i != 0) { + try { + // 如果有线程占有锁,可以直接阻塞 + this.wait(); + } catch (Exception e) { + e.printStackTrace(); + } + } + i = 1; + } + } + + @Override + public void lockInterruptibly() throws InterruptedException { + + } + + @Override + public boolean tryLock() { + return false; + } + + @Override + public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { + return false; + } + + @Override + public void unlock() { + synchronized (this) { + i = 0; + // 唤醒所有线程 + this.notifyAll(); + } + } + + @Override + public Condition newCondition() { + return null; + } + + /** + * 内部类 + */ + public class Sync extends AbstractQueuedSynchronizer { + + @Override + protected boolean tryAcquire(int arg) { + // 使用自旋锁 ,同时CAS必须保证原子性 + // 目前的CPU底层汇编都有这条指令了,即支持原语操作 + if (compareAndSetState(0, 1)) { + // 设置排它的拥有者,也就是互斥锁 + setExclusiveOwnerThread(Thread.currentThread()); + return true; + } + return false; + } + + @Override + protected boolean tryRelease(int arg) { + assert arg == 1; + if(!isHeldExclusively()) { + throw new IllegalMonitorStateException(); + } + // 释放锁 + setExclusiveOwnerThread(null); + setState(0); + return super.tryRelease(arg); + } + + + @Override + protected boolean isHeldExclusively() { + // 判断当前线程 是不是和排它锁的线程一样 + return getExclusiveOwnerThread() == Thread.currentThread(); + } + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Sync.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Sync.java" new file mode 100644 index 0000000000000000000000000000000000000000..914be86cc0f321a6c022bca8a7cd614eef0a74ee --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/AQS/Sync.java" @@ -0,0 +1,39 @@ +package com.moxi.interview.study.AQS; + +import java.util.concurrent.locks.AbstractQueuedSynchronizer; + +/** + * AQS + * + * @author: 陌溪 + * @create: 2020-07-17-19:56 + */ +public class Sync extends AbstractQueuedSynchronizer { + + @Override + protected boolean tryAcquire(int arg) { + // 使用自旋锁 ,同时CAS必须保证原子性 + // 目前的CPU底层汇编都有这条指令了,即支持原语操作 + if (compareAndSetState(0, 1)) { + // 设置排它的拥有者,也就是互斥锁 + setExclusiveOwnerThread(Thread.currentThread()); + return true; + } + return false; + } + + @Override + protected boolean tryRelease(int arg) { + // 释放锁 + setExclusiveOwnerThread(null); + setState(0); + return super.tryRelease(arg); + } + + + @Override + protected boolean isHeldExclusively() { + // 判断当前线程是不是 + return getState() == 1; + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/AlibabaTest1_20200420.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/AlibabaTest1_20200420.java" new file mode 100644 index 0000000000000000000000000000000000000000..a53cefbf11e6d7f364862952684d22c6facee232 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/AlibabaTest1_20200420.java" @@ -0,0 +1,72 @@ +package com.moxi.interview.study.LeetCode; + +import java.util.Scanner; + +/** + * @author: 陌溪 + * @create: 2020-04-20-18:56 + */ +public class AlibabaTest1_20200420 { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int a = sc.nextInt(); + int n = sc.nextInt(); + int pow[] = new int[n]; + for(int i=0; i 0) { + // 表示是否进行了战斗 + boolean flag = false; + for(int i=0; i maxMoney) { + maxMoney = money; + } + } + } + // 最后一个被打败 + if(pow[pow.length -1] == -1) { + break; + } + + // 钱花完了,一个怪也没打过 + if(money == 0 && !flag) { + break; + } + + // 非负判断 + if(money > 0) { + // 提升能力,再次战斗 + ability++; + money --; + } + } + System.out.println(maxMoney); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/AlibabaTest2_20200420.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/AlibabaTest2_20200420.java" new file mode 100644 index 0000000000000000000000000000000000000000..cbe74bfa7538f091ccf85b9ed2993006618d5cd4 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/AlibabaTest2_20200420.java" @@ -0,0 +1,37 @@ +package com.moxi.interview.study.LeetCode; + +import java.util.Scanner; + +/** + * @author: 陌溪 + * @create: 2020-04-20-18:56 + */ +public class AlibabaTest2_20200420 { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + int weight [] = new int [n]; + int path [][] = new int[n][n]; + for(int a=0; a< n; a++) { + weight[a] = sc.nextInt(); + } + for(int a=0; a< n-1; a++) { + int node1 = sc.nextInt(); + int node2 = sc.nextInt(); + path[node1 - 1][node2 - 1] = 1; + path[node2 - 1][node1 - 1] = 1; + } + + for(int a=0; a< n; a++) { + System.out.print(weight[a] + " "); + } + + for(int a=0; a< n; a++) { + for(int b=0; b< n; b++) { + System.out.print(path[a][b] + " "); + } + System.out.println(""); + } + + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo.java" new file mode 100644 index 0000000000000000000000000000000000000000..b0985991f422b459223ddc5eeab7a7b5ab8b3828 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo.java" @@ -0,0 +1,67 @@ +package com.moxi.interview.study.LeetCode; + +import java.util.HashMap; +import java.util.Map; + +/** + * 在整数数组中,如果一个整数的出现频次和它的数值大小相等,我们就称这个整数为「幸运数」。 + * + * 给你一个整数数组 arr,请你从中找出并返回一个幸运数。 + * + * 如果数组中存在多个幸运数,只需返回 最大 的那个。 + * 如果数组中不含幸运数,则返回 -1 。 + * 示例 1: + * + * 输入:arr = [2,2,3,4] + * 输出:2 + * 解释:数组中唯一的幸运数是 2 ,因为数值 2 的出现频次也是 2 。 + * 示例 2: + * + * 输入:arr = [1,2,2,3,3,3] + * 输出:3 + * 解释:1、2 以及 3 都是幸运数,只需要返回其中最大的 3 。 + * 示例 3: + * + * 输入:arr = [2,2,2,3,3] + * 输出:-1 + * 解释:数组中不存在幸运数。 + * 示例 4: + * + * 输入:arr = [5] + * 输出:-1 + * 示例 5: + * + * 输入:arr = [7,7,7,7,7,7,7] + * 输出:7 + * + * + * @author: 陌溪 + * @create: 2020-04-18-19:28 + */ +public class Demo { + public static int findLucky(int[] arr) { + Map map = new HashMap<>(); + for (int i = 0; i < arr.length; i++) { + if(map.get(arr[i]) == null) { + map.put(arr[i], 1); + } else { + int a = map.get(arr[i]) + 1; + map.put(arr[i], a); + } + } + int maxKey = -1; + for(int key : map.keySet()) { + if(map.get(key) == key) { + if(key > maxKey) { + maxKey = key; + } + } + } + + return maxKey; + } + public static void main(String[] args) { + System.out.println(findLucky(new int[]{7,7,7,7,7,7,7})); + } +} + diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo2.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo2.java" new file mode 100644 index 0000000000000000000000000000000000000000..5b2944e2dfa9fdf3b42349d05814e36cd1e5342a --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo2.java" @@ -0,0 +1,27 @@ +package com.moxi.interview.study.LeetCode; + +/** + * 数组arr是[0, 1, ..., arr.length - 1]的一种排列,我们将这个数组分割成几个“块”,并将这些块分别进行排序。之后再连接起来,使得连接的结果和按升序排序后的原数组相同。 + * + * 我们最多能将数组分成多少块? + * + * 示例 1: + * + * 输入: arr = [4,3,2,1,0] + * 输出: 1 + * 解释: + * 将数组分成2块或者更多块,都无法得到所需的结果。 + * 例如,分成 [4, 3], [2, 1, 0] 的结果是 [3, 4, 0, 1, 2],这不是有序的数组。 + * 示例 2: + * + * 输入: arr = [1,0,2,3,4] + * 输出: 4 + * 解释: + * 我们可以把它分成两块,例如 [1, 0], [2, 3, 4]。 + * 然而,分成 [1, 0], [2], [3], [4] 可以得到最多的块数。 + * + * @author: 陌溪 + * @create: 2020-04-18-19:37 + */ +public class Demo2 { +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo3.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo3.java" new file mode 100644 index 0000000000000000000000000000000000000000..9ae6cbe9292c2b21bd731a589fa86247ed973c96 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo3.java" @@ -0,0 +1,110 @@ +package com.moxi.interview.study.LeetCode; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 + * + * 示例 1: + * + * 输入: "abcabcbb" + * 输出: 3 + * 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 + + 示例 2: + + 输入: "bbbbb" + 输出: 1 + 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 + 示例 3: + + 输入: "pwwkew" + 输出: 3 + 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 +   请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。 + + * @author: 陌溪 + * @create: 2020-04-16-23:05 + */ +public class Demo3 { + /** + * 暴力法,时间复杂度 O(n^3) + * @param s + * @return + */ + public static int lengthOfLongestSubstring(String s) { + char [] chars = s.toCharArray(); + String maxResult = ""; + for(int a=0; a -1) { + break; + } else { + result += chars[b]; + } + } + if(result.length() > maxResult.length()) { + maxResult = result; + } + } + return maxResult.length(); + } + + /** + * 引入hashset + * @param s + * @return + */ + public static int lengthOfLongestSubstring2(String s) { + char [] chars = s.toCharArray(); + int maxResult = 0; + for(int a=0; a result = new HashSet<>(); + for(int b=a; b maxResult) { + maxResult = result.size(); + } + } + return maxResult; + } + + /** + * 官方算法 + * @param s + * @return + */ + public static int lengthOfLongestSubstring03(String s) { + int n = s.length(), ans = 0; + //创建map窗口,i为左区间,j为右区间,右边界移动 + Map map = new HashMap<>(); + for (int j = 0, i = 0; j < n; j++) { + // 如果窗口中包含当前字符, + if (map.containsKey(s.charAt(j))) { + //左边界移动到 相同字符的下一个位置和i当前位置中更靠右的位置,这样是为了防止i向左移动 + i = Math.max(map.get(s.charAt(j)), i); + } + //比对当前无重复字段长度和储存的长度,选最大值并替换 + //j-i+1是因为此时i,j索引仍处于不重复的位置,j还没有向后移动,取的[i,j]长度 + ans = Math.max(ans, j - i + 1); + // 将当前字符为key,下一个索引为value放入map中 + // value为j+1是为了当出现重复字符时,i直接跳到上个相同字符的下一个位置,if中取值就不用+1了 + map.put(s.charAt(j), j+1); + } + return ans; + } + + public static void main(String[] args) { + System.out.println(lengthOfLongestSubstring03("pwwkew")); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo5.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo5.java" new file mode 100644 index 0000000000000000000000000000000000000000..319fee0f48ebbd8dc288fb7becacdb7d92bd065f --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo5.java" @@ -0,0 +1,68 @@ +package com.moxi.interview.study.LeetCode; + +/** + 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 + + 示例 1: + + 输入: "babad" + 输出: "bab" + 注意: "aba" 也是一个有效答案。 + 示例 2: + + 输入: "cbbd" + 输出: "bb" + + * + * @author: 陌溪 + * @create: 2020-04-16-23:24 + */ +public class Demo5 { + + /** + * 中心扩展法 + * @param s + * @return + */ + public static String longestPalindrome(String s) { + char [] chars = s.toCharArray(); + String maxResult = ""; + // 一个中心 + for(int a=0; a= 0 && (increment + 1) < chars.length && (chars[decrement-1] == chars[increment + 1]) ) { + result = chars[decrement - 1] + result + chars[increment + 1]; + decrement--; + increment++; + } + if(result.length() > maxResult.length()) { + maxResult = result; + } + } + + // 当没有找到回文时 + String maxResult2 = ""; + for(int a =0; a= 0 && (increment + 1) < chars.length && (chars[decrement-1] == chars[increment + 1]) ) { + result = chars[decrement - 1] + "" + result + chars[increment + 1]; + decrement--; + increment++; + } + if(result.length() > maxResult2.length()) { + maxResult2 = result; + } + } + } + return maxResult.length() > maxResult2.length()? maxResult: maxResult2; + } + + public static void main(String[] args) { + System.out.println(longestPalindrome("babad")); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo6.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo6.java" new file mode 100644 index 0000000000000000000000000000000000000000..df583d658bf74f6f5c5f6356ab79c6207ff3ff0c --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Demo6.java" @@ -0,0 +1,35 @@ +package com.moxi.interview.study.LeetCode; + +import java.util.*; + +/** + * 青牛小学 + * + * @author: 陌溪 + * @create: 2020-09-08-19:10 + */ +public class Demo6 { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int count = sc.nextInt(); + List list = new ArrayList<>(); + for (int i = 0; i <= count+1; i++) { + list.add(sc.nextLine()); + } + + System.out.println(list.get(list.size() -1)); + String result = list.get(list.size() -1); + + result = result.replace(".", ""); + result = result.replace(" ", ""); + + char ch [] = result.toCharArray(); + Map chCountMap = new HashMap<>(); + for (int i = 0; i < ch.length; i++) { + + System.out.println(ch[i]); + } + + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/FindNumberIn2DArray_04.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/FindNumberIn2DArray_04.java" new file mode 100644 index 0000000000000000000000000000000000000000..a5e669ce6e9a449d7f4c2e74923f424284b89294 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/FindNumberIn2DArray_04.java" @@ -0,0 +1,67 @@ +package com.moxi.interview.study.LeetCode; + +/** + * 二维数组中的查找 + * + * @author: 陌溪 + * @create: 2020-06-26-15:32 + */ +public class FindNumberIn2DArray_04 { +// public static boolean findNumberIn2DArray(int[][] matrix, int target) { +// int [] oneLine = matrix[0]; +// int lineIndex = -1; +// // 找出比那个大 +// for(int a=1; a target) { +// lineIndex = a; +// break; +// } +// } +// // 比最大的还大时 +// if(target >= oneLine[oneLine.length - 1]) { +// lineIndex = oneLine.length; +// } +// +// for(int a=0;a= 0){ + if(matrix[i][j] < target){ + //当前元素小于目标元素,即向下一行移动 + i++; + }else if(matrix[i][j] > target){ + //当前元素大于目标元素,即向左侧移动 + j--; + }else{ + return true; + } + } + + //即不存在目标元素 + return false; + } + + public static void main(String[] args) { + int [][] array = new int[][]{ + {-5}}; + System.out.println(findNumberIn2DArray(array, -5)); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/FindRepeatNumber_03.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/FindRepeatNumber_03.java" new file mode 100644 index 0000000000000000000000000000000000000000..d337fc5cd9581e5888cdff91061deabbb9cd7bae --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/FindRepeatNumber_03.java" @@ -0,0 +1,24 @@ +package com.moxi.interview.study.LeetCode; + +import java.util.HashMap; +import java.util.Map; + +/** + * 找出重复的数 + * + * @author: 陌溪 + * @create: 2020-06-26-15:17 + */ +public class FindRepeatNumber_03 { + public int findRepeatNumber(int[] nums) { + Map map = new HashMap(); + for(int a=0; a= 0; i --) { + if (c[i] - '0' > max) { + max = c[i] - '0'; + max_index = i; + } + arr[i] = max_index; + } + for (int i = 0; i < c.length; i ++) { + if (arr[i] != i && c[arr[i]] != c[i]) { + char tmp = c[i]; + c[i] = c[arr[i]]; + c[arr[i]] = tmp; + break; + } + } + return Integer.parseInt(new String(c)); + + } + + public static void main(String[] args) { + maximumSwap(2376); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/ReplaceSpace_05.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/ReplaceSpace_05.java" new file mode 100644 index 0000000000000000000000000000000000000000..1e3c1afc9eac2753958808590e9a7d9b797884b8 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/ReplaceSpace_05.java" @@ -0,0 +1,45 @@ +package com.moxi.interview.study.LeetCode; + +/** + * 替换空格 + * + * @author: 陌溪 + * @create: 2020-06-26-16:13 + */ +public class ReplaceSpace_05 { + public String replaceSpace(String s) { + char [] ch = s.toCharArray(); + StringBuilder sb = new StringBuilder(); + for(int a=0; a len1 && len1 >= 0){ + char c = str.charAt(len1--); + if(c == ' '){ + str.setCharAt(len2--, '0'); + str.setCharAt(len2--, '2'); + str.setCharAt(len2--, '%'); + }else{ + str.setCharAt(len2--, c); + } + } + return str.toString(); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/ReversePrint.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/ReversePrint.java" new file mode 100644 index 0000000000000000000000000000000000000000..f2e647922e69ea2fc3feed7aaf2d5bd3ae2d64c2 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/ReversePrint.java" @@ -0,0 +1,27 @@ +package com.moxi.interview.study.LeetCode; + +import java.util.ArrayList; +import java.util.List; + +/** + * 翻转链表 + * + * @author: 陌溪 + * @create: 2020-06-26-17:09 + */ +public class ReversePrint { + public static void reversePrint() { + List list = new ArrayList<>(); + list.add(0, "a"); + list.add(0, "a"); + list.add(0, "a"); + for (String s : list) { + System.out.print(s + " "); + } + + } + + public static void main(String[] args) { + reversePrint(); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Test.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Test.java" new file mode 100644 index 0000000000000000000000000000000000000000..894b7acfbe3c4b7a8aa3943233703c8af2ec1858 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/LeetCode/Test.java" @@ -0,0 +1,9 @@ +package com.moxi.interview.study.LeetCode; + +import java.util.*; +public class Test { + public static void main(String[] args) { + ArrayList list = new ArrayList(); + System.out.println(""); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/SHA1/SHA1Demo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/SHA1/SHA1Demo.java" new file mode 100644 index 0000000000000000000000000000000000000000..d7224ab52fbd45cd30cee4be2148b63e24b07fe7 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/SHA1/SHA1Demo.java" @@ -0,0 +1,184 @@ +package com.moxi.interview.study.SHA1; + +import java.io.*; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.security.MessageDigest; + +/** + * @author: 陌溪 + * @create: 2020-06-06-16:21 + */ +public class SHA1Demo { + + public static String getSha1(String str) { + char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f' }; + try { + MessageDigest mdTemp = MessageDigest.getInstance("SHA1"); + mdTemp.update(str.getBytes("UTF-8")); + byte[] md = mdTemp.digest(); + int j = md.length; + char buf[] = new char[j * 2]; + int k = 0; + for (int i = 0; i < j; i++) { + byte byte0 = md[i]; + buf[k++] = hexDigits[byte0 >>> 4 & 0xf]; + buf[k++] = hexDigits[byte0 & 0xf]; + } + return new String(buf); + } catch (Exception e) { + return null; + } + } + + /** + * 获取文件中的全部内容 + * @return + */ + public static String getFileContent(String path) { + File file = new File(path); + Long fileLengthLong = file.length(); + byte[] fileContent = new byte[fileLengthLong.intValue()]; + try { + FileInputStream inputStream = new FileInputStream(file); + inputStream.read(fileContent); + inputStream.close(); + } catch (Exception e) { + // TODO: handle exception + } + String string = new String(fileContent); + return string; + } + + /** + * 创建大文件 + * @throws IOException + */ + public static void createBigFile() throws IOException { + File file = new File("D:\\file\\test.txt"); + FileWriter fileWriter = new FileWriter(file); + BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); + String str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1"; + for (int i = 0; i < 100000; i++) { + bufferedWriter.write(str); + bufferedWriter.newLine(); + } + bufferedWriter.flush(); + bufferedWriter.close(); + } + + /** + * 切割文件 + * @param filePath + * @param fileCount + * @throws IOException + */ + public static void splitFile(String filePath, int fileCount) throws IOException { + FileInputStream fis = new FileInputStream(filePath); + FileChannel inputChannel = fis.getChannel(); + final long fileSize = inputChannel.size(); + long average = fileSize / fileCount;//平均值 + long bufferSize = 200; //缓存块大小,自行调整 + ByteBuffer byteBuffer = ByteBuffer.allocate(Integer.valueOf(bufferSize + "")); // 申请一个缓存区 + long startPosition = 0; //子文件开始位置 + long endPosition = average < bufferSize ? 0 : average - bufferSize;//子文件结束位置 + for (int i = 0; i < fileCount; i++) { + if (i + 1 != fileCount) { + int read = inputChannel.read(byteBuffer, endPosition);// 读取数据 + readW: + while (read != -1) { + byteBuffer.flip();//切换读模式 + byte[] array = byteBuffer.array(); + for (int j = 0; j < array.length; j++) { + byte b = array[j]; + if (b == 10 || b == 13) { //判断\n\r + endPosition += j; + break readW; + } + } + endPosition += bufferSize; + byteBuffer.clear(); //重置缓存块指针 + read = inputChannel.read(byteBuffer, endPosition); + } + }else{ + endPosition = fileSize; //最后一个文件直接指向文件末尾 + } + + FileOutputStream fos = new FileOutputStream("D:\\file\\split\\test" + (i+1) + ".txt"); + FileChannel outputChannel = fos.getChannel(); + inputChannel.transferTo(startPosition, endPosition - startPosition, outputChannel);//通道传输文件数据 + outputChannel.close(); + fos.close(); + startPosition = endPosition + 1; + endPosition += average; + } + inputChannel.close(); + fis.close(); + } + + public static boolean mergeFiles(String[] fpaths, String resultPath) { + if (fpaths == null || fpaths.length < 1) { + return false; + } + if (fpaths.length == 1) { + return new File(fpaths[0]).renameTo(new File(resultPath)); + } + + File[] files = new File[fpaths.length]; + for (int i = 0; i < fpaths.length; i ++) { + files[i] = new File(fpaths[i]); + if (!files[i].exists() || !files[i].isFile()) { + return false; + } + } + + File resultFile = new File(resultPath); + + try { + FileChannel resultFileChannel = new FileOutputStream(resultFile, true).getChannel(); + for (int i = 0; i < fpaths.length; i ++) { + FileChannel blk = new FileInputStream(files[i]).getChannel(); + resultFileChannel.transferFrom(blk, resultFileChannel.size(), blk.size()); + blk.close(); + } + resultFileChannel.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + return false; + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + for (int i = 0; i < fpaths.length; i ++) { + files[i].delete(); + } + return true; + } + + public static void main(String[] args) throws Exception { + + // 生成大文件 + + // 切割文件 +// long startTime = System.currentTimeMillis(); +// splitFile("D:\\file\\test.txt",2); +// long endTime = System.currentTimeMillis(); +// System.out.println("耗费时间: " + (endTime - startTime) + " ms"); + + // 合并文件 +// String[] fpaths = new String[2]; +// for (int i = 0; i < 2; i++) { +// fpaths[i] = "D:\\file\\split\\test" + (i+1) + ".txt"; +// } +// mergeFiles(fpaths, "D:\\file\\result\\result.txt"); + + // 判断两个文件中的内容 + String oldText = getFileContent("D:\\file\\\\test.txt"); + String newText = getFileContent("D:\\file\\result\\result.txt"); + System.out.println(oldText.equals(newText)); + + } + +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/SHA1/SplitorMergeFiles.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/SHA1/SplitorMergeFiles.java" new file mode 100644 index 0000000000000000000000000000000000000000..8737c9f51b6b972b8ce862c5da15010744c7b9f8 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/SHA1/SplitorMergeFiles.java" @@ -0,0 +1,219 @@ +package com.moxi.interview.study.SHA1; + +import java.io.*; +import java.security.MessageDigest; + +public class SplitorMergeFiles { + + public static void main(String[] args) throws IOException { + + String file = "D:\\file\\split\\test.txt"; + + // 创建大文件 + createBigFile(file); + System.out.println("创建大文件成功"); + + // 切割文件 + int count = 10; + getSplitFile(file, count); + System.out.println("切割文件成功"); + + // 合并文件 + // 合并后的文件 + String resultFile = "D:\\file\\split\\result.txt"; + // 合并前的文件 + String tempFile = "D:\\file\\split\\test.txt"; + merge(resultFile, tempFile, 10); + System.out.println("合并文件成功"); + + // 判断两个文件中的内容 + String oldText = getFileContent("D:\\file\\split\\result.txt"); + String newText = getFileContent("D:\\file\\split\\test.txt"); + System.out.println("获取文件内容"); + + // 文件进行sha1加密 + String shaOldText = getSha1(oldText); + String shaNewText = getSha1(newText); + System.out.println("对原始文件以及合并的文件进行sha1加密"); + + System.out.println("两个文件是否相同:" + shaOldText.equals(shaNewText)); + } + + /** + * 创建大文件 + * @throws IOException + */ + public static void createBigFile(String path) throws IOException { + File file = new File(path); + FileWriter fileWriter = new FileWriter(file); + BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); + String str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1"; + for (int i = 0; i < 100000; i++) { + bufferedWriter.write(str); + bufferedWriter.newLine(); + } + bufferedWriter.flush(); + bufferedWriter.close(); + } + + /** + * 切割文件 + * @param file + * @param count + */ + public static void getSplitFile(String file,int count){ + + //预分配文件所占用的磁盘空间,在磁盘创建一个指定大小的文件,“r”表示只读,“rw”支持随机读写 + try { + RandomAccessFile raf = new RandomAccessFile(new File(file), "r"); + //计算文件大小 + long length = raf.length(); + System.out.println(length); + //计算文件切片后每一份文件的大小 + long maxSize = length / count; + + System.out.println(maxSize); + + long offset = 0L;//定义初始文件的偏移量(读取进度) + //开始切割文件 + for(int i = 0; i < count - 1; i++){ //count-1最后一份文件不处理 + //标记初始化 + long fbegin = offset; + //分割第几份文件 + long fend = (i+1) * maxSize; + //写入文件 + offset = getWrite(file, i, fbegin, fend); + + } + + //剩余部分文件写入到最后一份(如果不能平平均分配的时候) + if (length - offset > 0) { + //写入文件 + getWrite(file, count-1, offset, length); + } + + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * 指定文件每一份的边界,写入不同文件中 + * @param index 源文件的顺序标识 + * @param end 结束指针的位置 + * @return long + */ + public static long getWrite(String filePath,int index,long begin,long end){ + + long endPointer = 0L; + try { + //申明文件切割后的文件磁盘 + File file = new File(filePath); + if (file.exists()) { + file.delete(); + } else { + file.createNewFile(); + } + + RandomAccessFile in = new RandomAccessFile(new File(filePath), "r"); + //定义一个可读,可写的文件并且后缀名为.tmp的二进制文件 + RandomAccessFile out = new RandomAccessFile(new File(filePath + "_" + index + ".tmp"), "rw"); + + //申明具体每一文件的字节数组 + byte[] b = new byte[1024]; + int n = 0; + //从指定位置读取文件字节流 + in.seek(begin); + //判断文件流读取的边界 + while(in.getFilePointer() <= end && (n = in.read(b)) != -1){ + //从指定每一份文件的范围,写入不同的文件 + out.write(b, 0, n); + } + + //定义当前读取文件的指针 + endPointer = in.getFilePointer(); + + //关闭输入流 + in.close(); + //关闭输出流 + out.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + return endPointer; + } + + /** + * 文件合并 + * @param file 指定合并文件 + * @param tempFile 分割前的文件名 + * @param tempCount 文件个数 + */ + public static void merge(String file,String tempFile,int tempCount) { + RandomAccessFile raf = null; + try { + //申明随机读取文件RandomAccessFile + raf = new RandomAccessFile(new File(file), "rw"); + //开始合并文件,对应切片的二进制文件 + for (int i = 0; i < tempCount; i++) { + //读取切片文件 + RandomAccessFile reader = new RandomAccessFile(new File(tempFile + "_" + i + ".tmp"), "r"); + byte[] b = new byte[1024]; + int n = 0; + while ((n = reader.read(b)) != -1) { + raf.write(b, 0, n);//一边读,一边写 + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + raf.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * 获取文件中的全部内容 + * @return + */ + public static String getFileContent(String path) { + File file = new File(path); + Long fileLengthLong = file.length(); + byte[] fileContent = new byte[fileLengthLong.intValue()]; + try { + FileInputStream inputStream = new FileInputStream(file); + inputStream.read(fileContent); + inputStream.close(); + } catch (Exception e) { + // TODO: handle exception + } + String string = new String(fileContent); + return string; + } + + public static String getSha1(String str) { + char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f' }; + try { + MessageDigest mdTemp = MessageDigest.getInstance("SHA1"); + mdTemp.update(str.getBytes("UTF-8")); + byte[] md = mdTemp.digest(); + int j = md.length; + char buf[] = new char[j * 2]; + int k = 0; + for (int i = 0; i < j; i++) { + byte byte0 = md[i]; + buf[k++] = hexDigits[byte0 >>> 4 & 0xf]; + buf[k++] = hexDigits[byte0 & 0xf]; + } + return new String(buf); + } catch (Exception e) { + return null; + } + } +} \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/ThreadLocal/MyDemo01.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/ThreadLocal/MyDemo01.java" new file mode 100644 index 0000000000000000000000000000000000000000..a063f4c21f1583fb762c9718c9356dbe7ba152aa --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/ThreadLocal/MyDemo01.java" @@ -0,0 +1,33 @@ +package com.moxi.interview.study.ThreadLocal; + +/** + * 需求:线程隔离 + * 在多线程并发的场景下,每个线程中的变量都是相互独立的 + * 线程A:设置变量1,获取变量2 + * 线程B:设置变量2,获取变量2 + * @author: 陌溪 + * @create: 2020-07-10-17:03 + */ +public class MyDemo01 { + // 变量 + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public static void main(String[] args) { + MyDemo01 myDemo01 = new MyDemo01(); + for (int i = 0; i < 5; i++) { + new Thread(() -> { + myDemo01.setContent(Thread.currentThread().getName() + "的数据"); + System.out.println("-----------------------------------------"); + System.out.println(Thread.currentThread().getName() + "\t " + myDemo01.getContent()); + }, String.valueOf(i)).start(); + } + } +} \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/ThreadLocal/MyDemo02.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/ThreadLocal/MyDemo02.java" new file mode 100644 index 0000000000000000000000000000000000000000..0a1aa34b572fffa885112298e929d8cc838cbb42 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/ThreadLocal/MyDemo02.java" @@ -0,0 +1,42 @@ +package com.moxi.interview.study.ThreadLocal; + +/** + * 需求:线程隔离 + * 在多线程并发的场景下,每个线程中的变量都是相互独立的 + * 线程A:设置变量1,获取变量2 + * 线程B:设置变量2,获取变量2 + * @author: 陌溪 + * @create: 2020-07-10-17:03 + */ +/** + * 需求:线程隔离 + * 在多线程并发的场景下,每个线程中的变量都是相互独立的 + * 线程A:设置变量1,获取变量2 + * 线程B:设置变量2,获取变量2 + * @author: 陌溪 + * @create: 2020-07-10-17:03 + */ +public class MyDemo02 { + // 变量 + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public static void main(String[] args) { + MyDemo01 myDemo01 = new MyDemo01(); + ThreadLocal threadLocal = new ThreadLocal<>(); + for (int i = 0; i < 5; i++) { + new Thread(() -> { + threadLocal.set(Thread.currentThread().getName() + "的数据"); + System.out.println("-----------------------------------------"); + System.out.println(Thread.currentThread().getName() + "\t " + threadLocal.get()); + }, String.valueOf(i)).start(); + } + } +} \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/ThreadLocal/MyDemo03.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/ThreadLocal/MyDemo03.java" new file mode 100644 index 0000000000000000000000000000000000000000..b8868afb46cb7a922f7007ef7832e22b3cd1feec --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/ThreadLocal/MyDemo03.java" @@ -0,0 +1,35 @@ +package com.moxi.interview.study.ThreadLocal; + +/** + * 需求:线程隔离 + * 在多线程并发的场景下,每个线程中的变量都是相互独立的 + * 线程A:设置变量1,获取变量2 + * 线程B:设置变量2,获取变量2 + * @author: 陌溪 + * @create: 2020-07-10-17:03 + */ +public class MyDemo03 { + // 变量 + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public static void main(String[] args) { + MyDemo03 myDemo01 = new MyDemo03(); + for (int i = 0; i < 5; i++) { + new Thread(() -> { + synchronized (MyDemo03.class) { + myDemo01.setContent(Thread.currentThread().getName() + "的数据"); + System.out.println("-----------------------------------------"); + System.out.println(Thread.currentThread().getName() + "\t " + myDemo01.getContent()); + } + }, String.valueOf(i)).start(); + } + } +} \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/annotation/ClassLoaderDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/annotation/ClassLoaderDemo.java" index bd2f9ac143930001959e152e90a683511b8dc44b..5740925a788a48a119527d38a655ce596488614c 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/annotation/ClassLoaderDemo.java" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/annotation/ClassLoaderDemo.java" @@ -56,6 +56,6 @@ public class ClassLoaderDemo { System.out.println("==============="); // 数组类引用,不会初始化 - List list = new ArrayList<>(); + List list = new ArrayList(); } } diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/byteDance/CheckInclusion.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/byteDance/CheckInclusion.java" new file mode 100644 index 0000000000000000000000000000000000000000..aa8e6ca062af78db734ebc54fcf4ea7a381bb2df --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/byteDance/CheckInclusion.java" @@ -0,0 +1,78 @@ +package com.moxi.interview.study.byteDance; + +import java.util.HashSet; +import java.util.Set; + +/** + * 字符串的排列 + * + * 给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。 + * + * 换句话说,第一个字符串的排列之一是第二个字符串的子串。 + * + * 示例1: + * + * 输入: s1 = "ab" s2 = "eidbaooo" + * 输出: True + * 解释: s2 包含 s1 的排列之一 ("ba"). + * + * + * 示例2: + * + * 输入: s1= "ab" s2 = "eidboaoo" + * 输出: False + * + * + * 注意: + * + * 输入的字符串只包含小写字母 + * 两个字符串的长度都在 [1, 10,000] 之间 + * + * @author: 陌溪 + * @create: 2020-06-17-19:10 + */ +public class CheckInclusion { + + public static Set RollList(String str, int i){ + Set set = new HashSet<>(); + if (i>=(str.length()-1)) { + set.add(str); + return set; + } + char[] charArray = str.toCharArray(); + String now = ""; + //将第i个元素开始,与后面所有元素都换一次,就能得到所有组合 + //例如,abc,i=0,表示,第一个元素从0开始换,得到abc,bac,cba的组合,然后再去算bc,ac,ba的所有组合 + for (int k=i; k set = RollList(s1, 0); + for (String str : set) { + if(s2.indexOf(str) > -1) { + return true; + } + } + return false; + } + + + public static void main(String[] args) { +// System.out.println(checkInclusion("ab", "eidbaooo")); + Set set = RollList("abc", 0); + for (String str: set){ + System.out.println(str); + } + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/byteDance/EngthOfLongestSubstring.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/byteDance/EngthOfLongestSubstring.java" new file mode 100644 index 0000000000000000000000000000000000000000..57298d55ea196e5b42b493549ad10b56c8b36f0c --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/byteDance/EngthOfLongestSubstring.java" @@ -0,0 +1,46 @@ +package com.moxi.interview.study.byteDance; + +/** + * 无重复字符的最长子串 + * lengthOfLongestSubstring + * + * 输入: "abcabcbb" + * 输出: 3 + * 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 + * + * 输入: "bbbbb" + * 输出: 1 + * 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 + * + * 输入: "pwwkew" + * 输出: 3 + * 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 + * 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。 + * + * @author: 陌溪 + * @create: 2020-06-17-18:35 + */ +public class EngthOfLongestSubstring { + public static int lengthOfLongestSubstring(String s) { + char [] chars = s.toCharArray(); + int maxLength = 0; + for (int a=0; a -1) { + break; + } + tempStr += chars[b]; + if(tempStr.length() > maxLength) { + maxLength = tempStr.length(); + } + } + } + return maxLength; + } + + public static void main(String[] args) { + String str= "abcabcbb"; + System.out.println(lengthOfLongestSubstring(str)); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/byteDance/LongestCommonPrefix.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/byteDance/LongestCommonPrefix.java" new file mode 100644 index 0000000000000000000000000000000000000000..4ead0010849384f723d6064e56feb2436ca8189c --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/byteDance/LongestCommonPrefix.java" @@ -0,0 +1,69 @@ +package com.moxi.interview.study.byteDance; + +/** + * 最长公共前缀 + * + * 编写一个函数来查找字符串数组中的最长公共前缀。 + * 如果不存在公共前缀,返回空字符串 ""。 + * + * 示例 1: + * + * 输入: ["flower","flow","flight"] + * 输出: "fl" + * 示例 2: + * + * 输入: ["dog","racecar","car"] + * 输出: "" + * 解释: 输入不存在公共前缀。 + * 说明: + * + * 所有输入只包含小写字母 a-z 。 + * @author: 陌溪 + * @create: 2020-06-17-18:45 + */ +public class LongestCommonPrefix { + public static String longestCommonPrefix(String[] strs) { + if(strs.length == 0) { + return ""; + } + if(strs.length == 1) { + return strs[0]; + } + char [] pred = strs[0].toCharArray(); + if(pred.length == 0) { + return ""; + } + int count = 0; + while(true) { + int successCount = 0; + for(int a=0; a res = new ArrayList<>(); + + dfs(charArr, len, 0, used, path, res); + + // 记得转成字符串数组 + return res.toArray(new String[0]); + } + + /** + * @param charArr 字符数组 + * @param len 字符数组的长度 + * @param depth 当前递归深度 + * @param used 当前字符是否使用 + * @param path 从根结点到叶子结点的路径 + * @param res 保存结果集的变量 + */ + private void dfs(char[] charArr, + int len, + int depth, + boolean[] used, + StringBuilder path, + List res) { + if (depth == len) { + // path.toString() 恰好生成了新的字符对象 + res.add(path.toString()); + return; + } + for (int i = 0; i < len; i++) { + if (!used[i]) { + if (i > 0 && charArr[i] == charArr[i - 1] && !used[i - 1]) { + continue; + } + used[i] = true; + path.append(charArr[i]); + + dfs(charArr, len, depth + 1, used, path, res); + + // 递归完成以后,需要撤销选择,递归方法执行之前做了什么,递归方法执行以后就需要做相应的逆向操作 + path.deleteCharAt(path.length() - 1); + used[i] = false; + } + } + } + + public static void main(String[] args) { + Permutation solution = new Permutation(); + String[] res = solution.permutation("aba"); + System.out.println(Arrays.toString(res)); + System.out.println(); + } + +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/byteDance/strToInt.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/byteDance/strToInt.java" new file mode 100644 index 0000000000000000000000000000000000000000..d000f8d61f45b801f501ca7aba96101b7584bd5a --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/byteDance/strToInt.java" @@ -0,0 +1,31 @@ +package com.moxi.interview.study.byteDance; + +/** + * @author: 陌溪 + * @create: 2020-06-24-16:49 + */ +public class strToInt { + public static int StrToInt(String str) { + if(str == null || str.length() ==0) { + return 0; + } + // 判断是否是负数 + boolean start = str.charAt(0) == '-'; + int ret = 0; + for(int a=0; a '9') { + return 0; + } + ret = ret * 10 + (ch - '0'); + } + return ret; + } + + public static void main(String[] args) { + System.out.println(StrToInt("123")); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/dataStructure/DynamicProgramming.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/dataStructure/DynamicProgramming.java" new file mode 100644 index 0000000000000000000000000000000000000000..9136503e030d60d1f6c2dfb94d8084b24fe76f56 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/dataStructure/DynamicProgramming.java" @@ -0,0 +1,92 @@ +package com.moxi.interview.study.dataStructure; + +/** + * 动态规划 + * 解决 0-1背包问题 + * + * @author: 陌溪 + * @create: 2020-04-18-15:00 + */ +public class DynamicProgramming { + public static void main(String[] args) { + // 物品的重量 + int w [] = {1, 4, 3}; + + // 物品的价值 + int val [] = {1500, 3000, 2000}; + + // 背包的容量 + int m = 4; + + // 物品的个数 + int n = val.length; + + // 创建二维数组 v[i][j] 表示在前i个物品中,可以装入容量为j的背包中的商品最大值 + int [][] v = new int[n+1][m+1]; + + // 为了记录放入商品的情况,我们定义一个二维数组 + int [][] path = new int[n+1][m+1]; + + // 初始化第一行 和 第一列,这里在本程序中可以不去处理,因为数组默认就是0 + for(int i = 0; i j) { + v[i][j] = v[i-1][j]; + } else { + // 因为我们的i从1开始的,因此公式需要调整成 i -> i-1 +// v[i][j] = Math.max(v[i-1][j], val[i-1] + v[i-1][j - w[i -1]]); + + // 为了记录商品存放的背包的情况,我们不能直接的使用上面的公式,需要使用if else来体现公式 + if(v[i-1][j] < (val[i-1] + v[i-1][j - w[i -1]])) { + v[i][j] = (val[i-1] + v[i-1][j - w[i -1]]); + // 把当前的情况记录到path + path[i][j] = 1; + } else { + v[i][j] = v[i-1][j]; + } + } + } + } + + // 输出一下 + for(int i = 0; i< v.length; i++) { + for(int j = 0; j 0 && j>0) { + if(path[i][j] == 1) { + System.out.print(i + " "); + j -= w[i-1]; + } + // 找到一个 i需要减1 + i --; + } + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/dataStructure/KMP.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/dataStructure/KMP.java" new file mode 100644 index 0000000000000000000000000000000000000000..681ab064b4eb4583ad045d317d8ff3efcbd6c7f8 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/dataStructure/KMP.java" @@ -0,0 +1,11 @@ +package com.moxi.interview.study.dataStructure; + +/** + * 字符串匹配问题 + * + * @author: 陌溪 + * @create: 2020-04-18-19:09 + */ +public class KMP { + +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/hashMap/HashMapTest.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/hashMap/HashMapTest.java" new file mode 100644 index 0000000000000000000000000000000000000000..6991730457e94a252eb9950c4fb604cc593c71b0 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/hashMap/HashMapTest.java" @@ -0,0 +1,25 @@ +package com.moxi.interview.study.hashMap; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * JDK7中的HashMap + * + * @author: 陌溪 + * @create: 2020-06-05-21:08 + */ +public class HashMapTest { + public static void main(String[] args) { + + // 数组+链表 + Map map = new HashMap<>(); + map.put("123", "123"); + System.out.println(map.get("123")); + + List arrayList = new ArrayList<>(); + arrayList.add(1, 10); + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/nio/TestSocket.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/nio/TestSocket.java" new file mode 100644 index 0000000000000000000000000000000000000000..5a6ca2739190dcc8e83feb22a3af06c56b606ae9 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/nio/TestSocket.java" @@ -0,0 +1,35 @@ +package com.moxi.interview.study.nio; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * 服务器读取文件 + * @author: 陌溪 + * @create: 2020-07-01-20:40 + */ +public class TestSocket { + public static void main(String[] args) throws IOException { + ServerSocket server = new ServerSocket(8090); + System.out.println("step1: new ServerSocket(8090)"); + while(true) { + Socket client = server.accept(); + System.out.println("step2: client " + client.getPort()); + new Thread(() -> { + try { + InputStream in = client.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + while(true) { + System.out.println(reader.readLine()); + } + } catch (IOException e) { + e.printStackTrace(); + } + }, "t1").start(); + } + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/nowCode/ShellSort_1.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/nowCode/ShellSort_1.java" new file mode 100644 index 0000000000000000000000000000000000000000..b123258274fd56ec4b2a60308f27d396f53291f3 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/nowCode/ShellSort_1.java" @@ -0,0 +1,38 @@ +package com.moxi.interview.study.nowCode; + +/** + * 希尔排序 + * + * @author: 陌溪 + * @create: 2020-06-25-10:43 + */ +public class ShellSort_1 { + public static int[] shellSort(int[] arrList) { + int arrLen = arrList.length; + int h = 1; + while (h > arrLen /3){ + h = h*3 + 1; + } + + while(h >=1) { + for (int i = h; i < arrLen; i++) { + int j = i; + while(j >=h && arrList[j] < arrList[j - h]) { + int temp = arrList[j]; + arrList[j] = arrList[j-h]; + arrList[j-h] = temp; + j -= h; + } + } + h /= 3; + } + return arrList; + } + public static void main(String[] args) { + int [] arrList = new int[]{1,8,3,2,6,9}; + int [] resultList = shellSort(arrList); + for (int a=0; a { + System.out.println(snowFlakeDemo.snowflakeId()); + }, String.valueOf(i)).start(); + } + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/thread/ThreadPoolDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/thread/ThreadPoolDemo.java" new file mode 100644 index 0000000000000000000000000000000000000000..92c93899566591583d52fe60315dc65ef205742e --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/src/main/java/com/moxi/interview/study/thread/ThreadPoolDemo.java" @@ -0,0 +1,32 @@ +package com.moxi.interview.study.thread; + +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * @author: 陌溪 + * @create: 2020-06-04-14:42 + */ +public class ThreadPoolDemo { + public static void main(String[] args) { + // 一池5个处理线程(用池化技术,一定要记得关闭) + ExecutorService threadPool = Executors.newFixedThreadPool(3); + CopyOnWriteArrayList copyOnWriteArrayList = new CopyOnWriteArrayList(); + CopyOnWriteArrayList copyOnWriteArrayList2 = new CopyOnWriteArrayList(); + for (int i = 1; i <= 16; i++) { + copyOnWriteArrayList.add(i); + } + while(copyOnWriteArrayList.size() > 0) { + threadPool.execute(() -> { + Integer temp = copyOnWriteArrayList.get(0); + System.out.println(Thread.currentThread().getName() + "\t" + temp); + copyOnWriteArrayList2.add(temp); + copyOnWriteArrayList.remove(0); + }); + } + for (int i = 0; i < 15; i++) { + System.out.print(copyOnWriteArrayList2.get(i) + " "); + } + } +} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/SchoolInterview-1.0-SNAPSHOT.jar" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/SchoolInterview-1.0-SNAPSHOT.jar" deleted file mode 100644 index b608a09fe955cd6f3c4793a1259199226d494e00..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/SchoolInterview-1.0-SNAPSHOT.jar" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/META-INF/SchoolInterview.kotlin_module" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/META-INF/SchoolInterview.kotlin_module" deleted file mode 100644 index a49347afef10a9b5f95305e1058ba36adec7d6dd..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/META-INF/SchoolInterview.kotlin_module" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/GC/G1Demo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/GC/G1Demo.class" deleted file mode 100644 index c357a93f5a7ec443ab153ce421f88c183a71b685..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/GC/G1Demo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/GC/GCRootDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/GC/GCRootDemo.class" deleted file mode 100644 index 576d28c6d1dcf0b4f242b430e3e98cbcfec3c022..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/GC/GCRootDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/GC/HelloGC.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/GC/HelloGC.class" deleted file mode 100644 index 0486d2f341c1ab01564267fd082dea022fd8880e..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/GC/HelloGC.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/Lock/DeadLockDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/Lock/DeadLockDemo.class" deleted file mode 100644 index 0ca172d58bcd0ba3ffd076295f5a4fe65b4b3d5d..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/Lock/DeadLockDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/Lock/HoldLockThread.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/Lock/HoldLockThread.class" deleted file mode 100644 index ff15e285fe2aac379df3d7ed94a339c040eb8289..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/Lock/HoldLockThread.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/A.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/A.class" deleted file mode 100644 index 525c3287797d293f5e91bacf2f4a3a6a83fb34ba..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/A.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/AnnotationDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/AnnotationDemo.class" deleted file mode 100644 index 9c537efb1fe9fb2b11991665b2b586b9a9485213..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/AnnotationDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ClassCreateDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ClassCreateDemo.class" deleted file mode 100644 index 1d604164ead880d4f924d808396d43a22ef04353..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ClassCreateDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ClassLoaderDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ClassLoaderDemo.class" deleted file mode 100644 index f8e86d26b30daa5e46ca42a1b83d2edba3f93a80..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ClassLoaderDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ClassLoaderTypeDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ClassLoaderTypeDemo.class" deleted file mode 100644 index 4a58a78a7cf533f0c7a3adf5d586c774215f4d22..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ClassLoaderTypeDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/FieldKuang.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/FieldKuang.class" deleted file mode 100644 index a32e43e0fee2f7d462dd91ae7d7cfa26d4d0bb54..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/FieldKuang.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/GenericityDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/GenericityDemo.class" deleted file mode 100644 index 8ef5d1cfe29d371b46dd35a40c3cc62e1eb15602..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/GenericityDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/GetClassDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/GetClassDemo.class" deleted file mode 100644 index d4001a1d08dbe65bc91432813502a0cf71c9e0f4..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/GetClassDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/GetClassInfo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/GetClassInfo.class" deleted file mode 100644 index ab318463dcd4a7fd014494ea31e36a65dc83927c..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/GetClassInfo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/GetObjectByReflectionDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/GetObjectByReflectionDemo.class" deleted file mode 100644 index 995a594e9b78b9ee4e760d1c4b4a6fc8a9806745..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/GetObjectByReflectionDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/MateAnnotationDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/MateAnnotationDemo.class" deleted file mode 100644 index c7193b251357bbd482bb74eee11696b2bb6ff3cf..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/MateAnnotationDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/MyAnnotation.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/MyAnnotation.class" deleted file mode 100644 index 1cfc2923605a6b9a84fa5e5387c5189cae86971f..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/MyAnnotation.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ORMDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ORMDemo.class" deleted file mode 100644 index 50b65ea735792453ac8668a15c5e64329c14ff25..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ORMDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/Person.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/Person.class" deleted file mode 100644 index b499979454003878e04c70bbb83ec616789680ce..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/Person.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ReflectionDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ReflectionDemo.class" deleted file mode 100644 index c9e3ba89e6f639b1f6f666b9feb6bbb06f10ce88..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ReflectionDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ReflectionPerformance.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ReflectionPerformance.class" deleted file mode 100644 index 75529eaad3e3aef545c5bcc9f372569c5c8e7100..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/ReflectionPerformance.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/Student.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/Student.class" deleted file mode 100644 index c22b904fd19b7055bc343a374f5569afe75315d1..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/Student.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/Student2.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/Student2.class" deleted file mode 100644 index eb1a52aec8d666e146526ab1ba7abc35a393f0dd..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/Student2.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/SuperA.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/SuperA.class" deleted file mode 100644 index cb7ceaa8f4cd3bda3d682a0e43ae82139688ec25..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/SuperA.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/TableKuang.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/TableKuang.class" deleted file mode 100644 index 2da5afa245d433c4707086bf4f5dc9203972aca4..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/TableKuang.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/Teacher.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/Teacher.class" deleted file mode 100644 index 6de8be4d63855ad510199031d04416bad88381af..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/Teacher.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/User.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/User.class" deleted file mode 100644 index eb309be11907b301961f7ae8673aef6979ff9de6..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/annotation/User.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/Client.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/Client.class" deleted file mode 100644 index 19a1719f9296c6fcea65e7c7fa311195a68b8834..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/Client.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/Code.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/Code.class" deleted file mode 100644 index a952b3ce070d3c44453364f259032cf4201b7b9b..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/Code.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/CodeBlock.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/CodeBlock.class" deleted file mode 100644 index eee9c1c405ff0a3767c4362f641176aafbb9ee06..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/CodeBlock.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/CodeBlock02.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/CodeBlock02.class" deleted file mode 100644 index 298fd1b6a271f2671e788e07bdcb8f14054a715e..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/CodeBlock02.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/CodeBlock03.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/CodeBlock03.class" deleted file mode 100644 index 813c0adbdb7fad98cc21b9491f1668443cc7d84f..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/CodeBlock03.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/CodeBlock04.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/CodeBlock04.class" deleted file mode 100644 index 519345e2775ef7b3687fd6e8a6c43b12c77f8321..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/CodeBlock04.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/EqualsDemo$Person.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/EqualsDemo$Person.class" deleted file mode 100644 index 0bd1eb846313d29385fecd2c1bf99c27c9d7af35..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/EqualsDemo$Person.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/EqualsDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/EqualsDemo.class" deleted file mode 100644 index fececc977396552af78de71af5da77f9bf0fba37..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/EqualsDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/Father.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/Father.class" deleted file mode 100644 index 864c47ecb0901becac7e363fddf3dca9a256fa94..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/Father.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/OrderNumberCreateUtil.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/OrderNumberCreateUtil.class" deleted file mode 100644 index 5411016275a37ca6898c39251e9fc526b0d949de..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/OrderNumberCreateUtil.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/OrderService.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/OrderService.class" deleted file mode 100644 index 73118d2f08d3ec5aae078e538a3de3a548730376..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/OrderService.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/Son.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/Son.class" deleted file mode 100644 index b2ae1981513900df91b9af848c147e395bb2ca35..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/Son.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/ZkAbstractTemplateLock.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/ZkAbstractTemplateLock.class" deleted file mode 100644 index 8a707f567de80a6cbaf2acda0d0f702204e8ff23..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/ZkAbstractTemplateLock.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/ZkDistributedLock.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/ZkDistributedLock.class" deleted file mode 100644 index 588c5f52d5e72528132d2044ca46298d756d9fdb..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/ZkDistributedLock.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/ZkLock.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/ZkLock.class" deleted file mode 100644 index 7d832d51570755d2c806f356c0aeb22ad2a66e2c..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/basic/ZkLock.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/Employee.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/Employee.class" deleted file mode 100644 index 8e443f3f2af4907e726a284a832726387adc9617..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/Employee.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/FilterEmployeeByAge.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/FilterEmployeeByAge.class" deleted file mode 100644 index 0a9b0319582d7519151301c0dd09d5a7c7aefa53..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/FilterEmployeeByAge.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/FilterEmployeeBySalary.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/FilterEmployeeBySalary.class" deleted file mode 100644 index 8f8638728e214dd598a6408ba8a3f70fdf26cbbe..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/FilterEmployeeBySalary.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaCoreDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaCoreDemo.class" deleted file mode 100644 index 0e283cda88976c29f03470943f1e84750f5b7506..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaCoreDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaDemo$1.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaDemo$1.class" deleted file mode 100644 index a645624a2e19a8fe84306f0dbab36aacb0b2e8be..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaDemo$1.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaDemo$2.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaDemo$2.class" deleted file mode 100644 index 80eb26e100d045bc64c0d217c1ceda31f7f3d8e9..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaDemo$2.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaDemo.class" deleted file mode 100644 index 8b0788f53beabbeb9c6a7fb77da023e26ab430d6..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaTest$1.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaTest$1.class" deleted file mode 100644 index 6f56b539909090dd3dbca661723eecb436914d73..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaTest$1.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaTest.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaTest.class" deleted file mode 100644 index d93bc4717d730c7ffa2da13fc109aeeaaca7489a..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaTest.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaTest2.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaTest2.class" deleted file mode 100644 index a1b1a529b5360096c7a35e4b7322d2c2ae11e2a3..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/LambdaTest2.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/MyFun.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/MyFun.class" deleted file mode 100644 index c230c950057627f41b7f6d59f292bb6de6e6006f..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/MyFun.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/MyPredicte.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/MyPredicte.class" deleted file mode 100644 index 6f6254ca0007d2745077c1f25b5075bf4733d25e..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/lambda/MyPredicte.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/optional/OptionalDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/optional/OptionalDemo.class" deleted file mode 100644 index e76915d5e697fce04aa9bab30a772ae52d9ab97f..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/optional/OptionalDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/parallel/ForkJoinCalculate.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/parallel/ForkJoinCalculate.class" deleted file mode 100644 index b188dccec2f468e3d4891e77583b875ef4759810..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/parallel/ForkJoinCalculate.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/parallel/ParallelDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/parallel/ParallelDemo.class" deleted file mode 100644 index c18d62f2d511218c860e801cafb1a2f693d7e5ea..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/parallel/ParallelDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/ref/ArrayReferenceDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/ref/ArrayReferenceDemo.class" deleted file mode 100644 index 5f1e8d72194341a518bcc52b496f10d6da589eee..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/ref/ArrayReferenceDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/ref/ConstructorReferenceDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/ref/ConstructorReferenceDemo.class" deleted file mode 100644 index 13656544674a026d858461aedc94f86b4cd744ef..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/ref/ConstructorReferenceDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/ref/MethodReferenceDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/ref/MethodReferenceDemo.class" deleted file mode 100644 index 971e829a22389b3db960dec5b1cdcbaa820108ca..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/ref/MethodReferenceDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/stream/StreamAPiDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/stream/StreamAPiDemo.class" deleted file mode 100644 index e13e05281a96304a93b3db542e7abe8d18736a59..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/java8/stream/StreamAPiDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo1.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo1.class" deleted file mode 100644 index ad09ce305f9c100001c1ef5793829b4a6cdccd20..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo1.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo2.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo2.class" deleted file mode 100644 index c93fda03f2e1077c32ade9c91eeb3874b8466aa9..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo2.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo3.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo3.class" deleted file mode 100644 index cafdd32e1d29fab46d6527291a47bb597610d003..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo3.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo4.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo4.class" deleted file mode 100644 index 5f4c6e21fc773f6596d826522d58613baeda1969..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo4.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo5.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo5.class" deleted file mode 100644 index dd307cb9ba091c70923ca4567568b5d28e81bb94..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo5.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo6.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo6.class" deleted file mode 100644 index 20411bc0115a0b6f638e11fd6c9ca51365159b26..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/lq/Demo6.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/newNio/QQClient.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/newNio/QQClient.class" deleted file mode 100644 index d03fe4a231e88c1ae4d8bb14d9ea7ed7129e9c04..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/newNio/QQClient.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/newNio/QQServer.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/newNio/QQServer.class" deleted file mode 100644 index ba8a228af705af449b50f1cfc45f3378f511e478..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/newNio/QQServer.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/newNio/QQServerByNIO.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/newNio/QQServerByNIO.class" deleted file mode 100644 index 8c3864cb4543d339fcd0dc7eff5b9493b26f2db4..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/newNio/QQServerByNIO.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/newNio/QQServerByOneThread.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/newNio/QQServerByOneThread.class" deleted file mode 100644 index 734fa6c82acfafb81173ac1b777afc0c7a60ed71..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/newNio/QQServerByOneThread.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/BufferDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/BufferDemo.class" deleted file mode 100644 index 305ef43e403d292719d984e0f316563aa16d9c89..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/BufferDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/ChannelCharsetDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/ChannelCharsetDemo.class" deleted file mode 100644 index 10af0dd0eacd1fb42571c3b1cf498da0ca6986c1..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/ChannelCharsetDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/ChatClientDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/ChatClientDemo.class" deleted file mode 100644 index 59c5d76ac3c692decea62757b5f19f4056ff11d8..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/ChatClientDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/ChatServerDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/ChatServerDemo.class" deleted file mode 100644 index 9a80c3f8e33df89dfb9b13d5e6f318745bf5fa44..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/ChatServerDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/FileCopyByChannelDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/FileCopyByChannelDemo.class" deleted file mode 100644 index 7fdd411ca83a3c2594c468d6e1a83f10c85b38eb..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/FileCopyByChannelDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/FileCopyByDirectDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/FileCopyByDirectDemo.class" deleted file mode 100644 index de5abfadbf86df01e6cf8e9d17c715f6c2c06271..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/FileCopyByDirectDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/FileCopyDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/FileCopyDemo.class" deleted file mode 100644 index 3fa5ef1717a6767bfc1e5701d79d24c09662a68a..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/FileCopyDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/PipeDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/PipeDemo.class" deleted file mode 100644 index d0fa560d5d0e52196d0deca2ae672a808130ef94..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/PipeDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/ScatterAndGatherDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/ScatterAndGatherDemo.class" deleted file mode 100644 index 79db39f6235d9854b9e32fd457c2a964161159b2..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/ScatterAndGatherDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/TestBlockingDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/TestBlockingDemo.class" deleted file mode 100644 index dc753fa981b12d84b4a9b35f3fe26d1b65af7447..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/TestBlockingDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/TestNonBlockingNIODemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/TestNonBlockingNIODemo.class" deleted file mode 100644 index 9cc01e4a3c879c4e72f63a70f7f763887c7f1d92..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/nio/TestNonBlockingNIODemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/DIrectBufferMemoryDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/DIrectBufferMemoryDemo.class" deleted file mode 100644 index b10678205d78bebe8a9a75b2626d5e5515454461..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/DIrectBufferMemoryDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/GCOverheadLimitDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/GCOverheadLimitDemo.class" deleted file mode 100644 index d18d13fbb8176d3db50c3c4f0eec6b443ac6d905..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/GCOverheadLimitDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/JavaHeapSpaceDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/JavaHeapSpaceDemo.class" deleted file mode 100644 index 5f537b6db0c4144b00b9e200e0c6b3a112965dc2..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/JavaHeapSpaceDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/MetaspaceOutOfMemoryDemo$1.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/MetaspaceOutOfMemoryDemo$1.class" deleted file mode 100644 index eb95a2fec4b4ba2be0a2fdfe43f052dff0acbb26..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/MetaspaceOutOfMemoryDemo$1.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/MetaspaceOutOfMemoryDemo$OOMTest.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/MetaspaceOutOfMemoryDemo$OOMTest.class" deleted file mode 100644 index c01968e850f1a0c522cb574ae9dea48257cb9c1f..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/MetaspaceOutOfMemoryDemo$OOMTest.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/MetaspaceOutOfMemoryDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/MetaspaceOutOfMemoryDemo.class" deleted file mode 100644 index c69dce24e4e4dd0ef9fad4b066795b503387b112..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/MetaspaceOutOfMemoryDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/StackOverflowErrorDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/StackOverflowErrorDemo.class" deleted file mode 100644 index c2f7b543c6571c3664c613c4ef620b647172a85e..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/StackOverflowErrorDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/UnableCreateNewThreadDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/UnableCreateNewThreadDemo.class" deleted file mode 100644 index 8774df64b3fa6246e3da63b747a17670be13d1ca..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/oom/UnableCreateNewThreadDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/BlockingQueueDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/BlockingQueueDemo.class" deleted file mode 100644 index f8d4ad4a1c8c49530faf0fb52680a167d2e525b2..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/BlockingQueueDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/MyResource.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/MyResource.class" deleted file mode 100644 index 8a60a8479f0453a4d8f6db36643fe7e77ea859bd..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/MyResource.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/ProdConsumerBlockingQueueDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/ProdConsumerBlockingQueueDemo.class" deleted file mode 100644 index 34017990e414d85b11f558157e17b579aa85587a..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/ProdConsumerBlockingQueueDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/ProdConsumerTraditionDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/ProdConsumerTraditionDemo.class" deleted file mode 100644 index 2855ba3296c9bf9a795b00c9c3275eaee994305f..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/ProdConsumerTraditionDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/ShareData.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/ShareData.class" deleted file mode 100644 index aeb2ae2a0e1543aea49cd8d5efc365d7e68fe656..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/ShareData.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/SynchronousQueueDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/SynchronousQueueDemo.class" deleted file mode 100644 index 9b95bbd6d102f5f80de883a08055701705dd5a99..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/queue/SynchronousQueueDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/PhantomReferenceDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/PhantomReferenceDemo.class" deleted file mode 100644 index a80c91ecdcca518391dfc4ed7a4f3a9abb4dd11e..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/PhantomReferenceDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/SoftReferenceDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/SoftReferenceDemo.class" deleted file mode 100644 index 533d95f04226e6372868d83caf1b7c0f6a986232..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/SoftReferenceDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/StrongReferenceDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/StrongReferenceDemo.class" deleted file mode 100644 index 654eb06c83f49be99f3ae52f3924c45aa0641124..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/StrongReferenceDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/WeakHashMapDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/WeakHashMapDemo.class" deleted file mode 100644 index be06224b0338728f1686a218c935f3a4f82c5f5b..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/WeakHashMapDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/WeakReferenceDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/WeakReferenceDemo.class" deleted file mode 100644 index 30d1d5b2f2351a66f3a745a0b86281c4ed087d42..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/ref/WeakReferenceDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/AppConfig.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/AppConfig.class" deleted file mode 100644 index bfc07e17548d75a4fb8aba49d7fddd5304e97526..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/AppConfig.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/BeanCity.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/BeanCity.class" deleted file mode 100644 index 2f0eae9db8cb8d2ed7d8efb54d17b4bf03d08a52..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/BeanCity.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/BeanTest.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/BeanTest.class" deleted file mode 100644 index 51649728ef871a8609dd339252a210ebb3dfbff7..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/BeanTest.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/Test.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/Test.class" deleted file mode 100644 index 0208e2aec2123dd3dfe67efbea2d6d76d5a9013d..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/Test.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/TestBeanFactoryPostProcessor.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/TestBeanFactoryPostProcessor.class" deleted file mode 100644 index 021514c5d4c26552acb332f3ffcc12c054dd8296..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/spring/TestBeanFactoryPostProcessor.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ABADemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ABADemo.class" deleted file mode 100644 index 897f9ae844a8c737168049d70a0d7cf357680641..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ABADemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ArrayListNotSafeDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ArrayListNotSafeDemo.class" deleted file mode 100644 index df5d3c53060b439b3fba28cb993099202891233d..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ArrayListNotSafeDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/AtomicReferenceDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/AtomicReferenceDemo.class" deleted file mode 100644 index 784050fe878369861dc1770771f8a708c931160b..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/AtomicReferenceDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CASDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CASDemo.class" deleted file mode 100644 index b10942d51a3b90ba2bbc4cd8298b51b25af0f05e..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CASDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CallableDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CallableDemo.class" deleted file mode 100644 index e3aaf0db7952b195482c0f1059ff1b74a098cae5..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CallableDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CountDownLatchDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CountDownLatchDemo.class" deleted file mode 100644 index 5c8e4089687c9229a83161f3be939efc061981e1..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CountDownLatchDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CountryEnum.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CountryEnum.class" deleted file mode 100644 index 48dce67685c26d0bca79d3302d77e0bbf3d7aaee..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CountryEnum.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CyclicBarrierDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CyclicBarrierDemo.class" deleted file mode 100644 index d0f8f38a22b69239d34ad7603dd2352e15a5588e..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/CyclicBarrierDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyCache.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyCache.class" deleted file mode 100644 index 824cb98812f9c8924267e687025bbcc2acc87f7a..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyCache.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyData.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyData.class" deleted file mode 100644 index 72b8574dcb761bbfe872c3fe1a21f121944be308..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyData.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyThread.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyThread.class" deleted file mode 100644 index d3236690eade9522b0253c3656d46b49c2f21396..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyThread.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyThread2.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyThread2.class" deleted file mode 100644 index 457e0e0a654f11d61b0e4acd3ebe0d2f6b95dc9a..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyThread2.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyThreadPoolDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyThreadPoolDemo.class" deleted file mode 100644 index 1d88ed83008673c4d293d701d11e8356c76ef28d..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/MyThreadPoolDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/Person.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/Person.class" deleted file mode 100644 index 5a762d4b0240f2b733d97bf2bcc1f0463abd8b02..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/Person.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/Phone.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/Phone.class" deleted file mode 100644 index 413cb8b480f2b323ff4649f23d9c4b7f68f20f43..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/Phone.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ReadWriteLockDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ReadWriteLockDemo.class" deleted file mode 100644 index a98116f1e4bc1d51794087c94df0952dcdd686e2..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ReadWriteLockDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ReenterLockDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ReenterLockDemo.class" deleted file mode 100644 index d5b933a8a86bfad6595ecdd2572206cbfbfa4420..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ReenterLockDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ResortSeqDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ResortSeqDemo.class" deleted file mode 100644 index d8d85a1f147860de8b035df758d634a857dce09a..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ResortSeqDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SemaphoreDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SemaphoreDemo.class" deleted file mode 100644 index a8a1af102a02bf0292619bb4f9ed18db95a19646..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SemaphoreDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SequenceThread.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SequenceThread.class" deleted file mode 100644 index 710df224ecb51f726534f1a20ee2efb9735ac195..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SequenceThread.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ShareResource.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ShareResource.class" deleted file mode 100644 index 2f3bf6d7d55c143060f805bca823d6c7d92de728..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/ShareResource.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SingletonDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SingletonDemo.class" deleted file mode 100644 index fc809e6f521d51df7151f26289269f0e6152c042..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SingletonDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SpinLockDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SpinLockDemo.class" deleted file mode 100644 index 24e32487f966061afdff7e31aa712ee2c876bd28..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SpinLockDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SyncAndReentrantLockDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SyncAndReentrantLockDemo.class" deleted file mode 100644 index d48fc89ed44eed8410e4f70b04cfd6164e693bbe..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/SyncAndReentrantLockDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/T1.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/T1.class" deleted file mode 100644 index 0f1c547a0d2069a533019ea6aae95d268170fe13..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/T1.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/TransferValueDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/TransferValueDemo.class" deleted file mode 100644 index 3f8084f4877945889b656459a66488e43090fee9..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/TransferValueDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/User.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/User.class" deleted file mode 100644 index 64f542d8e7ee634564c295da80b1a3841f47427c..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/User.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/VolatileDemo.class" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/VolatileDemo.class" deleted file mode 100644 index e6eb8252d09b26b436483a62ac76485d66a2c285..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/classes/com/moxi/interview/study/thread/VolatileDemo.class" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst" deleted file mode 100644 index 007103697ca3a00e9213a8df50f93ab31430b66e..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst" +++ /dev/null @@ -1,30 +0,0 @@ -com\moxi\interview\study\thread\ABADemo.class -com\moxi\interview\study\thread\VolatileDemo.class -com\moxi\interview\study\queue\BlockingQueueDemo.class -com\moxi\interview\study\thread\CyclicBarrierDemo.class -com\moxi\interview\study\lq\Demo3.class -com\moxi\interview\study\thread\Phone.class -com\moxi\interview\study\lq\Demo1.class -com\moxi\interview\study\thread\CountryEnum.class -com\moxi\interview\study\thread\SpinLockDemo.class -com\moxi\interview\study\thread\SyncAndReentrantLockDemo.class -com\moxi\interview\study\thread\MyData.class -com\moxi\interview\study\thread\SemaphoreDemo.class -com\moxi\interview\study\lq\Demo4.class -com\moxi\interview\study\thread\ReenterLockDemo.class -com\moxi\interview\study\thread\CountDownLatchDemo.class -com\moxi\interview\study\thread\User.class -com\moxi\interview\study\thread\ResortSeqDemo.class -com\moxi\interview\study\thread\Person.class -com\moxi\interview\study\thread\T1.class -com\moxi\interview\study\queue\ProdConsumerTraditionDemo.class -com\moxi\interview\study\queue\ShareData.class -com\moxi\interview\study\lq\Demo2.class -com\moxi\interview\study\thread\CASDemo.class -com\moxi\interview\study\queue\SynchronousQueueDemo.class -com\moxi\interview\study\thread\TransferValueDemo.class -com\moxi\interview\study\thread\AtomicReferenceDemo.class -com\moxi\interview\study\thread\MyCache.class -com\moxi\interview\study\thread\SingletonDemo.class -com\moxi\interview\study\thread\ReadWriteLockDemo.class -com\moxi\interview\study\thread\ArrayListNotSafeDemo.class diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst" deleted file mode 100644 index dfc8a0e14a31759eb2ca234dd8386a7e5838dc29..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/Code/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst" +++ /dev/null @@ -1,25 +0,0 @@ -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\CyclicBarrierDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\queue\BlockingQueueDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\lq\Demo2.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\SingletonDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\queue\ProdConsumerTraditionDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\lq\Demo3.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\SpinLockDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\ABADemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\ArrayListNotSafeDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\ReadWriteLockDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\CountDownLatchDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\T1.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\Person.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\AtomicReferenceDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\CASDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\ResortSeqDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\SemaphoreDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\VolatileDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\lq\Demo4.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\SyncAndReentrantLockDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\ReenterLockDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\CountryEnum.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\lq\Demo1.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\thread\TransferValueDemo.java -C:\Users\Administrator\Desktop\LearningNotes\У\JUC\Code\src\main\java\com\moxi\interview\study\queue\SynchronousQueueDemo.java diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..77efe383e96756784253cc831db04604c6a10cec --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/JUC/README.md" @@ -0,0 +1,33 @@ +## JUC + +>来源Bilibili尚硅谷周阳老师学习视频:[尚硅谷Java大厂面试题第二季](https://www.bilibili.com/video/BV18b411M7xz) + +- [Volatile和JMM内存模型的可见性](./1_谈谈Volatile/1_Volatile和JMM内存模型的可见性)  [传送门](http://www.moguit.cn/#/info?blogUid=6c04e335ef5be646d10ff8cd98256348) +- [Volatile不保证原子性](./1_谈谈Volatile/2_Volatile不保证原子性)  [传送门](http://www.moguit.cn/#/info?blogUid=321c05d7ea1660a2f65339c50a7a2c66) +- [Volatile禁止指令重排](./1_谈谈Volatile/3_Volatile禁止指令重排)  [传送门](http://www.moguit.cn/#/info?blogUid=5e97152c1b36fbe533b594ade1545c72) +- [Volatile的应用](./1_谈谈Volatile/4_Volatile的应用)  [传送门](http://www.moguit.cn/#/info?blogUid=9947f60e4a35c6175eed671337a3fe13) +- [CAS底层原理](./2_谈谈CAS/5_CAS底层原理)  [传送门](http://www.moguit.cn/#/info?blogUid=0f36e78050dc34b71128fa178f68ced5) +- [原子类AtomicInteger的ABA问题](./3_谈谈原子类的ABA问题/6_原子类AtomicInteger的ABA问题)  [传送门](http://www.moguit.cn/#/info?blogUid=46973eba956ece213e8116ebbdb3c80a) +- [ArrayList为什么是线程不安全的](./4_ArrayList为什么线程不安全/ArrayList线程不安全的举例)  [传送门](http://www.moguit.cn/#/info?blogUid=e234c0b2a67556c9eef84f6ea234f373) +- [TransferValue是什么](./5_TransferValue是什么) +- [Java锁之读写锁](./6_Java的锁/Java锁之读写锁)  [传送门](http://www.moguit.cn/#/info?blogUid=ed4637e5173004e2510bea1822cc496f) +- [Java锁之公平锁和非公平锁](./6_Java的锁/Java锁之公平锁和非公平锁)  [传送门](http://www.moguit.cn/#/info?blogUid=8bf613b6c0fb5ca3155d89f6a159ee4b) +- [Java锁之可重入锁和递归锁](./6_Java的锁/Java锁之可重入锁和递归锁)  [传送门](http://www.moguit.cn/#/info?blogUid=6907a51312089de9bd4f4d299c35bee9) +- [Java锁之自旋锁](./6_Java的锁/Java锁之自旋锁)  [传送门](http://www.moguit.cn/#/info?blogUid=f92f19eac21a4e50e18672d97c7a087f) +- [CountDownLatch是什么](./7_CountDownLatch_CyclicBarrier_Semaphore使用/CountDownLatch)  [传送门](http://www.moguit.cn/#/info?blogUid=6ffcf37d1fa8a18f2dec8548c684c25b) +- [CyclicBarrier是什么](./7_CountDownLatch_CyclicBarrier_Semaphore使用/CyclicBarrier)  [传送门](http://www.moguit.cn/#/info?blogUid=cdc53a873275f88b77148286bf6fbb1c) +- [Semaphore是什么](./7_CountDownLatch_CyclicBarrier_Semaphore使用/Semaphore)  [传送门](http://www.moguit.cn/#/info?blogUid=753692205a5f9c8171fda50f7607c931) +- [Java中的阻塞队列](./8_阻塞队列)  [传送门](http://www.moguit.cn/#/info?blogUid=503f1b8d583ef5145344a889760b348b) +- [Synchronized和Lock的区别与好处](./Synchronized和Lock的区别与好处)  [传送门](http://www.moguit.cn/#/info?blogUid=12f448bcca7fc10c94c4c232bef7a1fa) +- [Java线程池详解](./10_线程池)  [传送门](http://www.moguit.cn/#/info?blogUid=c0e5cbeaeb39d9a3139331a72432fbb1) +- [死锁编码及快速定位](./11_死锁编码及快速定位)  [传送门](http://www.moguit.cn/#/info?blogUid=666b0babb173833986840a48e09173a8) +- [JVM体系结构](./12_JVM/JVM体系结构) +- [什么是GCRoots能做什么](./12_JVM/JVM面试题汇总/1_什么是GCRoots能做什么)  [传送门](http://www.moguit.cn/#/info?blogUid=a38f34e2e708b279f9bfd5df7807bdd1) +- [JVM参数调优](./12_JVM/JVM面试题汇总/2_JVM参数调优)  [传送门](http://www.moguit.cn/#/info?blogUid=fca3fbcefaed38d2bbecca2e6a111905) +- [Java中的强引用_软引用_弱引用_虚引用分别是什么](./12_JVM/JVM面试题汇总/3_Java中的强引用_软引用_弱引用_虚引用分别是什么)  [传送门](http://www.moguit.cn/#/info?blogUid=a6977c422f1da0a71a292e9fdeabf3c2) +- [Java内存溢出OOM](./12_JVM/JVM面试题汇总/4_Java内存溢出OOM)  [传送门](http://www.moguit.cn/#/info?blogUid=a608650963729d09a3c285a623a32be3) +- [垃圾回收器](./12_JVM/JVM面试题汇总/5_垃圾回收器)  [传送门](http://www.moguit.cn/#/info?blogUid=0b5a41c33fcb1fac230f2684a3208eb0) +- [Linux相关命令](./13_Linux相关命令)  [传送门](http://www.moguit.cn/#/info?blogUid=daf07eceb56cb41931b2d73427d93cb3) +- [Github学习](./14_Github学习)  [传送门](http://www.moguit.cn/#/info?blogUid=a31fc7326ace247a6540c482c58c7340) +- [乐观锁和悲观锁](./15_乐观锁和悲观锁) +- [源码](Code) \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/Kafka.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/Kafka.md" deleted file mode 100644 index 21c91b7dc34f35b7521930b5356263d63317a7bc..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/Kafka.md" +++ /dev/null @@ -1,414 +0,0 @@ -# **Kafka知识总结** - -## **一、讲讲acks参数对消息持久化的影响** - -### **目录** - -1. 写在前面 -2. 如何保证宕机时数据不丢失? -3. 多副本之间数据如何同步? -4. ISR到底指的是什么东西? -5. acks参数的含义? -6. 最后的思考 - -### **1.写在前面** - -面试大厂时,一旦简历上写了Kafka,几乎必然会被问到一个问题:说说acks参数对消息持久化的影响? - -这个acks参数在kafka的使用中,是非常核心以及关键的一个参数,决定了很多东西。 - -所以无论是为了面试还是实际项目使用,大家都值得看一下这篇文章对Kafka的acks参数的分析,以及背后的原理。 - -### **2.如何保证宕机的时候数据不丢失?(或者kafka如何保证高可用、或者Kafka如何保证高可用)** - -- Kafka 一个最基本的架构认识:由多个 broker 组成,每个 broker 是一个节点;创建一个 topic,这个 topic 可以划分为多个 partition,每个 partition 可以存在于不同的 broker 上,每个 partition 就放一部分数据。 - - 这就是**天然的分布式消息队列**,就是说一个 topic 的数据,是**分散放在多个机器上的,每个机器就放一部分数据**。 - -- 而且Kafka还提供replica**副本机制**,每个partition的数据都会同步到其他机器上,形成自己的多个replica副本。所有replica会选举出来一个leader出来,那么**生产和消费都跟这个leader打交道**,然后其他replica就是follower。写的时候,leader会负责把数据同步到所有follower上去,读的时候就直接读leader上的数据即可。 - -如果某个broker宕机了,那个broker上的partition在其他机器上都有副本。如果这个宕机的broker上面有某个partition的leader,那么从follower中重新选举一个新的leader出来,然后继续读写新的leader即可,这就是所谓的高可用。 - -![]() - -### 3.**多副本之间数据如何保证同步** - -其实任何一个Partition,只有Leader是对外提供读写服务的,也就是说,如果有一个客户端往一个Partition写入数据,此时一般就是写入这个Partition的Leader副本。 - -然后Leader副本接收到数据之后,Follower副本会不停的给他发送请求尝试去拉取最新的数据,拉取到自己本地后,写入磁盘中。如下图所示: - -![]() - -### **4.ISR到底指的是什么东西?** - -ISR全称是“In-Sync Replicas”,也就是**保持同步的副本**,他的含义就是,跟Leader始终保持同步的Follower有哪些。 - -大家可以想一下 ,如果说某个Follower所在的Broker因为JVM FullGC之类的问题,导致自己卡顿了,无法及时从Leader拉取同步数据,那么是不是会导致Follower的数据比Leader要落后很多? - -所以这个时候,就意味着Follower已经跟Leader不再处于同步的关系了。但是只要Follower一直及时从Leader同步数据,就可以保证他们是处于同步的关系的。 - -所以每个Partition都有一个ISR,这个ISR里一定会有Leader自己,因为Leader肯定数据是最新的,然后就是那些跟Leader保持同步的Follower,也会在ISR里。 - -### **5.acks参数的含义** - -首先这个acks参数,是在KafkaProducer,也就是生产者客户端里设置的 - -也就是说,你往kafka写数据的时候,就可以来设置这个acks参数。然后这个参数实际上有三种常见的值可以设置,分别是:**0、1 和 all**。 - -**第一种选择是把acks参数设置为0**,意思就是我的KafkaProducer在客户端,只要把消息发送出去,不管那条数据有没有在哪怕Partition Leader上落到磁盘,我就不管他了,直接就认为这个消息发送成功了。 - -如果你采用这种设置的话,那么你必须注意的一点是,可能你发送出去的消息还在半路。结果呢,Partition Leader所在Broker就直接挂了,然后结果你的客户端还认为消息发送成功了,此时就会**导致这条消息就丢失了**。 - -![]() - -**第二种选择是设置 acks = 1**,意思就是说只要Partition Leader接收到消息而且写入本地磁盘了,就认为成功了,不管他其他的Follower有没有同步过去这条消息了。 - -这种设置其实是**kafka默认的设置** - -也就是说,默认情况下,你要是不管acks这个参数,只要Partition Leader写成功就算成功。 - -但是这里有一个问题,万一Partition Leader刚刚接收到消息,Follower还没来得及同步过去,结果Leader所在的broker宕机了,此时也会导致这条消息丢失,因为人家客户端已经认为发送成功了。 - -![]() - -**最后一种情况,就是设置acks=all**,这个意思就是说,**Partition Leader接收到消息之后,还必须要求ISR列表里跟Leader保持同步的那些Follower都要把消息同步过去**,才能认为这条消息是写入成功了。 - -如果说Partition Leader刚接收到了消息,但是结果Follower没有收到消息,此时Leader宕机了,那么客户端会感知到这个消息没发送成功,他会重试再次发送消息过去。 - -此时可能Partition 2的Follower变成Leader了,此时ISR列表里只有最新的这个Follower转变成的Leader了,那么只要这个新的Leader接收消息就算成功了。 - -![]() - -### **6.最后的思考** - -acks=all 就可以代表数据一定不会丢失了吗? - -当然不是,如果你的Partition只有一个副本,也就是一个Leader,任何Follower都没有,你认为acks=all有用吗? - -当然没用了,因为ISR里就一个Leader,他接收完消息后宕机,也会导致数据丢失。 - -所以说,**这个acks=all,必须跟ISR列表里至少有2个以上的副本配合使用**,起码是有一个Leader和一个Follower才可以。 - -这样才能保证说写一条数据过去,一定是2个以上的副本都收到了才算是成功,此时任何一个副本宕机,不会导致数据丢失。 - -**参考**:https://mp.weixin.qq.com/s/IxS46JAr7D9sBtCDr8pd7A - -## 二、Kafka参数调优实战 - -### 目录 - -1. 背景引入:很多同学看不懂的Kafka参数 -2. 一段Kafka生产端的示例代码 -3. 内存缓冲的大小 -4. 多少数据打包为一个Batch合适? -5. 要是一个Batch迟迟无法凑满怎么办? -6. 最大请求大小 -7. 重试机制 -8. 持久化机制 - -#### 1、背景引入:很多同学看不懂的kafka参数 - -在使用Kafka的客户端编写代码与服务器交互的时候,是需要对客户端设置很多的参数的。 - -#### 2、一段Kafka生产端的示例代码 - -```scala -Properties props = new Properties(); -props.put("bootstrap.servers", "localhost:9092"); -props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); -props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); -props.put("buffer.memory", 67108864); -props.put("batch.size", 131072); -props.put("linger.ms", 100); -props.put("max.request.size", 10485760); -props.put("acks", "1"); -props.put("retries", 10); -props.put("retry.backoff.ms", 500); - -KafkaProducer producer = new KafkaProducer(props); -``` - -#### 3、内存缓冲的大小 - -首先看看“**buffer.memory**”这个参数是什么意思? - -Kafka的客户端发送数据到服务器,一般都是要经过**缓冲**的,也就是说,**通过KafkaProducer发送出去的消息都是先进入到客户端本地的内存缓冲里,然后把很多消息收集成一个一个的Batch,再发送到Broker上去的**。 - -![]() - -所以这个“**buffer.memory”的本质就是用来约束KafkaProducer能够使用的内存缓冲的大小的,他的默认值是32MB**。 - -你可以先想一下,如果这个内存缓冲设置的过小的话,可能会导致一个什么问题? - -首先要明确一点,那就是在内存缓冲里大量的消息会缓冲在里面,形成一个一个的Batch,每个Batch里包含多条消息。 - -然后KafkaProducer有一个Sender线程会把多个Batch打包成一个Request发送到Kafka服务器上去。 - -![]() - -那么如果要是**内存设置的太小**,可能**导致一个问题**:消息快速的写入内存缓冲里面,但是Sender线程来不及把Request发送到Kafka服务器。 - -这样是不是会造成内存缓冲很快就被写满?一旦被写满,就会阻塞用户线程,不让继续往Kafka写消息了。 - -所以对于“buffer.memory”这个参数应该结合自己的实际情况来进行压测,你需要测算一下在生产环境,你的用户线程会以每秒多少消息的频率来写入内存缓冲。 - -比如说每秒300条消息,那么你就需要压测一下,假设内存缓冲就32MB,每秒写300条消息到内存缓冲,是否会经常把内存缓冲写满?经过这样的压测,你可以调试出来一个合理的内存大小。 - -#### 4、多少数据打包为一个Batch合适? - -接着你需要思考第二个问题,就是你的“**batch.size**”应该如何设置?**这决定了你的每个Batch要存放多少数据就可以发送出去了**。 - -比如说你要是给一个Batch设置成是16KB的大小,那么里面凑够16KB的数据就可以发送了。 - -这个**参数的默认值是16KB**,一般可以尝试把这个参数调节大一些,然后利用自己的生产环境发消息的负载来测试一下。 - -比如说发送消息的频率就是每秒300条,那么如果比如“batch.size”调节到了32KB,或者64KB,是否可以提升发送消息的整体吞吐量。 - -因为理论上来说,提升batch的大小,可以允许更多的数据缓冲在里面,那么一次Request发送出去的数据量就更多了,这样吞吐量可能会有所提升。 - -但是**不能无限的大**,过于大了之后,要是数据老是缓冲在Batch里迟迟不发送出去,那么岂不是你发送消息的延迟就会很高,**导致高延迟问题**。 - -比如说,一条消息进入了Batch,但是要等待5秒钟Batch才凑满了64KB,才能发送出去。那这条消息的延迟就是5秒钟。 - -所以需要在这里按照生产环境的发消息的速率,调节不同的Batch大小自己测试一下最终出去的吞吐量以及消息的 延迟,设置一个最合理的参数。 - -#### 5、要是一个Batch迟迟无法凑满怎么办? - -要是一个Batch迟迟无法凑满,此时就需要引入另外一个参数了,“**linger.ms**” - -**含义是一个Batch被创建之后,最多过多久,不管这个Batch有没有写满,都必须发送出去了**。 - -给大家举个例子,比如说batch.size是16kb,但是现在某个低峰时间段,发送消息很慢。 - -这就导致可能Batch被创建之后,陆陆续续有消息进来,但是迟迟无法凑够16KB,难道此时就一直等着吗? - -当然不是,假设你现在设置“linger.ms”是50ms,那么只要这个Batch从创建开始到现在已经过了50ms了,哪怕他还没满16KB,也要发送他出去了。 - -所以“linger.ms”决定了你的消息一旦写入一个Batch,最多等待这么多时间,他一定会跟着Batch一起发送出去。 - -避免一个Batch迟迟凑不满,导致消息一直积压在内存里发送不出去的情况。**这是一个很关键的参数。** - -这个参数一般要非常慎重的来设置,要配合batch.size一起来设置。 - -举个例子,首先假设你的Batch是32KB,那么你得估算一下,正常情况下,一般多久会凑够一个Batch,比如正常来说可能20ms就会凑够一个Batch。 - -那么你的linger.ms就可以设置为25ms,也就是说,正常来说,大部分的Batch在20ms内都会凑满,但是你的linger.ms可以保证,哪怕遇到低峰时期,20ms凑不满一个Batch,还是会在25ms之后强制Batch发送出去。 - -如果要是你把linger.ms设置的太小了,比如说默认就是0ms,或者你设置个5ms,那可能导致你的Batch虽然设置了32KB,但是经常是还没凑够32KB的数据,5ms之后就直接强制Batch发送出去,这样也不太好其实,会导致你的Batch形同虚设,一直凑不满数据。 - -#### 6、最大请求大小 - -**“max.request.size”这个参数决定了每次发送给Kafka服务器请求的最大大小**,同时也会限制你一条消息的最大大小也不能超过这个参数设置的值,这个其实可以根据你自己的消息的大小来灵活的调整。 - -给大家举个例子,你们公司发送的消息都是那种大的报文消息,每条消息都是很多的数据,一条消息可能都要20KB。 - -此时你的batch.size是不是就需要调节大一些?比如设置个512KB?然后你的buffer.memory是不是要给的大一些?比如设置个128MB? - -只有这样,才能让你在大消息的场景下,还能使用Batch打包多条消息的机制。但是此时“max.request.size”是不是也得同步增加? - -因为可能你的一个请求是很大的,默认他是1MB,你是不是可以适当调大一些,比如调节到5MB? - -#### 7、重试机制 - -**“retries”和“retries.backoff.ms”决定了重试机制,也就是如果一个请求失败了可以重试几次,每次重试的间隔是多少毫秒**。 - -这个大家适当设置几次重试的机会,给一定的重试间隔即可,比如给100ms的重试间隔。 - -#### 8、持久化机制 - -“acks”参数决定了发送出去的消息要采用什么样的持久化策略,这个涉及到了很多其他的概念,大家可以参考之前专门为“acks”写过的一篇文章。 - -**参考**:[](https://mp.weixin.qq.com/s/YLrGg-jx5ddmHECmdccppw) - -## 三、消息中间件消费到的消息处理失败怎么办? - -消息中间件最核心的作用是:解耦、异步、削峰。 - -假如有如下的系统: - -![]() - -生产中存在这种情况:如果独立仓库系统或者第三方物流系统故障了,导致仓储系统消费到一条订单消息之后,尝试进行发货失败,也就是对这条消费到的消息处理失败。这种情况,怎么处理? - -#### 死信队列的使用:处理失败的消息 - -一般生产环境中,如果你有丰富的架构设计经验,都会在使用MQ的时候设计两个队列:一个是**核心业务队列**,一个是**死信队列**。 - -核心业务队列,就是比如上面专门用来让订单系统发送订单消息的,然后另外一个死信队列就是用来处理异常情况的。 - -面试被问到这个问题时,必须要结合你自己的业务实践经验来说。 - -比如说要是第三方物流系统故障了,此时无法请求,那么仓储系统每次消费到一条订单消息,尝试通知发货和配送,都会遇到对方的接口报错。 - -此时仓储系统就可以把这条消息拒绝访问,或者标志位处理失败!**注意,这个步骤很重要。** - -一旦标志这条消息处理失败了之后,MQ就会把这条消息转入提前设置好的一个死信队列中。 - -然后你会看到的就是,在第三方物流系统故障期间,所有订单消息全部处理失败,全部会转入死信队列。 - -然后你的仓储系统得专门有一个后台线程,监控第三方物流系统是否正常,能否请求的,不停的监视。 - -一旦发现对方恢复正常,这个后台线程就从死信队列消费出来处理失败的订单,重新执行发货和配送的通知逻辑。 - -**死信队列的使用,其实就是MQ在生产实践中非常重要的一环,也就是架构设计必须要考虑的**。 - -整个过程,如下图所示: - -![]() - -## 四、Kafka选举 - -Kafka中的选举大致可以分为三大类: - -- 控制器的选举 -- 分区leader的选举 -- 消费者相关的选举 - -#### 1、控制器选举 - -在Kafka集群中会有一个或多个broker,其中有一个broker会被选举为控制器(Kafka Controller),它负责管理整个集群中所有分区和副本的状态等工作。 - -比如**当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本**。再比如当检测到某个分区的ISR集合发生变化时,由控制器负责通知所有broker更新其元数据信息。 - -Kafka Controller的选举是依赖Zookeeper来实现的,在Kafka集群中那个broker能够成功创建/controller这个临时(Ephemeral)节点他就可以成为Kafka Controller。 - -这里需要说明一下的是Kafka Controller的实现还是相当复杂的,涉及到各个方面的内容,如果你掌握了Kafka Controller,你就掌握了Kafka的“半壁江山”。 - -#### 2、分区leader的选举 - -分区leader副本的选举**由Kafka Controller 负责具体实施**。 - -当创建分区(创建主题或增加分区都有创建分区的动作)或分区上线(比如分区中原先的leader副本下线,此时分区需要选举一个新的leader上线来对外提供服务)的时候都需要执行leader的选举动作。 - -基本思路是按照AR集合中副本的顺序查找第一个存活的副本,并且这个副本在ISR集合中。 - -一个分区的AR集合在分配的时候就被指定,并且只要不发生重分配的情况,集合内部副本的顺序是保持不变的,而分区的ISR集合中副本的顺序可能会改变。 - -注意:这里是根据AR的顺序而不是ISR的顺序进行选举的。这个说起来比较抽象,有兴趣的读者可以手动关闭/开启某个集群中的broker来观察一下具体的变化。 - -还有一些情况也会发生分区leader的选举,比如当分区进行重分配(reassign)的时候也需要执行leader的选举动作。 - -这个思路比较简单:从重分配的AR列表中找到第一个存活的副本,且这个副本在目前的ISR列表中。 - -再比如当发生优先副本(preferred replica partition leader election)的选举时,直接将优先副本设置为leader即可,AR集合中的第一个副本即为优先副本。 - -还有一种情况就是当某节点被优雅地关闭(也就是执行ControlledShutdown)时,位于这个节点上的leader副本都会下线,所以与此对应的分区需要执行leader的选举。 - -这里的具体思路为:从AR列表中找到第一个存活的副本,且这个副本在目前的ISR列表中,与此同时还要确保这个副本不处于正在被关闭的节点上。 - -#### 3、消费者相关的选择 - -组协调器GroupCoordinator需要为消费组内的消费者选举出一个消费组的leader,这个选举的算法也很简单,分两种情况分析。 - -- **如果消费组内还没有leader,那么第一个加入消费组的消费者即为消费组的leader**。 - -- **如果某一时刻leader消费者由于某些原因退出了消费组,那么会重新选举一个新的leader,这个重新选举leader的过程又更“随意”了,相关代码如下**: - -```scala -//scala code. -private val members = new mutable.HashMap[String, MemberMetadata] -var leaderId = members.keys.head -``` - -解释一下这2行代码:在GroupCoordinator中消费者的信息是以HashMap的形式存储的,其中key为消费者的member_id,而value是消费者相关的元数据信息。 - -leaderId表示leader消费者的member_id,它的取值为HashMap中的第一个键值对的key,这种选举的方式基本上和随机无异。 - -总体上来说,消费组的leader选举过程是很随意的。 - -到这里就结束了吗?还有分区分配策略的选举呢。 - -或许你对此有点陌生,但是用过Kafka的同学或许对partition.assignment.strategy(取值为RangeAssignor、RoundRobinAssignor、StickyAssignor等)这个参数并不陌生。 - -每个消费者都可以设置自己的分区分配策略,对消费组而言需要从各个消费者呈报上来的各个分配策略中选举一个彼此都“信服”的策略来进行整体上的分区分配。 - -这个分区分配的选举并非由leader消费者决定,而是根据消费组内的各个消费者投票来决定的。 - -**参考**:[](https://mp.weixin.qq.com/s/XvDpq1xxXPzRoRKMO-MxeQ) - -## 五、如何保证消息不被重复消费?(如何保证消息消费的幂等性) - -### 面试官心理分析 - -其实这是很常见的一个问题,这俩问题基本可以连起来问。既然是消费消息,那肯定要考虑会不会重复消费?能不能避免重复消费?或者重复消费了也别造成系统异常可以吗?这个是 MQ 领域的基本问题,其实本质上还是问你**使用消息队列如何保证幂等性**,这个是你架构里要考虑的一个问题。 - -### 面试题剖析 - -回答这个问题,首先大概说一说可能会有哪些重复消费的问题。 - -首先,比如 RabbitMQ、RocketMQ、Kafka,都有可能会出现消息重复消费的问题,挑 Kafka 来举个例子,说说怎么重复消费吧。 - -Kafka 实际上有个 offset 的概念,就是每个消息写进去,都有一个 offset,代表消息的序号,然后 consumer 消费了数据之后,**每隔一段时间**(**定时定期**),会把自己消费过的消息的 offset 提交一下,表示“我已经消费过了,下次我要是重启啥的,你就让我继续从上次消费到的 offset 来继续消费吧”。 - -但是,你有时候重启系统,看你怎么重启了,如果碰到点着急的,直接 kill 进程了,再重启。这会导致 consumer 有些消息处理了,但是**没来得及提交 offset,重启之后,少数消息会再次消费一次**。 - -例如,数据 1/2/3 依次进入 kafka,kafka 会给这三条数据每条分配一个 offset,代表这条数据的序号,我们就假设分配的 offset 依次是 152/153/154。消费者从 kafka 去消费的时候,也是按照这个顺序去消费。假如当消费者消费了 `offset=153` 的这条数据,刚准备去提交 offset 到 zookeeper,此时消费者进程被重启了。那么此时消费过的数据 1/2 的 offset 并没有提交,kafka 也就不知道你已经消费了 `offset=153` 这条数据。那么重启之后,消费者会找 kafka 说,嘿,哥儿们,你给我接着把上次我消费到的那个地方后面的数据继续给我传递过来。由于之前的 offset 没有提交成功,那么数据 1/2 会再次传过来,如果此时消费者没有去重的话,那么就会导致重复消费。 - -![]() - -**如何保证消息队列消费的幂等性**? - -回答这个问题需要结合业务思考,有如下几个思路: - -- 比如数据要写库,先根据主键查一下,如果这数据都有了,就别插入了,update 一下。 -- 比如是写 Redis,那没问题了,因为每次都是 set,天然幂等性。 -- 比如不是上面两个场景,那做的稍微复杂一点,你需要让生产者发送每条数据的时候,里面**加一个全局唯一的 id**,类似订单 id 之类的东西,然后你这里消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?如果没有消费过,你就处理,然后这个 id 写 Redis。如果消费过了,就别处理,保证别重复处理相同的消息即可。 -- 比如基于数据库的唯一键来保证重复数据不会重复插入多条。因为有唯一键约束了,重复数据插入只会报错,不会导致数据库中出现脏数据。 - -![]() - -## 六、如何保证消息的可靠性传输?(如何处理消息丢失的问题?) - -## 面试官心理分析 - -这个是肯定的,用 MQ 有个基本原则,就是**数据不能多一条,也不能少一条**,不能多,就是前面说的[重复消费和幂等性问题。不能少,就是说这数据别搞丢了。那这个问题你必须得考虑一下。 - -如果说你这个是用 MQ 来传递非常核心的消息,比如说计费、扣费的一些消息,那必须确保这个 MQ 传递过程中**绝对不会把计费消息给弄丢**。 - -## 面试题剖析 - -数据的丢失问题,可能出现在**生产者、MQ、消费者**中,从 Kafka 来分析一下。 - -### Kafka - -### 1、消费者丢失数据 - -唯一可能导致消费者弄丢数据的情况,是消费到了这个消息,然后消费者那边**自动提交了 offset**,让 Kafka 以为你已经消费好了这个消息,但其实你才刚准备处理这个消息,你还没处理,你自己就挂了,此时这条消息就丢咯。 - -由于 Kafka 会自动提交 offset,那么只要**关闭自动提交** offset,在处理完之后自己手动提交 offset,就可以保证数据不会丢。但是此时确实还是**可能会有重复消费**,比如你刚处理完,还没提交 offset,结果自己挂了,此时肯定会重复消费一次,自己保证幂等性就好了。 - -生产环境碰到的一个问题是Kafka 消费者消费到了数据之后是写到一个内存的 queue 里先缓冲一下,结果有的时候,你刚把消息写入内存 queue,然后消费者会自动提交 offset。然后此时我们重启了系统,就会导致内存 queue 里还没来得及处理的数据就丢失了。 - -### 2、Kafka弄丢数据 - -这块比较常见的一个场景,就是 Kafka 某个 broker 宕机,然后重新选举 partition 的 leader。如果此时其他的 follower 刚好还有些数据没有同步,结果此时 leader 挂了,然后选举某个 follower 成 leader 之后,不就少了一些数据?这就丢了一些数据啊。 - -所以此时一般是要求起码设置如下 4 个参数: - -- 给 topic 设置 `replication.factor` 参数:这个值必须大于 1,要求每个 partition 必须有至少 2 个副本。 -- 在 Kafka 服务端设置 `min.insync.replicas` 参数:这个值必须大于 1,这个是要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系,没掉队,这样才能确保 leader 挂了还有一个 follower 吧。 -- 在 producer 端设置 `acks=all`:这个是要求每条数据,必须是**写入所有 replica 之后,才能认为是写成功了**。 -- 在 producer 端设置 `retries=MAX`(很大很大很大的一个值,无限次重试的意思):这个是**要求一旦写入失败,就无限重试**,卡在这里了。 - -我们生产环境就是按照上述要求配置的,这样配置之后,至少在 Kafka broker 端就可以保证在 leader 所在 broker 发生故障,进行 leader 切换时,数据不会丢失。 - -### 3、生产者会不会弄丢数据? - -如果按照上述的思路设置了 `acks=all`,一定不会丢,要求是,你的 leader 接收到消息,所有的 follower 都同步到了消息之后,才认为本次写成功了。如果没满足这个条件,生产者会自动不断的重试,重试无限次。 - -## 七、如何保证消息的顺序性? - -Kafka:比如说我们建了一个 topic,有三个 partition。生产者在写的时候,其实可以指定一个 key,比如说我们指定了某个订单 id 作为 key,那么这个订单相关的数据,一定会被分发到同一个 partition 中去,而且这个 partition 中的数据一定是有顺序的。 -消费者从 partition 中取出来数据的时候,也一定是有顺序的。到这里,顺序还是 ok 的,没有错乱。接着,我们在消费者里可能会搞**多个线程来并发处理消息**。因为如果消费者是单线程消费处理,而处理比较耗时的话,比如处理一条消息耗时几十 ms,那么 1 秒钟只能处理几十条消息,这吞吐量太低了。而多个线程并发跑的话,顺序可能就乱掉了。 - -![]() - -#### 解决方案: - -- 一个 topic,一个 partition,一个 consumer,内部单线程消费,单线程吞吐量太低,一般不会用这个。 -- 写 N 个**内存 queue**,具有相同 key 的数据都到同一个内存 queue;然后对于 N 个线程,每个线程分别消费一个内存 queue 即可,这样就能保证顺序性。 - -![]() - - - diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/1.jpg" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/1.jpg" deleted file mode 100644 index a5bcb0aec5184a14373f290e78fc2505845c0852..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/1.jpg" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/1.txt" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/1.txt" deleted file mode 100644 index 32b96d17123dab05355f352cbb09d8ed783390b6..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/1.txt" +++ /dev/null @@ -1 +0,0 @@ -as \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/10.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/10.png" deleted file mode 100644 index d522b07b9d8b515501d7dfdb20c56c0a8a7c58cf..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/10.png" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/11.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/11.png" deleted file mode 100644 index 6d03589bb4ccbdfcea91d4cbb37f85690c72d314..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/11.png" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/12.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/12.png" deleted file mode 100644 index f022e2d542e16c79919edc42320b93a037e95a8c..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/12.png" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/13.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/13.png" deleted file mode 100644 index 2159d54adc8f0dcf620c482f1eb9b9b125af472d..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/13.png" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/2.jpg" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/2.jpg" deleted file mode 100644 index 9609c00e8ae4943e3c8d8844fa6e675a9eba2954..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/2.jpg" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/3.jpg" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/3.jpg" deleted file mode 100644 index 53c1ab792efeef252adeda256c67a51859557d7f..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/3.jpg" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/4.jpg" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/4.jpg" deleted file mode 100644 index b1ed413f70db29beaefb9a4c85b6153c0537c052..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/4.jpg" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/5.jpg" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/5.jpg" deleted file mode 100644 index 9609c00e8ae4943e3c8d8844fa6e675a9eba2954..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/5.jpg" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/6.jpg" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/6.jpg" deleted file mode 100644 index 5cc5383586a0c9d5fceb89c97f36785e4ed3b0a5..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/6.jpg" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/7.jpg" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/7.jpg" deleted file mode 100644 index 17405c38762c974918ca0bc14b1f0c59aeb8fd21..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/7.jpg" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/8.jpg" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/8.jpg" deleted file mode 100644 index 0b67bf71a9b34dc0185c1dd1314eb97825a95517..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/8.jpg" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/9.jpg" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/9.jpg" deleted file mode 100644 index e61cd8740894c70ebfaa46c8dbf7e3be5ad615ee..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/pictures/9.jpg" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ABADemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ABADemo.java" deleted file mode 100644 index 045b084bfa765de3d37d04ebe98ab2c7f7596a90..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ABADemo.java" +++ /dev/null @@ -1,52 +0,0 @@ -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.atomic.AtomicStampedReference; - -/* -* ABA问题的解决 AtomicStampedReference -* */ -public class ABADemo { - static AtomicReference atomicReference = new AtomicReference<>(100); - static AtomicStampedReference atomicStampedReference = new AtomicStampedReference<>(100,1); - - - public static void main(String[] args){ - new Thread(()->{ - atomicReference.compareAndSet(100,101); - atomicReference.compareAndSet(101,100); - },"t1").start(); - - new Thread(()->{ -// 暂停1秒钟线程2,保证上面t1线程完成一次ABA操作 - try{ TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace();} - System.out.println(atomicReference.compareAndSet(100,2019)+"\t"+atomicReference.get()); - },"t2").start(); - - try{TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();} - - System.out.println("======以下是ABA问题的解决====="); - new Thread(()->{ - int stamp = atomicStampedReference.getStamp(); - System.out.println(Thread.currentThread().getName()+"\t第1次版本号:"+stamp); - -// 暂停1秒钟t3线程 - try{TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();} - atomicStampedReference.compareAndSet(100,101,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1); - System.out.println(Thread.currentThread().getName()+"\t第2次版本号:"+atomicStampedReference.getStamp()); - atomicStampedReference.compareAndSet(101,100,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1); - System.out.println(Thread.currentThread().getName()+"\t第3次版本号:"+atomicStampedReference.getStamp()); - },"t3").start(); - - new Thread(()->{ - int stamp = atomicStampedReference.getStamp(); - System.out.println(Thread.currentThread().getName()+"\t第1次版本号:"+stamp); - -// 暂停1秒钟t4线程 - try{TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();} - boolean result = atomicStampedReference.compareAndSet(100,2019,stamp,atomicStampedReference.getStamp()+1); - - System.out.println(Thread.currentThread().getName()+"\t修改成功否: "+result+"\t当前最新实际版本号:"+atomicStampedReference.getStamp()); - - },"t4").start(); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/AtomicReferenceDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/AtomicReferenceDemo.java" deleted file mode 100644 index 16f83e005c0aed5f70b1b0268a4d63d85b66c44f..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/AtomicReferenceDemo.java" +++ /dev/null @@ -1,20 +0,0 @@ -import javax.jws.soap.SOAPBinding; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -class User{ - String userName; - int age; -} -public class AtomicReferenceDemo { - public static void main(String[] args){ - AtomicReference atomicReference = new AtomicReference<>(); - -// User z3 = new User("z3",22); -// User li4 = new User("li4",25); - -// atomicReference.set(z3); -// System.out.println(atomicReference.compareAndSet(z3,li4)+"\t"+atomicReference.get().toString()); - - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/BlockingQueueDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/BlockingQueueDemo.java" deleted file mode 100644 index 08910e8e48366907a7a2d254d2237d97b4551dad..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/BlockingQueueDemo.java" +++ /dev/null @@ -1,33 +0,0 @@ -import java.util.List; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; - -/* -* ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按FIFO原则对元素进行排序 -* LinkedBlockingQueue:是一个基于链表结构的阻塞队列,此队列按FIFO排序元素,吞吐量高于ArrayBlockingQueue -* SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移出操作,否则插入操作一直处于 -* 阻塞状态,吞吐量通常要高 -* -* -* -* 2.阻塞队列 -* 2.1阻塞队列有没有好的一面 -* 2.2不得不阻塞,你如何管理 -* */ -public class BlockingQueueDemo { - public static void main(String[] args) throws Exception{ -// List list = null; - BlockingQueue blockingQueue = new ArrayBlockingQueue<>(3); -// 往阻塞队列添加元素 - System.out.println(blockingQueue.add("a")); - System.out.println(blockingQueue.add("b")); - System.out.println(blockingQueue.add("c")); - -// 从阻塞队列取元素 - System.out.println(blockingQueue.element()); - - System.out.println(blockingQueue.remove()); - System.out.println(blockingQueue.remove()); - - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/CASDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/CASDemo.java" deleted file mode 100644 index dcb973dae442cba9c0135cf1078d510365ad70a3..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/CASDemo.java" +++ /dev/null @@ -1,13 +0,0 @@ -import java.util.concurrent.atomic.AtomicInteger; - -/* -* 1、CAS是什么? ==>compareAndSet -* 比较并交换 -* */ -public class CASDemo { - public static void main(String[] args){ - AtomicInteger atomicInteger = new AtomicInteger(5); - System.out.println(atomicInteger.compareAndSet(5,2019)+"\t current data: "+atomicInteger.get()); - System.out.println(atomicInteger.compareAndSet(5,1024)+"\t current data: "+atomicInteger.get()); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/CallableDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/CallableDemo.java" deleted file mode 100644 index 96451b96918e306fd38534645e47fdd4d0488bdf..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/CallableDemo.java" +++ /dev/null @@ -1,31 +0,0 @@ -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.FutureTask; - -/*class MyThread implements Runnable{ - public void run(){ - - } -}*/ - -class MyThread implements Callable { - public Integer call() throws Exception{ - System.out.println(".........come in callable"); - return 1024; - } -} - -/* -* -* */ -public class CallableDemo { - public static void main(String[] args) throws InterruptedException, ExecutionException { - FutureTask futureTask = new FutureTask<>(new MyThread()); - Thread t1 = new Thread(futureTask,"AA"); - t1.start(); - int r1 = 100; - int r2 = futureTask.get();//要求获得Callable线程的计算结果,如果没有计算完成就要强求,会导致阻塞,知道计算完成,建议放在最后 - - System.out.println(".....result"+r1+r2); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ContainerNotSafeDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ContainerNotSafeDemo.java" deleted file mode 100644 index 40356a1d169d6ed3326e06a70879a79b22c7c926..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ContainerNotSafeDemo.java" +++ /dev/null @@ -1,41 +0,0 @@ -import java.util.*; -import java.util.concurrent.CopyOnWriteArrayList; - -/* -* 集合类不安全问题:原因是为了保证并发性,add操作没有加锁 -* ArrayList -* */ -public class ContainerNotSafeDemo { - public static void main(String[] args){ -// List list = new ArrayList<>(); -// List list = Collections.synchronizedList(new ArrayList<>()); - List list = new CopyOnWriteArrayList<>(); - for(int i=1;i<=3;i++){ - new Thread(()->{ - list.add(UUID.randomUUID().toString().substring(0,8)); - System.out.println(list); - },String.valueOf(i)).start(); - } -// java.util.ConcurrentModificationException - /* - * 1 故障现象 - * java.util.ConcurrentModificationException - * - * 2 导致原因 - * 并发争抢修改导致,参考我们的花名册签名情况。 - * 一个人正在写入,另一个同学过来抢夺,导致数据不一致异常。并发修改异常。 - * 3 解决方案 - * 3.1 new Vector<>(); - * 3.2 Collections.synchronizedList(new ArrayList<>()); - * 3.3 new CopyOnWriteArrayList<>() - * 写时复制 - * CopyOnWrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容器Object[]添加, - * 而是先将当前object[]进行Copy,复制出一个新的容器Object[] newElements,然后新的容器Object[] newElements - * 里添加元素,添加完元素之后,再将原容器的引用指向新的容器setArray(newElements);这样做的好处是可以对 - * copyonwrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以copyonwrite容器也是一种 - * 读写分离的思想,读和写不同的容器。 - * - * 4 优化建议 - * */ - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/CountDownLatch.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/CountDownLatch.java" deleted file mode 100644 index 9412a560893426dc6963dfc1afb02eb598eacbdf..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/CountDownLatch.java" +++ /dev/null @@ -1,18 +0,0 @@ -/* -* -* */ -public class CountDownLatch { - public static void main(String[] args) throws Exception{ - java.util.concurrent.CountDownLatch countDownLatch = new java.util.concurrent.CountDownLatch(6); - - for(int i=1;i<=6;i++){ - new Thread(()->{ - System.out.println(Thread.currentThread().getName()+"\t 上完自习,离开教室"); - countDownLatch.countDown(); - },String.valueOf(i)).start(); - } - - countDownLatch.await(); - System.out.println(Thread.currentThread().getName()+"\t *****班长最后关门走人"); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/CyclicBarrierDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/CyclicBarrierDemo.java" deleted file mode 100644 index ef7344876b967f6d2dafda9861ba8ff32ff85f1d..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/CyclicBarrierDemo.java" +++ /dev/null @@ -1,26 +0,0 @@ -import java.util.concurrent.BrokenBarrierException; -import java.util.concurrent.CyclicBarrier; - -/* -* -* */ -public class CyclicBarrierDemo { - public static void main(String[] args){ - CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{System.out.println("召唤神龙");}); - - for(int i=1;i<=7;i++){ - final int tempInt = i; - new Thread(()->{ - System.out.println(Thread.currentThread().getName()+"\t 收集到第:"+tempInt+"龙珠"); - try{ - cyclicBarrier.await(); - } catch (InterruptedException e){ - e.printStackTrace(); - } catch (BrokenBarrierException e){ - e.printStackTrace(); - } - - },String.valueOf(i)).start(); - } - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/DeadLockDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/DeadLockDemo.java" deleted file mode 100644 index 4a727cf0d25d4b25a87d07c90ae85754ec1ac429..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/DeadLockDemo.java" +++ /dev/null @@ -1,46 +0,0 @@ -/* -* 死锁是指两个或者两个以上的进程在执行过程中,因抢夺资源而造成的一种互相等待的现象, -* 若无外力干涉它们将都无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足, -* 死锁出现的可能性也就很低,否则就会因争夺有限的资源而陷入死锁。 -* */ - -import java.util.concurrent.TimeUnit; - -class HoldLockThread implements Runnable{ - private String lockA; - private String lockB; - - public HoldLockThread(String lockA,String lockB){ - this.lockA = lockA; - this.lockB = lockB; - } - - public void run(){ - synchronized (lockA){ - System.out.println(Thread.currentThread().getName()+"\t自己持有:"+lockA+"\t尝试获得:"+lockB); - //暂停一下 - try{ TimeUnit.SECONDS.sleep(2); }catch (InterruptedException e){e.printStackTrace();} - - synchronized (lockB){ - System.out.println(Thread.currentThread().getName()+"\t自己持有:"+lockB+"\t尝试获得:"+lockA); - } - } - } -} - -public class DeadLockDemo { - public static void main(String[] args){ - String lockA = "lockA"; - String lockB = "lockB"; - - new Thread(new HoldLockThread(lockA,lockB),"ThreadAAA").start(); - new Thread(new HoldLockThread(lockB,lockA),"ThreadBBB").start(); - - /* - * linux ps -ef|grep xxxx ls -l查看当前进程的命令 - * windows下的java运行程序,也有类似ps的查看进程的命令,但是目前我们需要查看的只是java - * jps = java ps jps -l - * jstack - * */ - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/GCOverheadDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/GCOverheadDemo.java" deleted file mode 100644 index 29af9e7e74cbb299526c6382ccc95cafe91d155b..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/GCOverheadDemo.java" +++ /dev/null @@ -1,29 +0,0 @@ -import java.util.ArrayList; -import java.util.List; - -/* -* GC回收时间长时会抛出OutOfMemoryError。过长的定义是,超过98%的时间用来做GC并且回收了 -* 不到2%的堆内存,连续多次GC都只回收了不到2%的极端情况下才会抛出。 - -假设不抛出GC overhead limit错误会发生什么情况呢? -那就是GC清理的这么点内存很快会再次填满,迫使GC再次执行,这样就形成恶性循环,CPU使用率一直 -是100%,而GC缺没有任何成果。 -* */ - -public class GCOverheadDemo { - public static void main(String[] args){ - int i = 0; - List list = new ArrayList<>(); - - try{ - while(true){ - list.add(String.valueOf(++i).intern()); - } - }catch (Throwable e){ - System.out.println("***************i:"+i); - e.printStackTrace(); - throw e; - } - - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/GCRootDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/GCRootDemo.java" deleted file mode 100644 index d6af7210944056c26dd5eb4c9bb22126f63f333a..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/GCRootDemo.java" +++ /dev/null @@ -1,20 +0,0 @@ -/* -* 在java中可作为GC Roots的对象有: -* 1.虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。 -* 2.方法区中的类静态属性引用的对象。 -* 3.方法区中常量引用的对象 -* 4.本地方法栈中JNI(Native方法)引用的对象。 -* */ -public class GCRootDemo { - private byte[] byteArray = new byte[100*1024*1024]; - - public static void m1(){ - GCRootDemo t1 = new GCRootDemo(); - System.gc(); - System.out.println("第一次GC完成"); - } - - public static void main(String[] args){ - m1(); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/HelloGC.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/HelloGC.java" deleted file mode 100644 index 196e1d7c4925c78c69ccf58b7f07ac052795954f..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/HelloGC.java" +++ /dev/null @@ -1,9 +0,0 @@ -public class HelloGC { - public static int oneAddone(int x,int y){ - return x+y; - } - public static void main(String[] args) throws InterruptedException { - int res = oneAddone(1,1); - System.out.println(res); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/JavaHeapSpaceDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/JavaHeapSpaceDemo.java" deleted file mode 100644 index a57a136b7c1ca94143817fbeb76b70a01b8d7d7f..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/JavaHeapSpaceDemo.java" +++ /dev/null @@ -1,13 +0,0 @@ -import java.util.Random; - -public class JavaHeapSpaceDemo { - public static void main(String[] args){ - String str = "seu"; - - while(true){ - str += str + new Random().nextInt(11111111)+new Random().nextInt(22222222); - str.intern(); - } - - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/MetaspaceOOMT.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/MetaspaceOOMT.java" deleted file mode 100644 index 5f633cd0e6d428ec1aa0c840ee2864269b1e19c9..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/MetaspaceOOMT.java" +++ /dev/null @@ -1,32 +0,0 @@ - -/* -* Java8之后的版本使用Metaspace来替代永久代 -* Metaspace是方法区在HotSpot中的实现,它与持久带最大的区别在于:Metaspace并不在虚拟机内存中而是使用 -* 本地内存,也即在java8中,class metaspace(the virtual machines internal presentation of java class) -* ,被存储在叫做Metaspace的native memory -* -* 永久代(Metaspace)存放以下信息: -* 虚拟机加载的类信息 -* 常量池 -* 静态变量 -* 即时编译后的代码 -* */ - -public class MetaspaceOOMT { - static class OOMTest{ - - } - public static void main(String[] args){ - int i=0;//模拟多少次后发生异常 - - try{ - while (true){ - i++; - - } - }catch (Throwable e){ - System.out.println("********多少次后发生了异常:"+i); - e.printStackTrace(); - } - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/MyThreadPoolDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/MyThreadPoolDemo.java" deleted file mode 100644 index a39e53695299160f8a1ff21311288a5565803190..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/MyThreadPoolDemo.java" +++ /dev/null @@ -1,54 +0,0 @@ -/* -*第4种获得/使用java多线程的方式,通过线程池 -* (其他三种是:继承Thread类;实现Runnable接口,但是Runnable没有返回值,不抛异常; -* 实现Callable接口,有返回值,会跑出异常) -* */ - -import java.util.concurrent.*; - -//System.out.println(Runtime.getRuntime().availableProcessors()); -//Array Arrays 辅助工具类 -//Collection Collections -//Executor Executors -public class MyThreadPoolDemo { - public static void main(String[] args){ - ExecutorService threadPool = new ThreadPoolExecutor(2, - 5, - 1L, - TimeUnit.SECONDS, - new LinkedBlockingQueue<>(3), - Executors.defaultThreadFactory(), - new ThreadPoolExecutor.DiscardPolicy()); - - try{ - for(int i=1;i<=11;i++){ - threadPool.execute(()->{ - System.out.println(Thread.currentThread().getName()+"\t 办理业务"); - }); - } - }catch (Exception e){ - e.printStackTrace(); - }finally { - threadPool.shutdown(); - } - } - - private static void threadPoolInit() { - //ExecutorService threadPool = Executors.newFixedThreadPool(5);//一池5个处理线程 - //ExecutorService threadPool = Executors.newFixedThreadPool(1);//一池1个线程 - ExecutorService threadPool = Executors.newCachedThreadPool();//一池N个线程 - - //模拟10个用户来办理业务,每个用户就是一个来自外部的请求线程 - try{ - for(int i=1;i<=10;i++){ - threadPool.execute(()->{ - System.out.println(Thread.currentThread().getName()+"\t 办理业务"); - }); - } - }catch (Exception e){ - e.printStackTrace(); - }finally { - threadPool.shutdown(); - } - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/PhantomReferenceDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/PhantomReferenceDemo.java" deleted file mode 100644 index 423a7930728b78b2be4a024056446751afce3c8b..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/PhantomReferenceDemo.java" +++ /dev/null @@ -1,23 +0,0 @@ -import java.lang.ref.PhantomReference; -import java.lang.ref.ReferenceQueue; - -public class PhantomReferenceDemo { - public static void main(String[] args) throws InterruptedException { - Object o1 = new Object(); - ReferenceQueue referenceQueue = new ReferenceQueue<>(); - PhantomReference phantomReference = new PhantomReference<>(o1,referenceQueue); - - System.out.println(o1); - System.out.println(phantomReference.get()); - System.out.println(referenceQueue.poll()); - - System.out.println("================="); - o1 = null; - System.gc(); - Thread.sleep(500); - - System.out.println(o1); - System.out.println(phantomReference.get()); - System.out.println(referenceQueue.poll()); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ProdConsumer_BlockQueueDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ProdConsumer_BlockQueueDemo.java" deleted file mode 100644 index 8ed7f698d71f06d823a09d31a41a671b5cb8bd63..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ProdConsumer_BlockQueueDemo.java" +++ /dev/null @@ -1,89 +0,0 @@ -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -class MyResource{ - private volatile boolean FLAG = true;//默认开启,进行生产+消费 - private AtomicInteger atomicInteger = new AtomicInteger(); - - BlockingQueue blockingQueue = null; - public MyResource(BlockingQueue blockingQueue) { - this.blockingQueue = blockingQueue; - System.out.println(blockingQueue.getClass().getName()); - } - - public void myProd() throws Exception{ - String data = null; - boolean retValue; - while(FLAG){ - data = atomicInteger.incrementAndGet()+""; - retValue = blockingQueue.offer(data,2L, TimeUnit.SECONDS); - if(retValue){ - System.out.println(Thread.currentThread().getName()+"\t插入队列"+data+"成功"); - }else{ - System.out.println(Thread.currentThread().getName()+"\t插入队列"+data+"失败"); - } - TimeUnit.SECONDS.sleep(1); - } - System.out.println(Thread.currentThread().getName()+"\t生产停止"); - } - - public void myConsumer() throws Exception{ - String result = null; - while(FLAG){ - result = blockingQueue.poll(2L,TimeUnit.SECONDS); - if(null==result || result.equalsIgnoreCase("")){ - FLAG = false; - System.out.println(Thread.currentThread().getName()+"\t 超过2秒,消费退出"); - System.out.println(); - System.out.println(); - return; - } - System.out.println(Thread.currentThread().getName()+"\t消费队列"+result+"成功"); - } - } - - public void stop() throws Exception{ - this.FLAG = false; - } -} - -/* -* volatile/CAS/atomicInteger/BlockQueue/线程交互/原子引用 -* */ - -public class ProdConsumer_BlockQueueDemo { - public static void main(String[] args) throws Exception{ - MyResource myResource = new MyResource(new ArrayBlockingQueue<>(10)); - - new Thread(()->{ - System.out.println(Thread.currentThread().getName()+"\t 生产线程启动"); - System.out.println(); - System.out.println(); - try{ - myResource.myProd(); - }catch (Exception e){ - e.printStackTrace(); - } - },"Prod").start(); - - new Thread(()->{ - System.out.println(Thread.currentThread().getName()+"\t 消费线程启动"); - try{ - myResource.myConsumer(); - }catch (Exception e){ - e.printStackTrace(); - } - },"Consumer").start(); - - try{TimeUnit.SECONDS.sleep(5);}catch (InterruptedException e){e.printStackTrace();} - - System.out.println(); - System.out.println(); - System.out.println(); - - System.out.println("5秒钟到,main停止"); - myResource.stop(); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ProdConsumer_TraditionDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ProdConsumer_TraditionDemo.java" deleted file mode 100644 index cea7ae10e2c49b6d5d3e15a98a5ac7eadcd643ee..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ProdConsumer_TraditionDemo.java" +++ /dev/null @@ -1,85 +0,0 @@ -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -class ShareData{ //资源类 - private int number = 0; - private Lock lock = new ReentrantLock(); - private Condition condition = lock.newCondition(); - - public void increment() throws Exception{ - lock.lock(); - try{ - // 1.判断 - while(number !=0){ -// 等待,不能生产 - condition.await(); - } - //2.干活 - number++; - System.out.println(Thread.currentThread().getName()+"\t"+number); - //3.通知唤醒 - condition.signalAll(); - } catch (Exception e){ - e.printStackTrace(); - }finally { - lock.unlock(); - } - - } - - public void decrement() throws Exception{ - lock.lock(); - try{ - // 1.判断 - while(number ==0){ -// 等待,不能生产 - condition.await(); - } - //2.干活 - number--; - System.out.println(Thread.currentThread().getName()+"\t"+number); - //3.通知唤醒 - condition.signalAll(); - } catch (Exception e){ - e.printStackTrace(); - }finally { - lock.unlock(); - } - - } - -} - -/* -* 题目:一个初始值为0的变量,两个线程对其交替操作,一个加1,一个减1,来5轮 -* -* 1.线程操作资源类 -* 2.判断 干活 通知 -* 3.防止虚假唤醒机制 -* */ -public class ProdConsumer_TraditionDemo { - public static void main(String[] args){ - ShareData shareData = new ShareData(); - - new Thread(()->{ - for(int i=1;i<=5;i++){ - try { - shareData.increment(); - }catch (Exception e){ - e.printStackTrace(); - } - } - },"AAA").start(); - - new Thread(()->{ - for(int i=1;i<=5;i++){ - try { - shareData.decrement(); - }catch (Exception e){ - e.printStackTrace(); - } - } - },"BBB").start(); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ReadWriteLockDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ReadWriteLockDemo.java" deleted file mode 100644 index 809862409f0bfa2b3aaf31bedf49a9da638f5f30..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ReadWriteLockDemo.java" +++ /dev/null @@ -1,73 +0,0 @@ -/* -* 多个线程同时读一个资源类没有问题,所以为了满足并发量,读取共享资源应该可以同时进行。但是写共享 -* 资源只能有一个线程。 -* -* 写操作:原子+独占,整个过程必须是一个完整的统一体,中间不许被分割,被打断。 -* */ - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -class MyCache{ - private volatile Map map = new HashMap<>(); -// private Lock lock = new ReentrantLock(); - private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(); - public void put(String key,Object value){ - - reentrantReadWriteLock.writeLock().lock(); - try{ - System.out.println(Thread.currentThread().getName()+"\t 正在写入:"+key); - try{ - TimeUnit.MILLISECONDS.sleep(300); - } catch (InterruptedException e) {e.printStackTrace();} - map.put(key,value); - System.out.println(Thread.currentThread().getName()+"\t 写入完成"); - }catch (Exception e){ - e.printStackTrace(); - }finally { - reentrantReadWriteLock.writeLock().unlock(); - } - - } - - public void get(String key){ - reentrantReadWriteLock.readLock().lock(); - try { - System.out.println(Thread.currentThread().getName()+"\t 正在读取:"+key); - try{ - TimeUnit.MILLISECONDS.sleep(300); - } catch (InterruptedException e) {e.printStackTrace();} - Object result = map.get(key); - System.out.println(Thread.currentThread().getName()+"\t 读取完成"+result); - }catch (Exception e){ - e.printStackTrace(); - }finally { - reentrantReadWriteLock.readLock().unlock(); - } - - } - -} - -public class ReadWriteLockDemo { - public static void main(String[] args){ - MyCache myCache = new MyCache(); - for(int i=1;i<=5;i++){ - final int tempInt = i; - new Thread(()->{ - myCache.put(tempInt+"",tempInt+""); - },String.valueOf(i)).start(); - } - - for(int i=1;i<=5;i++){ - final int tempInt = i; - new Thread(()->{ - myCache.get(tempInt+""); - },String.valueOf(i)).start(); - } - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ReferenceQueueDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ReferenceQueueDemo.java" deleted file mode 100644 index c439b5b7f1a96017fee1ae8ecfa9ad2d1b4bd794..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/ReferenceQueueDemo.java" +++ /dev/null @@ -1,22 +0,0 @@ -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; - -public class ReferenceQueueDemo { - public static void main(String[] args) throws InterruptedException{ - Object o1 = new Object(); - ReferenceQueue referenceQueue = new ReferenceQueue<>(); - WeakReference weakReference = new WeakReference<>(o1,referenceQueue); - System.out.println(o1); - System.out.println(weakReference.get()); - System.out.println(referenceQueue.poll()); - - System.out.println("============="); - o1 = null; - System.gc(); - Thread.sleep(500); - - System.out.println(o1); - System.out.println(weakReference.get()); - System.out.println(referenceQueue.poll()); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/RenenterLockDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/RenenterLockDemo.java" deleted file mode 100644 index 7c7734d64ccbb4b9d7fb1352436e38f4fa273001..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/RenenterLockDemo.java" +++ /dev/null @@ -1,37 +0,0 @@ -/* -* 可重入锁(也就是递归锁):指的是同一个线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码, -* 在同一线程在外层方法获取锁的时候,在进入内层方法会自动获取锁。也就是说,线程可以进入任何一个 -* 它已经拥有的锁所有同步着的代码块。 -* */ -class Phone{ - public synchronized void sendSMS() throws Exception{ - System.out.println(Thread.currentThread().getId()+"\t invoked sendSMS()"); - sendEmail(); - } - - public synchronized void sendEmail() throws Exception{ - System.out.println(Thread.currentThread().getId()+"\t invoked sendEmail()"); - } -} - -public class RenenterLockDemo { - public static void main(String[] args){ - Phone phone = new Phone(); - new Thread(()->{ - try { - phone.sendSMS(); - } catch (Exception e){ - e.printStackTrace(); - } - },"t1").start(); - - new Thread(()->{ - try { - phone.sendSMS(); - } catch (Exception e){ - e.printStackTrace(); - } - },"t2").start(); - } - -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SemaphoreDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SemaphoreDemo.java" deleted file mode 100644 index b2256f80a6564f3658e4615adb3fd900cb9441bb..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SemaphoreDemo.java" +++ /dev/null @@ -1,27 +0,0 @@ -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - -/* -* -* */ -public class SemaphoreDemo { - public static void main(String[] args){ - Semaphore semaphore = new Semaphore(3); //模拟3个车位 - for(int i=1;i<=6;i++){ //模拟6部车 - new Thread(()->{ - try{ - semaphore.acquire(); - System.out.println(Thread.currentThread().getName()+"\t抢到车位"); - try{ - TimeUnit.SECONDS.sleep(3); - } catch (InterruptedException e) {e.printStackTrace();} - System.out.println(Thread.currentThread().getName()+"\t停车3秒后离开车位"); - } catch (InterruptedException e){ - e.printStackTrace(); - } finally { - semaphore.release(); - } - },String.valueOf(i)).start(); - } - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SingletonDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SingletonDemo.java" deleted file mode 100644 index dc5e92a2329d1a043a37e8ceffdfed2b7c42214b..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SingletonDemo.java" +++ /dev/null @@ -1,35 +0,0 @@ - -public class SingletonDemo { - private static SingletonDemo instance = null; - private SingletonDemo(){ - System.out.println(Thread.currentThread().getName()+"\t 我是构造函数SingletonDemo()"); - } -// DCL(Double Check Lock双端检锁机制) - public static SingletonDemo getInstance(){ - if(instance==null){ - synchronized (SingletonDemo.class){ - if(instance==null){ - instance = new SingletonDemo(); - } - } - - } - return instance; - } - - public static void main(String[] args){ -// 单线程(main线程的操作) -// System.out.println(SingletonDemo.getInstance()==SingletonDemo.getInstance()); -// System.out.println(SingletonDemo.getInstance()==SingletonDemo.getInstance()); -// System.out.println(SingletonDemo.getInstance()==SingletonDemo.getInstance()); -// -// System.out.println(",,,,,"); - -// 并发多线程后,情况发生了很大的变化 - for(int i=1;i<=10;i++){ - new Thread(()->{ - SingletonDemo.getInstance(); - },String.valueOf(i)).start(); - } - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SoftReferenceDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SoftReferenceDemo.java" deleted file mode 100644 index 1880c0405e586c99bba22340a9690da41ecf0fcc..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SoftReferenceDemo.java" +++ /dev/null @@ -1,41 +0,0 @@ -import java.lang.ref.SoftReference; - -public class SoftReferenceDemo { - /* - * 内存够用的时候就保留,不够用就回收 - * */ - public static void softRef_Memory_Enough(){ - Object o1 = new Object(); - SoftReference softReference = new SoftReference<>(o1); - System.out.println(o1); - System.out.println(softReference.get()); - - o1 = null; - System.gc(); - System.out.println(o1); - System.out.println(softReference.get()); - } - - public static void softRef_Memory_NotEnough(){ - Object o1 = new Object(); - SoftReference softReference = new SoftReference<>(o1); - System.out.println(o1); - System.out.println(softReference.get()); - - o1 = null; - - try{ - byte[] bytes = new byte[30*1024*1024]; - }catch (Throwable e){ - e.printStackTrace(); - }finally { - System.out.println(o1); - System.out.println(softReference.get()); - } - } - - public static void main(String[] args){ - //softRef_Memory_Enough(); - softRef_Memory_NotEnough(); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SpinLockDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SpinLockDemo.java" deleted file mode 100644 index 947a475596b6758b400584b9c85eeccb62f8a5ec..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SpinLockDemo.java" +++ /dev/null @@ -1,41 +0,0 @@ -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -/* -* 写一个自旋锁 -* 自旋锁的好处:循环比较获取直到成功为止,没有类似wait的阻塞。 -* */ -public class SpinLockDemo { - AtomicReference atomicReference = new AtomicReference<>(); - - public void myLock(){ - Thread thread = Thread.currentThread(); - System.out.println(Thread.currentThread().getName()+"\t come in "); - while(!atomicReference.compareAndSet(null,thread)){ - - } - } - - public void myUnLock(){ - Thread thread = Thread.currentThread(); - atomicReference.compareAndSet(thread,null); - System.out.println(Thread.currentThread().getName()+"\t invoked myUnLock()"); - } - - public static void main(String[] args){ -// 原子引用线程 - SpinLockDemo spinLockDemo = new SpinLockDemo(); - new Thread(()->{ - spinLockDemo.myLock(); - try{ TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) {e.printStackTrace();} - },"AA").start(); - - try{ TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace();} - - new Thread(()->{ - spinLockDemo.myLock(); - try{ TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) {e.printStackTrace();} - },"BB").start(); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/StackOverflowErrorDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/StackOverflowErrorDemo.java" deleted file mode 100644 index 5d9064b6a8be880faa15fa72e5548a67c65751ab..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/StackOverflowErrorDemo.java" +++ /dev/null @@ -1,9 +0,0 @@ -public class StackOverflowErrorDemo { - public static void main(String[] args){ - stackOverflowError(); - } - - private static void stackOverflowError() { - stackOverflowError(); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/StrongReferenceDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/StrongReferenceDemo.java" deleted file mode 100644 index d266bd133a39376a1da101c6ef74d1391170e919..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/StrongReferenceDemo.java" +++ /dev/null @@ -1,9 +0,0 @@ -public class StrongReferenceDemo { - public static void main(String[] args){ - Object obj1 = new Object();//这样定义默认的就是强引用 - Object obj2 = obj1;//obj2引用赋值 - obj1 = null; - System.gc(); - System.out.println(obj2); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SyncAndReentrantLockDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SyncAndReentrantLockDemo.java" deleted file mode 100644 index 7e305ba74ef29906c2e801d30366b25305ed9c93..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SyncAndReentrantLockDemo.java" +++ /dev/null @@ -1,108 +0,0 @@ -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -/* -* 题目:多线程之间按顺序调用,实现A->B->C三个线程启动,要求如下: -* A打印5次,B打印10次,C打印15次 -* 紧接着 -* A打印5次,B打印10次,C打印15次 -* 。。。。。 -* 打印10轮 -* */ -class ShareResource{ - private int number = 1;//A:1.B:2,C:3 - private Lock lock = new ReentrantLock(); - private Condition c1 = lock.newCondition(); - private Condition c2 = lock.newCondition(); - private Condition c3 = lock.newCondition(); - - public void print5(){ - lock.lock(); - try{ - //1判断 - while(number != 1){ - c1.await(); - } - //2干活 - for(int i=1;i<=5;i++){ - System.out.println(Thread.currentThread().getName()+"\t"+i); - } - //3通知 - number = 2; - c2.signal(); - }catch (Exception e){ - e.printStackTrace(); - }finally { - lock.unlock(); - } - } - - public void print10(){ - lock.lock(); - try{ - //1判断 - while(number != 2){ - c2.await(); - } - //2干活 - for(int i=1;i<=10;i++){ - System.out.println(Thread.currentThread().getName()+"\t"+i); - } - //3通知 - number = 3; - c3.signal(); - }catch (Exception e){ - e.printStackTrace(); - }finally { - lock.unlock(); - } - } - - public void print15(){ - lock.lock(); - try{ - //1判断 - while(number != 3){ - c3.await(); - } - //2干活 - for(int i=1;i<=15;i++){ - System.out.println(Thread.currentThread().getName()+"\t"+i); - } - //3通知 - number = 1; - c1.signal(); - }catch (Exception e){ - e.printStackTrace(); - }finally { - lock.unlock(); - } - } - - - - -} - -public class SyncAndReentrantLockDemo { - public static void main(String[] args){ - ShareResource shareResource = new ShareResource(); - - new Thread(()->{ - for(int i=1;i<=10;i++){ - shareResource.print5(); - } - },"A").start(); - new Thread(()->{ - for(int i=1;i<=10;i++){ - shareResource.print10(); - } - },"B").start(); - new Thread(()->{ - for(int i=1;i<=10;i++){ - shareResource.print15(); - } - },"C").start(); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SynchronousQueueDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SynchronousQueueDemo.java" deleted file mode 100644 index 49eb33ad25336589efd9cbcf31d07166878b6ad6..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/SynchronousQueueDemo.java" +++ /dev/null @@ -1,40 +0,0 @@ -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.TimeUnit; - -/* -* 阻塞队列SynchronousQueue演示 -* */ -public class SynchronousQueueDemo { - public static void main(String[] args){ - BlockingQueue blockingQueue = new SynchronousQueue<>(); - - new Thread(()->{ - try{ - System.out.println(Thread.currentThread().getName()+"\t put 1"); - blockingQueue.put("1"); - System.out.println(Thread.currentThread().getName()+"\t put 2"); - blockingQueue.put("2"); - System.out.println(Thread.currentThread().getName()+"\t put 3"); - blockingQueue.put("3"); - } catch (InterruptedException e){ - e.printStackTrace(); - } - },"AAA").start(); - - new Thread(()->{ - try{ - try{ TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e){ e.printStackTrace(); } - System.out.println(Thread.currentThread().getName()+"\t"+blockingQueue.take()); - - try{ TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e){ e.printStackTrace(); } - System.out.println(Thread.currentThread().getName()+"\t"+blockingQueue.take()); - - try{ TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e){ e.printStackTrace(); } - System.out.println(Thread.currentThread().getName()+"\t"+blockingQueue.take()); - } catch (InterruptedException e){ - e.printStackTrace(); - } - },"BBB").start(); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/VolatileDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/VolatileDemo.java" deleted file mode 100644 index ad7e2ae0ab242f4df3ef0fbdd3774ef4f5438f6d..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/VolatileDemo.java" +++ /dev/null @@ -1,54 +0,0 @@ -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -class MyData{ - volatile int number = 0; - public void addTo60(){ - this.number = 60; - } - public void addPlusPlus(){ - number++; - } - - AtomicInteger atomicInteger = new AtomicInteger(); - public void addMyAtommic(){ - atomicInteger.getAndIncrement(); - } -} -/* -1 验证volatile的可见性 - 1.1 加入int number=0,number变量之前根本没有添加volatile关键字修饰,没有可见性 - 1.2 添加了volatile,可以解决可见性问题 -2 验证volatile不保证原子性 - - 2.1 原子性是不可分割,完整性,也即某个线程正在做某个具体业务时,中间不可以被加塞或者分割。 - 需要整体完成,要么同时成功,要么同时失败。 - - 2.2 volatile不可以保证原子性演示 - - 2.3 如何解决原子性 - *加sync - *使用我们的JUC下AtomicInteger - -* */ -public class VolatileDemo { - public static void main(String[] args){ - MyData myData = new MyData(); - for (int i = 1; i <= 20 ; i++) { - new Thread(()->{ - for (int j = 1; j <= 1000 ; j++) { - myData.addPlusPlus(); - myData.addMyAtommic(); - } - },String.valueOf(i)).start(); - } - - //需要等待上述20个线程都计算完成后,再用main线程去的最终的结果是多少? -// try{TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();} - while(Thread.activeCount() > 2){ - Thread.yield(); - } - System.out.println(Thread.currentThread().getName()+"\t finnally number value: "+myData.number); - System.out.println(Thread.currentThread().getName()+"\t finnally number value: "+myData.atomicInteger); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/WeakHashMapDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/WeakHashMapDemo.java" deleted file mode 100644 index 9e0d416384e7442f1b51580dba6f9ccf50784402..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/WeakHashMapDemo.java" +++ /dev/null @@ -1,41 +0,0 @@ -import java.lang.ref.WeakReference; -import java.util.HashMap; -import java.util.WeakHashMap; - -public class WeakHashMapDemo { - public static void main(String[] args){ - myHashMap(); - System.out.println("========"); - myWeakHashMap(); - } - - private static void myHashMap(){ - HashMap map = new HashMap<>(); - Integer key = new Integer(1); - String value = "HashMap"; - - map.put(key,value); - System.out.println(map); - - key = null; - System.out.println(map); - - System.gc(); - System.out.println(map); - } - - private static void myWeakHashMap(){ - WeakHashMap map = new WeakHashMap<>(); - Integer key = new Integer(2); - String value = "WeakHashMap"; - - map.put(key,value); - System.out.println(map); - - key = null; - System.out.println(map); - - System.gc(); - System.out.println(map); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/WeakReferenceDemo.java" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/WeakReferenceDemo.java" deleted file mode 100644 index ba8c9c789a9a1defbedf4cba55f352d892f92b65..0000000000000000000000000000000000000000 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Demo\344\273\243\347\240\201/WeakReferenceDemo.java" +++ /dev/null @@ -1,17 +0,0 @@ -import java.lang.ref.WeakReference; - -public class WeakReferenceDemo { - public static void main(String[] args){ - Object o1 = new Object(); - WeakReference weakReference = new WeakReference<>(o1); - System.out.println(o1); - System.out.println(weakReference.get()); - - o1 = null; - System.gc(); - System.out.println("..............."); - - System.out.println(o1); - System.out.println(weakReference.get()); - } -} diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Java\351\235\242\350\257\225\351\242\230.xmind" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Java\351\235\242\350\257\225\351\242\230.xmind" deleted file mode 100644 index b2ca56fa2fabed8e54c46abd529eab4ccbdea31f..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267-\344\272\222\350\201\224\347\275\221\345\244\247\345\216\202\351\253\230\351\242\221\351\207\215\347\202\271\351\235\242\350\257\225\351\242\230\347\254\2542\345\255\243(\344\270\212)-\346\200\235\347\273\264\345\257\274\345\233\276+Demo\344\273\243\347\240\201/Java\351\235\242\350\257\225\351\242\230.xmind" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267Redis\350\257\276\347\250\213\346\200\235\347\273\264\345\257\274\345\233\276.xmind" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267Redis\350\257\276\347\250\213\346\200\235\347\273\264\345\257\274\345\233\276.xmind" deleted file mode 100644 index 5e58241b567814d240fb5a60015ea50693d4c7e6..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\345\260\232\347\241\205\350\260\267Redis\350\257\276\347\250\213\346\200\235\347\273\264\345\257\274\345\233\276.xmind" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\351\273\221\351\251\254\347\250\213\345\272\217\345\221\230-Redis\345\255\246\344\271\240\347\254\224\350\256\260.doc" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\351\273\221\351\251\254\347\250\213\345\272\217\345\221\230-Redis\345\255\246\344\271\240\347\254\224\350\256\260.doc" deleted file mode 100644 index 7104e1b884ae21d2e9bd951bb726fac03c9b6701..0000000000000000000000000000000000000000 Binary files "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java-master/\351\273\221\351\251\254\347\250\213\345\272\217\345\221\230-Redis\345\255\246\344\271\240\347\254\224\350\256\260.doc" and /dev/null differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java8\346\226\260\347\211\271\346\200\247/1_HashMap\345\217\230\345\214\226/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java8\346\226\260\347\211\271\346\200\247/1_HashMap\345\217\230\345\214\226/README.md" index 0f609e31d272e0d29af26395dc0a9b2d17beaaf2..715e0a3da74d9bbddc20c85cb6bfe39e44e6f84b 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java8\346\226\260\347\211\271\346\200\247/1_HashMap\345\217\230\345\214\226/README.md" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java8\346\226\260\347\211\271\346\200\247/1_HashMap\345\217\230\345\214\226/README.md" @@ -11,11 +11,7 @@ - 最大化减少空指针异常(Optional) - 。。。。 - - -## HashMap优化 - -### HashMap1.7 +## HashMap1.7 在JDK1.7 到 JDK1.8的时候,对HashMap做了优化 @@ -25,7 +21,7 @@ ![image-20200405101639700](images/image-20200405101639700.png) -### HashMap1.7存在死链问题 +## HashMap1.7存在死链问题 参考:[hashmap扩容时死循环问题](https://blog.csdn.net/chenyiminnanjing/article/details/82706942) @@ -165,7 +161,7 @@ e.next = newTable[i] 导致 key(3).next 指向了 key(7) 线程2生成的e和next的关系影响到了线程1里面的情况。从而打乱了正常的e和next的链。于是,当我们的线程一调用到,HashTable.get(11)时,即又到了3这个位置,需要插入新的,那这会就e 和next就乱了 -### HashMap每次扩容为什么是2倍 +## HashMap每次扩容为什么是2倍 参考:[HashMap初始容量为什么是2的n次幂](https://blog.csdn.net/apeopl/article/details/88935422) @@ -191,8 +187,7 @@ HashMap的容量为什么是2的n次幂,和这个(n - 1) & hash的计算方法 终上所述,HashMap计算添加元素的位置时,使用的位运算,这是特别高效的运算;另外,HashMap的初始容量是2的n次幂,扩容也是2倍的形式进行扩容,是因为容量是2的n次幂,可以使得添加的元素均匀分布在HashMap中的数组上,减少hash碰撞,避免形成链表的结构,使得查询效率降低 - -### JDK1.8结构变化 +## JDK1.8结构变化 由JDK1.7的,数组 + 链表 @@ -206,21 +201,132 @@ JDK1.8变为:数组 + 链表 + 红黑树 链表的查询和删除的时间复杂度: O(n),插入为:O(1) +## 为什么HashMap使用红黑树而不是AVL树 + +在JDK1.8版本后,Java对HashMap做了改进,在链表长度大于8的时候,将后面的数据由链表改成了红黑树,以加快检索的速度 + +但是为什么使用的红黑树,而不是AVL树或者其它树呢? + +> 最主要的原因:在CurrentHashMap中加锁了,实际上就是读写锁,如果写冲突就会等待,如果插入的时间过长,必然会导致等待的时间变长,而红黑树相比于AVL树,它的插入更快。 + +红黑树和AVL树都是常见的平衡二叉树,它们的查找,删除,修改的时间复杂度都是 O(log n) + +AVL树和红黑树相比有以下的区别 +- AVL树是更加严格的平衡,因此可以提供更快的查找速度,一般读取查找密集型任务,适用AVL树 +- 红黑树更适合插入修改密集型任务 +- 通常,AVL树的旋转比红黑树的旋转更加难以平衡和调试 -### ConcurrentHashMap变化 +### 总结 -#### 为何JDK8要放弃分段锁? +- AVL以及红黑树都是高度平衡的树形结构,它们非常的相似,真正的区别在于任何添加、删除操作时完成的旋转操作次数 +- 两种时间复杂度都是O(logN),其中N是叶子的数量,但实际上AVL树在查找密集型任务上更快,利用更好的平衡,树遍历平均更短,另一方面,插入和删除上,AVL树较慢,因为需要更高的旋转次数才能在修改时正确地重新平衡数据结构 +- 在AVL树中,从根到任何叶子节点的最短路径和最长路径之间的差异最多为1,在红黑树中,差异可以是2倍 +- 两个都是O(logN)查找,但是平衡二叉树可能需要 O(logN)旋转,而红黑树需要最多两次旋转使其达到平衡(尽可能需要检查O(logN)节点以确定旋转的位置),旋转本身是O(1)操作,因为你只需要移动指针。 + +## ConcurrentHashMap变化 + +### 为何JDK8要放弃分段锁? 由原来的分段锁,变成了CAS,也就是通过无锁化设计替代了阻塞同步的加锁操作,性能得到了提高。 +- 通过使用Synchronized + CAS的方式实现并发访问 + 通过分段锁的方式提高了并发度。分段是一开始就确定的了,后期不能再进行扩容的,其中的段Segment继承了重入锁ReentrantLock,有了锁的功能,同时含有类似HashMap中的数组加链表结构(这里没有使用红黑树),虽然Segment的个数是不能扩容的,但是单个Segment里面的数组是可以扩容的。 JDK1.8的ConcurrentHashMap摒弃了1.7的segment设计,而是JDK1.8版本的HashMap的基础上实现了线程安全的版本,即也是采用**数组+链表+红黑树**的形式,虽然ConcurrentHashMap的读不需要锁,但是需要保证能读到最新数据,所以必须加volatile。即数组的引用需要加volatile,同时一个Node节点中的val和next属性也必须要加volatile。 至于为什么抛弃Segment的设计,是因为分段锁的这个段不太好评定,如果我们的Segment设置的过大,那么隔离级别也就过高,那么就有很多空间被浪费了,也就是会让某些段里面没有元素,如果太小容易造成冲突 +### 弃用的原因 + +通过上述描述以及查看官方文档,弃用分段锁的原因主要有以下几点 + +- 加入多个分段锁 浪费了内存空间 +- 生产环境中,map在放入时 竞争同一个锁的概率非常小,分段锁反而会造成更新等操作的长时间等待 +- 为了提高GC的效率 + +### 新的同步方案 + +既然弃用了分段锁,那么一定有新的线程安全方案,我们来看看源码是怎么解决线程安全的呢? + +> 源码保留segment代码,但是并没有使用 +首先通过hash找到对应链表后,查看是否第一个object,如果是直接用CAS原则插入,无需加锁 + +```java +Node f; int n, i, fh; K fk; V fv; +if (tab == null || (n = tab.length) == 0) + // 这里在整个map第一次操作时,初始化hash桶, 也就是一个table + tab = initTable(); +else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { + //如果是第一个object, 则直接cas放入, 不用锁 + if (casTabAt(tab, i, null, new Node(hash, key, value))) + break; +} +``` + +然后, 如果不是链表第一个object, 则直接用链表第一个object加锁,这里加的锁是Synchronized,虽然效率不如 ReentrantLock, 但节约了空间,这里会一直用第一个object为锁, 直到重新计算map大小, 比如扩容或者操作了第一个object为止。 + +```java +// 这里的f即为第一个链表的object +synchronized (f) { + if (tabAt(tab, i) == f) { + if (fh >= 0) { + binCount = 1; + for (Node e = f;; ++binCount) { + K ek; + if (e.hash == hash && + ((ek = e.key) == key || + (ek != null && key.equals(ek)))) { + oldVal = e.val; + if (!onlyIfAbsent) + e.val = value; + break; + } + Node pred = e; + if ((e = e.next) == null) { + pred.next = new Node(hash, key, value); + break; + } + } + } + else if (f instanceof TreeBin) { // 太长会用红黑树 + Node p; + binCount = 2; + if ((p = ((TreeBin)f).putTreeVal(hash, key, + value)) != null) { + oldVal = p.val; + if (!onlyIfAbsent) + p.val = value; + } + } + else if (f instanceof ReservationNode) + throw new IllegalStateException("Recursive update"); + } +} +``` + +分段锁技术是在java8以前使用的,在java8已经弃用了,更新为synchronized+cas + +## ConcurrentHashMap为什么要使用synchronized而不是如ReentranLock这样的可重入锁? + +这个问题我们将要从几个角度来讨论 + +- 锁的粒度 + - 首先锁的粒度没有变粗,甚至变得更细了。每次扩容一次,ConcurrentHashMap的并发度就扩大 +- Hash冲突 + - 在JDK1.7中,ConcurrentHashMap从二次hash方式(Segment - > HashEntry)能够快速的找到查找的元素,在JDK1.8中,通过链表+红黑树的形式,弥补了put、get时的性能差距。 +- 扩容 + - JDK1.8中,在ConcurrentHashMap进行扩容时,其他线程可以通过检测数组中的节点决定是否对这条链表进行扩容,减少了扩容的粒度,提高了扩容的效率。 + +**为什么是用Synchronized 而不是 ReentrantLock?** + +- 减少内存开销 + - 假设使用可重入锁来获得同步支持,那么每个节点都需要通过继承AQS来获得同步支持。但并不是每个节点都需要同步支持,只有链表的头结点(红黑树的根节点)需要同步,这无疑带来了巨大的浪费 +- 获得JVM支持 + - 可重入锁毕竟是API这个级别的,后续的性能优化空间 很小 + - Synchronized则是由JVM直接支持,JVM能够在运行时做出对应的优化措施:锁粗化,锁消除,锁自旋等。这就是使得Synchronized能够随着JDK版本的升级而无需改动代码的前提下获得性能上的提升。 ## 内存结构优化 @@ -237,3 +343,9 @@ OOM错误发生概率降低 > MetaspaceSize > > MaxMetaspaceSize + +## 参考 + +- https://blog.csdn.net/zhangvalue/article/details/101483736 +- https://blog.csdn.net/apeopl/article/details/88935422 +- https://blog.csdn.net/chenyiminnanjing/article/details/82706942 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\344\270\255\347\232\204\344\270\223\344\270\232\350\257\215\346\261\207.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java\344\270\255\347\232\204\344\270\223\344\270\232\350\257\215\346\261\207.md" index 3d4d695293d8c053af50cc89d75ffea00180bd3c..f56213e4d4b7ba4e95a92f9371a820936af97dea 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/Java\344\270\255\347\232\204\344\270\223\344\270\232\350\257\215\346\261\207.md" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/Java\344\270\255\347\232\204\344\270\223\344\270\232\350\257\215\346\261\207.md" @@ -49,4 +49,11 @@ 49. myisam:MySQL数据库引擎 50. InnoDB:MySQL数据库引擎 51. sleuth:侦探,侦察 +52. seata:分布式事务解决方案 +53. transaction:事务 +54. SnowFlake:雪花算法,分布式ID的解决策略 +55. confirm:确认,RabbitMQ中的确认机制 +56. redis replication :redis主从复制 +57. Redis Cluster:Redis集群 +58. proxy:代理 diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/2_\344\273\243\347\240\201\345\235\227/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/2_\344\273\243\347\240\201\345\235\227/README.md" index 10f6adc84c54fdbe7730580183991062129d9437..43b3c32106ea2c73282f2440b8f1e01be2d3c767 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/2_\344\273\243\347\240\201\345\235\227/README.md" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/2_\344\273\243\347\240\201\345\235\227/README.md" @@ -76,6 +76,18 @@ public class CodeBlock02 { } ``` +运行结果如下 + +``` +第二构造块33333 +第一构造块33333 +构造方法2222 +========== +第二构造块33333 +第一构造块33333 +构造方法2222 +``` + 这里需要谈的就是,类加载机制了,因为我们都知道,当我们实例化一个类的时候 ``` diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/4_MySQL\347\232\204\345\255\230\345\202\250\345\274\225\346\223\216/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/4_MySQL\347\232\204\345\255\230\345\202\250\345\274\225\346\223\216/README.md" index dd7146bf999b0634228d6998b451eb2906c56172..1671d99fb89d748c0dbec1c894a73ea43952649b 100644 --- "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/4_MySQL\347\232\204\345\255\230\345\202\250\345\274\225\346\223\216/README.md" +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/4_MySQL\347\232\204\345\255\230\345\202\250\345\274\225\346\223\216/README.md" @@ -8,6 +8,11 @@ MyISAM是表锁,不支持事务和主外键 InnoDB默认可以创建16个索引 +- InnoDB支持事务,MyIsam不支持事务,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放到begin 和 commit之间,组成一个事务; +- InnoDB支持外键,而MyIsam不支持,对一个包含外键的InnoDB表转成MyIsam表会失败 +- InnoDB是聚集索引,数据文件和索引绑定在一块,必须要有主键,通过主键索引效率很高,但是辅助索引需要两次查询,先查询到主键,然后在通过主键查询到数据。因此主键不应该过大。主键过大的时候,其它索引也会很大。而MyIsam是非聚集索引,数据和文件是分离的,索引保存的是数据文件的指针,主键索引和辅助索引是独立的。 +- InnoDB不支持全文检索,而MyIsam支持全文检索,查询效率上MyIsam要高 + ## 硬盘 ![image-20200404085422944](images/image-20200404085422944.png) @@ -28,6 +33,53 @@ Mysql官方对索引的定位为:索引是帮助Mysql高效获取数据的数 为了加快Col2的查找,可以维护一个左边所示的二叉树,每个节点分别包含索引键值和一个指向对应数据记录的物理地址的指针,这样就可以运用二叉树在一定的复杂度内获取相应数据,从而快速的检索出符合条件的记录。 +## 聚簇索引和非聚簇索引 + +- 聚簇索引:将数据存储与索引放到一块,索引结构的叶子节点保存了行数据 +- 非聚簇索引:将数据与索引分开,索引结构的叶子节点指向了数据对应的位置 + +在InnoDB中,在聚簇索引之上创建的索引被称为辅助索引,非聚簇索引都是辅助索引,像复合索引,前缀索引,唯一索引。辅助索引叶子节点存储不再是行的物理位置,而是主键值,辅助索引访问数据总是需要二次查找,这个就被称为 回表操作 + +![image-20200723105915972](images/image-20200723105915972.png) + +InnoDB使用的是聚簇索引,将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶节点,之后获得行数据。 + +若对Name列进行条件搜索,则需要两个步骤:第一步在辅助索引B+树中检索Name,到达其叶子节点获取对应的主键。第二步使用主键在主索引B+树种再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据。(重点在于通过其他键需要建立辅助索引) + +**聚簇索引具有唯一性**,由于聚簇索引是将数据跟索引结构放到一块,因此一个表仅有一个聚簇索引。 + +**表中行的物理顺序和索引中行的物理顺序是相同的**,**在创建任何非聚簇索引之前创建聚簇索引**,这是因为聚簇索引改变了表中行的物理顺序,数据行 按照一定的顺序排列,并且自动维护这个顺序; + +**聚簇索引默认是主键**,如果表中没有定义主键,InnoDB 会选择一个**唯一且非空的索引**代替。如果没有这样的索引,InnoDB 会**隐式定义一个主键(类似oracle中的RowId)**来作为聚簇索引。如果已经设置了主键为聚簇索引又希望再单独设置聚簇索引,必须先删除主键,然后添加我们想要的聚簇索引,最后恢复设置主键即可。 + +MyISAM使用的是非聚簇索引,**非聚簇索引的两棵B+树看上去没什么不同**,节点的结构完全一致只是存储的内容不同而已,主键索引B+树的节点存储了主键,辅助键索引B+树存储了辅助键。表数据存储在独立的地方,这两颗B+树的叶子节点都使用一个地址指向真正的表数据,对于表数据来说,这两个键没有任何差别。由于**索引树是独立的,通过辅助键检索无需访问主键的索引树**。 + +![image-20200723110258929](images/image-20200723110258929.png) + +### 使用聚簇索引的优势 + +**每次使用辅助索引检索都要经过两次B+树查找,**看上去聚簇索引的效率明显要低于非聚簇索引,这不是多此一举吗?聚簇索引的优势在哪? + +1.由于行数据和聚簇索引的叶子节点存储在一起,同一页中会有多条行数据,访问同一数据页不同行记录时,已经把页加载到了Buffer中(缓存器),再次访问时,会在内存中完成访问,不必访问磁盘。这样主键和行数据是一起被载入内存的,找到叶子节点就可以立刻将行数据返回了,如果按照主键Id来组织数据,获得数据更快。 + +2.辅助索引的叶子节点,存储主键值,而不是数据的存放地址。好处是当行数据放生变化时,索引树的节点也需要分裂变化;或者是我们需要查找的数据,在上一次IO读写的缓存中没有,需要发生一次新的IO操作时,可以避免对辅助索引的维护工作,只需要维护聚簇索引树就好了。另一个好处是,因为辅助索引存放的是主键值,减少了辅助索引占用的存储空间大小。 + +注:我们知道一次io读写,可以获取到16K大小的资源,我们称之为读取到的数据区域为Page。而我们的B树,B+树的索引结构,叶子节点上存放好多个关键字(索引值)和对应的数据,都会在一次IO操作中被读取到缓存中,所以在访问同一个页中的不同记录时,会在内存里操作,而不用再次进行IO操作了。除非发生了页的分裂,即要查询的行数据不在上次IO操作的换村里,才会触发新的IO操作。 + +3.因为MyISAM的主索引并非聚簇索引,那么他的数据的物理地址必然是凌乱的,拿到这些物理地址,按照合适的算法进行I/O读取,于是开始不停的寻道不停的旋转。聚簇索引则只需一次I/O。(强烈的对比) + +4.不过,如果涉及到大数据量的排序、全表扫描、count之类的操作的话,还是MyISAM占优势些,因为索引所占空间小,这些操作是需要在内存中完成的。 + +### **聚簇索引需要注意的地方** + +当使用主键为聚簇索引时,主键最好不要使用uuid,因为uuid的值太过离散,不适合排序且可能出线新增加记录的uuid,会插入在索引树中间的位置,导致索引树调整复杂度变大,消耗更多的时间和资源。 + +建议使用int类型的自增,方便排序并且默认会在索引树的末尾增加主键值,对索引树的结构影响最小。而且,主键值占用的存储空间越大,辅助索引中保存的主键值也会跟着变大,占用存储空间,也会影响到IO操作读取到的数据量。 + +**为什么主键通常建议使用自增id** + +**聚簇索引的数据的物理存放顺序与索引顺序是一致的**,即:**只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的**。如果主键不是自增id,那么可以想 象,它会干些什么,不断地调整数据的物理地址、分页,当然也有其他一些措施来减少这些操作,但却无法彻底避免。但,如果是自增的,那就简单了,它只需要一 页一页地写,索引结构相对紧凑,磁盘碎片少,效率也高。 + ## B+树 B树:Balance Tree,多路平衡查找树 @@ -119,11 +171,17 @@ InnoDB:并不支持Hash索引 #### 问题 +可以看出平衡二叉树的缺点就是 + +- 维护平衡过程的成本代价很高,因为每次删除一个节点或者增加一个节点的话,需要一次或多次的左旋和右旋去维护平衡状态 +- 查询的效率不稳定,还要看运气的成分在里面 +- 如果节点很多的话,那么这个AVL树的高度还是会很高的,查询效率会很低。 + 从算法的数学逻辑来讲,二叉树的查找速度和比较次数都是最小的,那为什么我们选择BTree?因为AVL还有一个问题,那就是 磁盘IO的问题 - 磁盘IO的次数,就是由树高来决定的,也即磁盘的IO次数最坏的情况下就等于树的高度。 -随着数据量增加,树就会越高,那么查找的就越慢,而且导致的IO操作增加 +因为节点存储的数据太少,没有很好的利用操作系统和磁盘数据交换的特性,也没有利用好磁盘IO的预读能力。因为操作系统和磁盘之间一次数据交换是以页为单位的,一页 = 4K,即每次IO操作系统会将4K数据加载镜像内存。但是在二叉树每个节点的结构只保存一个关键字 和 数据区,两个子节点的引用,并不能填满4K的内容,辛辛苦苦的做了一次IO操作,却只加载了一个关键字,在树的高度很高,恰好要搜索的关键字位于叶子节点或支节点的时候,取一个关键字要做很多次的IO。因此平衡二叉树不太适合MySQL的查询结构。 #### 解决方法 @@ -131,8 +189,6 @@ InnoDB:并不支持Hash索引 那么就需要将树进行压缩,也就是将原来的瘦高 -> 矮胖,通过降低树的高度达到减少IO的次数 - - ### B树 B树,又被称为 2-3树,也就是B树上的节点,可能是2,也可能是3 @@ -225,8 +281,18 @@ B+树算法:通过集成B树的特征,B+树相比B树,新增叶子节点 从B树到B+树,B+树在B树的基础上的一种优化使其更适合实现外存储索引结构,InnoDB存储引擎就是用B+树实现的索引结构 +一般我们存储的数据在百万级别的话,B+树的高度都是三层左右 + B树和B+树的不同之处 - 非叶子节点只存储键值信息 -- 所有叶子节点之间都有一个链指针 -- 数据记录都存放在叶子节点中 \ No newline at end of file +- 所有叶子节点之间都有双向链指针 + - 可以基于叶子节点之间的范围查找 + - 或者基于根节点的查找 +- 数据记录都存放在叶子节点中 + +## 参考 + +https://blog.csdn.net/qq_36520235/article/details/94317993 + +https://my.oschina.net/xiaoyoung/blog/3046779 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/4_MySQL\347\232\204\345\255\230\345\202\250\345\274\225\346\223\216/images/image-20200723105915972.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/4_MySQL\347\232\204\345\255\230\345\202\250\345\274\225\346\223\216/images/image-20200723105915972.png" new file mode 100644 index 0000000000000000000000000000000000000000..d6e52cbd9559fcf30db25ae1338bcec7f7f89c12 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/4_MySQL\347\232\204\345\255\230\345\202\250\345\274\225\346\223\216/images/image-20200723105915972.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/4_MySQL\347\232\204\345\255\230\345\202\250\345\274\225\346\223\216/images/image-20200723110258929.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/4_MySQL\347\232\204\345\255\230\345\202\250\345\274\225\346\223\216/images/image-20200723110258929.png" new file mode 100644 index 0000000000000000000000000000000000000000..4eb44458ec63522eaf98efa1e3a5a3d61f08b9f6 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/4_MySQL\347\232\204\345\255\230\345\202\250\345\274\225\346\223\216/images/image-20200723110258929.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/5_JDK\345\212\250\346\200\201\344\273\243\347\220\206\345\222\214CGLIB\345\212\250\346\200\201\344\273\243\347\220\206/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/5_JDK\345\212\250\346\200\201\344\273\243\347\220\206\345\222\214CGLIB\345\212\250\346\200\201\344\273\243\347\220\206/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..754e8f9b8943f3d414b1dd34f481c905ead5ac66 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/5_JDK\345\212\250\346\200\201\344\273\243\347\220\206\345\222\214CGLIB\345\212\250\346\200\201\344\273\243\347\220\206/README.md" @@ -0,0 +1,310 @@ +# Java两种动态代理JDK动态代理和CGLIB动态代理 + +## 代理模式 + +代理模式是23种设计模式的一种,他是指一个对象A通过持有另一个对象B,可以具有B同样的行为的模式。为了对外开放协议,B往往实现了一个接口,A也会去实现接口。但是B是“真正”实现类,A则比较“虚”,他借用了B的方法去实现接口的方法。A虽然是“伪军”,但它可以增强B,在调用B的方法前后都做些其他的事情。Spring AOP就是使用了动态代理完成了代码的动态“织入”。 + +使用代理好处还不止这些,一个工程如果依赖另一个工程给的接口,但是另一个工程的接口不稳定,经常变更协议,就可以使用一个代理,接口变更时,只需要修改代理,不需要一一修改业务代码。从这个意义上说,所有调外界的接口,我们都可以这么做,不让外界的代码对我们的代码有侵入,这叫防御式编程。代理其他的应用可能还有很多。 + +上述例子中,类A写死持有B,就是B的静态代理。如果A代理的对象是不确定的,就是动态代理。动态代理目前有两种常见的实现,jdk动态代理和cglib动态代理。 + +## JDK动态代理 + +jdk动态代理是jre提供给我们的类库,可以直接使用,不依赖第三方。先看下jdk动态代理的使用代码,再理解原理。首先有个“明星”接口类,有唱、跳两个功能: + +```java +public interface Star +{ + String sing(String name); + + String dance(String name); +} +``` + +然后有明星实现类,“刘德华” + +```java + +public class LiuDeHua implements Star +{ + @Override + public String sing(String name) + { + System.out.println("给我一杯忘情水"); + + return "唱完" ; + } + + @Override + public String dance(String name) + { + System.out.println("开心的马骝"); + + return "跳完" ; + } +} +``` + +明星演出前需要有人收钱,由于要准备演出,自己不做这个工作,一般交给一个经纪人。便于理解,它的名字以Proxy结尾,但他不是代理类,原因是它没有实现我们的明星接口,无法对外服务,它仅仅是一个wrapper。 + +``` +package proxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +public class StarProxy implements InvocationHandler +{ + // 目标类,也就是被代理对象 + private Object target; + + public void setTarget(Object target) + { + this.target = target; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable + { + // 这里可以做增强 + System.out.println("收钱"); + + Object result = method.invoke(target, args); + + return result; + } + + // 生成代理类 + public Object CreatProxyedObj() + { + return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); + } + +} +``` + +上述例子中,方法CreatProxyedObj返回的对象才是我们的代理类,它需要三个参数,前两个参数的意思是在同一个classloader下通过接口创建出一个对象,该对象需要一个属性,也就是第三个参数,它是一InvocationHandler。需要注意的是这个CreatProxyedObj方法不一定非得在我们的StarProxy类中,往往放在一个工厂类中。上述代理的代码使用过程一般如下: + +- new一个目标对象 + +- new一个InvocationHandler,将目标对象set进去 + +- 通过CreatProxyedObj创建代理对象,强转为目标对象的接口类型即可使用,实际上生成的代理对象实现了目标接口。 + +``` +Star ldh = new LiuDeHua(); + +StarProxy proxy = new StarProxy(); + +proxy.setTarget(ldh); + +Object obj = proxy.CreatProxyedObj(); + +Star star = (Star)obj; +``` + +Proxy(jdk类库提供)根据B的接口生成一个实现类,我们称为C,它就是动态代理类(该类型是 $Proxy+数字 的“新的类型”)。生成过程是:由于拿到了接口,便可以获知接口的所有信息(主要是方法的定义),也就能声明一个新的类型去实现该接口的所有方法,这些方法显然都是“虚”的,它调用另一个对象的方法。当然这个被调用的对象不能是对象B,如果是对象B,我们就没法增强了,等于饶了一圈又回来了。 + +所以它调用的是B的包装类,这个包装类需要我们来实现,但是jdk给出了约束,它必须实现InvocationHandler,上述例子中就是StarProxy, 这个接口里面有个方法,它是所有Target的所有方法的调用入口(invoke),调用之前我们可以加自己的代码增强。 + +看下我们的实现,我们在InvocationHandler里调用了对象B(target)的方法,调用之前增强了B的方法。 + +```java +@Override +public Object invoke(Object proxy, Method method, Object[] args) throws Throwable +{ + // 这里增强 + System.out.println("收钱"); + + Object result = method.invoke(target, args); + + return result; +} +``` + +所以可以这么认为C代理了InvocationHandler,InvocationHandler代理了我们的类B,两级代理。 + +整个JDK动态代理的秘密也就这些,简单一句话,动态代理就是要生成一个包装类对象,由于代理的对象是动态的,所以叫动态代理。由于我们需要增强,这个增强是需要留给开发人员开发代码的,因此代理类不能直接包含被代理对象,而是一个InvocationHandler,该InvocationHandler包含被代理对象,并负责分发请求给被代理对象,分发前后均可以做增强。从原理可以看出,JDK动态代理是“对象”的代理。 + +下面看下动态代理类到底如何调用的InvocationHandler的,为什么InvocationHandler的一个invoke方法能为分发target的所有方法。C中的部分代码示例如下,通过反编译生成后的代码查看,摘自链接地址。Proxy创造的C是自己(Proxy)的子类,且实现了B的接口,一般都是这么修饰的: + +```java +public final class XXX extends Proxy implements XXX +``` + +一个方法代码如下 + +```java + + public final String SayHello(String paramString) + { + try + { + return (String)this.h.invoke(this, m4, new Object[] { paramString }); + } + catch (Error|RuntimeException localError) + { + throw localError; + } + catch (Throwable localThrowable) + { + throw new UndeclaredThrowableException(localThrowable); + } +} +``` + +可以看到,C中的方法全部通过调用h实现,其中h就是InvocationHandler,是我们在生成C时传递的第三个参数。这里还有个关键就是SayHello方法(业务方法)跟调用invoke方法时传递的参数m4一定要是一一对应的,但是这些对我们来说都是透明的,由Proxy在newProxyInstance时保证的。留心看到C在invoke时把自己this传递了过去,InvocationHandler的invoke的第一个方法也就是我们的动态代理实例类,业务上有需要就可以使用它。(所以千万不要在invoke方法里把请求分发给第一个参数,否则很明显就死循环了)C类中有B中所有方法的成员变量 + +``` +private static Method m1; +private static Method m3; +private static Method m4; +private static Method m2; +private static Method m0; +``` + +这些变量在static静态代码块初始化,这些变量是在调用invocationhander时必要的入参,也让我们依稀看到Proxy在生成C时留下的痕迹。 + +``` +static + { + try + { + m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); + m3 = Class.forName("jiankunking.Subject").getMethod("SayGoodBye", new Class[0]); + m4 = Class.forName("jiankunking.Subject").getMethod("SayHello", new Class[] { Class.forName("java.lang.String") }); + m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); + m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); + return; + } + catch (NoSuchMethodException localNoSuchMethodException) + { + throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); + } + catch (ClassNotFoundException localClassNotFoundException) + { + throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); + } + } +``` + +从以上分析来看,要想彻底理解一个东西,再多的理论不如看源码,底层的原理非常重要。 + +jdk动态代理类图如下 + +![image-20200429101023902](images/image-20200429101023902.png) + +## CGLIB动态代理 + +我们了解到,“代理”的目的是构造一个和被代理的对象有同样行为的对象,一个对象的行为是在类中定义的,对象只是类的实例。所以构造代理,不一定非得通过持有、包装对象这一种方式。 + +通过“继承”可以继承父类所有的公开方法,然后可以重写这些方法,在重写时对这些方法增强,这就是cglib的思想。根据里氏代换原则(LSP),父类需要出现的地方,子类可以出现,所以cglib实现的代理也是可以被正常使用的。 + +先看下代码 + +```java +package proxy; + +import java.lang.reflect.Method; + +import net.sf.cglib.proxy.Enhancer; +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.MethodProxy; + +public class CglibProxy implements MethodInterceptor +{ + // 根据一个类型产生代理类,此方法不要求一定放在MethodInterceptor中 + public Object CreatProxyedObj(Class clazz) + { + Enhancer enhancer = new Enhancer(); + + enhancer.setSuperclass(clazz); + + enhancer.setCallback(this); + + return enhancer.create(); + } + + @Override + public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable + { + // 这里增强 + System.out.println("收钱"); + + return arg3.invokeSuper(arg0, arg2); + } +} +``` + +从代码可以看出,它和jdk动态代理有所不同,对外表现上看CreatProxyedObj,它只需要一个类型clazz就可以产生一个代理对象, 所以说是“类的代理”,且创造的对象通过打印类型发现也是一个新的类型。不同于jdk动态代理,jdk动态代理要求对象必须实现接口(三个参数的第二个参数),cglib对此没有要求。 + +cglib的原理是这样,它生成一个继承B的类型C(代理类),这个代理类持有一个MethodInterceptor,我们setCallback时传入的。 C重写所有B中的方法(方法名一致),然后在C中,构建名叫“CGLIB”+“$父类方法名$”的方法(下面叫cglib方法,所有非private的方法都会被构建),方法体里只有一句话super.方法名(),可以简单的认为保持了对父类方法的一个引用,方便调用。 + +这样的话,C中就有了重写方法、cglib方法、父类方法(不可见),还有一个统一的拦截方法(增强方法intercept)。其中重写方法和cglib方法肯定是有映射关系的。 + +C的重写方法是外界调用的入口(LSP原则),它调用MethodInterceptor的intercept方法,调用时会传递四个参数,第一个参数传递的是this,代表代理类本身,第二个参数标示拦截的方法,第三个参数是入参,第四个参数是cglib方法,intercept方法完成增强后,我们调用cglib方法间接调用父类方法完成整个方法链的调用。 + +这里有个疑问就是intercept的四个参数,为什么我们使用的是arg3而不是arg1? + +``` + @Override + public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable + { + System.out.println("收钱"); + + return arg3.invokeSuper(arg0, arg2); + } +``` + + 因为如果我们通过反射 arg1.invoke(arg0, ...)这种方式是无法调用到父类的方法的,子类有方法重写,隐藏了父类的方法,父类的方法已经不可见,如果硬调arg1.invoke(arg0, ...)很明显会死循环。 + +所以调用的是cglib开头的方法,但是,我们使用arg3也不是简单的invoke,而是用的invokeSuper方法,这是因为cglib采用了fastclass机制,不仅巧妙的避开了调不到父类方法的问题,还加速了方法的调用。 + +fastclass基本原理是,给每个方法编号,通过编号找到方法执行避免了通过反射调用。 + +对比JDK动态代理,cglib依然需要一个第三者分发请求,只不过jdk动态代理分发给了目标对象,cglib最终分发给了自己,通过给method编号完成调用。cglib是继承的极致发挥,本身还是很简单的,只是fastclass需要另行理解。 + +## JDK动态代理和CGLIB的区别 + +DK动态代理只能对实现了接口的类生成代理,而不能针对类。 + +CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final, 对于final类或方法,是无法继承的 + +使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,在jdk6之前比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类 + +在jdk6、jdk7、jdk8逐步对JDK动态代理优化之后,在调用次数较少的情况下,JDK代理效率高于CGLIB代理效率,只有当进行大量调用的时候,jdk6和jdk7比CGLIB代理效率低一点,但是到jdk8的时候,jdk代理效率高于CGLIB代理,总之,每一次jdk版本升级,jdk代理效率都得到提升,而CGLIB代理消息确有点跟不上步伐Spring如何选择用 + +JDK还是CGLIB? + +- 当Bean实现接口时,Spring就会用JDK的动态代理。 +- 当Bean没有实现接口时,Spring使用CGlib是实现。 + +为什么继承只能使用CGLib,因为JDK代理生成的代理类,默认会继承一个类,由于java是单继承,所以当原始类继承一个类的时候,只能使用CGLib动态代理 + +## 总结 + +- 如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP。 +- 如果目标对象实现了接口,可以强制使用CGLIB实现AOP。 +- 如果目标对象没有实现了接口,必须采用CGLIB库,Spring会自动在JDK动态代理和CGLIB之间转换 + + + +JDK代理是不需要第三方库支持,只需要JDK环境就可以进行代理,使用条件: + +- 实现InvocationHandler + +- 使用Proxy.newProxyInstance产生代理对象 + +- 被代理的对象必须要实现接口 + + +CGLib必须依赖于CGLib的类库,但是它需要类来实现任何接口代理的是指定的类生成一个子类, + + + +## 来源 + +https://blog.csdn.net/yhl_jxy/article/details/80635012 + +https://blog.csdn.net/flyfeifei66/article/details/81481222 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/5_JDK\345\212\250\346\200\201\344\273\243\347\220\206\345\222\214CGLIB\345\212\250\346\200\201\344\273\243\347\220\206/images/image-20200429101023902.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/5_JDK\345\212\250\346\200\201\344\273\243\347\220\206\345\222\214CGLIB\345\212\250\346\200\201\344\273\243\347\220\206/images/image-20200429101023902.png" new file mode 100644 index 0000000000000000000000000000000000000000..c4ea564b8288e6615ecb0a20ee217ac57b5a829d Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\237\272\347\241\200\351\235\242\350\257\225\351\242\230/5_JDK\345\212\250\346\200\201\344\273\243\347\220\206\345\222\214CGLIB\345\212\250\346\200\201\344\273\243\347\220\206/images/image-20200429101023902.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..2542f04082d32e612cdb5e43d9124af5790af525 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/README.md" @@ -0,0 +1,410 @@ +# 集群高并发情况下如何保证分布式唯一全局Id生成 + +## 问题 + +### 为什么需要分布式全局唯一ID以及分布式ID的业务需求 + +在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识,如在美团点评的金融、支付、餐饮、酒店 + +猫眼电影等产品的系统中数据逐渐增长,对数据库分库分表后需要有一个唯一ID来标识一条数据或信息; + +特别Ian的订单、骑手、优惠券都需要有唯一ID做标识 + +此时一个能够生成全局唯一ID的系统是非常必要的 + +![image-20200418080900190](images/image-20200418080900190.png) + +### ID生成规则部分硬性要求 + +- 全局唯一 +- 趋势递增 + - 在MySQL的InnoDB引擎中使用的是聚集索引,由于多数RDBMS使用Btree的数据结构来存储索引,在主键的选择上面我们应该尽量使用有序的主键保证写入性能 +- 单调递增 + - 保证下一个ID一定大于上一个ID,例如事务版本号、IM增量消息、排序等特殊需求 +- 信息安全 + - 如果ID是连续,恶意用户的爬取工作就非常容易做了,直接按照顺序下载指定URL即可,如果是订单号就危险了,竞争对手可以直接知道我们一天的单量,所以在一些应用场景下,需要ID无规则不规则,让竞争对手不好猜 +- 含时间戳 + - 一样能够快速在开发中了解这个分布式ID什么时候生成的 + +### ID号生成系统的可用性要求 + +- 高可用 + - 发布一个获取分布式ID请求,服务器就要保证99.999%的情况下给我创建一个唯一分布式ID +- 低延迟 + - 发一个获取分布式ID的请求,服务器就要快,极速 +- 高QPS + - 例如并发一口气10万个创建分布式ID请求同时杀过来,服务器要顶得住且一下子成功创建10万个分布式ID + + + +## 一般通用解决方案 + +### UUID + +`UUID.randomUUID()` , UUID的标准型包含32个16进制数字,以连字号分为五段,形式为 8-4-4-4-12的36个字符,性能非常高,本地生成,没有网络消耗。 + +#### 存在问题 + +入数据库性能差,因为UUID是无序的 + +- 无序,无法预测他的生成顺序,不能生成递增有序的数字 + +首先分布式id一般都会作为逐渐,但是按照mysql官方推荐主键尽量越短越好,UUID每一个都很长,所以不是很推荐。 + +- 主键,ID作为主键时,在特定的环境下会存在一些问题 + +比如做DB主键的场景下,UUID就非常不适用MySQL官方有明确的说明 + +- 索引,B+树索引的分裂 + +既然分布式ID是主键,然后主键是包含索引的,而mysql的索引是通过B+树来实现的,每一次新的UUID数据的插入,为了查询的优化,都会对索引底层的B+树进行修改,因为UUID数据是无序的,所以每一次UUID数据的插入都会对主键的B+树进行很大的修改,这一点很不好,插入完全无序,不但会导致一些中间节点产生分裂,也会白白创造出很多不饱和的节点,这样大大降低了数据库插入的性能。 + + + +UUID只能保证全局唯一性,不满足后面的趋势递增,单调递增 + + + +### 数据库自增主键 + +#### 单机 + +在分布式里面,数据库的自增ID机制的主要原理是:数据库自增ID和mysql数据库的replace into实现的,这里的replace into跟insert功能 类似,不同点在于:replace into首先尝试插入数据列表中,如果发现表中已经有此行数据(根据主键或唯一索引判断)则先删除,在插入,否则直接插入新数据。 + +REPLACE INTO的含义是插入一条记录,如果表中唯一索引的值遇到冲突,则替换老数据 + +![image-20200418083435048](images/image-20200418083435048.png) + +``` +REPLACE into t_test(stub) values('b'); +select LAST_INSERT_ID(); +``` + +我们每次插入的时候,发现都会把原来的数据给替换,并且ID也会增加 + +这就满足了 + +- 递增性 +- 单调性 +- 唯一性 + +在分布式情况下,并且并发量不多的情况,可以使用这种方案来解决,获得一个全局的唯一ID + +#### 集群分布式集群 + +那数据库自增ID机制适合做分布式ID吗?答案是不太适合 + +系统水平扩展比较困难,比如定义好步长和机器台数之后,如果要添加机器该怎么办,假设现在有一台机器发号是:1,2,3,4,5,(步长是1),这个时候需要扩容机器一台,可以这样做:把第二胎机器的初始值设置得比第一台超过很多,貌似还好,但是假设线上如果有100台机器,这个时候扩容要怎么做,简直是噩梦,所以系统水平扩展方案复杂难以实现。 + +数据库压力还是很大,每次获取ID都得读写一次数据库,非常影响性能,不符合分布式ID里面的延迟低和高QPS的规则(在高并发下,如果都去数据库里面获取ID,那是非常影响性能的) + + + +### 基于Redis生成全局ID策略 + +#### 单机版 + +因为Redis是单线程,天生保证原子性,可以使用原子操作INCR和INCRBY来实现 + +INCRBY:设置增长步长 + +#### 集群分布式 + +注意:在Redis集群情况下,同样和MySQL一样需要设置不同的增长步长,同时key一定要设置有效期,可以使用Redis集群来获取更高的吞吐量。 + +假设一个集群中有5台Redis,可以初始化每台Redis的值分别是 1,2,3,4,5 , 然后设置步长都是5 + +``` +各个Redis生成的ID为: +A:1 6 11 16 21 +B:2 7 12 17 22 +C:3 8 13 18 23 +D:4 9 14 19 24 +E:5 10 15 20 25 +``` + +但是存在的问题是,就是Redis集群的维护和保养比较麻烦,配置麻烦。因为要设置单点故障,哨兵值守 + +但是主要是的问题就是,为了一个ID,却需要引入整个Redis集群,有种杀鸡焉用牛刀的感觉 + +## 雪花算法 + +### 是什么 + +Twitter的分布式自增ID算法,Snowflake + +最初Twitter把存储系统从MySQL迁移到Cassandra(由Facebook开发一套开源分布式NoSQL数据库系统)因为Cassandra没有顺序ID生成机制,所有开发了这样一套全局唯一ID生成服务。 + +Twitter的分布式雪花算法SnowFlake,经测试SnowFlake每秒可以产生26万个自增可排序的ID + +- twitter的SnowFlake生成ID能够按照时间有序生成 +- SnowFlake算法生成ID的结果是一个64Bit大小的整数,为一个Long型(转换成字符串后长度最多19) +- 分布式系统内不会产生ID碰撞(由datacenter 和 workerID做区分)并且效率较高 + +分布式系统中,有一些需要全局唯一ID的场景,生成ID的基本要求 + +- 在分布式环境下,必须全局唯一性 +- 一般都需要单调递增,因为一般唯一ID都会存在数据库,而InnoDB的特性就是将内容存储在主键索引上的叶子节点,而且是从左往右递增的,所有考虑到数据库性能,一般生成ID也最好是单调递增的。为了防止ID冲突可以使用36位UUID,但是UUID有一些缺点,首先是它相对比较长,并且另外UUID一般是无序的 +- 可能还会需要无规则,因为如果使用唯一ID作为订单号这种,为了不让别人知道一天的订单量多少,就需要这种规则 + +### 结构 + +雪花算法的几个核心组成部分 + +![image-20200418091447935](images/image-20200418091447935.png) + +在Java中64bit的证书是long类型,所以在SnowFlake算法生成的ID就是long类存储的 + +#### 第一部分 + +二进制中最高位是符号位,1表示负数,0表示正数。生成的ID一般都是用整数,所以最高位固定为0。 + +#### 第二部分 + +第二部分是41bit时间戳位,用来记录时间戳,毫秒级 + +41位可以表示 2^41 -1 个数字 + +如果只用来表示正整数,可以表示的范围是: 0 - 2^41 -1,减1是因为可以表示的数值范围是从0开始计算的,而不是从1。 + +也就是说41位可以表示 2^41 - 1 毫秒的值,转换成单位年则是 69.73年 + +#### 第三部分 + +第三部分为工作机器ID,10Bit用来记录工作机器ID + +可以部署在2^10 = 1024个节点,包括5位 datacenterId(数据中心,机房) 和 5位 workerID(机器码) + +5位可以表示的最大正整数是 2 ^ 5 = 31个数字,来表示不同的数据中心 和 机器码 + +#### 第四部分 + +12位bit可以用来表示的正整数是 2^12 = 4095,即可以用0 1 2 .... 4094 来表示同一个机器同一个时间戳内产生的4095个ID序号。 + +#### SnowFlake可以保证 + +所有生成的ID按时间趋势递增 + +整个分布式系统内不会产生重复ID,因为有datacenterId 和 workerId来做区分 + +### 实现 + +雪花算法是由scala算法编写的,有人使用java实现,[github地址](https://github.com/beyondfengyu/SnowFlake/blob/master/SnowFlake.java) + +``` +/** + * twitter的snowflake算法 -- java实现 + * + * @author beyond + * @date 2016/11/26 + */ +public class SnowFlake { + + /** + * 起始的时间戳 + */ + private final static long START_STMP = 1480166465631L; + + /** + * 每一部分占用的位数 + */ + private final static long SEQUENCE_BIT = 12; //序列号占用的位数 + private final static long MACHINE_BIT = 5; //机器标识占用的位数 + private final static long DATACENTER_BIT = 5;//数据中心占用的位数 + + /** + * 每一部分的最大值 + */ + private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT); + private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT); + private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT); + + /** + * 每一部分向左的位移 + */ + private final static long MACHINE_LEFT = SEQUENCE_BIT; + private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT; + private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT; + + private long datacenterId; //数据中心 + private long machineId; //机器标识 + private long sequence = 0L; //序列号 + private long lastStmp = -1L;//上一次时间戳 + + public SnowFlake(long datacenterId, long machineId) { + if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) { + throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0"); + } + if (machineId > MAX_MACHINE_NUM || machineId < 0) { + throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0"); + } + this.datacenterId = datacenterId; + this.machineId = machineId; + } + + /** + * 产生下一个ID + * + * @return + */ + public synchronized long nextId() { + long currStmp = getNewstmp(); + if (currStmp < lastStmp) { + throw new RuntimeException("Clock moved backwards. Refusing to generate id"); + } + + if (currStmp == lastStmp) { + //相同毫秒内,序列号自增 + sequence = (sequence + 1) & MAX_SEQUENCE; + //同一毫秒的序列数已经达到最大 + if (sequence == 0L) { + currStmp = getNextMill(); + } + } else { + //不同毫秒内,序列号置为0 + sequence = 0L; + } + + lastStmp = currStmp; + + return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分 + | datacenterId << DATACENTER_LEFT //数据中心部分 + | machineId << MACHINE_LEFT //机器标识部分 + | sequence; //序列号部分 + } + + private long getNextMill() { + long mill = getNewstmp(); + while (mill <= lastStmp) { + mill = getNewstmp(); + } + return mill; + } + + private long getNewstmp() { + return System.currentTimeMillis(); + } + + public static void main(String[] args) { + SnowFlake snowFlake = new SnowFlake(2, 3); + + for (int i = 0; i < (1 << 12); i++) { + System.out.println(snowFlake.nextId()); + } + + } +} +``` + +### 工程落地经验 + +#### hutools工具包 + +地址:https://github.com/looly/hutool + +#### SpringBoot整合雪花算法 + +引入hutool工具类 + +``` + + cn.hutool + hutool-all + 5.3.1 + +``` + +整合 + +``` +/** + * 雪花算法 + * + * @author: 陌溪 + * @create: 2020-04-18-11:08 + */ +public class SnowFlakeDemo { + private long workerId = 0; + private long datacenterId = 1; + private Snowflake snowFlake = IdUtil.createSnowflake(workerId, datacenterId); + + @PostConstruct + public void init() { + try { + // 将网络ip转换成long + workerId = NetUtil.ipv4ToLong(NetUtil.getLocalhostStr()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 获取雪花ID + * @return + */ + public synchronized long snowflakeId() { + return this.snowFlake.nextId(); + } + + public synchronized long snowflakeId(long workerId, long datacenterId) { + Snowflake snowflake = IdUtil.createSnowflake(workerId, datacenterId); + return snowflake.nextId(); + } + + public static void main(String[] args) { + SnowFlakeDemo snowFlakeDemo = new SnowFlakeDemo(); + for (int i = 0; i < 20; i++) { + new Thread(() -> { + System.out.println(snowFlakeDemo.snowflakeId()); + }, String.valueOf(i)).start(); + } + } +} +``` + +得到结果 + +``` +1251350711346790400 +1251350711346790402 +1251350711346790401 +1251350711346790403 +1251350711346790405 +1251350711346790404 +1251350711346790406 +1251350711346790407 +1251350711350984704 +1251350711350984706 +1251350711350984705 +1251350711350984707 +1251350711350984708 +1251350711350984709 +1251350711350984710 +1251350711350984711 +1251350711350984712 +1251350711355179008 +1251350711355179009 +1251350711355179010 +``` + + + +### 优缺点 + +#### 优点 + +- 毫秒数在高维,自增序列在低位,整个ID都是趋势递增的 +- 不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是非常高的 +- 可以根据自身业务特性分配bit位,非常灵活 + +#### 缺点 + +- 依赖机器时钟,如果机器时钟回拨,会导致重复ID生成 +- 在单机上是递增的,但由于涉及到分布式环境,每台机器上的时钟不可能完全同步,有时候会出现不是全局递增的情况,此缺点可以认为无所谓,一般分布式ID只要求趋势递增,并不会严格要求递增,90%的需求只要求趋势递增。 + +#### 其它补充 + +为了解决时钟回拨问题,导致ID重复,后面有人专门提出了解决的方案 + +- 百度开源的分布式唯一ID生成器 UidGenerator +- Leaf - 美团点评分布式ID生成系统 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/images/005F78AC.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/images/005F78AC.png" new file mode 100644 index 0000000000000000000000000000000000000000..34d320208f3dc3784a4151c7eb648211bd4438a5 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/images/005F78AC.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/images/image-20200418080900190.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/images/image-20200418080900190.png" new file mode 100644 index 0000000000000000000000000000000000000000..73d6a98293bcb15aa4b338283f113eda380f3ce1 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/images/image-20200418080900190.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/images/image-20200418083435048.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/images/image-20200418083435048.png" new file mode 100644 index 0000000000000000000000000000000000000000..a1cb962c02b81945830d2ab17fde6bc7deb36c22 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/images/image-20200418083435048.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/images/image-20200418091447935.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/images/image-20200418091447935.png" new file mode 100644 index 0000000000000000000000000000000000000000..f106e470fc64fada82d70a0052a983b65722644a Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\345\244\247\345\216\202\351\235\242\350\257\225\347\254\254\344\270\211\345\255\243/\351\233\206\347\276\244\351\253\230\345\271\266\345\217\221\346\203\205\345\206\265\344\270\213\345\246\202\344\275\225\344\277\235\350\257\201\345\210\206\345\270\203\345\274\217\345\224\257\344\270\200\345\205\250\345\261\200Id\347\224\237\346\210\220/images/image-20200418091447935.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/1_\344\272\254\344\270\234\351\235\242\347\273\217/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/1_\344\272\254\344\270\234\351\235\242\347\273\217/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..21c843322c63367ee9c36cf4a174a108004ac5ca --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/1_\344\272\254\344\270\234\351\235\242\347\273\217/README.md" @@ -0,0 +1,190 @@ +作者:惊阵嗯 +链接:https://www.nowcoder.com/discuss/432918 +来源:牛客网 + +平时基本都在看牛油发的各种面经,对自己的春招作用很大,于是想写下京东的面经回馈给大家,顺便留下本菜鸡在这个春招里的一点痕迹。 + + 广东某二本科班,无比赛无项目,学校带学院后缀的那种,至今没有面试官听过我的学校,这两个月不断挣扎,曾与阿里、腾讯面试官面对面讨论技术,最终成功斩获多家名企的感谢信,包括但不限于阿里、腾讯、字节、美团、网易,人称“感谢信收藏家”,收获感upup~ + + 大概大二下学期我就意识到可能要凉,学校不占优,技术又差的一批,这样下去达成“毕业即失业”成就岂不是板上钉钉? + + 于是我把目标看向了春招,很多人可能觉得春招很早,这不是毕业生参与的事情嘛?恰恰相反,春招不仅仅面向应届毕业生,同时也是各大名企大肆招聘暑期实习生的时间,这个时间点你可不能错过。 + + 暑期实习生一般具有以下几个特征:转正率高(相对日常来说)、实习生培养计划、转正周期短(一般两个月就可发起转正)、规模大、流程正式(一般暑期实习生的流程和正式校招相仿)。 + + 其实暑期实习生留用是非常多的,秋招很大一部分的HC是被转正留用的实习生给占了,从另一方面来讲,就算转正失败,这段经历也是难能可贵的,在秋招中势必会得心应手,起码可以保证了offer的下限。 + + 其次,我个人觉得实习是非常重要的,尤其是在比较大型的公司实习,大牛云集,规范化的流程,内部技术底蕴沉淀很足,以我个人为例子,我特别喜欢在空闲时间查看团队的线上故障记录wiki,上面都是一些前人非常宝贵的经验,例如一些面试中比较常问的慢查询排查和优化、内存溢出、频繁FGC、设计模式的实际应用等等,在下次面试中如果被问到,你就可以大声的喊出:“我可以!我能行!另外就是技术沉淀这一块,像我现在正在实习的公司内部非常多优秀的自研框架,自研的消息队列和RPC框架等等,都是已经放在了线上,而且承受住非常高的并发考验的框架产品,都非常值得去研究和学习,甚至有可能这款框架的架构师就坐在你旁边呢~ + + 最后给我体会非常深刻的就是企业级项目的复杂度,太复杂太难了,一对比我之前写的项目可能连鸡毛都算不上(:泪目了 + + + + **一面(视频面) 1小时30分钟** + + 1、类加载机制概念、加载步骤、双亲委托机制、全盘委托机制、类加载器种类及继承关系 + + 2、如何实现让类加载器去加载网络上的资源文件?怎么自定义类加载器?自定义的加载器还符合双亲委托机制吗?怎么打破双亲委托机制? + + 3、实例化对象的方式有几种? + + 4、由Object类的clone方法引申到深复制和浅复制的区别 + + 5、反射的概念、用法、实践 + + 6、Java内存模型和JVM内存结构 + + 7、有一台4核8G的机器,该给JVM里的堆区和虚拟机栈分配多大的内存?(初始值、最大值、堆区年轻代和老年代的分配比例等等) + + 8、堆内存中的年轻代分配内存过少或过多分别有什么影响?复制算***导致Stop-the-World吗? + + 9、哪些参数可以设置JVM中的内存分配? + + 10、需要在线程范围内去共享一个变量,怎么实现?ThreadLocal源码实现、Key弱引用导致的内存泄露、怎么避免? + + (这道题我一直理解成在多个线程之间去共享变量,说了volatile,面试官一直说不对,后来我猜意识到是在线程范围内共享变量....) + + 11、volatile的作用、实现机制、缓存一致性实现 + + 12、AtomicInteger原子类的作用、源码实现机制 + + 13、CAS无锁算法概念、源码实现机制、Unsafe类源码延伸到HotSpot虚拟机对应的C++方法再延伸对应的汇编函数 + + 14、ReentrantLock中非公平锁的源码实现、AQS源码实现、为什么需要自旋锁?锁膨胀的过程? + + 15、线程池的使用场景、常用参数、拒绝策略 + + 16、阻塞队列的种类、底层数据结构和使用场景 + + 17、手写BIO的Socket编程、BIO和NIO的区别 + + 18、Netty线程模型、零拷贝、粘包拆包、心跳机制、Pipeline源码 + + 19、责任链模型、策略模式、模板模式、设计模式里的原则 + + 20、Top K问题,找到上千万个数字中从大到小的前10个数字 + + 21、MySQL中的聚集索引和稀疏索引区别、索引是越多越好吗?什么样的字段适合建索引? + + 22、索引覆盖和回表的概念、怎么避免回表? + + 23、为什么采用B+树而不用AVL树? + + 24、事务的底层实现 + + 25、MVCC的概念及实现机制 + + 26、Redis为什么这么快?为什么不用多线程? + + 27、哈希表查询的时间复杂度、哈希冲突的解决方法? + + 28、Sorted Set的应用场景、跳表的实现、查询和插入的时间复杂度? + + 29、Dubbo的应用场景、底层通信组件、服务降级、负载均衡、接口暴露、序列化方式、让你实现一个简单的RPC框架你会怎么做? + + 30、Zookeeper的应用场景、watch机制、领导者选举算法、ZK实现分布式锁 + + 31、对称加密、非对称加密、数字证书、HTTPS的连接过程、SSL加密一定安全吗?SSL在哪一层实现加密? + + 32、OSI七层协议?路由器工作在那一层?HTTP、TCP、FTP、DNS工作在哪一层? + + 33、ARP协议的作用及流程 + + 34、Git的操作、代码冲突的解决方法 + + 35、Redis的缓存穿透、缓存雪崩、数据一致性的解决方案 + + 36、Elasticsearch的倒排索引、index和document的概念、脑裂问题 + + 37、RabbitMQ应用场景、生产/消费者和发布/订阅模式概念和应用、数据丢失问题 + + 38、商品超卖的解决方法、MySQL乐观锁和Redis乐观锁 + + 39、手写SQL:有一个成绩表,表里有三个字段分别是姓名、课程和成绩,求课程平均分大于85分的学生姓名和平均成绩。 + + + 40、算法:写归并排序和快排、分析时间复杂度、怎么评定是不是一个稳定的排序算法? + + + + **二面(视频面) 50分钟** + + 1、Hashmap和Concurrenthashmap + + 2、线程池核心参数、拒绝策略 + + 3、SynchroQueue的应用场景? 可以存几个元素? + + 4、Lock的公平锁和非公平锁的怎么实现的 + + 5、说说AQS + + 6、Lock是怎么给线程分配锁的? + + 7、Spring Bean的生命周期 + + 8、说一说Spring的AOP + + 9、SpringBoot启动过程的源码 + + 10、怎么学习开源框架 + + 11、Netty零拷贝?心跳机制?粘包拆包? + + 12、ASM怎么实现cglib + + 13、说一说数据库有哪些索引?聚簇索引和非聚簇索引区别?什么是索引覆盖和回表?什么是索引下推? + + 14、二叉树和B+树的区别 + + 15、了解哪些常用的Linux命令 + + 16、Linux根目录下有哪些文件夹 + + 17、JVM常用命令 + + 18、jstat的常用参数 + + 19、进程通信方式 + + 20、Linux线程调度方式 + + 21、Linux的缓存有几级 + + 22、Redis的删除策略? + + 22、什么是分布式?分布式和微服务有什么联系?CAP理论听过吗?为什么CAP理论最多职能满足两个? + + 23、算法:环形链表入口 + + + + + **HR面(电话面) 18分钟** + + 没有自我介绍,直入主题。 + + 1、你觉得笔试难度怎么样? + + 2、我看你前几轮的综合成绩都蛮高的,未来想在北京发展吗? + + 3、像广州深圳杭州互联网公司都很多,为什么投了北京的岗位呢? + + 4、我可能比较直白一点,你的学历在我们这些候选人里面是比较低的,你觉得你的优势在哪里? + + 5、想过考研吗?不考研的话未来可能几年后你觉得有能力能胜任这些工作吗? + + 6、你觉得为什么自己没有上一些比较好的学校?专业是自己选的吗? + + 7、实习时长?给前两轮面试官一个评价? + + + + + 最后我反问了一些部门相关的信息,在这个过程中类似于压力面吧,大家可以从问题看到,都是问的比较犀利的,其实我完全可以理解,当时电话里我也一直说没关系没关系,我知道自己学历不占优势,甚至是劣势,从企业的角度看,有那么多985211的同学为什么要录取你呢? + + 这是很正常的利益权衡,最后真的很感谢狗东能给这次机会,尤其是非常感谢一面和二面面试官,在一面的自我介绍的时候我就调侃,自己学历这么差竟然能被捞出来面试,面试官就安慰我说没关系,我们这里比较看重能力,然后全程面试非常温和,我不懂的地方也和我详细的讲解,最后还给了我非常多的建议,真的超级赞,二面应该是一位leader的角色,头发很少哈哈哈,但是同样待人非常温和,不出意外应该是未来的leader了,最后同样也给了我非常多的意见,非常感谢! + + 从三月初投简历到现在五月底,能够给面试机会的企业寥寥无几,尤其是今年疫情的原因,找工作变得难上加难,这里非常感谢给我第一个offer的蘑菇街,让我在之后的面试更加游刃有余,甚至还拒掉了一些面试,今年春招一共拿到了京东、唯品会、蘑菇街、Thoughtworks四个offer,不出意外应该是七月份前往京东,做一个小小的北漂族,顺利的话希望能够在狗东转正,先为秋招垫下一个良好的开端,秋招加油! + + (对了,找合租小伙伴啦!入职时间为7月2号,地点是亦庄的小伙伴合租可以拉上我哦~) \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/2_\345\255\227\350\212\202\350\267\263\345\212\250\351\235\242\350\257\225\346\200\273\347\273\223/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/2_\345\255\227\350\212\202\350\267\263\345\212\250\351\235\242\350\257\225\346\200\273\347\273\223/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..a93a80a4b97f360c7361e96fe831cda86170a0ff --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/2_\345\255\227\350\212\202\350\267\263\345\212\250\351\235\242\350\257\225\346\200\273\347\273\223/README.md" @@ -0,0 +1,216 @@ +# 字节跳动面试总结 + +## 前言 + +前阵子字节跳动的提前批开始了,看宣传是说有海量HC,机会多多,本着涨涨面经的心理,然后就投递了一下杭州那边的Data部门,首先在这里还要非常感谢内推我的小哥哥,非常热心的帮我跟踪进度,因为中间还出了一些小插曲(我投错部门了。。。),还是热心的小哥哥帮我联系HR,最后把我转到想要投递的部门了~ + +## 第一面 + +第一面我觉得应该是基础面,重点考察的是自己技术的广度 和一些技术的掌握情况,一面小哥哥也没有深究于某个特定的点,面试时间大约1个小时。 + +- 自我介绍 + +- 怎么打算投递后台岗位的,没有考虑契合自己研究方向的工作 + +- 有了解过OAuth2.0么,说说你对OAuth2.0的理解 +- 蘑菇博客开发过程中,有了解或学习其它的开源框架么 +- 蘑菇博客文章发布的流程是怎么样的,是多人博客系统么 +- 对其它的一些博客框架有了解么,比如hexo +- hexo和蘑菇博客相比有什么区别呢?蘑菇博客多了哪些功能和优势 +- 看你蘑菇博客用到了RabbitMQ,那谈谈为什么引入RabbitMQ? +- RabbitMQ和其它消息队列,比如ActiveMQ,RocketMQ,Kafka有什么区别 +- Redis在你博客项目中的使用,为什么引入Redis? +- Redis中存储的是热门文章,是通过什么来得到的?这样做会有什么问题么? +- 有听过长尾效应么?你通过推荐字段设置的推荐等级,这样会让这些文章一直保持在较高的点击量,而且热度和点击量也不会随着时间而降低,有什么解决方案么? +- 我看到你有用到JustAuth这个登录授权?说说它会存在账号泄漏的问题么? +- 下面谈谈Redis,它会存在线程切换的问题么? +- 谈谈Redis单线程模型和IO多路复用 +- Redis的大Key的问题,如果有个Value的大小是2M,会有什么问题么?最大支持的Value大小是多少? +- 谈谈Redis集群 Redis Cluster,以及主从复制原理? +- 说说Redis中的哨兵,即Redis Sentinel +- 下面来聊聊Linux,你知道Linux怎么查看当前的负载情况么? +- 你还知道其它的一些Linux命令么? +- cat、tail、vi、vim命令的区别,分别说一说? +- 如果Linux下需要打开或者查看大文件,你会怎么做? +- 下面聊聊Http Code,你知道 3XX 状态码 对应的是什么? +- 在谈谈你知道的其它一些状态码,4XX 和 5XX? +- 下面我们来做个题目吧?语言任意,选择喜欢的(ps:其实是[leetCode原题](https://leetcode-cn.com/problems/merge-intervals/),没有做过类似的,想了几分钟没有思路,哭。。,想问问思路,然后说换一题吧,那就,事后想想还挺简单的,根据第一位排序一下就好了) + +```python +# 给定一些数组,例如下面的格式,他们都表示一个区间,然后你需要将区间进行合并 +[1,2],[2,4],[3,7],[8,11] +# 如上所示, [1,2] 和 [2,4] = [1,4] +# 然后 [1,4] 和 [3,7] = [1,7] +# 最后 [1,7] 和 [8,11] 无法合并,所以最后结果应该返回 [1,7],[8,11] +``` + +- 那就换个题目吧,看看下面这个题目,找数组出现次数最多的TOP N,回头听室友说,好像又是leetcode原题,泪目,算法能力太弱,没怎么刷题。 + +```python +# 给定一个数组,例如 [1,1,2,2,2,3,3,3,3]这样的,里面的数组不一定连续并且有序,假设我输入 2,这个2表示出现次数最高的两个 +# 那么你需要给我返回 2,3 +``` + +然后我最开始的思路就是,通过hash存储出现的次数,然后key就是数组中出现的值。最后在对hash中的次数进行排序,最后得到top N,因为时间复杂度是O(N^2),问有没有优化思路,能否优化到O(N),想了半天没有想出来,没有充分运用已经构建好的hash表 + +后面面试官给讲了一下思路。最后我们一次遍历,已经得到这样一个hash表 + +```python +# key:数组中的值,value:出现的次数 +map = { + 1: 2 + 2: 3 + 3: 4 +} +# 因为说过出现的次数是不会有相同的,所以可以翻转hash,也就是把原来的key作为value,value作为key +tmpMap = { + 2: 1, + 3: 2, + 4: 3 +} +# 然后因为数组的出现次数最多是 len(array),也就是数组的长度,那么我们只需要从长度最高的去遍历,然后从hash中取,如果能取到,表明就是最多的 +count = 0 +ret = [] +for i in range(len(array), 0, -1): + if tmpMap.get(i): + ret.append(tmpMap.get(i)) + count += 1 + if count > 2: + return ret +``` + +- 反问环节,问了问面试的表现,被告知算法能力比较薄弱,以为就此凉凉。。。然后一面说这边可以让你进入下一环节,这边大概需要等5到10分钟左右 + + + +## 第二面 + +二面考察的是技术深度面试,面试时间大约50分钟左右 + +- 自我介绍 +- 博客已经开源了么,用的什么开源协议,博客的用户多么? +- 看你博客中用到了Solr和ElasticSearch,谈谈它们的原理,以及倒排索引? +- 对于Solr或者ES里面用到的一些中文分词器有了解过么? +- 谈谈那些技术栈,你比较熟悉的是那些,mysql 和redis? +- 聊聊MySQL的底层索引结构,InnoDB里面的B+Tree? +- B Tree 和 B+ Tree的区别 + +- 聊聊MySQL索引的发展过程?是一来就是B+Tree的么?从 没有索引、hash、二叉排序树、AVL树、B树、B+树 聊。 +- 谈谈MySQL里面的事务,说说什么是事务? +- MySQL里面有那些事务级别,并且不同的事务级别会出现什么问题? +- 谈谈可重复读和幻读的区别? +- MySQL中如果使用like进行模糊匹配的时候,是否会使用索引?一定不会用么?(索引这块了解的太少了,二面结束后,回去恶补了一下) +- 谈谈Redis吧,在你项目中的具体使用? +- 谈谈Redis如何实现分布式锁? +- 蘑菇博客是否存在缓存不一致的情况,你是如何解决的? +- 谈谈Redis中缓存穿透的问题,以及解决的方法? +- 还有其它解决缓存穿透的方法么?布隆过滤器有了解过么? +- Redis中大面积的缓存失效,然后请求全部打到数据库,有什么解决方法? +- 如果出现一些热点数据,比如明星之间的新闻,造成大量的吃瓜用户涌入后台,但是服务器还没有缓存对应的数据,这样可能造成数据库宕机,如何避免这样的情况? +- 聊聊 JVM的组成结构? +- 谈谈垃圾收集原理?以及垃圾收集算法 +- 复制算法 和 标记整理算法? +- 为什么不在新生代使用标记整理算法?或者在老年代使用复制算法? +- 有了解过Volatile么?谈谈你对Volatile的理解 +- Volatile如何保证可见性的?以及如何实现可见性的机制。 +- 如果大量的使用Volatile存在什么问题? +- 谈谈操作系统的线程,以及它的状态 +- 线程和进程的区别? +- 为什么要提出多线程应用,而不是多进程应用呢? +- Linux你平时都有用到什么命令呢? +- 如果我需要查看端口号或者进程号,你会使用什么命令? +- 谈谈你做的另外一个项目吧?稍微介绍一下 +- 来吧,写个题目试试 + +```python +# 链表的两两翻转 +# 给定链表: 1->2->3->4->5->6->7 +# 返回结果: 2->1->4->3->6->5->7 +``` + +- 毕业时间是什么时候?现在面试的是实习岗位么? +- 反问环节:追问面试表现?告知 Redis这块掌握的还可以,但是MySQL这块显得不足。问后续的安排。 + +## 第三面 + +应该是Leader面,面试时间大概50分钟 + +- 自我介绍 +- 好奇一下,用码云的人应该不多吧,为什么没有用Github? +- 你英文水平怎么样? +- 聊聊开源项目吧?我看这项目已经有800多赞了,你在这开源项目主要做了什么工作? +- 我们找些点来聊聊吧?先从ES和Solr开始,你们这两个都有在用么? +- SQL的方式实现搜索,你是怎么做的呢? +- 使用like匹配的时候,会不会查询非常慢呢? +- ES和Solr的底层都用了lunce,谈谈你对lunce的理解? +- lunce里面也有用到分词器,比如一些新的词 “新冠肺炎” ,它能不能做到很好的划分呢? +- 除了人为的维护词库,来解决最新词语的分割,你还有知道其它什么更好的方法么? +- 你有了解过其它什么开源的分词库么? +- 谈谈字典树? +- Solr 和 ES底层都用了Lunce,那他们两者有什么区别呢? +- Solr所谓的集群环境 和 ES所谓的分布式环境,它们之间有什么区别呢? +- 上面你有提到微服务,你有了解过微服务是个什么样的理念么? +- 你现在的微服务,也是打包成多个jar包,部署在一个服务器上,如果服务器出现问题了,也会造成服务不可用,有没有好的解决方法呢? +- 聊聊服务的注册与发现? +- 服务的注册和发现,其实依赖于一个注册中心的概念,会不会出现注册中心挂掉,而导致整个服务不可用,有没有什么好的解决方法呢? +- 有了解过Zookeeper整个的选举过程么? +- 谈谈Zookeeper的分布式一致性协议? +- 聊聊索引,我给你写个表,看看下面的查询语句,走了那些索引? + +```sql +create table 'tb' ( + id int, + name varchar(64), + status int, + createtime timestamp, + PRIMARY KEY (`id`) +) + +-- 创建了三个普通索引 +create index index_name on table('name') +create index index_status on table('status') +create index index_createtime on table('createtime') + +-- 给定SQL语句,判断下面查询会用到几个索引 +select * from tb where status = 1 and name = "zhangsan" +``` + +- 上述SQL用到了几个索引?分别是那几个? +- 有了解过InnoDB底层的索引结构么? +- 通过两个索引查询出来的结果,会进行什么要的操作?交集,并集? +- 如果你在MySQL中遇到一些慢查询,有什么解决方法么? +- 谈谈explain?执行的explain后,出现的那些字段,能够帮助我们呢? +- 我看你的博客里面,关于Redis还有好几篇文章,我们可以聊一聊你对Redis的理解? +- 为什么Redis能够保持这么高的并发响应? +- 有了解过IO多路复用技术是个什么样的原理 +- 通过一个线程,同时连接多个线程不会存在多个线程切换么?(感觉进坑了。。) +- 当你通过jedis进行连接redis的时候,已经和一个进程连接了 ,redis还能够和其它的进程进行通信么? +- Redis每秒能够处理处理十万请求,如果按照你上面说的,那说明它每次交互只在 1/十万 秒内完成? +- 有了解过Redis的源码么? +- MySQL用了B+Tree,Redis中的SortSet内部用了跳跃表,他们之间有什么差别?为什么MySQL不用跳跃表,或者是Redis不用B+Tree呢? +- 感觉自己编码功底怎么样?那我们先聊聊操作系统的知识在给你一道题吧。在操作系统中,有高速缓存,主存,虚拟内存,外存,有知道它们之间有什么样的关系,以及它们的作用是啥? +- 对它们来说,肯定会存在一个问题,就是当我们的主存满了,或者虚存满了,那么需要存在一个换页操作,你知道有那些换页算法么? +- 我们来聊聊LRU?叫你手写一个LRU算法谈谈你的思路? +- 用链表的方式实现,时间复杂度是O(N),有没有什么方式能够让它是O(1)的时间复杂度呢? +- OK,思路还可以,那你手写一个LRU算法吧?(双向链表 + Hash?) +- 反问环节:问了下组织架构,已经python和go在项目中的使用。然后问了下面试的表现,得:代码写的不算好吧,LRU写成这样我觉得是不太合适的。(心碎的声音,感觉到凉凉的气息...),结束后以为面试已经结束,后面在准备关页面的时候,面试官说等一下,还有同学和我聊? + +## HR面 + +花10来分钟做个简单的沟通 + +- 自我介绍 +- 考研的时候为什么选择的是这个学校呢? +- 回顾一下,上大学到现在这段时间内,让自己最有挫败感的事情是什么呢? +- 有那些方面需要在改进的么? +- 回顾一下,上大学到现在这段时间内,让自己最有成就感的是什么事情呢? +- 对毕业工作的地点是有什么想法? +- 校招也陆陆续续开始了,在面试流程中的公司还有那些么? +- 对于以后参加的工作,你主要会看重那些方面呢? +- 毕业时间? +- 同学这块,大家都有在投递字节这边的岗位么? +- 反问环节:关于面试结果,告知,这边只是做简单的了解,面试结果大约会在一周左右出来,到时候会有邮件或者电话通知。关于面试的结果,需要综合前面的几个面试官进行综合评测,才能决定是否录取。 + +## 总结 + +字节跳动总体来说,面试体验还很不错的,尤其是在手撕代码题的时候,面试老哥会先叫你提供思路,如果你说的思路有问题的话,会帮你拨正,然后在进入coding阶段,但是怎奈何平时没怎么练习算法,leetcode做的少,面试两行泪。。这也算是提前批打响第一枪,期待后面精彩表现~ \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/3_\344\272\254\344\270\234\351\233\266\345\224\256\346\217\220\345\211\215\346\211\271Java\344\270\200\351\235\242/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/3_\344\272\254\344\270\234\351\233\266\345\224\256\346\217\220\345\211\215\346\211\271Java\344\270\200\351\235\242/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..56816dfafa553548a72384a80e71438cf36da536 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/3_\344\272\254\344\270\234\351\233\266\345\224\256\346\217\220\345\211\215\346\211\271Java\344\270\200\351\235\242/README.md" @@ -0,0 +1,39 @@ +# 京东零售 提前批 Java一面 + +## 前言 + +今天面试的是京东零售部门,主要好像是负责数据中台这块的业务,面试小哥还不错~ + +## 第一面 + +- 自我介绍 +- Java什么时候开始学习的? +- 找一个最熟悉的实习项目来介绍一下? +- 那个项目主要用的什么技术框架? +- 为什么考虑在项目中用Redis呢? +- Redis中的数据如果会变换,你会做什么样的处理? +- 网站应该涉及到登录模块的,是怎么做用户的识别以及用户操作日志的收集? +- 你实习参与的这个系统是基于单体架构,还有很多可以完善的地方,你能想到哪些呢? +- 对微服务架构有了解么,说说它的设计理念? +- 微服务之间还有什么不好的地方? +- 谈谈Feign组件? +- Feign内部是基于Ribbon,谈谈Ribbon以及它的负载均衡算法? +- 假设我有三个服务A、B、C,然后 A调用B,B调用C,假设C有问题,会导致服务不可用。那么你有什么解决方法呢? +- 讲讲什么是Hystrix?Hystrix怎么解决服务雪崩 和 服务降级 +- Java里面的容器有哪些? +- ArrayList 和 Vector的区别? +- HashMap 和 HashTable的区别?(这不是和上面讲的一样么... 主动提起 CopyOnWriteArrayList 和 CurrentHashMap) +- 刚刚你提到了CurrentHashMap,那你了解HashMap的内部实现机制么 +- 刚刚你提到了红黑树 + 链表,HashMap这么做它的效率为什么会更高呢? +- JVM里面常见的垃圾回收算法有哪些? +- 怎么确定一个对象是否是垃圾呢? +- 你一般在实际开发中用了哪些垃圾收集器? +- 对于不同垃圾收集器,在不同的应用场景下,你有什么理解么? +- 刚刚提到你在自己的低配置服务器(1核2G)会使用Serial GC ,出于什么考虑的? +- 假设现在不受资源限制,那么你会考虑怎么选择垃圾收集器呢? +- 线程池中线程的数量是通过什么来设置,一般设置的基准是什么?(IO密集型和计算密集型) +- 反问环节 + +## 后语 + +一周到两周内给通知,关注官网的面试进度和邮件通知。 许愿二面~ \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/4_\344\272\254\344\270\234\351\233\266\345\224\256\346\217\220\345\211\215\346\211\271Java\344\272\214\351\235\242/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/4_\344\272\254\344\270\234\351\233\266\345\224\256\346\217\220\345\211\215\346\211\271Java\344\272\214\351\235\242/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..07a9a44618991349010da23bcd292be93ae2370c --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/4_\344\272\254\344\270\234\351\233\266\345\224\256\346\217\220\345\211\215\346\211\271Java\344\272\214\351\235\242/README.md" @@ -0,0 +1,26 @@ +# 京东零售 提前批 Java 二面 + +## 前言 + +今天面试的是京东零售部门的二面,面试时间大概20分钟左右 + +## 第二面 + +- 自我介绍 +- 聊聊项目,里面有哪些功能呢? +- 数据库用的什么? +- 你用了SpringBoot么?谈谈SpringBoot核心注解 +- SpringBoot主类注解和配置类注解? +- 谈谈SpringBoot的自动配置? +- 谈谈SpringBoot的约定大于配置? +- SpringBoot中的系统配置加载优先级,例如 Application.yml, Bootstrap.yml 以及.properties +- 知道什么yaml? 以及它的优势是什么 +- 你刚刚说前台用vue,前端框架有很多,为什么采用的是Vue? +- 你都用的Spring全家桶,为什么没有用SpringData? +- 说说Mybatis和Hibernate的区别? +- 谈谈什么是位图? +- 字典树?它的优点是什么? +- 算法题:假如有一个100层,有两个玻璃杯,也就是两次错误的机会,检测一下,玻璃杯从哪一层开始碎的? + - 第一次遇到这个,第一感觉就想到了二分法,然后发现不对。。 + - 然后有想到了 redis里面的跳跃表,然后给他讲了下思路。。然后直接就到了反问环节?? +- 反问环节 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/5_\346\273\264\346\273\264\345\207\272\350\241\214\346\217\220\345\211\215\346\211\271Java123\351\235\242/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/5_\346\273\264\346\273\264\345\207\272\350\241\214\346\217\220\345\211\215\346\211\271Java123\351\235\242/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..f9d0089502df2900d56b676688465293768bcf1c --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\347\273\217\346\261\207\346\200\273/5_\346\273\264\346\273\264\345\207\272\350\241\214\346\217\220\345\211\215\346\211\271Java123\351\235\242/README.md" @@ -0,0 +1,171 @@ +# 滴滴SP提前批Java123面 + +## 前言 + +前阵子还是在牛客网上发布的SP专场,看到里面有很多岗位,然后抱着试一试的态度投递了几个,没想到竟然能够被滴滴捞起来,给了一次面试的机会。不得不说,滴滴的效率也是非常高的,一下午的时候,就把三轮技术面都完成了,从下午的两点半,面到下午五点半~ 面完感觉身体被掏空... + +面试中项目部分问题是围绕我的开源项目 [蘑菇博客](https://gitee.com/moxi159753/mogu_blog_v2) 展开的,还有就是我为了面试突击准备的 [学习笔记](https://gitee.com/moxi159753/LearningNotes)(二面面试官好像感兴趣.. 直接打开我笔记来问....),欢迎感兴趣的小伙伴能够star支持一下~ + +## 第一面 + +一面主要考察的是一些基础的,面试时间大概30分钟 + +- 自我介绍 +- 前端和后端项目你都做过,你未来的职业规划是什么? +- 现在你投的是研发工程师,有初级、中级、高级,你觉得你是等级的? +- 看你都是偏向于JavaWeb开发这块,有学习和了解过什么书籍来提升自己么? +- 你觉得微服务架构能解决高并发问题呢?能解决哪一类? +- 假设现在你是一个单体应用程序,然后能够支撑200的QPS,然后如果我想要能够支撑起400的QPS,那么你会怎么做?说说你的思路和解决方法 +- 按照你这样说的,通过Nginx的负载均衡,搭建出一个集群就能够解决并发的问题,为什么还要用微服务? +- 你平时做微服务相关的项目,一般面临的问题是哪方面的? +- 如何能够快速的发现,某个服务出现问题,然后进行定位?(回答了一下链路追踪技术zipkin) +- 那谈谈zipkin链路追踪技术的内部原理吧? +- 有没有更简单的方法,去判断某个服务宕机了(通过eureka的面板,看服务的状态是up还是down) +- 还是刚刚的场景,A调用B,B调用C,然后你发现这个链有问题,你是怎么一个排查流程(从Chrome浏览器的F12,查看Network,然后看到每个接口的耗时,发现出有问题的接口) +- 我看你用的都是SpringCloud,Dubbo有用过么? 能简单介绍下?(滴滴内部好像都是基于dubbo来做的) +- 你觉得自己有哪些优点和优势? +- 平时有看过哪些书籍呢?你对哪本书总结的比较深入? +- 你平时常用到的集合框架有哪些? +- ArrayList和LinkedList的区别? +- 讲讲ArrayList的扩容机制? +- 树形结构遍历的话有哪些方法? +- MySQL的索引有哪些? +- 按照算法来进行划分的话,索引能够分为哪几种? +- 主键索引和普通索引底层使用的算法是哪个算法? +- SQL分析有用过么?谈谈explain的用法,如果确定一条SQL走了那些索引? +- 你做[开源博客](https://gitee.com/moxi159753/mogu_blog_v2)的时候,有写过项目文档么?谈谈一份项目文档应该包含什么? +- 项目分为前端和后端,比如你在写后端的时候,前端的小伙伴都在等你么?(并不是,因为我们通过提前约定好具体的接口文档,以及返回值,然后通过swagger-ui进行交互,同时前端还可以使用mock框架,模拟出一些假数据来进行开发) +- 反问环节,问面试表现和建议。 + +技术栈要广,同时也要某一方面比较精的,广可以慢慢来,精的话最好从一开始就确定。 + +## 第二面 + +二面老哥主要就是考察的算法,上来就是手撕代码,二面老哥非常赞,幽默,问的问题也很有引导性,交互性很强~,面试时间大概1小时 + +- 自我介绍 +- 二面老哥好像对我码云感兴趣,叫我给他发一下[码云地址](https://gitee.com/moxi159753) +- 我先去看看你的码云,然后给你道题先做着吧!(求求你问我,我不想做题了...) + +```bash +某个富翁招收保镖,为了提高吸引力,设置了一个特殊的工资,第一天保镖能获取1元报酬,随后两天能获得2元,在随后三天能够获得3元...以此类推,给定一个天数,得出能够获得的报酬 + +输入 3, 返回5 1+2+2 = 5 +输入 10,返回30 1+2+2+3+3+3+4+4+4+4 = 30 + +# 首先用一层for循环解决,然后后面面试官说能不能推导出公式来 +``` + +- 假设你现在从前端请求某个接口,然后从前台到后端经历了什么,说的越详细越好(从hosts,DNS,filter,前端控制器,Spring MVC,ORM(mybatis),到前后端分离以及服务器渲染讲了一下) +- 假设在刚刚你说的,如果没有filter这一层的时候,会出现什么问题呢? +- 谈谈servlet的生命周期? +- HandlerMapping在里面的作用是什么,如果没有HandlerMapping会有什么问题?假设没有HandlerMapping的话,你能够自己实现一个么,说说你的思路? +- 谈谈Spring里用到的设计模式? +- 看你[学习笔记](https://gitee.com/moxi159753/LearningNotes)里面提到了 JDK动态代理 和 CGLib动态代理,谈谈他们是什么,以及应用场景? +- 那再来一题吧~!二面老哥安慰到,是不是一面没做题,二面突然写这么多,有点慌??(说实话,我很方..) + +```bash +近期末,让小东头疼的考试又即将到来了,而且是小东最不喜欢的科目,遗憾的事, +小东得知d天后他必须参加此次考试,小东的父亲对他非常严格,要求他立即开始复习 +功课。为照顾她的情绪,父亲要求她每天该科目的学习时间在iminTime到imaxTime之间 +,并计划在考试前检查小东是否按要求做了。若未能完成,小东将会受到惩罚。 + +现在小东的父亲要求检查小东的备考情况。遗憾的事,由于专注于备考,小东只是记录 +了自己备考的总时间sumTime,并没有记录每天复习所用的时间,也不知道准备情况是否 +符合父亲的要求。他想知道是否能够制作一个满足需求的时间表以应付父亲的检查 + +输入: +输入中有多组测试数据。每组测试数据的第一行包含两个整数d和sumTime,1<=d<=30, +0<=sumTime<=240,分别表示小东复习的天数及每天用于复习的时间之和。紧随其后的d行 +中,每行包括两个空格分隔的整数,为小东父亲要求小东在这一天用于复习时间的范围 +iminTime和imaxTime +0<=iminTime<=imaxTime<=8. + +输出: +对每组测试数据,若能够做出一个满足小东父亲要求的时间表,则在单独的一行中输出Yes +,并在随后的一行中给出每天复习花费的时间。否则输出No。若满足要求的时间表不唯一, +小东希望给父亲留下比较用功的映像,开始时每天复习的时间比较长 + +样例输入: +1 48 +5 7 +2 5 +0 1 +3 5 + +样例输出: +No +Yes +1 4 +``` + +第一次见到这个题,看题目都看了10多分钟....,后面因为时间不太够,大概讲了一些思路,没有叫实现代码 + +- 聊聊状态码吧?1XX,2XX,3XX,4XX,5XX +- 如何制造出4XX 或者 5XX的错误呢 ? +- 常见的中间件你都用过什么? +- 谈谈为什么你会用到消息队列? +- RabbitMQ,而不是Kafka、ActiveMQ或者RocketMQ呢,谈谈每个消息队列的场景,以及你当初的消息中间件的选型依据。 +- 消息队列的底层实现是什么? +- 谈谈你对阻塞队列的理解? +- 反问环节 + +二面老哥给人感觉很不错,全程很幽默,在面试上引导性也很强,聊的还不错,最后给我的建议就是希望能够把写博客这件事情坚持下去~ + +## 第三面 + +三面主要考察的是项目这块,和老哥聊的也还不错,面试时间大概1小时 + +- 自我介绍 +- 能详细介绍一下你的开源项目么?为什么想到做这个事情? +- 能介绍一下项目都有哪些的功能么? +- 你最近做的项目是银行的一个项目,主要职责是前端开发,那会为什么选型用Vue,而不是其它比如React 或者AngularJS呢,说说你的想法,以及这三门前端主流开发框架的区别? +- 谈谈nginx在你项目中的应用? +- 为什么要用nginx做静态资源映射,为什么要做静态资源映射的事情呢?nginx不能直接作为静态资源服务器么? +- 后台有做权限控制么?能谈谈RBAC权限模型么? +- 除了RBAC权限模型以外,你还有了解过其它的权限框架么? +- 谈谈你对SpringSecurity的理解? +- 项目中的服务都是通过什么端口进行暴露的,这样会有什么问题么? +- 了解过服务网关么?说说zuul 或者 gateway? +- 服务和服务之间调用是通过什么?(讲了一下RestTemplate 到 Feign 以及 OpenFeign) +- 知道nginx的反向代理么?后台暴露的服务,有用到nginx做反向代理么? +- 谈谈服务发现组件?eureka 以及 nacos的区别? +- 谈谈JVM的内存结构? +- 为什么方法区是线程共有的?它里面是主要存放了哪些东西呢? +- 堆也是线程共有的,那么怎么解决线程占用的问题? +- 有用过ThreadLocal么?谈谈ThreadLocal以及它的使用场景? +- 接口的幂等性有听过么?说说你的项目中有没有遇到接口幂等性的问题,以及如何解决? +- 如何解决接口的重复提交的问题?(IP+接口名,存放redis中设置过期时间) +- 堆的内存结构是什么? +- 为什么年轻代要使用 8:1:1 来进行划分成eden区、Survivor0,Survivor1区,这么做的好处是什么? +- 什么样的对象可能会进入老年代?如果一个对象进入到老年代后会怎么样? +- 老年代什么时候会触发major GC?还有其它的比如 Minor GC、Full GC 它们的触发条件又是什么? +- 有听过CMS 和 G1垃圾收集器么?谈谈这两个垃圾收集器 +- 说说G1的垃圾收集过程? +- 说说CMS的垃圾收集过程?CMS存在Stop-The-World么?在哪一个阶段会存在呢? +- CMS和G1的区别是什么,什么时候用CMS,什么时候用G1呢? +- HashMap线程安全么,什么操作是不安全的呢? +- 谈谈HashMap的扩容机制? +- HashMap的头插法听过么,为什么后面JDK1.8又变成了尾插法? +- 谈谈CurrentHashMap? +- 为什么原来用的是分段锁,后面JDK1.8以后又不用分段锁了?而是采用Synchronized + CAS呢 +- HashMap底层结构是什么,什么时候会用到红黑树? +- 为什么红黑树的时间复杂度是O(logN)?谈谈AVL树和红黑树的区别? +- 你刚刚提到了二叉树的查找,你可以写代码么?来写一个二叉树的遍历吧 + + - 用非递归的方式写了二叉树的先序遍历(后面本来打算自己写一些测试样例测试,面试官打住了...) + +- 计算机网络结构里面的TCP/IP协议里面的分层模型,具体有哪几层?以及每一层的作用能说一下么? +- TCP里面的三次握手能够详细的介绍一下么? +- 为什么是三次握手,而不是两次握手呢,或者四次握手? +- 在讲讲四次挥手的流程? +- 为什么断开连接需要四次挥手呢? +- 为什么坚持写这个[开源项目](https://gitee.com/moxi159753/mogu_blog_v2)这么久? +- 反问环节,咨询了一下面试表现,以及需要提高的地方。 + +和三面老哥聊了会,技术面到这里结束了,后续是HR来进行面试的流程跟进 + +## 后言 + +滴滴的面试流程快到惊人,一下午就把技术面完了,说实话在第一面的时候,面试官下线后,我本来打算收拾电脑马上准备去实验室了,刚把电脑关机,然后回头HR电话就来了,说准备马上二面.. ,然后二面结束马上三面又来了。后面想着会不会HR面也一起面呢?不过后面通过小伙伴说的,好像滴滴需要大概一到两周后才有结果,那就许愿HR面,许愿OC~ + diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/10_\350\256\276\350\256\241\344\270\200\344\270\252\351\253\230\345\271\266\345\217\221\347\263\273\347\273\237/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/10_\350\256\276\350\256\241\344\270\200\344\270\252\351\253\230\345\271\266\345\217\221\347\263\273\347\273\237/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..8d10150da8c61db4c0a305bb5300836cc287e1ed --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/10_\350\256\276\350\256\241\344\270\200\344\270\252\351\253\230\345\271\266\345\217\221\347\263\273\347\273\237/README.md" @@ -0,0 +1,42 @@ +# 如何设计一个高并发系统 + +## 前言 + +假设你在某知名电商公司干过高并发系统,用户上亿,一天流量几十亿,高峰期并发量上万,甚至是十万。那么人家一定会仔细盘问你的系统架构,你们系统啥架构?怎么部署的?部署了多少台机器?缓存咋用的?MQ咋用的?数据库咋用的?就是深挖你到底是如何抗下高并发的。 + +因为真正干过高并发的人一定知道,脱离了业务的系统架构都是在纸上谈兵,真正在复杂业务场景而且还高并发的时候,那系统架构一定不是那么简单的,用个redis,用mq就能搞定?当然不是,真实的系统架构搭配上业务之后,会比这种简单的所谓“高并发架构”要复杂很多倍。 + +如果有面试官问你个问题说,如何设计一个高并发系统?那么不好意思,一定是因为你实际上没干过高并发系统。面试官看你简历就没啥出彩的,感觉就不咋地,所以就会问问你,如何设计一个高并发系统?其实说白了本质就是看看你有没有自己研究过,有没有一定的知识积累。 + +![01_高并发系统的架构组成](images/01_高并发系统的架构组成.png) + +## 面试题剖析 + +其实所谓的高并发,如果你要理解这个问题呢,其实就得从高并发的根源出发,为啥会有高并发? + +浅显一点,很简单,就是因为刚开始系统都是连接数据库的,但是要知道数据库支撑到每秒并发两三千的时候,基本就快完了。所以才有说,很多公司,刚开始干的时候,技术比较low,结果业务发展太快,有的时候系统扛不住压力就挂了。 + + 当然会挂了,凭什么不挂?你数据库如果瞬间承载每秒5000,8000,甚至上万的并发,一定会宕机,因为比如mysql就压根儿扛不住这么高的并发量。 + + 所以为啥高并发厉害?就是因为现在用互联网的人越来越多,很多app、网站、系统承载的都是高并发请求,可能高峰期每秒并发量几千,很正常的。如果是什么双十一了之类的,每秒并发几万几十万都有可能。 + + 那么如此之高的并发量,加上原本就如此之复杂的业务,咋玩儿?真正厉害的,一定是在复杂业务系统里玩儿过高并发架构的人,但是你没有,那么我给你说一下你该怎么回答这个问题: + +- 系统拆分,将一个系统拆分为多个子系统,用dubbo来搞。然后每个系统连一个数据库,这样本来就一个库,现在多个数据库,不也可以抗高并发么。 + +- 缓存,必须得用缓存。大部分的高并发场景,都是读多写少,那你完全可以在数据库和缓存里都写一份,然后读的时候大量走缓存不就得了。毕竟人家redis轻轻松松单机几万的并发啊。没问题的。所以你可以考虑考虑你的项目里,那些承载主要请求的读场景,怎么用缓存来抗高并发。 +- MQ,必须得用MQ。可能你还是会出现高并发写的场景,比如说一个业务操作里要频繁搞数据库几十次,增删改增删改,疯了。那高并发绝对搞挂你的系统,你要是用redis来承载写那肯定不行,人家是缓存,数据随时就被LRU了,数据格式还无比简单,没有事务支持。所以该用mysql还得用mysql啊。那你咋办?用MQ吧,大量的写请求灌入MQ里,排队慢慢玩儿,后边系统消费后慢慢写,控制在mysql承载范围之内。所以你得考虑考虑你的项目里,那些承载复杂写业务逻辑的场景里,如何用MQ来异步写,提升并发性。MQ单机抗几万并发也是ok的,这个之前还特意说过。 + +- 分库分表,可能到了最后数据库层面还是免不了抗高并发的要求,好吧,那么就将一个数据库拆分为多个库,多个库来抗更高的并发;然后将一个表拆分为多个表,每个表的数据量保持少一点,提高sql跑的性能。 + +- 读写分离,这个就是说大部分时候数据库可能也是读多写少,没必要所有请求都集中在一个库上吧,可以搞个主从架构,主库写入,从库读取,搞一个读写分离。读流量太多的时候,还可以加更多的从库。 + +- Elasticsearch,可以考虑用es。es是分布式的,可以随便扩容,分布式天然就可以支撑高并发,因为动不动就可以扩容加机器来抗更高的并发。那么一些比较简单的查询、统计类的操作,可以考虑用es来承载,还有一些全文搜索类的操作,也可以考虑用es来承载。 + +上面的6点,基本就是高并发系统肯定要干的一些事儿,大家可以仔细结合之前讲过的知识考虑一下,到时候你可以系统的把这块阐述一下,然后每个部分要注意哪些问题,之前都讲过了,你都可以阐述阐述,表明你对这块是有点积累的。 + + 说句实话,毕竟真正你厉害的一点,不是在于弄明白一些技术,或者大概知道一个高并发系统应该长什么样?其实实际上在真正的复杂的业务系统里,做高并发要远远比我这个图复杂几十倍到上百倍。你需要考虑,哪些需要分库分表,哪些不需要分库分表,单库单表跟分库分表如何join,哪些数据要放到缓存里去啊,放哪些数据再可以抗掉高并发的请求,你需要完成对一个复杂业务系统的分析之后,然后逐步逐步的加入高并发的系统架构的改造,这个过程是务必复杂的,一旦做过一次,一旦做好了,你在这个市场上就会非常的吃香。 + +其实大部分公司,真正看重的,不是说你掌握高并发相关的一些基本的架构知识,架构中的一些技术RocketMQ、Kafka、Redis、Elasticsearch,高并发这一块,次一等的人才。对一个有几十万行代码的复杂的分布式系统,一步一步架构、设计以及实践过高并发架构的人,这个经验是难能可贵的。 + + \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/10_\350\256\276\350\256\241\344\270\200\344\270\252\351\253\230\345\271\266\345\217\221\347\263\273\347\273\237/images/01_\351\253\230\345\271\266\345\217\221\347\263\273\347\273\237\347\232\204\346\236\266\346\236\204\347\273\204\346\210\220.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/10_\350\256\276\350\256\241\344\270\200\344\270\252\351\253\230\345\271\266\345\217\221\347\263\273\347\273\237/images/01_\351\253\230\345\271\266\345\217\221\347\263\273\347\273\237\347\232\204\346\236\266\346\236\204\347\273\204\346\210\220.png" new file mode 100644 index 0000000000000000000000000000000000000000..fdcbc070bd2af4bf1975eec630772692b033e65a Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/10_\350\256\276\350\256\241\344\270\200\344\270\252\351\253\230\345\271\266\345\217\221\347\263\273\347\273\237/images/01_\351\253\230\345\271\266\345\217\221\347\263\273\347\273\237\347\232\204\346\236\266\346\236\204\347\273\204\346\210\220.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..b7ddd2d9a887d8d5928b386e6da4ad6e1ac20173 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" @@ -0,0 +1,408 @@ + + + + +# 数据库分库分表的面试连环炮 + +## 面试题 + +- 为什么要分库分表?(设计高并发系统的时候,数据库层面该如何设计) +- 用过哪些分库分表中间件? +- 不同的分库分表中间件都有什么优缺点? +- 你们具体是如何对数据库如何进行垂直拆分或水平拆分的? +- 现在有一个未分库分表的系统,未来要分库分表,如何设计才可以让系统从未分库分表动态切换到分库分表上? +- 如何设计可以动态扩容缩容的分库分表方案? +- 分库分表后,ID主键如何处理? + +## 为什么要分库分表? + +说白了,分库分表是两回事儿,大家可别搞混了,可能是光分库不分表,也可能是光分表不分库,都有可能。我先给大家抛出来一个场景。 + +假如我们现在是一个小创业公司(或者是一个BAT公司刚兴起的一个新部门),现在注册用户就20万,每天活跃用户就1万,每天单表数据量就1000,然后高峰期每秒钟并发请求最多就10。。。天,就这种系统,随便找一个有几年工作经验的,然后带几个刚培训出来的,随便干干都可以。 + +结果没想到我们运气居然这么好,碰上个CEO带着我们走上了康庄大道,业务发展迅猛,过了几个月,注册用户数达到了2000万!每天活跃用户数100万!每天单表数据量10万条!高峰期每秒最大请求达到1000!同时公司还顺带着融资了两轮,紧张了几个亿人民币啊!公司估值达到了惊人的几亿美金!这是小独角兽的节奏! + +好吧,没事,现在大家感觉压力已经有点大了,为啥呢?因为每天多10万条数据,一个月就多300万条数据,现在咱们单表已经几百万数据了,马上就破千万了。但是勉强还能撑着。高峰期请求现在是1000,咱们线上部署了几台机器,负载均衡搞了一下,数据库撑1000 QPS也还凑合。但是大家现在开始感觉有点担心了,接下来咋整呢。。。。。。 + +再接下来几个月,我的天,CEO太牛逼了,公司用户数已经达到1亿,公司继续融资几十亿人民币啊!公司估值达到了惊人的几十亿美金,成为了国内今年最牛逼的明星创业公司!天,我们太幸运了。 + +但是我们同时也是不幸的,因为此时每天活跃用户数上千万,每天单表新增数据多达50万,目前一个表总数据量都已经达到了两三千万了!扛不住啊!数据库磁盘容量不断消耗掉!高峰期并发达到惊人的5000~8000!别开玩笑了,哥。我跟你保证,你的系统支撑不到现在,已经挂掉了! + +好吧,所以看到你这里你差不多就理解分库分表是怎么回事儿了,实际上这是跟着你的公司业务发展走的,你公司业务发展越好,用户就越多,数据量越大,请求量越大,那你单个数据库一定扛不住。 + + 比如你单表都几千万数据了,你确定你能抗住么?绝对不行,单表数据量太大,会极大影响你的sql执行的性能,到了后面你的sql可能就跑的很慢了。一般来说,就以我的经验来看,单表到几百万的时候,性能就会相对差一些了,你就得分表了。 + + 分表是啥意思?就是把一个表的数据放到多个表中,然后查询的时候你就查一个表。比如按照用户id来分表,将一个用户的数据就放在一个表中。然后操作的时候你对一个用户就操作那个表就好了。这样可以控制每个表的数据量在可控的范围内,比如每个表就固定在200万以内。 + + 分库是啥意思?就是你一个库一般我们经验而言,最多支撑到并发2000,一定要扩容了,而且一个健康的单库并发值你最好保持在每秒1000左右,不要太大。那么你可以将一个库的数据拆分到多个库中,访问的时候就访问一个库好了。 + + 这就是所谓的分库分表,为啥要分库分表?你明白了吧 + +![01_分库分表的由来](images/01_分库分表的由来.png) + +## 用过哪些分库分表中间件? + +### 分类 + +数据库中间件分为两类 + +- proxy:中间经过一层代理,需要独立部署 +- client:在客户端就知道指定到那个数据库 + +### 各个中间件 + +这个其实就是看看你了解哪些分库分表的中间件,各个中间件的优缺点是啥?然后你用过哪些分库分表的中间件。 + + 比较常见的包括:cobar、TDDL、atlas、sharding-jdbc、mycat + + cobar:阿里b2b团队开发和开源的,属于proxy层方案。早些年还可以用,但是最近几年都没更新了,基本没啥人用,差不多算是被抛弃的状态吧。而且不支持读写分离、存储过程、跨库join和分页等操作。 + + TDDL:淘宝团队开发的,属于client层方案。不支持join、多表查询等语法,就是基本的crud语法是ok,但是支持读写分离。目前使用的也不多,因为还依赖淘宝的diamond配置管理系统。 + + atlas:360开源的,属于proxy层方案,以前是有一些公司在用的,但是确实有一个很大的问题就是社区最新的维护都在5年前了。所以,现在用的公司基本也很少了。 + + sharding-jdbc:当当开源的,属于client层方案。确实之前用的还比较多一些,因为SQL语法支持也比较多,没有太多限制,而且目前推出到了2.0版本,支持分库分表、读写分离、分布式id生成、柔性事务(最大努力送达型事务、TCC事务)。而且确实之前使用的公司会比较多一些(这个在官网有登记使用的公司,可以看到从2017年一直到现在,是不少公司在用的),目前社区也还一直在开发和维护,还算是比较活跃,个人认为算是一个现在也可以选择的方案。 + + mycat:基于cobar改造的,属于proxy层方案,支持的功能非常完善,而且目前应该是非常火的而且不断流行的数据库中间件,社区很活跃,也有一些公司开始在用了。但是确实相比于sharding jdbc来说,年轻一些,经历的锤炼少一些。 + +### 总结 + + 所以综上所述,现在其实建议考量的,就是sharding-jdbc和mycat,这两个都可以去考虑使用。 + +sharding-jdbc这种client层方案的优点在于不用部署,运维成本低,不需要代理层的二次转发请求,性能很高,但是如果遇到升级啥的需要各个系统都重新升级版本再发布,各个系统都需要耦合sharding-jdbc的依赖; + +mycat这种proxy层方案的缺点在于需要部署,自己及运维一套中间件,运维成本高,但是好处在于对于各个项目是透明的,如果遇到升级之类的都是自己中间件那里搞就行了。 + +通常来说,这两个方案其实都可以选用,但是我个人建议中小型公司选用sharding-jdbc,client层方案轻便,而且维护成本低,不需要额外增派人手,而且中小型公司系统复杂度会低一些,项目也没那么多; + +但是中大型公司最好还是选用mycat这类proxy层方案,因为可能大公司系统和项目非常多,团队很大,人员充足,那么最好是专门弄个人来研究和维护mycat,然后大量项目直接透明使用即可。 + +我们,数据库中间件都是自研的,也用过proxy层,后来也用过client层 + +## 如何对数据库如何进行垂直拆分或水平拆分的? + +### 拆分方法 + +- 垂直拆分 +- 水平拆分 + +### 水平拆分 + + 水平拆分的意思,就是把一个表的数据给弄到多个库的多个表里去,但是每个库的表结构都一样,只不过每个库表放的数据是不同的,所有库表的数据加起来就是全部数据。水平拆分的意义,就是将数据均匀放更多的库里,然后用多个库来抗更高的并发,还有就是用多个库的存储容量来进行扩容。 + +### 垂直拆分 + +垂直拆分的意思,就是把一个有很多字段的表给拆分成多个表,或者是多个库上去。每个库表的结构都不一样,每个库表都包含部分字段。一般来说,会将较少的访问频率很高的字段放到一个表里去,然后将较多的访问频率很低的字段放到另外一个表里去。因为数据库是有缓存的,你访问频率高的行字段越少,就可以在缓存里缓存更多的行,性能就越好。这个一般在表层面做的较多一些。 + + 这个其实挺常见的,不一定我说,大家很多同学可能自己都做过,把一个大表拆开,订单表、订单支付表、订单商品表。 + + 还有表层面的拆分,就是分表,将一个表变成N个表,就是让每个表的数据量控制在一定范围内,保证SQL的性能。否则单表数据量越大,SQL性能就越差。一般是200万行左右,不要太多,但是也得看具体你怎么操作,也可能是500万,或者是100万。你的SQL越复杂,就最好让单表行数越少。 + + 好了,无论是分库了还是分表了,上面说的那些数据库中间件都是可以支持的。就是基本上那些中间件可以做到你分库分表之后,中间件可以根据你指定的某个字段值,比如说userid,自动路由到对应的库上去,然后再自动路由到对应的表里去。 + + 你就得考虑一下,你的项目里该如何分库分表?一般来说,垂直拆分,你可以在表层面来做,对一些字段特别多的表做一下拆分;水平拆分,你可以说是并发承载不了,或者是数据量太大,容量承载不了,你给拆了,按什么字段来拆,你自己想好;分表,你考虑一下,你如果哪怕是拆到每个库里去,并发和容量都ok了,但是每个库的表还是太大了,那么你就分表,将这个表分开,保证每个表的数据量并不是很大。 + + 而且这儿还有两种分库分表的方式,一种是按照range来分,就是每个库一段连续的数据,这个一般是按比如时间范围来的,但是这种一般较少用,因为很容易产生热点问题,大量的流量都打在最新的数据上了;或者是按照某个字段hash一下均匀分散,这个较为常用。 + + range来分,好处在于说,后面扩容的时候,就很容易,因为你只要预备好,给每个月都准备一个库就可以了,到了一个新的月份的时候,自然而然,就会写新的库了;缺点,但是大部分的请求,都是访问最新的数据。实际生产用range,要看场景,你的用户不是仅仅访问最新的数据,而是均匀的访问现在的数据以及历史的数据 + + hash分法,好处在于说,可以平均分配没给库的数据量和请求压力;坏处在于说扩容起来比较麻烦,会有一个数据迁移的这么一个过程![02_数据库如何拆分](images/02_数据库如何拆分.png) + +## 如何让系统不停机迁移到分库分表 + +现在有一个未分库分表的系统,未来要分库分表,如何设计才可以让系统从未分库分表动态切换到分库分表上? + +### 剖析 + +你看看,你现在已经明白为啥要分库分表了,你也知道常用的分库分表中间件了,你也设计好你们如何分库分表的方案了(水平拆分、垂直拆分、分表),那问题来了,你接下来该怎么把你那个单库单表的系统给迁移到分库分表上去?所以这都是一环扣一环的,就是看你有没有全流程经历过这个过程 + +假设,你现有有一个单库单表的系统,在线上在跑,假设单表有600万数据,3个库,每个库里分了4个表,每个表要放50万的数据量 + +假设你已经选择了一个分库分表的数据库中间件,sharding-jdbc,mycat,都可以,你怎么把线上系统平滑地迁移到分库分表上面去 + +### 停机迁移方案 + +我先给你说一个最low的方案,就是很简单,大家伙儿凌晨12点开始运维,网站或者app挂个公告,说0点到早上6点进行运维,无法访问。。。。。。 + +接着到0点,停机,系统挺掉,没有流量写入了,此时老的单库单表数据库静止了。然后你之前得写好一个导数的一次性工具,此时直接跑起来,然后将单库单表的数据哗哗哗读出来,写到分库分表里面去。 + +导数完了之后,就ok了,修改系统的数据库连接配置啥的,包括可能代码和SQL也许有修改,那你就用最新的代码,然后直接启动连到新的分库分表上去。 + +验证一下,ok了,完美,大家伸个懒腰,看看看凌晨4点钟的北京夜景,打个滴滴回家吧 + +但是这个方案比较low,谁都能干,我们来看看高大上一点的方案 + + ![01_长时间停机分库分表](images/01_长时间停机分库分表.png) + +### 双写迁移方案 + +这个是我们常用的一种迁移方案,比较靠谱一些,不用停机,不用看北京凌晨4点的风景 + +简单来说,就是在线上系统里面,之前所有写库的地方,增删改操作,都除了对老库增删改,都加上对新库的增删改,这就是所谓双写,同时写俩库,老库和新库。 + +然后系统部署之后,新库数据差太远,用之前说的导数工具,跑起来读老库数据写新库,写的时候要根据gmt_modified这类字段判断这条数据最后修改的时间,除非是读出来的数据在新库里没有,或者是比新库的数据新才会写。 + +接着导万一轮之后,有可能数据还是存在不一致,那么就程序自动做一轮校验,比对新老库每个表的每条数据,接着如果有不一样的,就针对那些不一样的,从老库读数据再次写。反复循环,直到两个库每个表的数据都完全一致为止。 + +接着当数据完全一致了,就ok了,基于仅仅使用分库分表的最新代码,重新部署一次,不就仅仅基于分库分表在操作了么,还没有几个小时的停机时间,很稳。所以现在基本玩儿数据迁移之类的,都是这么干了。 + +![02_不停机双写方案](images/02_不停机双写方案.png) + +## 如何设计可以动态扩容的分库分表方案? + +### 思考步骤 + +- 选择一个数据库中间件,调研、学习、测试 +- 设计你的分库分表的一个方案,你要分成多少个库,每个库分成多少个表,3个库每个库4个表 +- 基于选择好的数据库中间件,以及在测试环境建立好的分库分表的环境,然后测试一下能否正常进行分库分表的读写 +- 完成单库单表到分库分表的迁移,双写方案 +- 线上系统开始基于分库分表对外提供服务 +- 扩容了,扩容成6个库,每个库需要12个表,你怎么来增加更多库和表呢? + +这个是你必须面对的一个事儿,就是你已经弄好分库分表方案了,然后一堆库和表都建好了,基于分库分表中间件的代码开发啥的都好了,测试都ok了,数据能均匀分布到各个库和各个表里去,而且接着你还通过双写的方案咔嚓一下上了系统,已经直接基于分库分表方案在搞了。 + +那么现在问题来了,你现在这些库和表又支撑不住了,要继续扩容咋办?这个可能就是说你的每个库的容量又快满了,或者是你的表数据量又太大了,也可能是你每个库的写并发太高了,你得继续扩容。 + +### 停机扩容 + +这个方案就跟停机迁移一样,步骤几乎一致,唯一的一点就是那个导数的工具,是把现有库表的数据抽出来慢慢倒入到新的库和表里去。但是最好别这么玩儿,有点不太靠谱,因为既然分库分表就说明数据量实在是太大了,可能多达几亿条,甚至几十亿,你这么玩儿,可能会出问题。 + +从单库单表迁移到分库分表的时候,数据量并不是很大,单表最大也就两三千万 + +写个工具,多弄几台机器并行跑,1小时数据就导完了 + +3个库+12个表,跑了一段时间了,数据量都1亿~2亿了。光是导2亿数据,都要导个几个小时,6点,刚刚导完数据,还要搞后续的修改配置,重启系统,测试验证,10点才可以搞完 + +### 优化后的方案 + +一开始上来就是32个库,每个库32个表,1024张表 + +我可以告诉各位同学说,这个分法,第一,基本上国内的互联网肯定都是够用了,第二,无论是并发支撑还是数据量支撑都没问题 + +每个库正常承载的写入并发量是1000,那么32个库就可以承载32 * 1000 = 32000的写并发,如果每个库承载1500的写并发,32 * 1500 = 48000的写并发,接近5万/s的写入并发,前面再加一个MQ,削峰,每秒写入MQ 8万条数据,每秒消费5万条数据。 + +有些除非是国内排名非常靠前的这些公司,他们的最核心的系统的数据库,可能会出现几百台数据库的这么一个规模,128个库,256个库,512个库,1024张表,假设每个表放500万数据,在MySQL里可以放50亿条数据 + +每秒的5万写并发,总共50亿条数据,对于国内大部分的互联网公司来说,其实一般来说都够了 + +谈分库分表的扩容,第一次分库分表,就一次性给他分个够,32个库,1024张表,可能对大部分的中小型互联网公司来说,已经可以支撑好几年了 + +一个实践是利用32 * 32来分库分表,即分为32个库,每个库里一个表分为32张表。一共就是1024张表。根据某个id先根据32取模路由到库,再根据32取模路由到库里的表。 + +刚开始的时候,这个库可能就是逻辑库,建在一个数据库上的,就是一个mysql服务器可能建了n个库,比如16个库。后面如果要拆分,就是不断在库和mysql服务器之间做迁移就可以了。然后系统配合改一下配置即可。 + +比如说最多可以扩展到32个数据库服务器,每个数据库服务器是一个库。如果还是不够?最多可以扩展到1024个数据库服务器,每个数据库服务器上面一个库一个表。因为最多是1024个表么。 + +这么搞,是不用自己写代码做数据迁移的,都交给dba来搞好了,但是dba确实是需要做一些库表迁移的工作,但是总比你自己写代码,抽数据导数据来的效率高得多了。 + +![01_分库分表扩容方案](images/01_分库分表扩容方案.png) + +哪怕是要减少库的数量,也很简单,其实说白了就是按倍数缩容就可以了,然后修改一下路由规则。 + +``` +对2 ^ n取模 + +orderId 模 32 = 库 + +orderId / 32 模 32 = 表 + +259 3 8 + +1189 5 5 + +352 0 11 + +4593 17 15 +``` + +### 总结 + +- 设定好几台数据库服务器,每台服务器上几个库,每个库多少个表,推荐是32库 * 32表,对于大部分公司来说,可能几年都够了 +- 路由的规则,orderId 模 32 = 库,orderId / 32 模 32 = 表 +- 扩容的时候,申请增加更多的数据库服务器,装好mysql,倍数扩容,4台服务器,扩到8台服务器,16台服务 +- 由dba负责将原先数据库服务器的库,迁移到新的数据库服务器上去,很多工具,库迁移,比较便捷 +- 我们这边就是修改一下配置,调整迁移的库所在数据库服务器的地址 +- 重新发布系统,上线,原先的路由规则变都不用变,直接可以基于2倍的数据库服务器的资源,继续进行线上系统的提供服务 + +## 分库分表后ID主键如何处理 + +### 前言 + +其实这是分库分表之后你必然要面对的一个问题,就是id咋生成?因为要是分成多个表之后,每个表都是从1开始累加,那肯定不对啊,需要一个全局唯一的id来支持。所以这都是你实际生产环境中必须考虑的问题。 + +### 数据库自增ID + +这个就是说你的系统里每次得到一个id,都是往一个库的一个表里插入一条没什么业务含义的数据,然后获取一个数据库自增的一个id。拿到这个id之后再往对应的分库分表里去写入。 + + 这个方案的好处就是方便简单,谁都会用;缺点就是单库生成自增id,要是高并发的话,就会有瓶颈的;如果你硬是要改进一下,那么就专门开一个服务出来,这个服务每次就拿到当前id最大值,然后自己递增几个id,一次性返回一批id,然后再把当前最大id值修改成递增几个id之后的一个值;但是无论怎么说都是基于单个数据库。 + + 适合的场景:你分库分表就俩原因,要不就是单库并发太高,要不就是单库数据量太大;除非是你并发不高,但是数据量太大导致的分库分表扩容,你可以用这个方案,因为可能每秒最高并发最多就几百,那么就走单独的一个库和表生成自增主键即可。 + + 并发很低,几百/s,但是数据量大,几十亿的数据,所以需要靠分库分表来存放海量的数据![01_分库分表的id主键问题](images/01_分库分表的id主键问题.png) + +## UUID + +好处就是本地生成,不要基于数据库来了;不好之处就是,uuid太长了,作为主键性能太差了,不适合用于主键。 + + 适合的场景:如果你是要随机生成个什么文件名了,编号之类的,你可以用uuid,但是作为主键是不能用uuid的。 + +## 获取系统时间戳 + +这个就是获取当前时间即可,但是问题是,并发很高的时候,比如一秒并发几千,会有重复的情况,这个是肯定不合适的。基本就不用考虑了。 + +适合的场景:一般如果用这个方案,是将当前时间跟很多其他的业务字段拼接起来,作为一个id,如果业务上你觉得可以接受,那么也是可以的。你可以将别的业务字段值跟当前时间拼接起来,组成一个全局唯一的编号,订单编号,时间戳 + 用户id + 业务含义编码 + +## Snowflake算法(雪花算法) + +twitter开源的分布式id生成算法,就是把一个64位的long型的id,1个bit是不用的,用其中的41 bit作为毫秒数,用10 bit作为工作机器id,12 bit作为序列号 + +1 bit:不用,为啥呢?因为二进制里第一个bit为如果是1,那么都是负数,但是我们生成的id都是正数,所以第一个bit统一都是0 + +41 bit:表示的是时间戳,单位是毫秒。41 bit可以表示的数字多达2^41 - 1,也就是可以标识2 ^ 41 - 1个毫秒值,换算成年就是表示69年的时间。 + +10 bit:记录工作机器id,代表的是这个服务最多可以部署在2^10台机器上哪,也就是1024台机器。但是10 bit里5个bit代表机房id,5个bit代表机器id。意思就是最多代表2 ^ 5个机房(32个机房),每个机房里可以代表2 ^ 5个机器(32台机器)。 + +12 bit:这个是用来记录同一个毫秒内产生的不同id,12 bit可以代表的最大正整数是2 ^ 12 - 1 = 4096,也就是说可以用这个12bit代表的数字来区分同一个毫秒内的4096个不同的id + +64位的long型的id,64位的long -> 二进制 + +`0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000000` + +2018-01-01 10:00:00 -> 做了一些计算,再换算成一个二进制,41bit来放 -> 0001100 10100010 10111110 10001001 `` + +机房id,17 -> 换算成一个二进制 -> 10001 + +机器id,25 -> 换算成一个二进制 -> 11001 + +snowflake算法服务,会判断一下,当前这个请求是否是,机房17的机器25,在2175/11/7 12:12:14时间点发送过来的第一个请求,如果是第一个请求 + +假设,在2175/11/7 12:12:14时间里,机房17的机器25,发送了第二条消息,snowflake算法服务,会发现说机房17的机器25,在2175/11/7 12:12:14时间里,在这一毫秒,之前已经生成过一个id了,此时如果你同一个机房,同一个机器,在同一个毫秒内,再次要求生成一个id,此时我只能把加1 + +比如我们来观察上面的那个,就是一个典型的二进制的64位的id,换算成10进制就是910499571847892992。 + +![02_snowflake算法](images/02_snowflake算法.png) + +### 算法 + +```java +public class IdWorker{ + + private long workerId; + private long datacenterId; + private long sequence; + + public IdWorker(long workerId, long datacenterId, long sequence){ + // sanity check for workerId +// 这儿不就检查了一下,要求就是你传递进来的机房id和机器id不能超过32,不能小于0 + if (workerId > maxWorkerId || workerId < 0) { + throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0",maxWorkerId)); + } + if (datacenterId > maxDatacenterId || datacenterId < 0) { + throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0",maxDatacenterId)); + } + System.out.printf("worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d", + timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId); + + this.workerId = workerId; + this.datacenterId = datacenterId; + this.sequence = sequence; + } + + private long twepoch = 1288834974657L; + + private long workerIdBits = 5L; + private long datacenterIdBits = 5L; + private long maxWorkerId = -1L ^ (-1L << workerIdBits); // 这个是二进制运算,就是5 bit最多只能有31个数字,也就是说机器id最多只能是32以内 + private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); // 这个是一个意思,就是5 bit最多只能有31个数字,机房id最多只能是32以内 + private long sequenceBits = 12L; + + private long workerIdShift = sequenceBits; + private long datacenterIdShift = sequenceBits + workerIdBits; + private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; + private long sequenceMask = -1L ^ (-1L << sequenceBits); + + private long lastTimestamp = -1L; + + public long getWorkerId(){ + return workerId; + } + + public long getDatacenterId(){ + return datacenterId; + } + + public long getTimestamp(){ + return System.currentTimeMillis(); + } + +public synchronized long nextId() { +// 这儿就是获取当前时间戳,单位是毫秒 + long timestamp = timeGen(); + + if (timestamp < lastTimestamp) { + System.err.printf("clock is moving backwards. Rejecting requests until %d.", lastTimestamp); + throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", + lastTimestamp - timestamp)); + } + +// 0 +// 在同一个毫秒内,又发送了一个请求生成一个id,0 -> 1 + + if (lastTimestamp == timestamp) { + sequence = (sequence + 1) & sequenceMask; // 这个意思是说一个毫秒内最多只能有4096个数字,无论你传递多少进来,这个位运算保证始终就是在4096这个范围内,避免你自己传递个sequence超过了4096这个范围 + if (sequence == 0) { + timestamp = tilNextMillis(lastTimestamp); + } + } else { + sequence = 0; + } + +// 这儿记录一下最近一次生成id的时间戳,单位是毫秒 + lastTimestamp = timestamp; + +// 这儿就是将时间戳左移,放到41 bit那儿;将机房id左移放到5 bit那儿;将机器id左移放到5 bit那儿;将序号放最后10 bit;最后拼接起来成一个64 bit的二进制数字,转换成10进制就是个long型 + return ((timestamp - twepoch) << timestampLeftShift) | + (datacenterId << datacenterIdShift) | + (workerId << workerIdShift) | + sequence; + } + +0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000000 + + + private long tilNextMillis(long lastTimestamp) { + long timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + private long timeGen(){ + return System.currentTimeMillis(); + } + + //---------------测试--------------- + public static void main(String[] args) { + IdWorker worker = new IdWorker(1,1,1); + for (int i = 0; i < 30; i++) { + System.out.println(worker.nextId()); + } + } + +} +``` + +怎么说呢,大概这个意思吧,就是说41 bit,就是当前毫秒单位的一个时间戳,就这意思;然后5 bit是你传递进来的一个机房id(但是最大只能是32以内),5 bit是你传递进来的机器id(但是最大只能是32以内),剩下的那个10 bit序列号,就是如果跟你上次生成id的时间还在一个毫秒内,那么会把顺序给你累加,最多在4096个序号以内。 + + 所以你自己利用这个工具类,自己搞一个服务,然后对每个机房的每个机器都初始化这么一个东西,刚开始这个机房的这个机器的序号就是0。然后每次接收到一个请求,说这个机房的这个机器要生成一个id,你就找到对应的Worker,生成。 + + 他这个算法生成的时候,会把当前毫秒放到41 bit中,然后5 bit是机房id,5 bit是机器id,接着就是判断上一次生成id的时间如果跟这次不一样,序号就自动从0开始;要是上次的时间跟现在还是在一个毫秒内,他就把seq累加1,就是自动生成一个毫秒的不同的序号。 + + 这个算法那,可以确保说每个机房每个机器每一毫秒,最多生成4096个不重复的id。 + + 利用这个snowflake算法,你可以开发自己公司的服务,甚至对于机房id和机器id,反正给你预留了5 bit + 5 bit,你换成别的有业务含义的东西也可以的。 + + 这个snowflake算法相对来说还是比较靠谱的,所以你要真是搞分布式id生成,如果是高并发啥的,那么用这个应该性能比较好,一般每秒几万并发的场景,也足够你用了。 + + \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\345\210\206\345\272\223\345\210\206\350\241\250\346\211\251\345\256\271\346\226\271\346\241\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\345\210\206\345\272\223\345\210\206\350\241\250\346\211\251\345\256\271\346\226\271\346\241\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..277246007b66b45d9abd37330326d75ef7797fdd Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\345\210\206\345\272\223\345\210\206\350\241\250\346\211\251\345\256\271\346\226\271\346\241\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204id\344\270\273\351\224\256\351\227\256\351\242\230.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204id\344\270\273\351\224\256\351\227\256\351\242\230.png" new file mode 100644 index 0000000000000000000000000000000000000000..65595016f134927fbaaf238f2e6e5cf76e6eb098 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204id\344\270\273\351\224\256\351\227\256\351\242\230.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\347\224\261\346\235\245.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\347\224\261\346\235\245.png" new file mode 100644 index 0000000000000000000000000000000000000000..18461bc965093a53871b501d416de9e6b81879ff Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\347\224\261\346\235\245.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\351\225\277\346\227\266\351\227\264\345\201\234\346\234\272\345\210\206\345\272\223\345\210\206\350\241\250.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\351\225\277\346\227\266\351\227\264\345\201\234\346\234\272\345\210\206\345\272\223\345\210\206\350\241\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..90918e027585bf23f6ac8aacdadd977f4767a7be Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\351\225\277\346\227\266\351\227\264\345\201\234\346\234\272\345\210\206\345\272\223\345\210\206\350\241\250.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/02_snowflake\347\256\227\346\263\225.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/02_snowflake\347\256\227\346\263\225.png" new file mode 100644 index 0000000000000000000000000000000000000000..79720a0e8653c0d3b3be3250878513bbfc41c1b8 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/02_snowflake\347\256\227\346\263\225.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/02_\344\270\215\345\201\234\346\234\272\345\217\214\345\206\231\346\226\271\346\241\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/02_\344\270\215\345\201\234\346\234\272\345\217\214\345\206\231\346\226\271\346\241\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..402a7800717bbd0167f059317c1a34efc7dde5fa Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/02_\344\270\215\345\201\234\346\234\272\345\217\214\345\206\231\346\226\271\346\241\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/02_\346\225\260\346\215\256\345\272\223\345\246\202\344\275\225\346\213\206\345\210\206.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/02_\346\225\260\346\215\256\345\272\223\345\246\202\344\275\225\346\213\206\345\210\206.png" new file mode 100644 index 0000000000000000000000000000000000000000..74b9efb469041fca2e01d3ae426eafba2b1d8156 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/11_\346\225\260\346\215\256\345\272\223\345\210\206\345\272\223\345\210\206\350\241\250\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/02_\346\225\260\346\215\256\345\272\223\345\246\202\344\275\225\346\213\206\345\210\206.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/12_MySQL\350\257\273\345\206\231\345\244\215\345\210\266\345\217\212\344\270\273\344\273\216\345\220\214\346\255\245\346\227\266\345\273\266/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/12_MySQL\350\257\273\345\206\231\345\244\215\345\210\266\345\217\212\344\270\273\344\273\216\345\220\214\346\255\245\346\227\266\345\273\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..f83897a02f82b61c5ea32d2bd7239102310e3dcf --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/12_MySQL\350\257\273\345\206\231\345\244\215\345\210\266\345\217\212\344\270\273\344\273\216\345\220\214\346\255\245\346\227\266\345\273\266/README.md" @@ -0,0 +1,65 @@ + + +# MySQL读写分离及主从时延 + +## 面试题 + +- 如何实现mysql的读写分离? +- MySQL主从复制原理的是啥? +- 如何解决mysql主从同步的延时问题? + +## 前言 + +这个,高并发这个阶段,那肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是app,其实都是读多写少。所以针对这个情况,就是写一个主库,但是主库挂多个从库,然后从多个从库来读,那不就可以支撑更高的读并发压力了吗? + +## 如何实现mysql的读写分离? + +其实很简单,就是基于主从复制架构,简单来说,就搞一个主库,挂多个从库,然后我们就单单只是写主库,然后主库会自动把数据给同步到从库上去。一般情况下,主库可以挂4-5个从库 + +![01_为什么MySQL要读写分离?](images/01_为什么MySQL要读写分离?.png) + +## MySQL主从复制原理的是啥? + +MySQL里有一个概念,叫binlog日志,就是每个增删改类的操作,会改变数据的操作,除了更新数据以外,对这个增删改操作还会写入一个日志文件,记录这个操作的日志。 + +主库将变更写binlog日志,然后从库连接到主库之后,从库有一个IO线程,将主库的binlog日志拷贝到自己本地,写入一个中继日志中。接着从库中有一个SQL线程会从中继日志读取binlog,然后执行binlog日志中的内容,也就是在自己本地再次执行一遍SQL,这样就可以保证自己跟主库的数据是一样的。 + +这里有一个非常重要的一点,就是从库同步主库数据的过程是串行化的,也就是说主库上并行的操作,在从库上会串行执行。所以这就是一个非常重要的点了,由于从库从主库拷贝日志以及串行执行SQL的特点,在高并发场景下,从库的数据一定会比主库慢一些,是有延时的。所以经常出现,刚写入主库的数据可能是读不到的,要过几十毫秒,甚至几百毫秒才能读取到。 + +而且这里还有另外一个问题,就是如果主库突然宕机,然后恰好数据还没同步到从库,那么有些数据可能在从库上是没有的,有些数据可能就丢失了。 + +所以mysql实际上在这一块有两个机制,一个是半同步复制,用来解决主库数据丢失问题;一个是并行复制,用来解决主从同步延时问题。 + +这个所谓半同步复制,semi-sync复制,指的就是主库写入binlog日志之后,就会将强制此时立即将数据同步到从库,从库将日志写入自己本地的relay log之后,接着会返回一个ack给主库,主库接收到至少一个从库的ack之后才会认为写操作完成了。 + +所谓并行复制,指的是从库开启多个线程,并行读取relay log中不同库的日志,然后并行重放不同库的日志,这是库级别的并行。 + +- 主从复制的原理 +- 主从延迟问题产生的原因 +- 主从复制的数据丢失问题,以及半同步复制的原理 +- 并行复制的原理,多库并发重放relay日志,缓解主从延迟问题 + +![02_MySQL主从复制原理](images/02_MySQL主从复制原理.png) + +## MySQL主从同步延时问题(重点) + +线上确实处理过因为主从同步延时问题,导致的线上的bug,小型的生产事故 + + show status,Seconds_Behind_Master,你可以看到从库复制主库的数据落后了几ms + + 其实这块东西我们经常会碰到,就比如说用了mysql主从架构之后,可能会发现,刚写入库的数据结果没查到,结果就完蛋了。。。。 + + 所以实际上你要考虑好应该在什么场景下来用这个mysql主从同步,建议是一般在读远远多于写,而且读的时候一般对数据时效性要求没那么高的时候,用mysql主从同步 + + 所以这个时候,我们可以考虑的一个事情就是,你可以用mysql的并行复制,但是问题是那是库级别的并行,所以有时候作用不是很大 + + 所以这个时候。。通常来说,我们会对于那种写了之后立马就要保证可以查到的场景,采用强制读主库的方式,这样就可以保证你肯定的可以读到数据了吧。其实用一些数据库中间件是没问题的。 + + 一般来说,如果主从延迟较为严重 + +- 分库,将一个主库拆分为4个主库,每个主库的写并发就500/s,此时主从延迟可以忽略不计 +- 打开mysql支持的并行复制,多个库并行复制,如果说某个库的写入并发就是特别高,单库写并发达到了2000/s,并行复制还是没意义。28法则,很多时候比如说,就是少数的几个订单表,写入了2000/s,其他几十个表10/s。 +- 重写代码,写代码的同学,要慎重,当时我们其实短期是让那个同学重写了一下代码,插入数据之后,直接就更新,不要查询 +- 如果确实是存在必须先插入,立马要求就查询到,然后立马就要反过来执行一些操作,对这个查询设置直连主库。不推荐这种方法,你这么搞导致读写分离的意义就丧失了 + + ![03_MySQL主从延迟导致的生产环境的问题](images/03_MySQL主从延迟导致的生产环境的问题.png) \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/12_MySQL\350\257\273\345\206\231\345\244\215\345\210\266\345\217\212\344\270\273\344\273\216\345\220\214\346\255\245\346\227\266\345\273\266/images/01_\344\270\272\344\273\200\344\271\210MySQL\350\246\201\350\257\273\345\206\231\345\210\206\347\246\273\357\274\237.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/12_MySQL\350\257\273\345\206\231\345\244\215\345\210\266\345\217\212\344\270\273\344\273\216\345\220\214\346\255\245\346\227\266\345\273\266/images/01_\344\270\272\344\273\200\344\271\210MySQL\350\246\201\350\257\273\345\206\231\345\210\206\347\246\273\357\274\237.png" new file mode 100644 index 0000000000000000000000000000000000000000..9ef590a307f777b8b68ba95fc57d0b37c5d7cfd4 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/12_MySQL\350\257\273\345\206\231\345\244\215\345\210\266\345\217\212\344\270\273\344\273\216\345\220\214\346\255\245\346\227\266\345\273\266/images/01_\344\270\272\344\273\200\344\271\210MySQL\350\246\201\350\257\273\345\206\231\345\210\206\347\246\273\357\274\237.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/12_MySQL\350\257\273\345\206\231\345\244\215\345\210\266\345\217\212\344\270\273\344\273\216\345\220\214\346\255\245\346\227\266\345\273\266/images/02_MySQL\344\270\273\344\273\216\345\244\215\345\210\266\345\216\237\347\220\206.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/12_MySQL\350\257\273\345\206\231\345\244\215\345\210\266\345\217\212\344\270\273\344\273\216\345\220\214\346\255\245\346\227\266\345\273\266/images/02_MySQL\344\270\273\344\273\216\345\244\215\345\210\266\345\216\237\347\220\206.png" new file mode 100644 index 0000000000000000000000000000000000000000..a7327d04a69997fa9245639fed985fbb341d880e Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/12_MySQL\350\257\273\345\206\231\345\244\215\345\210\266\345\217\212\344\270\273\344\273\216\345\220\214\346\255\245\346\227\266\345\273\266/images/02_MySQL\344\270\273\344\273\216\345\244\215\345\210\266\345\216\237\347\220\206.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/12_MySQL\350\257\273\345\206\231\345\244\215\345\210\266\345\217\212\344\270\273\344\273\216\345\220\214\346\255\245\346\227\266\345\273\266/images/03_MySQL\344\270\273\344\273\216\345\273\266\350\277\237\345\257\274\350\207\264\347\232\204\347\224\237\344\272\247\347\216\257\345\242\203\347\232\204\351\227\256\351\242\230.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/12_MySQL\350\257\273\345\206\231\345\244\215\345\210\266\345\217\212\344\270\273\344\273\216\345\220\214\346\255\245\346\227\266\345\273\266/images/03_MySQL\344\270\273\344\273\216\345\273\266\350\277\237\345\257\274\350\207\264\347\232\204\347\224\237\344\272\247\347\216\257\345\242\203\347\232\204\351\227\256\351\242\230.png" new file mode 100644 index 0000000000000000000000000000000000000000..5cc48c27c7bf74c7ddc04740a1d35df1db4259b6 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/12_MySQL\350\257\273\345\206\231\345\244\215\345\210\266\345\217\212\344\270\273\344\273\216\345\220\214\346\255\245\346\227\266\345\273\266/images/03_MySQL\344\270\273\344\273\216\345\273\266\350\277\237\345\257\274\350\207\264\347\232\204\347\224\237\344\272\247\347\216\257\345\242\203\347\232\204\351\227\256\351\242\230.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/13_\345\246\202\344\275\225\350\256\276\350\256\241\351\253\230\345\217\257\347\224\250\347\263\273\347\273\237\346\236\266\346\236\204/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/13_\345\246\202\344\275\225\350\256\276\350\256\241\351\253\230\345\217\257\347\224\250\347\263\273\347\273\237\346\236\266\346\236\204/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..f67bd3d56d35acbd06f283648bf0f72962adf9ee --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/13_\345\246\202\344\275\225\350\256\276\350\256\241\351\253\230\345\217\257\347\224\250\347\263\273\347\273\237\346\236\266\346\236\204/README.md" @@ -0,0 +1,2 @@ +# 如何设计高可用系统架构-系统熔断、降级、限流 + diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..9b239ea93f21db657b31969e376939ee54dbd3d4 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" @@ -0,0 +1,430 @@ +# 消息队列的面试连环炮 + +## 前言 + +- 你用过消息队列么? +- 说说你们项目里是怎么用消息队列的? + - 我们有一个订单系统,订单系统会每次下一个新订单的时候,就会发送一条消息到ActiveMQ里面去,后台有一个库存系统,负责获取消息,然后更新库存。 +- 为什么使用消息队列? + - 你的订单系统不发送消息到MQ,而是直接调用库存系统的一个接口,然后直接调用成功了,库存也更新了,那就不需要使用消息队列了呀 + - 使用消息队列的主要作用是:异步、解耦、削峰 +- 消息队列都有什么优缺点? +- Kafka、activeMQ、RibbitMQ、RocketMQ都有什么优缺点? +- 如何保证消息队列的高可用? +- 如何保证消息不被重复消费?如何保证消息消费时的幂等性? +- 如何保证消息的可靠性传输,要是消息丢失了怎么办? +- 如何保证消息的顺序性? +- 如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决? +- 如果让你写一个消息队列,该如何进行架构设计,说一下你的思路? + +面试官问的问题不是发散的,而是从点、铺开,比如先聊一聊高并发的话题,就这个话题里面继续聊聊缓存、MQ等等东西。对于每个小话题,比如说MQ,就会从浅入深。 + +## 为什么使用消息队列? + +### 剖析 + +首先明白为什么系统中要使用到消息队列这种东西? + +因为之前面试的大量候选人,说自己项目中使用了Redis,MQ,但是其实他们并不清楚为什么要用这个东西,说白了就是为了用而用,或者是别人设计的架构,从头到尾就没有思考过。 + +没有对自己的架构问过为什么的人,一定是平时没有思考的人,面试官对这类候选人印象通常不好。 + +### 解答 + +其实就是问问你消息队列有哪些场景,然后你项目里面的具体是什么场景,说说你在这个场景里用什么消息队列是什么? + +消息队列的场景使用场景很多,主要是三个:解耦、异步、和削峰 + +### 解耦 + +#### 不使用MQ时 + +A系统发送数据到B、C、D系统,但没有使用消息队列时候的耦合场景 + +![image-20200418212721479](images/image-20200418212721479.png) + +当后面系统不断增加,比如 E,F系统的加入,以及D系统的移除 + +![image-20200418213021225](images/image-20200418213021225.png) + +因为A系统和其它各种系统耦合起来,那么需要处理的事情会给出多 + +#### 使用MQ后 + +系统A发送一条消息,到消息队列中,哪个系统需要获取到哪里,那么从MQ中消费数据,如果新系统E加入的话,那么只需要编写代码,然后也直接从MQ中消费即可,当系统D不需要这个数据时,那么只需要不对该消息进行消费即可。系统A不需要考虑给谁发送数据,也不需要维护这个代码,不需要考虑人家是否调用成功、失败、超时等等情况 + +![image-20200419205127214](images/image-20200419205127214.png) + +总结:通过一个MQ,发布和订阅模型,Pub/Sub模型,系统A就和其它系统彻底解耦。 + +需要考虑一下负责的系统中,是否有类似的场景,就是一个系统或者一个模块,调用了多个系统,互相之间的调用很复杂,维护起来很麻烦。但是其实这个调用是不需要同步调用接口的,如果用MQ给他异步化解耦,也是可以的,这个时候可以考虑在自己的项目中,是不是可以运用这个MQ来进行系统的解耦。 + +### 异步 + +#### 不用MQ的同步高延时请求场景 + +下面的一个场景就是系统A,调用了其它三个系统的服务,我们发现用户在执行一个请求后,需要花费很长的时间 + +![image-20200419205855859](images/image-20200419205855859.png) + +我们发现,用户执行一个接口,就需要花费350毫秒,假设我们将每个接口的耗时增加,可能会将近花费1秒,这个时候一般用户几乎不能接受,因为一般互联网类的企业,对用户的直接操作,一般要求是每个请求都必须在200ms以内完成,因为这个是对用户是无感知的 + +#### 使用MQ进行异步化 + +![image-20200419213232855](images/image-20200419213232855.png) + +系统A只需要发送消息到MQ中就直接返回了,然后其它系统各自在MQ中进行消费。用户在执行系统A的时候,就会感觉非常快就得到响应了。 + +### 削峰 + +#### 没有用MQ的削峰 + +![image-20200419213609511](images/image-20200419213609511.png) + +一般的MySQL,抗到QPS=2000的时候就已经达到了瓶颈,如果每秒请求达到了5000的话,可能直接就把MySQL打死了。如果MySQL被打死,然后整个系统就崩溃,然后系统就没法使用。 + +但是中午的高峰期过了之后,到下午的时候,就成了低峰期,可能也就一万用户同时在网站上操作,每秒的请求数量可能就50个请求,对整个系统几乎没有任何压力。 + +#### 使用MQ来进行削峰 + +![image-20200419235201993](images/image-20200419235201993.png) + +削峰就是大量的请求过来,然后MQ将其消化掉了,然后通过其它系统从MQ中取消息,在逐步进行消费,保证系统的有序运行。一般高峰期不会持续太长,在一段时间后,就会被下游系统消化掉。 + +## 消息队列有什么优点和缺点? + +优点上面已经说了:解耦、异步、削峰,缺点呢?显而易见的 + +- 系统可用性降低:系统引入的外部依赖越多,越容易挂掉,本来你就是A系统调用BCD三个系统接口就好了,人家ABCD四个系统好好的,没啥问题,这个时候却加入了MQ进来,万一MQ挂了怎么办?MQ挂了整套系统也会崩溃了。 +- 系统复杂性提高:硬生生加个MQ进来,你怎么保证消息没有重复消费?怎么处理消息丢失的情况?怎么保证消息传递的顺序性? +- 一致性问题:A系统处理完了直接返回成功了,人都以为你的请求成功了,但是问题是,要在BCD三个系统中,BD两个系统写库成功了,结果C系统写库失败了,这样就会存在数据不一致的问题。 +- 所以说消息队列实际上是一种复杂的架构,你引入它有好多好处,但是也得针对它带来的坏处做各种额外的技术方案和架构来规避掉,最后发现系统复杂性提升了一个数量级,也许是复杂10倍,但是关键时刻,用还是得用。 + +![image-20200420070841754](images/image-20200420070841754.png) + + + +## 有什么区别,以及适用场景? + +主流MQ包括:kafka、ActiveMQ、RabbitMQ和RocketMQ + +常见的MQ其实就上面的四种 + +| 特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka | +| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | +| 单机吞吐量 | 万级,吞吐量比RocketMQ和Kafka要低一个数量级 | 万级,吞吐量比RocketMQ和Kafka要低一个数量级 | 10万级,RocketMQ也是可以支撑高吞吐的一种MQ | 10万级1这是kafka最大的优点,就是吞吐量高。一般配置和数据类的系统进行实时数据计算、日志采集等场景 | +| 时效性 | ms级 | 微妙级,这是RabbitMQ的一大特点,就是延迟最低 | ms级 | 延迟在ms级内 | +| 可用性 | 基于主从架构实现高可用 | 高,基于主从架构实现高可用 | 非常高,分布式架构 | 非常高,kafka是分布式的,一个数据多个副本,少数机器宕机后,不会丢失数据,不会导致不可用 | +| 消息可靠性 | 有较低的概率丢失数据 | 消息不丢失 | 经过参数优化配置,可以做到0丢失 | 经过参数优化配置可以做到0丢失 | +| 核心特点 | MQ领域的功能及其完备 | 基于Erlang开发,所以并发能力强,性能及其好,延时很低 | MQ功能较为完善,还是分布式的,扩展性好 | 功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用,是实时上的标准。 | +| | 非常成熟,功能强大,在业内大量公司以及项目都有应用。 但是偶尔消息丢失的概率,并且现在社区以及国内应用都越来越少,官方社区对ActiveMQ5.X维护越来越少,而且确实主要是基于解耦和异步来用的,较少在大规模吞吐场景中使用 | erlang语言开发的,性能及其好,延时很低。而且开源的版本,就提供的管理界面非常棒,在国内一些互联网公司近几年用RabbitMQ也是比较多一些,特别适用于中小型的公司 缺点显而易见,就是吞吐量会低一些,这是因为它做的实现机制比较中,因为使用erlang开发,目前没有多少公司使用其开发。所以针对源码界别的定制,非常困难,因此公司的掌控非常弱,只能依赖于开源社区的维护。 | 接口简单易用,毕竟在阿里大规模应用过,有阿里平台保障,日处理消息上 百亿之多,可以做到大规模吞吐,性能也非常好,分布式扩展也很方便,社区维护还可以,可靠性和可用性都是OK的,还可以支撑大规模的topic数量,支持复杂MQ业务场景。 | 仅仅提供较少的核心功能,但是提供超高的吞吐量,ms级别的延迟,极高的可用性以及可靠性,分布式可以任意扩展。 同时kafka最好是支撑较少的topic数量即可,保证其超高的吞吐量。 | + +综上所述: + +- 一般的业务要引入MQ,最早大家都是用ACviceMQ,但是现在大家用的不多了,没有经过大规模吞吐量场景的验证,社区也不是很活跃,所以大家还是算了,不太图鉴使用 +- RabbitMQ后面被大量的中小型公司所使用,但是erlang语言阻碍了大量的Java工程师深入研究和掌握它,对公司而言,几乎处于不可控的状态,但是RabbitMQ目前开源稳定,活跃度也表较高。 +- RocketMQ是阿里开源的一套消息中间件,目前也已经经历了天猫双十一,同时底层使用Java进行开发 + +如果中小型企业技术实力一般,技术挑战不是很高,可以推荐,RabbitMQ。如果公司的基础研发能力很强,想精确到源码级别的掌握,那么推荐使用RocketMQ。同时如果项目是聚焦于大数据领域的实时计算,日志采集等场景,那么Kafka是业内标准。 + + + +## + +## 如何保证消息队列的高可用? + +### 剖析 + +这个问题用的很好,不会具体到某个MQ,而是问一个整体,然后通过你使用的MQ,来具体谈谈该MQ的可用性的理解。 + +### RabbitMQ高可用性 + +RabbitMQ是比较有代表性的,因为是基于主从做高可用性的。 + +RabbitMQ 三种模式:单机模式,普通集群模式,镜像集群模式 + +#### 单机模式 + +就是demo级别的,一般就是本地启动后玩一玩,没有人生产环境中使用。 + +#### 普通集群模式 + +- 意思就是在多台机器上启动多个RabbitMQ实例,每台机器启动一个,但是创建的Queue,只会放在一个RabbitMQ实例上,但是每个实例都同步queue元数据,在消费的时候,实际上是连接到另外一个实例上,那么这个实例会从queue所在实例上拉取数据过来,这种方式确实很麻烦,也不怎么好,没做到所谓的分布式 ,就是个普通集群。因为这导致你要么消费每次随机连接一个实例,然后拉取数据,要么固定连接那个queue所在实例消费数据,前者有数据拉取的开销,后者导致单实例性能瓶颈。 +- 而且如果那个放queue的实例宕机了,会导致接下来其它实例无法从那个实例拉取,如果 你开启了消息持久化,让rabbitmq落地存储消息的话,消息不一定会丢,得等到这个实例恢复了,然后才可以继续从这个queue拉取数据。 + +![image-20200420091806944](images/image-20200420091806944.png) + +这里没有什么所谓的高可用性可言,这个方案主要就是为了解决吐吞量,就是集群中的多个节点来服务于某个queue的读写操作。 + +存在两个缺点 + +- 可能会在RabbitMQ中存在大量的数据传输 +- 可用性没有什么保障,如果queue所在的节点宕机,就会导致queue的消息丢失 + +#### 集群镜像模式 + +这种模式,才是RabbitMQ的高可用模式,和普通的集群模式不一样的是,你创建的queue无论元数据还是queue里的消息都会存在与多个实例中,然后每次你写消息到queu的时候,都会自动把消息推送到多个实例的queue中进行消息同步。 + +这样的好处在于,你任何一个机器宕机了,别的机器都可以用。坏处在于,性能开销提升,消息同步所有的机器,导致网络带宽压力和消耗增加,第二就是没有什么扩展性科研,如果某个queue负载很重,你加机器,新增的机器也包含了这个queue的所有数据,并没有办法线性扩展你的queue + +那么如何开启集群镜像策略呢?就是在RabbitMQ的管理控制台,新增一个策略,这个策略就是镜像集群模式下的策略,指定的时候,可以要求数据同步到所有的节点,也可以要求就 同步到指定数量的节点,然后再次创建queue的时候,应用这个策略,就会自动将数据同步到其它节点上去了。 + +![image-20200420102752707](images/image-20200420102752707.png) + +集群镜像模式下,任何一个节点宕机了都是没问题的,因为其他节点还包含了这个queue的完整的数据,别的consumer可以到其它活着的节点上消费数据。 + +但是这个模式还存在问题:就是不是分布式的,如果这个queue的数据量很大,大到这个机器上的容量无法容纳的时候,此时应该怎么办呢? + + + +### kafka实现高可用 + +![image-20200420104251328](images/image-20200420104251328.png) + +kafka一个最基本的架构认识:多个broker组件,每个broker是一个节点,你创建一个topic,这个topic可以划分成多个partition,每个partition可以存在于不同的broker上,每个partition就放一部分数据。 + +这就是天然的分布式消息队列,就是说一个topic的数据,是分散在多个机器上的,每个机器上就放一部分数据。 + +实际上RabbitMQ之类的,并不是分布式消息队列,他就是传统的消息队列,只不过提供了一些集群、HA的机制而已,因为无论怎么玩,RabbitMQ一个queue的数据都放在一个节点里了,镜像集群下,也是每个节点都放这个queu的完整数据。 + +kafka0.8以前,是没有HA机制的,就是任何一个broker宕机了,那个broker上的partition就废了,没法读也没办法写,没有什么高可用可言,而在0.8版本后,提供了HA机制,就是replica副本机制,每个partition的数据都会同步到其它机器上,形成自己的多个replica副本,然后所有的replica就是follower,写的时候,leader会负责数据都同步到所有的follower上,读的时候就直接读取leader上的数据即可。只能读写leader?很简单,要是你能随意读写每个follower,那么就需要保证数据一致性的问题,系统复杂度太高,很容易出问题,kafka会均匀的将一个partition的所有replica分布在不同的机器上,这样才能够提高容错性 + +每个副本不会存储节点的全部数据,而是数据可能分布在不同的机器上。 + +![image-20200420105712380](images/image-20200420105712380.png) + +同时多个副本中,会选取一个作为leader,其它的副本是作为follower,并且只有leader能对外提供读写,同时leader在写入数据后,它还会把全部的数据同步到follower中,保证数据的备份。 + +此时,高可用的架构就出来了,假设现在某个机器宕机了,比如其中的一个leader宕机了,但是因为每个leader下还有多个follower,并且每个follower都进行了数据的备份,因此kafka会自动感知leader已经宕机,同时将其它的follower给选举出来,作为新的leader,并向外提供服务支持。 + + + +## 如果保证消息的重复消费? + +面试题:如何保证消息的重复消费?如何保证消息消费的幂等性? + +### 剖析 + +其实这是一个常见的问题,既然是消费消息,那肯定是要考虑会不会重复消费?能不能避免重复消费?或者重复消费了也别造成系统异常可以吗?关于消息重复消费的问题,其实本质上就是问你使用消息队列如何保证幂等性,这个是你架构中要考虑的问题。 + +首先是比尔RabbitMQ、RocketMQ、Kafka都会出现消息重复消费的问题,因为这个问题通常不是MQ自己保证的,而是保证消息的不丢失,我们首先从Kafka上来说: + +kafka实际上有个offset的概念,就是每个消息写进去,都有一个offset,代表他的序号,然后consumer消费了数据之后,每隔一段时间,会把自己消费过的消息offset提交一下,代表我已经消费过了,下次我要是重启啥的,你就让我从上次消费到的offset来继续消费。 + +但是凡事总有以外,比如我们之前生产经常遇到的,就是你有时候重启系统,看你怎么重启,如果碰到着急的,直接kill杀死进程,然后重启,这就会导致consumer有些消息处理了没来得及提交offset,然后重启后,就会造成少数消息重复消费的问题。 + +重复消费不可怕,重要的是有没有考虑过重复消费之后,怎么保证幂等性? + +例如:有个系统,消费一条数据往数据库插入一条,要是消息重复消费了两次,那么就插入两条数据了,这个数据也就出错了。 + +![image-20200420112217458](images/image-20200420112217458.png) + +消费者如果在准备提交offset,但是还没有提交的时候,消费者进程被重启,那么此时已经消费过数据的offset并没有提交,kafka也就不知道你已经消费了,那么消费者再次上线进行消费的时候,会把已经消费的数据,重新在传递过来,这就是消息重复消费的问题。 + +### 幂等性是什么? + +通俗点说:幂等性就是一个数据,或者一个请求,给你执行多次,得保证对应的数据不会改变,并且不能出错,这就是幂等性。 + +## 怎么保证消息队列消费的幂等性? + +一条数据重复出现两次,但是数据库里只有一条数据,这就保证了系统的幂等性。 + +### 解决思路 + +- 比如那个数据要写库,首先根据主键查一下,如果这个数据已经有了,那就别插入了,执行update即可 +- 如果用的是redis,那就没问题了,因为每次都是set操作,天然的幂等性 +- 如果不是上面的两个场景,那就做的稍微复杂一点,需要让生产者发送每条消息的时候,需要加一个全局唯一的id,类似于订单id之后的东西,然后你这里消费到了之后,先根据这个id去redis中查找,之前消费过了么,如果没有消费过,那就进行处理,然后把这个id写入到redis中,如果消费过了,那就别处理了,保证别重复消费相同的消息即可。 +- 还有比如基于数据库唯一键来保证重复数据不会重复插入多条,我们之前线上系统就有这个问题,就是拿到数据的时候,每次重启可能会重复,因为Kafka消费者还没来得及提交offset,重复数据拿到了以后,我们进行插入的时候,因为有了唯一键约束了,所以重复数据只会插入报错,不会导致数据库中出现脏数据。 + +![image-20200420113844967](images/image-20200420113844967.png) + + + +## 如何保证消息传输不丢失? + +面试题:如何保证消息的可靠性传输(如何处理消息丢失的问题)? + +### 剖析 + +消息队列有三个重要原则:消息不能多,不能少 + +不能多,指的就是刚刚提到的重复消费和幂等性问题,不能少,指的是数据在传输过程中,不会丢失。 + +如果说使用MQ用来传递非常核心的消息,比如说计费,扣费的一些消息,比如设计和研发一套核心的广告平台,计费系统是一个很重的业务,操作是很耗时的,所以说广告系统整体的架构里面,实际是将计费做成异步化的,然后中间就是加了一个MQ。例如在广告主投放了一个广告,约定的是每次用户点击一次就扣费一次,结果是用户动不动就点击了一次,扣费的时候搞的消息丢了,公司就会不断的少几块钱。这样积少成多,这就是造成了公司的巨大损失。 + +### 为什么会丢数据 + +丢数据,一般分为两种,要么是MQ自己弄丢了,要么是我们消费的时候弄丢了。我们可以从RabbitMQ和Kafka分别来进行分析。 + +RabbitMQ一般来说都是承载公司的核心业务的,数据是绝对不能弄丢的。 + +![image-20200420120701475](images/image-20200420120701475.png) + + + +#### 生产者弄丢了数据 + +生产者将数据发送到RabbitMQ的时候,可能数据就在半路给搞丢了,因为网络啥的问题,都有可能。 + +此时选择用RabbitMQ提供的事务功能,就是生产者发送数据之前,开启RabbitMQ事务(channel.txSelect),然后发送消息,此时就可以回滚事务(channel.txRollback),然后重试发送消息,如果收到了消息,那么可以提交事务,但是问题是,RabbitMQ事务机制一搞,基本上吞吐量会下来,因为太损耗性能。 + +![image-20200420121835297](images/image-20200420121835297.png) + +所以一般来说,如果你要确保写RabbitMQ消息别丢,可以开启confirm模式,在生产者那里设置了开启confirm模式之后,RabbitMQ会给你回传一个ack消息,告诉你这个消息OK了,如果RabbitMQ没能处理这个消息,会给你回调一个接口,告诉你这个消息接收失败,你可以重试 + +``` +// 开启事务 +try { + // 发送消息 +} catch(Exception e) { + // 重试发送消息 +} +// 提交 +``` + +但是,因为事务机制,是同步的 + +针对于上述事务造成性能下降的问题,下面的方法是开启confirm模式 + +- 首先把channel设置成confirm模式 + +- 然后发送一个消息 +- 发送完消息之后,就不用管了 +- RabbitMQ如果接收到这个消息的话,就会回调你生产者本地的一个接口,通知你说这条消息我们已经收到了 +- RabbitMQ如果在接收消息的时候出错了,就会回调这个接口 + +一般生产者如果要保证消息不丢失,一般是用confirm机制,因为是异步的模式,在发送消息之后,不会阻塞,直接可以发送下一条消息,这样吞吐量会更高一些。 + + + +#### RabbitMQ丢失数据 + +这个就是RabbitMQ自己丢失数据,这个时候就必须开启RabbitMQ的持久化,就是消息写入之后,同时需要持久化到磁盘中,哪怕是RabbitMQ自己宕机了,也能够从磁盘中读取之前存储的消息,这样数据一般就不会丢失了,但是存在一个极端的情况,就是RabbitMQ还没持久化的时候,就已经宕机了,那么可能会造成少量的数据丢失,但是这个概率是比较小的。 + +设置持久化的两个步骤,第一个是创建queue的时候,将其持久化的,这样就保证了RabbitMQ持久化queue的元数据,但是不会持久化queue中的数据,第二个就是发送消息的时候,将消息的deliveryMode设置为2,就是将消息设置为持久化的,此时RabbitMQ将会将消息持久化到磁盘上,必须同时设置两个持久化才行,哪怕是Rabbit挂了,也会从磁盘中恢复queue 和 queue中的数据。 + +而且持久化可以跟生产者那边的confirm机制配置起来,只有消息被持久化到磁盘后,才会通知生产者ACK了,所以哪怕是在持久化磁盘之前,RabbitMQ挂了,数据丢了,生产者收不到ACK,你也是可以自己重发的。 + + + +#### 消费者丢失数据 + +消费者丢失数据,主要是因为打开了AutoAck的机制,消费者会自动通知RabbitMQ,表明自己已经消费完这条数据了,但是如果你消费到了一条消息,还在处理中,还没处理完,此时消费者就会自动AutoAck了,通知RabbitMQ说这条消息已经被消费了,此时不巧的是,消费者系统宕机了,这条消息就会丢失,因为RabbitMQ以为这条消息已经处理掉。 + +在消费者层面上,我们需要将AutoAck给关闭,然后每次自己确定已经处理完了一条消息后,你再发送ack给RabbitMQ,如果你还没处理完就宕机了,此时RabbitMQ没收到你发的Ack消息,然后RabbitMQ就会将这条消息分配给其它的消费者去处理。 + + + +## 如何保证消息的顺序性? + +### 场景 + +以前做过一个MySQL binlog同步系统,压力还是非常大的,日同步数据要达到上亿。常见一点的在于 大数据项目中,就需要同步一个mysql库过来,然后对公司业务的系统做各种的复杂操作。 + +在mysql里增删改一条数据,对应出来的增删改3条binlog,接着这三条binlog发送到MQ里面,到消费出来依次执行,这个时候起码得保证能够顺序执行,不然本来是:增加、修改、删除,然后被换成了:删除、修改、增加,不全错了呢。 + +本来这个数据同步过来,应该是最后删除的,结果因为顺序搞错了,最后这个数据被保留了下来,数据同步就出错 + +- RabbitMQ:一个queue,多个consumer,这不明显乱了 +- Kafka:一个topic,一个partition,一个consumer,内部多线程,就会乱套 + +在消息队列中,一个queue中的数据,一次只会被一个消费者消费掉 + +![image-20200420150800480](images/image-20200420150800480.png) + +但因为不同消费者的执行速度不一致,在存入数据库后,造成顺序不一致的问题 + +![image-20200420150935355](images/image-20200420150935355.png) + +### RabbitMQ保证消息顺序性 + +RabbitMQ:拆分多个queue,每个queue一个consumer,就是多一些queue而已,确实是麻烦,或者就是一个queue,但是对应一个consumer,然后这个consumer内部用内存队列做排队,然后分发给底层不同的worker来处理。 + +下图为:一个consumer 对应 一个 queue,这样就保证了消息消费的顺序性。 + +![image-20200420151354856](images/image-20200420151354856.png) + +### Kafka保证消息消息顺序性 + +一个topic,一个partition,一个consumer,内部单线程消费,写N个内存,然后N个线程分别消费一个内存queu即可。注意,kafka中,写入一个partition中的数据,一定是有顺序的, + +![image-20200420152349066](images/image-20200420152349066.png) + +但是在一个消费者的内部,假设有多个线程并发的进行数据的消费,那么这个消息又会乱掉 + +![image-20200420152542344](images/image-20200420152542344.png) + +这样时候,我们需要引入内存队列,然后我们通过消息的key,然后我们通过hash算法,进行hash分发,将相同订单key的散列到我们的同一个内存队列中,然后每一个线程从这个Queue中拉数据,同一个内存Queue也是有顺序的。 + +![image-20200420153622880](images/image-20200420153622880.png) + + + +## 百万消息积压在队列中如何处理? + +如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有百万消息积压接小时,说说解决思路? + +### 剖析 + +MQ大幅度积压这件事挺常见的,一般不出,出了的话就是大型生产事故,例如:消费端每次消费之后要写MySQL,结果MySQL挂了,消费端就不动了,或者一直出错,导致消息消费速度极其慢。 + +### 场景1:积压大量消息 + +几千万的消息积压在MQ中七八个小时,这也是一个真实遇到过的一个场景,确实是线上故障了,这个时候要不然就是修复consumer,让他恢复消费速度,然后傻傻的等待几个小时消费完毕,但是很显然这是一种比较不机智的做法。 + +假设1个消费者1秒消费1000条,1秒3个消费者能消费3000条,一分钟就是18万条,1000万条也需要花费1小时才能够把消息处理掉,这个时候在设备允许的情况下,如何才能够快速处理积压的消息呢? + +一般这个时候,只能够做紧急的扩容操作了,具体操作步骤和思路如下所示: + +- 先修复consumer的问题,确保其恢复消费速度,然后将现有consumer都停止 +- 临时建立好原先10倍或者20倍的queue数量 +- 然后写一个临时的分发数据的consumer程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的10倍数量的queue +- 接着临时征用10倍机器来部署consumer,每一批consumer消费一个临时queue的数据 +- 这种做法相当于临时将queue资源和consumer资源扩大了10倍,以正常的10倍速度 + +![image-20200420160304030](images/image-20200420160304030.png) + +也就是让消费者把消息,重新写入MQ中,然后在用 10倍的消费者来进行消费。 + +![image-20200420160319662](images/image-20200420160319662.png) + + + +### 场景2:大量消息积压,并且设置了过期时间 + +假设你用的是RabbitMQ,RabbitMQ是可以设置过期时间的,就是TTL,如果消息在queue中积压超过一定的时间,就会被RabbitMQ给清理掉,这个数据就没了。这个时候就不是数据被大量积压的问题,而是大量的数据被直接搞丢了。 + +这种情况下,就不是说要增加consumer消费积压的消息,因为实际上没有啥积压的,而是丢了大量的消息,我们可以采取的一个方案就是,批量重导,这个之前线上也有遇到类似的场景,就是大量的消息积压的时候,然后就直接丢弃了数据,然后等高峰期过了之后,例如在晚上12点以后,就开始写程序,将丢失的那批数据,写个临时程序,一点点查询出来,然后重新 添加MQ里面,把白天丢的数据,全部补回来。 + +假设1万个订单积压在MQ里面,没有处理,其中1000个订单都丢了,你只能手动写程序把那1000个订单查询出来,然后手动发到MQ里面去再补一次。 + + + +### 场景3:大量消息积压,导致MQ磁盘满了 + +如果走的方式是消息积压在MQ里,那么如果你很长时间都没有处理掉,此时导致MQ都快写满了,咋办? + +这个时候,也是因为方案一执行的太慢了,只能写一个临时程序,接入数据来消费,然后消费一个丢弃一个,都不要了,快速消费掉所有的消息。然后走第二个方案,到凌晨的时候,在把消息填入MQ中进行消费。 + + + +## 如何设计一个消息中间件架构? + +如果让你写一个消息队列,该如何进行架构设计?说下你的思路 + +这种问题,说白了,起码不求你看过那些技术的源码,但是你应该大概知道那些技术的基本原理,核心组成部分,基本架构个构成,然后参照一些开源技术把一个系统设计出来的思路说一下就好了。 + +### 思路 + +- 首先MQ得支持可伸缩性,那就需要快速扩容,就可以增加吞吐量和容量,可以设计一个分布式的系统,参考kafka的设计理念,broker - > topic -> partition,每个partition放一台机器,那就存一部分数据,如果现在资源不够了,可以给topic增加partition,然后做数据迁移,增加机器,不就可以存放更多的数据,提高更高的吞吐量。 +- 其次得考虑一下这个MQ的数据要不要落地磁盘?也就是需不需要保证消息持久化,因为这样可以保证数据的不丢失,那落地盘的时候怎么落?顺序写,这样没有磁盘随机读写的寻址开销,磁盘顺序读的性能是很高的,这就是kafka的思路。 +- 其次需要考虑MQ的可用性?这个可以具体到我们上面提到的消息队列保证高可用,提出了多副本 ,leader 和follower模式,当一个leader宕机的时候,马上选取一个follower作为新的leader对外提供服务。 +- 需不需要支持数据0丢失?可以参考kafka零丢失方案 + +其实一个MQ肯定是很复杂的,问这个问题其实是一个开放性问题,主要是想看看有没有从架构的角度整体构思和设计的思维以及能力 + + + +## 消息队列相关问题总结 + +一般而言,如果一个面试官水平还不错,会沿着从浅入深挖一个点,然后按着这个思路一直问下去,除了这里的七大问题之后,甚至还能挑着你熟悉的一个MQ一直问到源码级别,还可能结合项目来仔细问,先讲讲具体的业务细节,然后将业务跟这些MQ的问题场景结合起来,看看你的每个细节是如何处理和实现的。 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200418212721479.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200418212721479.png" new file mode 100644 index 0000000000000000000000000000000000000000..abc74d395d97253d33b3855afd8da69811d1f87b Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200418212721479.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200418213021225.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200418213021225.png" new file mode 100644 index 0000000000000000000000000000000000000000..2f394017539877cbc3212400226d64629dd4e0ed Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200418213021225.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419205127214.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419205127214.png" new file mode 100644 index 0000000000000000000000000000000000000000..ec263851914e461b6b11b63d7f6cb56d27884c87 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419205127214.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419205855859.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419205855859.png" new file mode 100644 index 0000000000000000000000000000000000000000..9efd7c2b05f2caf880acb38a9d99ada04a61a1b0 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419205855859.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419213232855.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419213232855.png" new file mode 100644 index 0000000000000000000000000000000000000000..8c1e6c94a032a552945ddec240fddfddbe54baba Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419213232855.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419213609511.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419213609511.png" new file mode 100644 index 0000000000000000000000000000000000000000..b0ddcbc040aaa6870af456d013761a13b33dfba3 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419213609511.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419235201993.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419235201993.png" new file mode 100644 index 0000000000000000000000000000000000000000..bbfa1522c3c68ef7e68fef45ae797e65dc7f41fa Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200419235201993.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420070841754.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420070841754.png" new file mode 100644 index 0000000000000000000000000000000000000000..66456f40a85009aa08a735fa99e6092fedbe6781 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420070841754.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420091806944.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420091806944.png" new file mode 100644 index 0000000000000000000000000000000000000000..aaa22c7a1a08dccc6736fcb15315e49a557a3f4d Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420091806944.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420102752707.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420102752707.png" new file mode 100644 index 0000000000000000000000000000000000000000..7fca494483d9d825133b3619b00b49d45b343d79 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420102752707.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420104251328.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420104251328.png" new file mode 100644 index 0000000000000000000000000000000000000000..eca1cd5cfefddcd064a86c3ae15cc085aee02285 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420104251328.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420105712380.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420105712380.png" new file mode 100644 index 0000000000000000000000000000000000000000..2b1042fd33bbe8d338b798b20fe964fb3ee64220 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420105712380.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420112217458.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420112217458.png" new file mode 100644 index 0000000000000000000000000000000000000000..cb3fa0d7f027fadee87f11fb08a633c11fe7a1ab Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420112217458.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420113844967.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420113844967.png" new file mode 100644 index 0000000000000000000000000000000000000000..daca1741140ec3483653ac534b77dc99a1af4a82 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420113844967.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420120701475.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420120701475.png" new file mode 100644 index 0000000000000000000000000000000000000000..480c733554e754d71e0e8fd3e111b682c5f65b92 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420120701475.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420121835297.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420121835297.png" new file mode 100644 index 0000000000000000000000000000000000000000..6671ba2d13b90601872fa4a809367b7835f90698 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420121835297.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420150800480.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420150800480.png" new file mode 100644 index 0000000000000000000000000000000000000000..c40f11d7b1245efa028a2d319ee0bffc10e15ba7 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420150800480.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420150935355.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420150935355.png" new file mode 100644 index 0000000000000000000000000000000000000000..e929f4214eceae27506804cdf25dc7a6543dd7e8 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420150935355.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420151354856.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420151354856.png" new file mode 100644 index 0000000000000000000000000000000000000000..1963fc913f1f939938b42952612b58cf0161512f Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420151354856.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420152349066.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420152349066.png" new file mode 100644 index 0000000000000000000000000000000000000000..ffc58c9a83d32e29fc5fb52390832ea54cef40af Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420152349066.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420152542344.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420152542344.png" new file mode 100644 index 0000000000000000000000000000000000000000..837e9e2b0d1fee9ab2d69120e5d57db8c2f916c8 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420152542344.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420153622880.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420153622880.png" new file mode 100644 index 0000000000000000000000000000000000000000..63d4c7973f283a52080dd7cb99bec170f073e2ae Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420153622880.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420160304030.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420160304030.png" new file mode 100644 index 0000000000000000000000000000000000000000..04c79b393bd00e2cb6fb57c6b644de2927976f9a Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420160304030.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420160319662.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420160319662.png" new file mode 100644 index 0000000000000000000000000000000000000000..389fb068925ca212109b62b06ec2807c508e2825 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/1_\346\266\210\346\201\257\351\230\237\345\210\227\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420160319662.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..fdc663d54f11d193f510cbdf34135c55ac080c1b --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" @@ -0,0 +1,422 @@ +# 分布式搜索引擎的面试连环炮 + +业内目前来说事实上的一个标准,就是分布式搜索引擎一般大家都是用ElasticSearch,(原来的话使用的是Solr),但是确实,这两年大家一般都用更加易用的es。 + +ElasticSearch 和 Solr 底层都是基于Lucene,而Lucene的底层原理是 **倒排索引** + +## 倒排索引是什么 + +倒排索引适用于快速的全文检索,一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表 + +例如: + +假设文档集合中包含五个文档,每个文档的内容如下所示,在图中最左端一栏是每个文档对应的编号,我们的任务就是对这个文档集合建立倒排索引 + +![image-20200420174829608](images/image-20200420174829608.png) + +中文和英文等语言不通,单词之间没有明确分割符号,所以首先要用分词系统将文档自动切分成单词序列,这样每个文档就转换为由单词序列构成的数据流,为了系统后续处理方便,需要对每个不同的单词赋予唯一的单词编号,同时记录下哪些文档包含这个单词,在如此处理结束后,我们就可以得到最简单的倒排索引了 + +![image-20200420175115061](images/image-20200420175115061.png) + +索引系统还可以记录除此之外的更多信息,下图是记录了单词出现的频率(TF)即这个单词在文档中出现的次数,之所以要记录这个信息,是因为词频信息在搜索结果排序时,计算查询和文档相似度是很重要的一个计算因子,所以将其记录在倒排列表中,以便后续排序时进行分值计算。 + +![image-20200420175534595](images/image-20200420175534595.png) + +倒排列表还可以记录单词在某个文档出现的位置信息 + +``` +(1, <11>, 1), (2, <7>, 1), (3, <3, 9>, 2) +``` + +有了这个索引系统,搜索引擎可以很方便地响应用户的查询,比如用户输入查询词 "Facebook",搜索系统查找倒排索引,从中可以读出包含这个单词的文档,这些文档就是提供给用户的搜索结果,而利用单词频率信息,文档频率信息即可以对这些候选搜索结果进行排序,计算文档和查询的相似性,按照相似性得分由高到低排序输出,此即为搜索系统的部分内部流程。 + +## 中文分词器原理 + +### 方法1 + +分词器的原理本质上是词典分词。在现有内存中初始化一个词典,然后在分词过程中挨个读取字符和字典中的字符相匹配,把文档中所有词语拆分出来的过程。 + +### 方法2 字典树 + +Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。 + +下面一个存放了[大学、大学生、学习、学习机、学生、生气、生活、活着]这个词典的trie树: +![image-20200630105344435](images/image-20200630105344435.png) + +它可以看作是用每个词第n个字做第n到第n+1层节点间路径哈希值的哈希树,每个节点是实际要存放的词。 + +现在用这个树来进行“大学生活”的匹配。依然从“大”字开始匹配,如下图所示:从根节点开始,沿最左边的路径匹配到了大字,沿着“大”节点可以匹配到“大学”,继续匹配则可以匹配到“大学生”,之后字典中再没有以“大”字开头的词,至此已经匹配到了[大学、大学生]第一轮匹配结束 + +![image-20200630105421277](images/image-20200630105421277.png) + +继续匹配“学”字开头的词,方法同上步,可匹配出[学生] + +![image-20200630105436614](images/image-20200630105436614.png) + +继续匹配“生”和“活”字开头的词,这样“大学生活”在词典中的词全部被查出来。 + +可以看到,以匹配“大”字开头的词为例,第一种匹配方式需要在词典中查询是否包含“大”、“大学”、“大学”、“大学生活”,共4次查询,而使用trie树查询时当找到“大学生”这个词之后就停止了该轮匹配,减少了匹配的次数,当要匹配的句子越长,这种性能优势就越明显。 + +### 失败指针 + +再来看一下上面的匹配过程,在匹配“大学生”这个词之后,由于词典中不存在其它以“大”字开头的词,本轮结束,将继续匹配以“学”字开头的词,这时,需要再回到根节点继续匹配,如果这个时候“大学生”节点有个指针可以直指向“学生”节点,就可以减少一次查询,类似地,当匹配完“学生”之后如果“学生”节点有个指针可以指向“生活”节点,就又可以减少一次查询。这种当下一层节点无法匹配需要进行跳转的指针就是失败指针,创建好失败指针的树看起来如下图: +![image-20200630105709557](images/image-20200630105709557.png) + +图上红色的线就是失败指针,指向的是当下层节点无法匹配时应该跳转到哪个节点继续进行匹配 + +失败指针的创建过程通常为: + +- 创建好trie树。 + + +- BFS每一个节点(不能使用DFS,因为每一层节点的失败指针在创建时要确保上一层节点的失败指针全部创建完成)。 + + +- 根节点的子节点的失败指针指向根节点。 + + +- 其它节点查找其父节点的失败指针指向的节点的子节点是否有和该节点字相同的节点,如果有则失败指针指向该节点,如果没有则重复刚才的过程直至找到字相同的节点或根节点。 + +查询过程如下: + +![image-20200630105955680](images/image-20200630105955680.png) + +## ES的分布式架构原理能说一下么? + +![01_elasticsearch分布式架构原理](images/01_elasticsearch分布式架构原理.png) + +elasticsearch设计的理念就是分布式搜索引擎,底层其实还是基于lucene的。 + +核心思想就是在多台机器上启动多个es进程实例,组成了一个es集群。 + +es中存储数据的基本单位是索引,比如说你现在要在es中存储一些订单数据,你就应该在es中创建一个索引,order_idx,所有的订单数据就都写到这个索引里面去,一个索引差不多就是相当于是mysql里的一张表。index -> type -> mapping -> document -> field。 + +index:mysql里的一张表 + +type:没法跟mysql里去对比,一个index里可以有多个type,每个type的字段都是差不多的,但是有一些略微的差别。 + +好比说,有一个index,是订单index,里面专门是放订单数据的。就好比说你在mysql中建表,有些订单是实物商品的订单,就好比说一件衣服,一双鞋子;有些订单是虚拟商品的订单,就好比说游戏点卡,话费充值。就两种订单大部分字段是一样的,但是少部分字段可能有略微的一些差别。 + +所以就会在订单index里,建两个type,一个是实物商品订单type,一个是虚拟商品订单type,这两个type大部分字段是一样的,少部分字段是不一样的。 + +很多情况下,一个index里可能就一个type,但是确实如果说是一个index里有多个type的情况,你可以认为index是一个类别的表,具体的每个type代表了具体的一个mysql中的表 + +每个type有一个mapping,如果你认为一个type是一个具体的一个表,index代表了多个type的同属于的一个类型,mapping就是这个type的表结构定义,你在mysql中创建一个表,肯定是要定义表结构的,里面有哪些字段,每个字段是什么类型。。。 + +mapping就代表了这个type的表结构的定义,定义了这个type中每个字段名称,字段是什么类型的,然后还有这个字段的各种配置 + +实际上你往index里的一个type里面写的一条数据,叫做一条document,一条document就代表了mysql中某个表里的一行给,每个document有多个field,每个field就代表了这个document中的一个字段的值 + +接着你搞一个索引,这个索引可以拆分成多个shard,每个shard存储部分数据。 + +接着就是这个shard的数据实际是有多个备份,就是说每个shard都有一个primary shard,负责写入数据,但是还有几个replica shard。primary shard写入数据之后,会将数据同步到其他几个replica shard上去。 + +通过这个replica的方案,每个shard的数据都有多个备份,如果某个机器宕机了,没关系啊,还有别的数据副本在别的机器上呢。高可用了吧。 + +es集群多个节点,会自动选举一个节点为master节点,这个master节点其实就是干一些管理的工作的,比如维护索引元数据拉,负责切换primary shard和replica shard身份拉,之类的。 + +要是master节点宕机了,那么会重新选举一个节点为master节点。 + +如果是非master节点宕机了,那么会由master节点,让那个宕机节点上的primary shard的身份转移到其他机器上的replica shard。急着你要是修复了那个宕机机器,重启了之后,master节点会控制将缺失的replica shard分配过去,同步后续修改的数据之类的,让集群恢复正常。 + +其实上述就是elasticsearch作为一个分布式搜索引擎最基本的一个架构设计 + +## ES查询和读取数据的工作原理是什么? + +![01_es读写底层原理剖析](images/01_es读写底层原理剖析.png) + +(1)es写数据过程 + +1)客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点) + +2)coordinating node,对document进行路由,将请求转发给对应的node(有primary shard) + +3)实际的node上的primary shard处理请求,然后将数据同步到replica node + +4)coordinating node,如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端 + +(2)es读数据过程 + +查询,GET某一条数据,写入了某个document,这个document会自动给你分配一个全局唯一的id,doc id,同时也是根据doc id进行hash路由到对应的primary shard上面去。也可以手动指定doc id,比如用订单id,用户id。 + +你可以通过doc id来查询,会根据doc id进行hash,判断出来当时把doc id分配到了哪个shard上面去,从那个shard去查询 + +1)客户端发送请求到任意一个node,成为coordinate node + +2)coordinate node对document进行路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primary shard以及其所有replica中随机选择一个,让读请求负载均衡 + +3)接收请求的node返回document给coordinate node + +4)coordinate node返回document给客户端 + +(3)es搜索数据过程 + +es最强大的是做全文检索,就是比如你有三条数据 + +java真好玩儿啊 + +java好难学啊 + +j2ee特别牛 + +你根据java关键词来搜索,将包含java的document给搜索出来 + +es就会给你返回:java真好玩儿啊,java好难学啊 + +1)客户端发送请求到一个coordinate node + +2)协调节点将搜索请求转发到所有的shard对应的primary shard或replica shard也可以 + +3)query phase:每个shard将自己的搜索结果(其实就是一些doc id),返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果 + +4)fetch phase:接着由协调节点,根据doc id去各个节点上拉取实际的document数据,最终返回给客户端 + +(4)搜索的底层原理,倒排索引,画图说明传统数据库和倒排索引的区别 + +(5)写数据底层原理 + +1)先写入buffer,在buffer里的时候数据是搜索不到的;同时将数据写入translog日志文件 + +2)如果buffer快满了,或者到一定时间,就会将buffer数据refresh到一个新的segment file中,但是此时数据不是直接进入segment file的磁盘文件的,而是先进入os cache的。这个过程就是refresh。 + +每隔1秒钟,es将buffer中的数据写入一个新的segment file,每秒钟会产生一个新的磁盘文件,segment file,这个segment file中就存储最近1秒内buffer中写入的数据 + +但是如果buffer里面此时没有数据,那当然不会执行refresh操作咯,每秒创建换一个空的segment file,如果buffer里面有数据,默认1秒钟执行一次refresh操作,刷入一个新的segment file中 + +操作系统里面,磁盘文件其实都有一个东西,叫做os cache,操作系统缓存,就是说数据写入磁盘文件之前,会先进入os cache,先进入操作系统级别的一个内存缓存中去 + +只要buffer中的数据被refresh操作,刷入os cache中,就代表这个数据就可以被搜索到了 + +为什么叫es是准实时的?NRT,near real-time,准实时。默认是每隔1秒refresh一次的,所以es是准实时的,因为写入的数据1秒之后才能被看到。 + +可以通过es的restful api或者java api,手动执行一次refresh操作,就是手动将buffer中的数据刷入os cache中,让数据立马就可以被搜索到。 + +只要数据被输入os cache中,buffer就会被清空了,因为不需要保留buffer了,数据在translog里面已经持久化到磁盘去一份 + +3)只要数据进入os cache,此时就可以让这个segment file的数据对外提供搜索了 + +4)重复1~3步骤,新的数据不断进入buffer和translog,不断将buffer数据写入一个又一个新的segment file中去,每次refresh完buffer清空,translog保留。随着这个过程推进,translog会变得越来越大。当translog达到一定长度的时候,就会触发commit操作。 + +buffer中的数据,倒是好,每隔1秒就被刷到os cache中去,然后这个buffer就被清空了。所以说这个buffer的数据始终是可以保持住不会填满es进程的内存的。 + +每次一条数据写入buffer,同时会写入一条日志到translog日志文件中去,所以这个translog日志文件是不断变大的,当translog日志文件大到一定程度的时候,就会执行commit操作。 + +5)commit操作发生第一步,就是将buffer中现有数据refresh到os cache中去,清空buffer + +6)将一个commit point写入磁盘文件,里面标识着这个commit point对应的所有segment file + +7)强行将os cache中目前所有的数据都fsync到磁盘文件中去 + +translog日志文件的作用是什么?就是在你执行commit操作之前,数据要么是停留在buffer中,要么是停留在os cache中,无论是buffer还是os cache都是内存,一旦这台机器死了,内存中的数据就全丢了。 + +所以需要将数据对应的操作写入一个专门的日志文件,translog日志文件中,一旦此时机器宕机,再次重启的时候,es会自动读取translog日志文件中的数据,恢复到内存buffer和os cache中去。 + +commit操作:1、写commit point;2、将os cache数据fsync强刷到磁盘上去;3、清空translog日志文件 + +8)将现有的translog清空,然后再次重启启用一个translog,此时commit操作完成。默认每隔30分钟会自动执行一次commit,但是如果translog过大,也会触发commit。整个commit的过程,叫做flush操作。我们可以手动执行flush操作就是将所有os cache数据刷到磁盘文件中去。 + +不叫做commit操作,flush操作。es中的flush操作,就对应着commit的全过程。我们也可以通过es api,手动执行flush操作,手动将os cache中的数据fsync强刷到磁盘上去,记录一个commit point,清空translog日志文件。 + +9)translog其实也是先写入os cache的,默认每隔5秒刷一次到磁盘中去,所以默认情况下,可能有5秒的数据会仅仅停留在buffer或者translog文件的os cache中,如果此时机器挂了,会丢失5秒钟的数据。但是这样性能比较好,最多丢5秒的数据。也可以将translog设置成每次写操作必须是直接fsync到磁盘,但是性能会差很多。 + +实际上你在这里,如果面试官没有问你es丢数据的问题,你可以在这里给面试官炫一把,你说,其实es第一是准实时的,数据写入1秒后可以搜索到;可能会丢失数据的,你的数据有5秒的数据,停留在buffer、translog os cache、segment file os cache中,有5秒的数据不在磁盘上,此时如果宕机,会导致5秒的数据丢失。 + +如果你希望一定不能丢失数据的话,你可以设置个参数,官方文档,百度一下。每次写入一条数据,都是写入buffer,同时写入磁盘上的translog,但是这会导致写性能、写入吞吐量会下降一个数量级。本来一秒钟可以写2000条,现在你一秒钟只能写200条,都有可能。 + +10)如果是删除操作,commit的时候会生成一个.del文件,里面将某个doc标识为deleted状态,那么搜索的时候根据.del文件就知道这个doc被删除了 + +11)如果是更新操作,就是将原来的doc标识为deleted状态,然后新写入一条数据 + +12)buffer每次refresh一次,就会产生一个segment file,所以默认情况下是1秒钟一个segment file,segment file会越来越多,此时会定期执行merge + +13)每次merge的时候,会将多个segment file合并成一个,同时这里会将标识为deleted的doc给物理删除掉,然后将新的segment file写入磁盘,这里会写一个commit point,标识所有新的segment file,然后打开segment file供搜索使用,同时删除旧的segment file。 + +es里的写流程,有4个底层的核心概念,refresh、flush、translog、merge + +当segment file多到一定程度的时候,es就会自动触发merge操作,将多个segment file给merge成一个segment file。 + +## ES在数据量很大的情况下(数十亿级别)如何提高查询性能? + +![01_filesystem cache对es性能的影响](images/01_filesystem cache对es性能的影响.png) + +说实话,es性能优化是没有什么银弹的,啥意思呢?就是不要期待着随手调一个参数,就可以万能的应对所有的性能慢的场景。也许有的场景是你换个参数,或者调整一下语法,就可以搞定,但是绝对不是所有场景都可以这样。 + +一块一块来分析吧 + +在这个海量数据的场景下,如何提升es搜索的性能,也是我们之前生产环境实践经验所得 + +(1)性能优化的杀手锏——filesystem cache + +os cache,操作系统的缓存 + +你往es里写的数据,实际上都写到磁盘文件里去了,磁盘文件里的数据操作系统会自动将里面的数据缓存到os cache里面去 + +es的搜索引擎严重依赖于底层的filesystem cache,你如果给filesystem cache更多的内存,尽量让内存可以容纳所有的indx segment file索引数据文件,那么你搜索的时候就基本都是走内存的,性能会非常高。 + +性能差距可以有大,我们之前很多的测试和压测,如果走磁盘一般肯定上秒,搜索性能绝对是秒级别的,1秒,5秒,10秒。但是如果是走filesystem cache,是走纯内存的,那么一般来说性能比走磁盘要高一个数量级,基本上就是毫秒级的,从几毫秒到几百毫秒不等。 + +之前有个学员,一直在问我,说他的搜索性能,聚合性能,倒排索引,正排索引,磁盘文件,十几秒。。。。 + +学员的真实案例 + +比如说,你,es节点有3台机器,每台机器,看起来内存很多,64G,总内存,64 * 3 = 192g + +每台机器给es jvm heap是32G,那么剩下来留给filesystem cache的就是每台机器才32g,总共集群里给filesystem cache的就是32 * 3 = 96g内存 + +我就问他,ok,那么就是你往es集群里写入的数据有多少数据量? + +如果你此时,你整个,磁盘上索引数据文件,在3台机器上,一共占用了1T的磁盘容量,你的es数据量是1t,每台机器的数据量是300g + +你觉得你的性能能好吗?filesystem cache的内存才100g,十分之一的数据可以放内存,其他的都在磁盘,然后你执行搜索操作,大部分操作都是走磁盘,性能肯定差 + +当时他们的情况就是这样子,es在测试,弄了3台机器,自己觉得还不错,64G内存的物理机。自以为可以容纳1T的数据量。 + +归根结底,你要让es性能要好,最佳的情况下,就是你的机器的内存,至少可以容纳你的总数据量的一半 + +比如说,你一共要在es中存储1T的数据,那么你的多台机器留个filesystem cache的内存加起来综合,至少要到512G,至少半数的情况下,搜索是走内存的,性能一般可以到几秒钟,2秒,3秒,5秒 + +如果最佳的情况下,我们自己的生产环境实践经验,所以说我们当时的策略,是仅仅在es中就存少量的数据,就是你要用来搜索的那些索引,内存留给filesystem cache的,就100G,那么你就控制在100gb以内,相当于是,你的数据几乎全部走内存来搜索,性能非常之高,一般可以在1秒以内 + +比如说你现在有一行数据 + +id name age ....30个字段 + +但是你现在搜索,只需要根据id name age三个字段来搜索 + +如果你傻乎乎的往es里写入一行数据所有的字段,就会导致说70%的数据是不用来搜索的,结果硬是占据了es机器上的filesystem cache的空间,单挑数据的数据量越大,就会导致filesystem cahce能缓存的数据就越少 + +仅仅只是写入es中要用来检索的少数几个字段就可以了,比如说,就写入es id name age三个字段就可以了,然后你可以把其他的字段数据存在mysql里面,我们一般是建议用es + hbase的这么一个架构。 + +hbase的特点是适用于海量数据的在线存储,就是对hbase可以写入海量数据,不要做复杂的搜索,就是做很简单的一些根据id或者范围进行查询的这么一个操作就可以了 + +从es中根据name和age去搜索,拿到的结果可能就20个doc id,然后根据doc id到hbase里去查询每个doc id对应的完整的数据,给查出来,再返回给前端。 + +你最好是写入es的数据小于等于,或者是略微大于es的filesystem cache的内存容量 + +然后你从es检索可能就花费20ms,然后再根据es返回的id去hbase里查询,查20条数据,可能也就耗费个30ms,可能你原来那么玩儿,1T数据都放es,会每次查询都是5~10秒,现在可能性能就会很高,每次查询就是50ms。 + +elastcisearch减少数据量仅仅放要用于搜索的几个关键字段即可,尽量写入es的数据量跟es机器的filesystem cache是差不多的就可以了;其他不用来检索的数据放hbase里,或者mysql。 + +所以之前有些学员也是问,我也是跟他们说,尽量在es里,就存储必须用来搜索的数据,比如说你现在有一份数据,有100个字段,其实用来搜索的只有10个字段,建议是将10个字段的数据,存入es,剩下90个字段的数据,可以放mysql,hadoop hbase,都可以 + +这样的话,es数据量很少,10个字段的数据,都可以放内存,就用来搜索,搜索出来一些id,通过id去mysql,hbase里面去查询明细的数据 + +(2)数据预热 + +假如说,哪怕是你就按照上述的方案去做了,es集群中每个机器写入的数据量还是超过了filesystem cache一倍,比如说你写入一台机器60g数据,结果filesystem cache就30g,还是有30g数据留在了磁盘上。 + +举个例子,就比如说,微博,你可以把一些大v,平时看的人很多的数据给提前你自己后台搞个系统,每隔一会儿,你自己的后台系统去搜索一下热数据,刷到filesystem cache里去,后面用户实际上来看这个热数据的时候,他们就是直接从内存里搜索了,很快。 + +电商,你可以将平时查看最多的一些商品,比如说iphone 8,热数据提前后台搞个程序,每隔1分钟自己主动访问一次,刷到filesystem cache里去。 + +对于那些你觉得比较热的,经常会有人访问的数据,最好做一个专门的缓存预热子系统,就是对热数据,每隔一段时间,你就提前访问一下,让数据进入filesystem cache里面去。这样期待下次别人访问的时候,一定性能会好一些。 + +(3)冷热分离 + +关于es性能优化,数据拆分,我之前说将大量不搜索的字段,拆分到别的存储中去,这个就是类似于后面我最后要讲的mysql分库分表的垂直拆分。 + + es可以做类似于mysql的水平拆分,就是说将大量的访问很少,频率很低的数据,单独写一个索引,然后将访问很频繁的热数据单独写一个索引 + +你最好是将冷数据写入一个索引中,然后热数据写入另外一个索引中,这样可以确保热数据在被预热之后,尽量都让他们留在filesystem os cache里,别让冷数据给冲刷掉。 + +你看,假设你有6台机器,2个索引,一个放冷数据,一个放热数据,每个索引3个shard + +3台机器放热数据index;另外3台机器放冷数据index + +然后这样的话,你大量的时候是在访问热数据index,热数据可能就占总数据量的10%,此时数据量很少,几乎全都保留在filesystem cache里面了,就可以确保热数据的访问性能是很高的。 + +但是对于冷数据而言,是在别的index里的,跟热数据index都不再相同的机器上,大家互相之间都没什么联系了。如果有人访问冷数据,可能大量数据是在磁盘上的,此时性能差点,就10%的人去访问冷数据;90%的人在访问热数据。 + + + +(4)document模型设计 + +有不少同学问我,mysql,有两张表 + +订单表:id order_code total_price + +1 测试订单 5000 + +订单条目表:id order_id goods_id purchase_count price + +1 1 1 2 2000 + +2 1 2 5 200 + + + +我在mysql里,都是select * from order join order_item on order.id=order_item.order_id where order.id=1 + +1 测试订单 5000 1 1 1 2 2000 + +1 测试订单 5000 2 1 2 5 200 + + 在es里该怎么玩儿,es里面的复杂的关联查询,复杂的查询语法,尽量别用,一旦用了性能一般都不太好 + +设计es里的数据模型 + +写入es的时候,搞成两个索引,order索引,orderItem索引 + +order索引,里面就包含id order_code total_price + +orderItem索引,里面写入进去的时候,就完成join操作,id order_code total_price id order_id goods_id purchase_count price + +写入es的java系统里,就完成关联,将关联好的数据直接写入es中,搜索的时候,就不需要利用es的搜索语法去完成join来搜索了 + +document模型设计是非常重要的,很多操作,不要在搜索的时候才想去执行各种复杂的乱七八糟的操作。es能支持的操作就是那么多,不要考虑用es做一些它不好操作的事情。如果真的有那种操作,尽量在document模型设计的时候,写入的时候就完成。另外对于一些太复杂的操作,比如join,nested,parent-child搜索都要尽量避免,性能都很差的。 + +很多同学在问我,很多复杂的乱七八糟的一些操作,如何执行 + +两个思路,在搜索/查询的时候,要执行一些业务强相关的特别复杂的操作: + +1)在写入数据的时候,就设计好模型,加几个字段,把处理好的数据写入加的字段里面 + +2)自己用java程序封装,es能做的,用es来做,搜索出来的数据,在java程序里面去做,比如说我们,基于es,用java封装一些特别复杂的操作 + +(5)分页性能优化 + +es的分页是较坑的,为啥呢?举个例子吧,假如你每页是10条数据,你现在要查询第100页,实际上是会把每个shard上存储的前1000条数据都查到一个协调节点上,如果你有个5个shard,那么就有5000条数据,接着协调节点对这5000条数据进行一些合并、处理,再获取到最终第100页的10条数据。 + +分布式的,你要查第100页的10条数据,你是不可能说从5个shard,每个shard就查2条数据?最后到协调节点合并成10条数据?你必须得从每个shard都查1000条数据过来,然后根据你的需求进行排序、筛选等等操作,最后再次分页,拿到里面第100页的数据。 + +你翻页的时候,翻的越深,每个shard返回的数据就越多,而且协调节点处理的时间越长。非常坑爹。所以用es做分页的时候,你会发现越翻到后面,就越是慢。 + +我们之前也是遇到过这个问题,用es作分页,前几页就几十毫秒,翻到10页之后,几十页的时候,基本上就要5~10秒才能查出来一页数据了 + +1)不允许深度分页/默认深度分页性能很惨 + +你系统不允许他翻那么深的页,pm,默认翻的越深,性能就越差 + +2)类似于app里的推荐商品不断下拉出来一页一页的 + +类似于微博中,下拉刷微博,刷出来一页一页的,你可以用scroll api,自己百度 + +scroll会一次性给你生成所有数据的一个快照,然后每次翻页就是通过游标移动,获取下一页下一页这样子,性能会比上面说的那种分页性能也高很多很多 + +针对这个问题,你可以考虑用scroll来进行处理,scroll的原理实际上是保留一个数据快照,然后在一定时间内,你如果不断的滑动往后翻页的时候,类似于你现在在浏览微博,不断往下刷新翻页。那么就用scroll不断通过游标获取下一页数据,这个性能是很高的,比es实际翻页要好的多的多。 + +但是唯一的一点就是,这个适合于那种类似微博下拉翻页的,不能随意跳到任何一页的场景。同时这个scroll是要保留一段时间内的数据快照的,你需要确保用户不会持续不断翻页翻几个小时。 + +无论多少页,性能基本上都是毫秒级的 + +因为scroll api是只能一页一页往后翻的,是不能说,先进入第10页,然后去120页,回到58页,不能随意乱跳页。所以现在很多产品,都是不允许你随意翻页的,app,也有一些网站,做的就是你只能往下拉,一页一页的翻 + +## ES生产集群的部署架构是什么?每个索引的数据量大概是多少?么给索引大概有多少分片? + +这个问题,包括后面的redis什么的,谈到es、redis、mysql分库分表等等技术,面试必问!就是你生产环境咋部署的?说白了,这个问题没啥技术含量,就是看你有没有在真正的生产环境里干过这事儿! + +有些同学可能是没在生产环境中干过的,没实际去拿线上机器部署过es集群,也没实际玩儿过,也没往es集群里面导入过几千万甚至是几亿的数据量,可能你就不太清楚这里面的一些生产项目中的细节 + +如果你是自己就玩儿过demo,没碰过真实的es集群,那你可能此时会懵,但是别懵。。。你一定要云淡风轻的回答出来这个问题,表示你确实干过这事儿 + +3、面试题剖析 + +其实这个问题没啥,如果你确实干过es,那你肯定了解你们生产es集群的实际情况,部署了几台机器?有多少个索引?每个索引有多大数据量?每个索引给了多少个分片?你肯定知道! + +但是如果你确实没干过,也别虚,我给你说一个基本的版本,你到时候就简单说一下就好了 + +(1)es生产集群我们部署了5台机器,每台机器是6核64G的,集群总内存是320G + +(2)我们es集群的日增量数据大概是2000万条,每天日增量数据大概是500MB,每月增量数据大概是6亿,15G。目前系统已经运行了几个月,现在es集群里数据总量大概是100G左右。 + +(3)目前线上有5个索引(这个结合你们自己业务来,看看自己有哪些数据可以放es的),每个索引的数据量大概是20G,所以这个数据量之内,我们每个索引分配的是8个shard,比默认的5个shard多了3个shard。 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_elasticsearch\345\210\206\345\270\203\345\274\217\346\236\266\346\236\204\345\216\237\347\220\206.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_elasticsearch\345\210\206\345\270\203\345\274\217\346\236\266\346\236\204\345\216\237\347\220\206.png" new file mode 100644 index 0000000000000000000000000000000000000000..e8ab6d2912af5f264dd673f8eae272a493709cb2 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_elasticsearch\345\210\206\345\270\203\345\274\217\346\236\266\346\236\204\345\216\237\347\220\206.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_es\350\257\273\345\206\231\345\272\225\345\261\202\345\216\237\347\220\206\345\211\226\346\236\220.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_es\350\257\273\345\206\231\345\272\225\345\261\202\345\216\237\347\220\206\345\211\226\346\236\220.png" new file mode 100644 index 0000000000000000000000000000000000000000..73be6427ce3fe1b02ccd78896593730206791cdc Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_es\350\257\273\345\206\231\345\272\225\345\261\202\345\216\237\347\220\206\345\211\226\346\236\220.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_filesystem cache\345\257\271es\346\200\247\350\203\275\347\232\204\345\275\261\345\223\215.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_filesystem cache\345\257\271es\346\200\247\350\203\275\347\232\204\345\275\261\345\223\215.png" new file mode 100644 index 0000000000000000000000000000000000000000..98293fa080d4c208b89dd0f80035556e383c3fe8 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_filesystem cache\345\257\271es\346\200\247\350\203\275\347\232\204\345\275\261\345\223\215.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420174829608.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420174829608.png" new file mode 100644 index 0000000000000000000000000000000000000000..1beaa87042014ece430467deb19af3751762b3c8 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420174829608.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420175115061.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420175115061.png" new file mode 100644 index 0000000000000000000000000000000000000000..cf583476ec18e5664a450e61f99f20b6d35453ce Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420175115061.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420175534595.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420175534595.png" new file mode 100644 index 0000000000000000000000000000000000000000..e9592ceb898df01cdf719e532d70decdb7fcfe72 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200420175534595.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105344435.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105344435.png" new file mode 100644 index 0000000000000000000000000000000000000000..0abd8b8c5986c29a7d623912290bc2fa8e8aa016 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105344435.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105421277.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105421277.png" new file mode 100644 index 0000000000000000000000000000000000000000..0373dc9340a0b9d7aba457fc9cfde4fe261d2764 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105421277.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105436614.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105436614.png" new file mode 100644 index 0000000000000000000000000000000000000000..74267b4fa3a9b72361ed439f39501b1a97cf3221 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105436614.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105709557.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105709557.png" new file mode 100644 index 0000000000000000000000000000000000000000..a0db481855b710923fbf4ad3c5f4760432153efe Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105709557.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105955680.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105955680.png" new file mode 100644 index 0000000000000000000000000000000000000000..1c43a9e2e3c7808686fcfeebf7d204455027e3d8 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/2_\345\210\206\345\270\203\345\274\217\346\220\234\347\264\242\345\274\225\346\223\216\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200630105955680.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/3_\345\210\206\345\270\203\345\274\217\347\274\223\345\255\230/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/3_\345\210\206\345\270\203\345\274\217\347\274\223\345\255\230/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..7d423b49535de63db52b261db14b96fb7b22f71d --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/3_\345\210\206\345\270\203\345\274\217\347\274\223\345\255\230/README.md" @@ -0,0 +1,43 @@ +# 分布式缓存 + +在项目中缓存是如何使用的?缓存如果使用不当会造成什么后果? + +## 为啥在项目里要用缓存? + +用缓存,主要是两个用途:高性能 和 高并发 + +### 高性能 + +假设有这么个场景,有一个操作,一个请求过来,然后执行N条SQL语句,然后半天才查询出一个结果,耗时600ms,但是这个结果可能接下来几个小时就不会变了,或者变了也可以不用立即反馈给用户,这个时候就可以使用缓存了。 + +我们可以把花费了600ms查询出来的数据,丢进缓存中,一个key对应一个value,下次再有人来查询的时候,就不走mysql了,而是直接从缓存中读取,通过key直接查询出value,耗时2ms,性能提升300倍。这就是所谓的高性能。 + +就是把一些复杂操作耗时查询出来的结果,如果确定后面不怎么变化了,但是马上还有很多读请求,这个时候,就可以直接把结果存放在缓存中,后面直接读取缓存即可。 + +![image-20200421122211630](images/image-20200421122211630.png) + +就第一次从数据库中获取,后面直接从缓存中获取即可,性能提升很高 + +### 高并发 + +MySQL这么重的数据库,并不适合于高并发,虽然可以使用,但是天然支持的就不好,因为MySQL的单机撑到2000QPS的时候,就容易报警了 + +![image-20200421124116765](images/image-20200421124116765.png) + +#### 为什么缓存可以支持高并发 + +首先因为缓存是走内存的,内存天然就可以支持高并发,但是数据库因为是存储在硬盘上的,因此不要超过2000QPS + +#### 场景 + +所以要是有一个系统,高峰期过来每秒的请求有1W个,要是MySQL单机的话,一定会宕机的,这个时候就只能用上缓存,把很多数据放到缓存中,这样请求过来了之后,就直接从缓存中获取数据,而不查询数据库。缓存的功能很简单,说白了就是一个 key - value式数据库,单机支撑的并发量轻松超过一秒几万 到 十多万,单机的承载量是mysql单机的几十倍。 + +#### 缓存带来的不良后果 + +场景的缓存问题有三个 + +- 缓存与数据库双写不一致的问题 +- 缓存穿透 +- 缓存雪崩 +- 缓存并发竞争 + diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/3_\345\210\206\345\270\203\345\274\217\347\274\223\345\255\230/images/image-20200421122211630.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/3_\345\210\206\345\270\203\345\274\217\347\274\223\345\255\230/images/image-20200421122211630.png" new file mode 100644 index 0000000000000000000000000000000000000000..418fae90b9a6dccb489467d1de993bd2121da298 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/3_\345\210\206\345\270\203\345\274\217\347\274\223\345\255\230/images/image-20200421122211630.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/3_\345\210\206\345\270\203\345\274\217\347\274\223\345\255\230/images/image-20200421124116765.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/3_\345\210\206\345\270\203\345\274\217\347\274\223\345\255\230/images/image-20200421124116765.png" new file mode 100644 index 0000000000000000000000000000000000000000..63bfe0194d3f36a1fcc6d4827f6e1eca5c253ad4 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/3_\345\210\206\345\270\203\345\274\217\347\274\223\345\255\230/images/image-20200421124116765.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..bd32ec6228622d9a3cfbd075471d02af33de8b6c --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" @@ -0,0 +1,746 @@ + + +# Redis的面试连环炮 + +## 面试题 + +- [Redis和Memcache有什么区别](##Redis和Memcache有什么区别) +- [Redis的线程模型是什么?](##Redis的线程模型是什么?) +- Redis的数据类型及应用场景? +- 为什么单线程的Redis比多线程的Memcache的效率要高? +- 为什么Redis是单线程但是还可以支撑高并发? +- Redis如何通过读写分离来承受百万的QPS +- Redis的持久化策略有哪些?AOF和RDB各有什么优缺点 +- Redis的过期策略以及LRU算法 +- 如何保证Redis的高并发和高可用? +- redis的主从复制原理能介绍一下么? +- redis的哨兵原理能介绍一下么? +- Redis主备切换的数据丢失问题:异步复制、集群脑裂 +- Redis哨兵的底层原理 + +## 剖析 + +Redis最基本的一个内部原理和特点就是NIO异步的单线程工作模型。Memcache是早些年个大互联网公司常用的缓存方案,但是现在近几年都是使用的redis,没有什么公司使用Memcache了。 + +注意:Redis中单个Value的大小最大为512MB,redis的key和string类型value限制均为512MB + +## Redis和Memcache的区别 + +从Redis作者给出的几个比较 + +- Redis拥有更多的数据结构 + - Redis相比Memcache来说,拥有更多的数据结构和支持更丰富的数据操作,通常在Memcache里,你需要将数据拿到客户端来进行类似的修改,在set进去。这就大大增加了网络IO的次数和体积,在Redis中,这些复杂的操作通常和一般的set/get一样高效。所以,如果需要缓存能够支持更复杂的结构和操作,那么Redis是不错的选择 +- Redis内存利用率对比 + - 使用简单的key-value存储的话,Memcache的内存利用率更高,而Redis采用Hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcache +- 性能对比 + - 由于Redis只使用了单核,而Memcache可以使用多核,所以平均每核上Redis在存储小数据比Memcache性能更高,而在100K以上的数据中,Memcache性能更高,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcache还有略有逊色。 +- 集群模式 + - Memcache没有原生的集群模式,需要依赖客户端来实现往集群中分片写入数据,但是Redis目前是原生支持cluster模式的。 + + + +## Redis都有哪些数据类型,及使用场景 + +- String + + - 最基本的类型,就和普通的set 和 get,做简单的key - value 存储 + +- Hash + + - 这个是 类似于Map的一种结构,就是一半可以将结构化数据,比如对象(前提是这个对象没有嵌套其它对象)给缓存在redis中,每次读写redis缓存的时候,可以操作hash里面的某个字段 + + ``` + key=150 + value={ + "id": 150, + "name": "张三", + "age": 20, + } + ``` + + - Hash类的数据结构,主要用来存放一些对象,把一些简单的对象给缓存起来,后续操作的时候,你可以直接仅仅修改这个对象中某个字段的值。 + +- List + + - 有序列表,可以通过list存储一些列表型的数据结构,类似粉丝列表,文章的评论列表之类的东西。 + - 可以通过lrange命令,从某个元素开始读取多少个元素,可以基于list实现分页查询,基于Redis实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西,性能高,就是一页一页走。 + - 可以制作一个简单的消息队列,从list头插入,从list 的尾巴取出 + +- Set + + - 无序列表,自动去重 + - 直接基于Set将系统中需要去重的数据丢进去,如果你需要对一些数据进行快速的全局去重,就可以使用基于JVM内存里的HashSet进行去重,但是如果你的某个系统部署在多台机器上的话,只有使用Redis进行全局的Set去重 + - 可以基于set玩儿交集、并集、差集的操作,比如交集吧,可以把两个人的粉丝列表整一个交集,看看俩人的共同好友是谁?把两个大v的粉丝都放在两个set中,对两个set做交集 + +- Sort Set + + - 排序的set,去重但是可以排序,写进去的时候给一个分数,自动根据分数排序,这个可以玩儿很多的花样,最大的特点是有个分数可以自定义排序规则 + + - 比如说你要是想根据时间对数据排序,那么可以写入进去的时候用某个时间作为分数,人家自动给你按照时间排序了 + + - 排行榜:将每个用户以及其对应的什么分数写入进去,zadd board score username,接着zrevrange board 0 99,就可以获取排名前100的用户;zrank board username,可以看到用户在排行榜里的排名 + +``` +zadd board 85 zhangsan +zadd board 72 wangwu +zadd board 96 lisi +zadd board 62 zhaoliu + +96 lisi +85 zhangsan +72 wangwu +62 zhaoliu + +zrevrange board 0 3 + +获取排名前3的用户 + +96 lisi +85 zhangsan +72 wangwu + +zrank board zhaoliu + +``` + + + +## Redis持久化对于生产环境的意义 + +故障发生时候会怎么样? + +如何应对故障的发生? + +### Redis持久化的意义 + +Redis持久化的意义,在于故障恢复,也属于高可用的一个环节。例如 + +当存放在内存中数据,会因为Redis的突然挂掉,而导致数据丢失 + +![image-20200422075753772](images/image-20200422075753772.png) + +Redis的持久化,就是将内存中的数据,持久化到磁盘上中,然后将磁盘上的数据放到阿里云ODPS中 + +![image-20200422080013776](images/image-20200422080013776.png) + +通过持久化将数据存储在磁盘中,然后定期比如说同步和备份到一些云存储服务上去。 + +### Redis中的RDB和AOF两种持久化机制 + +当出现Redis宕机时,我们需要做的是重启redis,尽快让他对外提供服务,缓存全部无法命中,在redis里根本找不到数据,这时候就会出现缓存雪崩的问题。所有的请求,没有在Redis中命中,就会去MySQL数据库这种数据源头中找,一下子MySQL无法承受高并发,那么系统将直接宕机。这个时候MySQL宕机,因为没办法从MySQL中将缓存恢复到Redis中,因为Redis中的数据是从MySQL中来的。 + +### RDB持久化机制 + +简单来说RDB:就是将Redis中的数据,每个一段时间,进行数据持久化 + +![image-20200422083709495](images/image-20200422083709495.png) + +### AOF持久化机制 + +Redis将内存中的数据,存放到一个AOF文件中,但是因为Redis只会写一个AOF文件,因此这个AOF文件会越来越大。 + +AOF机制对每条写入命令作为日志,以append-only的模式写入一个日志文件中,在Redis重启的时候,可以通过回放AOF日志中的写入指令来重新构建整个数据集。 + +![image-20200422083910566](images/image-20200422083910566.png) + +因为Redis中的数据是有一定限量的,不可能说Redis内存中的数据不限量增长,进而导致AOF无限量增长。 + +内存大小是一定的,到一定时候,Redis就会用缓存淘汰算法,LRU,自动将一部分数据从内存中给清除。 + +AOF,是存放每条写命令的,所以会不断的膨胀,当大到一定的时候,AOF做rewrite操作。 + +AOF rewrite操作,就会基于当时redis内存中的数据,来重新构造一个更小的AOF文件,然后将旧的膨胀的很大的文件给删了。 + +![image-20200422085957064](images/image-20200422085957064.png) + +如果我们想要Redis仅仅作为纯内存的缓存来使用,那么可以禁止RDB和AOF所有的持久化机制 + +通过AOF和RDB,都可以将Redis内存中的数据给持久化到磁盘上面来,然后可以将这些数据备份到其它地方去,例如阿里云的OOS。 + +如果Redis挂了,服务器上的内存和磁盘上的数据都丢了,可以从云服务上拷贝回来之前的数据,放到指定的目录下,然后重新启动Redis,Redis就会自动根据持久化数据文件,去恢复内存中的数据,继续对外提供服务。 + +如果同时使用RDB和AOF两种持久化机制,那么在Redis重启的时候,会使用AOF来重新构建数据,因为AOF中的数据更加完整。 + +### RDB持久化机制的优点 + +- RDB会生成多个数据文件,每个数据文件都代表了某个时刻中Redis的数据,这种多个数据文件的方式,非常适合做冷备份,可以将这种完整的数据文件发送到一些远程的安全存储上去,例如阿里云ODPS分布式存储上,以预定好的备份策略来定期备份Redis中的数据 + - RDB也可以做冷备份,生成多个文件,每个文件代表了某个时刻的完整的数据快照 + - AOF也可以做冷备,只有一个文件,但是你可以每隔一段时间,去copy一份文件出来 + - RDB做冷备份的优势在于,可以由Redis去控制固定时长生成快照文件的事情,比较方便。AOF还需要自己写一些脚本去做这个事情,各种定时。 +- RDB对Redis对外提供的读写服务,影响非常小,可以让Redis保持高性能,因为Redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可。 + - RDB每次写都是些Redis内存的,只是在一定的时间内,才将数据写入磁盘 + - AOF每次都要写文件,虽然可以快速写入 OS Cache中,但是还是会有一定的时间开销,速度肯定比RDB略慢一点。 +- 相对于AOF持久化机制来说,直接基于RDB数据文件来重启和恢复Redis进程,更加快速。 + - RDB数据做冷备份,在最坏的情况下,提供数据恢复的时候,速度比AOF快。 + - AOF,存放的指令日志,做数据恢复的时候,其实是要回放和执行所有的指令日志,来恢复出来内存中的所有数据的,而RDB就是一份数据文件,恢复的时候,直接加载进内存即可。 + +综合上面可以知道:RDB特别适合做冷备份 + +### RDB持久化的缺点 + +- 如果想要在Redis故障时,尽可能的少丢失数据,那么RDB没有AOF好,一般来说,RDB数据快照文件,都是每隔5分钟,或者更长时间生成一次,这个时候就得接受一旦Redis经常宕机,那么丢失最近5分钟的数据。 + +![image-20200422093446392](images/image-20200422093446392.png) + +​ 这个文件也是RDB最大的缺点,就是不适合做第一优先级的恢复方案,如果你依赖RDB做第一优先级方案,会导致数据丢失的比较多。 + + + +- RDB每次在fork子进程来执行RDB快照数据生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,或者甚至数秒 + - 一般不要让RDB的间隔太长,否则每次生成的RDB文件太长,会对Redis本身的性能会有影响 + + + +### AOF持久化的优点 + +- AOF可以更好的保护数据不丢失,一般AOF会间隔一秒,通过一个后台线程执行一次fsync操作,最多丢失1秒 +- AOF日志文件以append-only模式写入,所有没有任何磁盘寻址开销,写入性能非常高,而且文件不容易破损,即使文件尾部破损,也很容易快速修复。 +- AOF日志文件及时过大的时候,出现后台的重写操作,也不会影响客户端的读写,因为rewrite log 的时候,会对其中的数据进行压缩,创建出一份需要恢复数据的最小日志出来,再创建新日志文件的时候,老的日志文件还是照常写入,当新的merge后的日志文件ready的时候,再交换新老日志文件即可。 +- AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复,比如某人不小心用了 flushall命令,清空了整个Redis数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令删除了,然后再将该AOF文件放回去,就可以通过恢复机制,自动回复所有的数据。 + +### AOF持久化机制的缺点 + +- 对于同一份数据来说,AOF日志通常比RDB数据快照文件更大 +- AOF开启后,支持写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,因此这也就造成了性能不是很高。 + - 如果你要保证一条数据都不丢,也可以的,AOF的fsync设置成每次写入一条数据,fsync一次,这样Redis的QPS会大降。 +- AOF这种较为复杂的基于命令日志/merge/回放的方式,比基于RDB每次持久化一份完整的数据快照的方式,更加脆弱一些,容易有BUG,不过AOF就是为了避免rewrite过程导致的BUG,因此每次rewrite并不是基于旧的指令来进行merge的,而是基于当时内存中数据进行指令的重新构建,这与健壮性会好一些。 +- 唯一的缺点:就是做数据恢复的时候,会比较慢,还有做冷备,定期的被封,不太方便,可能要自己手动写复杂的脚本去做。 + + + +### RDB和AOF的选择 + +- 不要仅仅使用RDB,因为那样会导致你丢失很多的数据 +- 也不要仅仅使用AOF,因为这样有两个问题 + - AOF做冷备,没有RDB冷备恢复快 + - RDB每次简单粗暴的生成数据快照,更加健壮,可以避免AOF这种复杂的被封和恢复机制的BUG +- 综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择,用RDB来做不同程度的冷备,在AOF文件都丢失或者损坏不可用的时候,可以使用RDB来进行快速的数据恢复。 + + + +## Redis的线程模型 + +### 文件事件处理器 + +Redis基于reactor模式开发了网络事件处理器,这个处理器叫做文件事件处理器,file event handler,这个文件事件处理器是单线程的,因此Redis才叫做单线程的模型,采用IO多路复用机制同时监听多个socket,根据socket上的事件来选择相应的事件处理器来处理这个事件。 + +文件事件处理器是单线程模式下运行的,但是通过IO多路复用机制监听了多个socket,可以实现高性能的网络通信模型,又可以跟内部的其它单线程的模块进行对接,保证了Redis内部的线程模型的简单性。 + +文件事件处理器的结构包含4个部分:多个socket,IO多路复用程序,文件事件分派器,事件处理器等。 + +多个socket可能并发的产生不同的操作,每个操作对应不同的文件事件,但是IO多路复用程序会监听多个socket,但是会把socket放入到一个队列中排队,每次从队列中取出一个socket给事件分派器,事件分派器把socket给对应的时间处理器。 + +![image-20200421185741787](images/image-20200421185741787.png) + +![image-20200421185725418](images/image-20200421185725418.png) + +每次我们一个socket请求过来 和 redis中的 server socket建立连接后,通过IO多路复用程序,就会往队列中插入一个socket,文件事件分派器就是将队列中的socket取出来,分派到对应的处理器,在处理器处理完成后,才会从队列中在取出一个。 + +这里也就是用一个线程,监听了客户端的所有请求,被称为Redis的单线程模型。 + + + +## 为什么Redis单线程模型效率这么高? + +- 纯内存操作 +- 核心是非阻塞的IO多路复用机制 +- 单线程反而避免了多线程频繁上下文切换的问题 + + + +## Redis的过期策略 + +### Redis中的数据为什么会丢失 + +之前有同学问过我,说我们生产环境的redis怎么经常会丢掉一些数据?写进去了,过一会儿可能就没了。我的天,同学,你问这个问题就说明redis你就没用对啊。redis是缓存,你给当存储了是吧? + +啥叫缓存?用内存当缓存。内存是无限的吗,内存是很宝贵而且是有限的,磁盘是廉价而且是大量的。可能一台机器就几十个G的内存,但是可以有几个T的硬盘空间。redis主要是基于内存来进行高性能、高并发的读写操作的。 + +那既然内存是有限的,比如redis就只能用10个G,你要是往里面写了20个G的数据,会咋办?当然会干掉10个G的数据,然后就保留10个G的数据了。那干掉哪些数据?保留哪些数据?当然是干掉不常用的数据,保留常用的数据了。所以说,这是缓存的一个最基本的概念,数据是会过期的,要么是你自己设置个过期时间,要么是redis自己给干掉。 + +``` +set key value 过期时间(1小时) +set进去的key,1小时之后就没了,就失效了 +``` + +### 数据明明都过期了,怎么还占用着内存啊? + +还有一种就是如果你设置好了一个过期时间,你知道redis是怎么给你弄成过期的吗?什么时候删除掉?如果你不知道,之前有个学员就问了,为啥好多数据明明应该过期了,结果发现redis内存占用还是很高?那是因为你不知道redis是怎么删除那些过期key的。 + +redis 内存一共是10g,你现在往里面写了5g的数据,结果这些数据明明你都设置了过期时间,要求这些数据1小时之后都会过期,结果1小时之后,你回来一看,redis机器,怎么内存占用还是50%呢?5g数据过期了,我从redis里查,是查不到了,结果过期的数据还占用着redis的内存。 + +### 定期删除和惰性删除 + +我们Redis设置了过期时间,其实内部是 定期删除 + 惰性删除两个再起作用的。 + +所谓定期删除,指的是redis默认是每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。假设redis里放了10万个key,都设置了过期时间,你每隔几百毫秒,就检查10万个key,那redis基本上就死了,cpu负载会很高的,消耗在你的检查过期key上了。注意,这里可不是每隔100ms就遍历所有的设置过期时间的key,那样就是一场性能上的灾难。实际上redis是每隔100ms随机抽取一些key来检查和删除的。 + +但是问题是,定期删除可能会导致很多过期key到了时间并没有被删除掉,那咋整呢?所以就是惰性删除了。这就是说,在你获取某个key的时候,redis会检查一下 ,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除,不会给你返回任何东西。 + +并不是key到时间就被删除掉,而是你查询这个key的时候,redis再懒惰的检查一下 + +通过上述两种手段结合起来,保证过期的key一定会被干掉。 + +很简单,就是说,你的过期key,靠定期删除没有被删除掉,还停留在内存里,占用着你的内存呢,除非你的系统去查一下那个key,才会被redis给删除掉。 + +但是实际上这还是有问题的,如果定期删除漏掉了很多过期key,然后你也没及时去查,也就没走惰性删除,此时会怎么样?如果大量过期key堆积在内存里,导致redis内存块耗尽了,咋整? + +答案是:走内存淘汰机制。 + +### Redis内存淘汰机制 + +如果redis的内存占用过多的时候,此时会进行内存淘汰,有如下一些策略: + +``` +redis 10个key,现在已经满了,redis需要删除掉5个key + +1个key,最近1分钟被查询了100次 + +1个key,最近10分钟被查询了50次 + +1个key,最近1个小时倍查询了1次 +``` + +1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用吧,实在是太恶心了 + +2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最常用的) + +3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key,这个一般没人用吧,为啥要随机,肯定是把最近最少使用的key给干掉啊 + +4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key(这个一般不太合适) + +5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key + +6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除 + +很简单,你写的数据太多,内存满了,或者触发了什么条件,redis lru,自动给你清理掉了一些最近很少使用的数据 + +## Redis中的LRU算法 + +Java版本的LRU + +``` +public class LRUCache extends LinkedHashMap { + +private final int CACHE_SIZE; + + // 这里就是传递进来最多能缓存多少数据 + public LRUCache(int cacheSize) { + super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true); // 这块就是设置一个hashmap的初始大小,同时最后一个true指的是让linkedhashmap按照访问顺序来进行排序,最近访问的放在头,最老访问的就在尾 + CACHE_SIZE = cacheSize; + } + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > CACHE_SIZE; // 这个意思就是说当map中的数据量大于指定的缓存个数的时候,就自动删除最老的数据 + } + +``` + + + +## 如何保证Redis的高并发及高可用? + +如何保证Redis的高并发和高可用? + +redis的主从复制原理能介绍一下么? + +redis的哨兵原理能介绍一下么? + +### 剖析 + +就是如果你用redis缓存技术的话,肯定要考虑如何用redis来加多台机器,保证redis是高并发的,还有就是如何让Redis保证自己不是挂掉以后就直接死掉了,redis高可用 + +我这里会选用我之前讲解过这一块内容,redis高并发、高可用、缓存一致性 + +redis高并发:主从架构,一主多从,一般来说,很多项目其实就足够了,单主用来写入数据,单机几万QPS,多从用来查询数据,多个从实例可以提供每秒10万的QPS。 + +redis高并发的同时,还需要容纳大量的数据:一主多从,每个实例都容纳了完整的数据,比如redis主就10G的内存量,其实你就最对只能容纳10g的数据量。如果你的缓存要容纳的数据量很大,达到了几十g,甚至几百g,或者是几t,那你就需要redis集群,而且用redis集群之后,可以提供可能每秒几十万的读写并发。 + +redis高可用:如果你做主从架构部署,其实就是加上哨兵就可以了,就可以实现,任何一个实例宕机,自动会进行主备切换。 + +## Redis如何通过读写分离来承受百万的QPS + +### redis高并发跟整个系统的高并发之间的关系 + +redis,你要搞高并发的话,不可避免,要把底层的缓存搞得很好 + +mysql,高并发,做到了,那么也是通过一系列复杂的分库分表,订单系统,事务要求的,QPS到几万,比较高了 + +要做一些电商的商品详情页,真正的超高并发,QPS上十万,甚至是百万,一秒钟百万的请求量 + +光是redis是不够的,但是redis是整个大型的缓存架构中,支撑高并发的架构里面,非常重要的一个环节 + +首先,你的底层的缓存中间件,缓存系统,必须能够支撑的起我们说的那种高并发,其次,再经过良好的整体的缓存架构的设计(多级缓存架构、热点缓存),支撑真正的上十万,甚至上百万的高并发 + +### redis不能支撑高并发的瓶颈在哪里? + +因为单机的Redis,QPS只能在上万左右,成为了支撑高并发的瓶颈。 + +### ![redis单机的瓶颈](images/redis单机的瓶颈.png)如果redis要支撑超过10万+的并发,那应该怎么做? + +单机的redis几乎不太可能说QPS超过10万+,除非一些特殊情况,比如你的机器性能特别好,配置特别高,物理机,维护做的特别好,而且你的整体的操作不是太复杂,单机在几万。 + +读写分离,一般来说,对缓存,一般都是用来支撑读高并发的,写的请求是比较少的,可能写请求也就一秒钟几千,一两千。大量的请求都是读,一秒钟二十万次读 + +读写分离:主从架构 -> 读写分离 -> 支撑10万+读QPS的架构 + +![redis主从实现读写分离支撑10万+的高并发](images/redis主从实现读写分离支撑10万+的高并发.png) + +架构做成主从架构,一主多从,主服务器负责写,并且将数据同步到其它的slave节点,从节点负责读,所有的读请求全部走节点。 + +同时这样的架构,支持碎片扩容,就是说如果QPS在增加,也很简单,只需要增加 Redis Slave节点即可。 + +### Redis主从架构 + +redis主从架构 -> 读写分离架构 -> 可支持水平扩展的读高并发架构 + +#### 基本原理 + +- redis采用异步方式复制数据到slave节点,不过redis 2.8开始,slave node会周期性地确认自己每次复制的数据量 +- 一个master node是可以配置多个slave node的 +- slave node也可以连接其他的slave node +- slave node做复制的时候,是不会block master node的正常工作的 +- slave node在做复制的时候,也不会block对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了 +- slave node主要用来进行横向扩容,做读写分离,扩容的slave node可以提高读的吞吐量 + +![image-20200422073720488](images/image-20200422073720488.png) + +写操作存放在master node,同时在异步把master上的信息,同步到每个slave node上。 + +#### master持久化对于主从架构的安全保障的意义 + +如果采用了主从架构,那么建议必须开启master node的持久化!不建议用slave node作为master node的数据热备,因为那样的话,如果你关掉master的持久化,可能在master宕机重启的时候数据是空的,然后可能一经过复制,salve node数据也丢了 + +master -> RDB和AOF都关闭了 -> 全部在内存中 + +master宕机,重启,是没有本地数据可以恢复的,然后就会直接认为自己IDE数据是空的 + +master就会将空的数据集同步到slave上去,所有slave的数据全部清空 + +100%的数据丢失 + +master节点,必须要使用持久化机制 + +第二个,master的各种备份方案,要不要做,万一说本地的所有文件丢失了; 从备份中挑选一份rdb去恢复master; 这样才能确保master启动的时候,是有数据的 + +即使采用了后续讲解的高可用机制,slave node可以自动接管master node,但是也可能sentinal还没有检测到master failure,master node就自动重启了,还是可能导致上面的所有slave node数据清空故障 + + + +#### Redis主从复制原理 + +当启动一个slave node的时候,它会发送一个PSYNC命令给master node,如果这是slave node重新连接master node,那么master node仅仅会复制给slave部分缺少的数据; 否则如果是slave node第一次连接master node,那么会触发一次full resynchronization + +开始full resynchronization的时候,master会启动一个后台线程,开始生成一份RDB快照文件,同时还会将从客户端收到的所有写命令缓存在内存中。RDB文件生成完毕之后,master会将这个RDB发送给slave,slave会先写入本地磁盘,然后再从本地磁盘加载到内存中。然后master会将内存中缓存的写命令发送给slave,slave也会同步这些数据。 + +slave node如果跟master node有网络故障,断开了连接,会自动重连。master如果发现有多个slave node都来重新连接,仅仅会启动一个rdb save操作,用一份数据服务所有slave node。![redis主从复制的原理](images/redis主从复制的原理.png) + +### 主从复制的断点续传 + +从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份 + +master node会在内存中常见一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制,但是如果没有找到对应的offset,那么就会执行一次resynchronization + +### 无磁盘化复制 + +master在内存中直接创建rdb,然后发送给slave,不会在自己本地落地磁盘了 + +``` +repl-diskless-sync +# 等待一定时长再开始复制,因为要等更多slave重新连接过来 +repl-diskless-sync-delay +``` + + + +### Redis主从复制的完整复制流程 + +#### 主从复制流程图 + +- slave node启动,仅仅保存master node的信息,包括master node的host和ip,但是复制流程没开始master host和ip是从哪儿来的,redis.conf里面的slaveof配置的 +- slave node内部有个定时任务,每秒检查是否有新的master node要连接和复制,如果发现,就跟master node建立socket网络连接 +- slave node发送ping命令给master node +- 口令认证,如果master设置了requirepass,那么salve node必须发送masterauth的口令过去进行认证 +- master node第一次执行全量复制,将所有数据发给slave node +- master node后续持续将写命令,异步复制给slave node + +![复制的完整的基本流程](images/复制的完整的基本流程.png) + +#### 数据同步相关核心机制 + +指的就是第一次slave连接msater的时候,执行的全量复制,那个过程里面你的一些细节的机制 + +- master和slave都会维护一个offset + + +master会在自身不断累加offset,slave也会在自身不断累加offset +slave每秒都会上报自己的offset给master,同时master也会保存每个slave的offset + +这个倒不是说特定就用在全量复制的,主要是master和slave都要知道各自的数据的offset,才能知道互相之间的数据不一致的情况 + +- backlog + + +master node有一个backlog,默认是1MB大小 +master node给slave node复制数据时,也会将数据在backlog中同步写一份 +backlog主要是用来做全量复制中断候的增量复制的 + +- master run id + + +info server,可以看到master run id +如果根据host+ip定位master node,是不靠谱的,如果master node重启或者数据出现了变化,那么slave node应该根据不同的run id区分,run id不同就做全量复制 +如果需要不更改run id重启redis,可以使用redis-cli debug reload命令 + +- psync + + +从节点使用psync从master node进行复制,psync runid offset master node会根据自身的情况返回响应信息,可能是FULLRESYNC runid offset触发全量复制,可能是CONTINUE触发增量复制![maste run id的作用](images/maste run id的作用.png) + +#### 全量复制 + +- master执行bgsave,在本地生成一份rdb快照文件 +- master node将rdb快照文件发送给salve node,如果rdb复制时间超过60秒(repl-timeout),那么slave node就会认为复制失败,可以适当调节大这个参数 +- 对于千兆网卡的机器,一般每秒传输100MB,6G文件,很可能超过60s +- master node在生成rdb时,会将所有新的写命令缓存在内存中,在salve node保存了rdb之后,再将新的写命令复制给salve node +- client-output-buffer-limit slave 256MB 64MB 60,如果在复制期间,内存缓冲区持续消耗超过64MB,或者一次性超过256MB,那么停止复制,复制失败 +- slave node接收到rdb之后,清空自己的旧数据,然后重新加载rdb到自己的内存中,同时基于旧的数据版本对外提供服务 + +rdb生成、rdb通过网络拷贝、slave旧数据的清理、slave aof rewrite,很耗费时间 + +如果slave node开启了AOF,那么会立即执行BGREWRITEAOF,重写AOF + +#### 增量复制 + +- 如果全量复制过程中,master-slave网络连接断掉,那么salve重新连接master时,会触发增量复制 +- master直接从自己的backlog中获取部分丢失的数据,发送给slave node,默认backlog就是1MB +- msater就是根据slave发送的psync中的offset来从backlog中获取数据的 + +#### 异步复制 + +master每次接收到写命令之后,现在内部写入数据,然后异步发送给slave node + +#### 心跳机制 + +master默认每隔10秒发送一次心跳,salve node每隔1秒发送一个心跳 + + + +### Redis主从架构如何才能做到99.99%的高可用性? + +架构上,高可用性,99.99%的高可用性 + +99.99%,公式,系统可用的时间 / 系统故障的时间,365天,在365天 * 99.99%的时间内,你的系统都是可以哗哗对外提供服务的,那就是高可用性,99.99% + +系统可用的时间 / 总的时间 = 高可用性,然后会对各种时间的概念,说一大堆解释 + +#### 系统可用性 + +![什么是99.99%高可用性](images/什么是99.99%高可用性.png) + +#### 系统处于不可用 + +![系统处于不可用是什么意思](images/系统处于不可用是什么意思.png) + +#### Redis的不可用 + +一个slave宕机后,不会影响系统的可用性,还有其它slave在提供相同数据的情况下对外提供查询服务。 + +![redis的不可用](images/redis的不可用.png) + +master宕机后,相当于系统不可用了。 + +#### Redis高可用的方案 + +当Redis的master节点宕机后,redis的高可用架构中,有一个故障转移,叫failover,也可以做主备切换。 + +![redis基于哨兵的高可用性](images/redis基于哨兵的高可用性.png) + +#### 总结 + +Redis实现高并发:一主多从,一般来说,很多项目其实就足够了,单主用来写数据,单机几万QPS,多从用来查询数据,多个从实例可以提供每秒10万QPS + +Redis高并发的同时,还需要容纳大量的数据:一主多从,每个实例都容纳了完整的数据,比如Redis主就10G内存量,其实你就可以对只能容纳10G的数据量。如果你的缓存要容纳的数据量很大,达到了几十G,甚至几百G,那就需要使用到Redis集群,而且用Redis集群之后,提供可能每秒几十万的读写并发。 + +Redis高可用:如果用主从架构部署,在加上哨兵就可以实现任何一个实例宕机,就会自动进行主备切换。 + + + +## Redis哨兵架构 + +### 哨兵介绍 + +sentinal,中文名是哨兵 + +哨兵是redis集群架构中非常重要的一个组件,主要功能如下 + +- 集群监控,负责监控redis master和slave进程是否正常工作 +- 消息通知,如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员 +- 故障转移,如果master node挂掉了,会自动转移到slave node上 +- 配置中心,如果故障转移发生了,通知client客户端新的master地址 + +哨兵本身也是分布式的,作为一个哨兵集群去运行,互相协同工作 + +- 故障转移时,判断一个master node是宕机了,需要大部分的哨兵都同意才行,涉及到了分布式选举的问题 +- 即使部分哨兵节点挂掉了,哨兵集群还是能正常工作的,因为如果一个作为高可用机制重要组成部分的故障转移系统本身是单点的,那就很坑爹了 + +目前采用的是sentinal 2版本,sentinal 2相对于sentinal 1来说,重写了很多代码,主要是让故障转移的机制和算法变得更加健壮和简单 + +### 哨兵的核心知识 + +- 哨兵至少需要3个实例,来保证自己的健壮性 +- 哨兵 + redis主从的部署架构,是不会保证数据零丢失的,只能保证redis集群的高可用性 +- 对于哨兵 + redis主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练 + +### 为什么Redis的哨兵集群只有2个节点无法正常工作? + +哨兵集群必须部署2个以上节点 + +如果哨兵集群仅仅部署了个2个哨兵实例,s1 和 s2,quorum=1 + +``` ++----+ +----+ +| M1 |---------| R1 | +| S1 | | S2 | ++----+ +----+ +``` + +Configuration: quorum = 1 + +master宕机,s1和s2中只要有1个哨兵认为master宕机就可以还行切换,同时s1和s2中会选举出一个哨兵来执行故障转移同时这个时候,需要majority,也就是大多数哨兵都是运行的,2个哨兵的majority就是2(2的majority=2,3的majority=2,5的majority=3,4的majority=2),2个哨兵都运行着,就可以允许执行故障转移但是如果整个M1和S1运行的机器宕机了,那么哨兵只有1个了,此时就没有majority来允许执行故障转移,虽然另外一台机器还有一个R1,但是故障转移不会执行 + +### 经典的3节点哨兵集群 + +``` + + +----+ + | M1 | + | S1 | + +----+ + | ++----+ | +----+ +| R2 |----+----| R3 | +| S2 | | S3 | ++----+ +----+ +``` + +Configuration: quorum = 2,majority + +如果M1所在机器宕机了,那么三个哨兵还剩下2个,S2和S3可以一致认为master宕机,然后选举出一个来执行故障转移,同时3个哨兵的majority是2,所以还剩下的2个哨兵运行着,就可以允许执行故障转移 + + + +### Redis主备切换的数据丢失问题:异步复制、集群脑裂 + +主备切换的过程,可能会导致数据丢失 + +#### 异步复制导致的数据丢失 + +因为master -> slave的复制是异步的,所以可能有部分数据还没复制到slave,master就宕机了,此时这些部分数据就丢失了。 + +![异步复制导致的数据丢失问题](images/异步复制导致的数据丢失问题.png) + +#### 脑裂导致的数据丢失 + +脑裂,也就是说,某个master所在机器突然脱离了正常的网络,跟其他slave机器不能连接,但是实际上master还运行着,此时哨兵可能就会认为master宕机了,然后开启选举,将其他slave切换成了master + +这个时候,集群里就会有两个master,也就是所谓的脑裂。此时虽然某个slave被切换成了master,但是可能client还没来得及切换到新的master,还继续写向旧master的数据可能也丢失了 + +因此旧master再次恢复的时候,会被作为一个slave挂到新的master上去,自己的数据会清空,重新从新的master复制数据 + +![集群脑裂导致的数据丢失问题](images/集群脑裂导致的数据丢失问题.png) + +同时原来的master节点上的,client像 旧的 master中写入数据,当网络分区恢复正常后,client写的数据就会因为复制,导致数据的丢失。 + +#### 解决异步复制和脑裂导致数据丢失 + +``` +min-slaves-to-write 1 +min-slaves-max-lag 10 +``` + +要求至少有1个slave,数据复制和同步的延迟不能超过10秒 + +如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒钟,那么这个时候,master就不会再接收任何请求了,上面两个配置可以减少异步复制和脑裂导致的数据丢失 + +- 减少异步复制的数据丢失 + + +有了min-slaves-max-lag这个配置,就可以确保说,一旦slave复制数据和ack延时太长,就认为可能master宕机后损失的数据太多了,那么就拒绝写请求,这样可以把master宕机时由于部分数据未同步到slave导致的数据丢失降低的可控范围内 + +![异步复制导致数据丢失如何降低损失](images/异步复制导致数据丢失如何降低损失.png) + +- 减少脑裂的数据丢失 + + +如果一个master出现了脑裂,跟其他slave丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的slave发送数据,而且slave超过10秒没有给自己ack消息,那么就直接拒绝客户端的写请求,这样脑裂后的旧master就不会接受client的新数据,也就避免了数据丢失,上面的配置就确保了,如果跟任何一个slave丢了连接,在10秒后发现没有slave给自己ack,那么就拒绝新的写请求,因此在脑裂场景下,最多就丢失10秒的数据![脑裂导致数据丢失的问题如何降低损失](images/脑裂导致数据丢失的问题如何降低损失.png) + +### Redis哨兵的底层原理 + +#### sdown和odown转换机制 + +sdown和odown两种失败状态 + +sdown是主观宕机,就一个哨兵如果自己觉得一个master宕机了,那么就是主观宕机 + +odown是客观宕机,如果quorum数量的哨兵都觉得一个master宕机了,那么就是客观宕机 + +sdown达成的条件很简单,如果一个哨兵ping一个master,超过了is-master-down-after-milliseconds指定的毫秒数之后,就主观认为master宕机 + +sdown到odown转换的条件很简单,如果一个哨兵在指定时间内,收到了quorum指定数量的其他哨兵也认为那个master是sdown了,那么就认为是odown了,客观认为master宕机 + +#### 哨兵集群的自动发现机制 + +哨兵互相之间的发现,是通过redis的pub/sub系统实现的,每个哨兵都会往__sentinel__:hello这个channel里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在 + +每隔两秒钟,每个哨兵都会往自己监控的某个master+slaves对应的__sentinel__:hello channel里发送一个消息,内容是自己的host、ip和runid还有对这个master的监控配置 + +每个哨兵也会去监听自己监控的每个master+slaves对应的__sentinel__:hello channel,然后去感知到同样在监听这个master+slaves的其他哨兵的存在 + +每个哨兵还会跟其他哨兵交换对master的监控配置,互相进行监控配置的同步 + +#### slave配置的自动纠正 + +哨兵会负责自动纠正slave的一些配置,比如slave如果要成为潜在的master候选人,哨兵会确保slave在复制现有master的数据; 如果slave连接到了一个错误的master上,比如故障转移之后,那么哨兵会确保它们连接到正确的master上 + +#### slave->master选举算法 + +如果一个master被认为odown了,而且majority哨兵都允许了主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个slave来,会考虑slave的一些信息 + +- 跟master断开连接的时长 +- slave优先级 +- 复制offset +- run id + +如果一个slave跟master断开连接已经超过了down-after-milliseconds的10倍,外加master宕机的时长,那么slave就被认为不适合选举为master + +``` +(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state +``` + +接下来会对slave进行排序 + +- 按照slave优先级进行排序,slave priority越低,优先级就越高 +- 如果slave priority相同,那么看replica offset,哪个slave复制了越多的数据,offset越靠后,优先级就越高 +- 如果上面两个条件都相同,那么选择一个run id比较小的那个slave + +#### quorum和majority + +每次一个哨兵要做主备切换,首先需要quorum数量的哨兵认为odown,然后选举出一个哨兵来做切换,这个哨兵还得得到majority哨兵的授权,才能正式执行切换 + +如果quorum < majority,比如5个哨兵,majority就是3,quorum设置为2,那么就3个哨兵授权就可以执行切换 + +但是如果quorum >= majority,那么必须quorum数量的哨兵都授权,比如5个哨兵,quorum是5,那么必须5个哨兵都同意授权,才能执行切换 + +#### configuration epoch + +哨兵会对一套redis master+slave进行监控,有相应的监控的配置 + +执行切换的那个哨兵,会从要切换到的新master(salve->master)那里得到一个configuration epoch,这就是一个version号,每次切换的version号都必须是唯一的 + +如果第一个选举出的哨兵切换失败了,那么其他哨兵,会等待failover-timeout时间,然后接替继续执行切换,此时会重新获取一个新的configuration epoch,作为新的version号 + +#### configuraiton传播 + +哨兵完成切换之后,会在自己本地更新生成最新的master配置,然后同步给其他的哨兵,就是通过之前说的pub/sub消息机制,这里之前的version号就很重要了,因为各种消息都是通过一个channel去发布和监听的,所以一个哨兵完成一次新的切换之后,新的master配置是跟着新的version号的,其他的哨兵都是根据版本号的大小来更新自己的master配置的 diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200421185725418.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200421185725418.png" new file mode 100644 index 0000000000000000000000000000000000000000..441da5ba25bda86e3a117b91d7c8cf205b89651e Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200421185725418.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200421185741787.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200421185741787.png" new file mode 100644 index 0000000000000000000000000000000000000000..9f0c6cc9918f71b765947e2537fa7a8e363c26a8 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200421185741787.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422073720488.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422073720488.png" new file mode 100644 index 0000000000000000000000000000000000000000..39945b7d4748108349dd650b9b9a2f2e079ecb80 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422073720488.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422075753772.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422075753772.png" new file mode 100644 index 0000000000000000000000000000000000000000..71063e1c24dbf8a560cbd59d8ce8f7921fc97267 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422075753772.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422080013776.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422080013776.png" new file mode 100644 index 0000000000000000000000000000000000000000..f9bb3e52e12285699e422937331577da376fe7c5 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422080013776.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422083709495.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422083709495.png" new file mode 100644 index 0000000000000000000000000000000000000000..c678eb5d2eb7621aa2cc79f92c2d8e551cf08421 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422083709495.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422083910566.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422083910566.png" new file mode 100644 index 0000000000000000000000000000000000000000..a4715d1ca4396dabd4a2be5a3d721320de008533 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422083910566.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422085957064.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422085957064.png" new file mode 100644 index 0000000000000000000000000000000000000000..65bcfd49f6889585e575e010ddc2bde28ab40a6e Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422085957064.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422093446392.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422093446392.png" new file mode 100644 index 0000000000000000000000000000000000000000..164a50ae28533a97dbf590d59e76e25da17ef6dd Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/image-20200422093446392.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/maste run id\347\232\204\344\275\234\347\224\250.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/maste run id\347\232\204\344\275\234\347\224\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..e7984e9ea4c20e1fa1e222d8137f4a2eed4e43ea Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/maste run id\347\232\204\344\275\234\347\224\250.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\344\270\273\344\273\216\345\244\215\345\210\266\347\232\204\345\216\237\347\220\206.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\344\270\273\344\273\216\345\244\215\345\210\266\347\232\204\345\216\237\347\220\206.png" new file mode 100644 index 0000000000000000000000000000000000000000..68966f84272a42532d25f7dac4c2ff5a366244fc Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\344\270\273\344\273\216\345\244\215\345\210\266\347\232\204\345\216\237\347\220\206.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\344\270\273\344\273\216\345\256\236\347\216\260\350\257\273\345\206\231\345\210\206\347\246\273\346\224\257\346\222\22110\344\270\207+\347\232\204\351\253\230\345\271\266\345\217\221.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\344\270\273\344\273\216\345\256\236\347\216\260\350\257\273\345\206\231\345\210\206\347\246\273\346\224\257\346\222\22110\344\270\207+\347\232\204\351\253\230\345\271\266\345\217\221.png" new file mode 100644 index 0000000000000000000000000000000000000000..2eb432b1174b204957f1c2737fd5ff4266a8f631 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\344\270\273\344\273\216\345\256\236\347\216\260\350\257\273\345\206\231\345\210\206\347\246\273\346\224\257\346\222\22110\344\270\207+\347\232\204\351\253\230\345\271\266\345\217\221.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\345\215\225\346\234\272\347\232\204\347\223\266\351\242\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\345\215\225\346\234\272\347\232\204\347\223\266\351\242\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..b8243d2a6fbc5bae90f47552716024f3d4779bcd Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\345\215\225\346\234\272\347\232\204\347\223\266\351\242\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\345\237\272\344\272\216\345\223\250\345\205\265\347\232\204\351\253\230\345\217\257\347\224\250\346\200\247.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\345\237\272\344\272\216\345\223\250\345\205\265\347\232\204\351\253\230\345\217\257\347\224\250\346\200\247.png" new file mode 100644 index 0000000000000000000000000000000000000000..80f4ac4c7042baa883d15b7c24d9406f58cc9846 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\345\237\272\344\272\216\345\223\250\345\205\265\347\232\204\351\253\230\345\217\257\347\224\250\346\200\247.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\347\232\204\344\270\215\345\217\257\347\224\250.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\347\232\204\344\270\215\345\217\257\347\224\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..c149375178c3fb681e305cb4c491b424e64523af Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/redis\347\232\204\344\270\215\345\217\257\347\224\250.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\344\273\200\344\271\210\346\230\25799.99%\351\253\230\345\217\257\347\224\250\346\200\247.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\344\273\200\344\271\210\346\230\25799.99%\351\253\230\345\217\257\347\224\250\346\200\247.png" new file mode 100644 index 0000000000000000000000000000000000000000..4932e69ab9580ea9dbe8073a991425135fda66c8 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\344\273\200\344\271\210\346\230\25799.99%\351\253\230\345\217\257\347\224\250\346\200\247.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\345\244\215\345\210\266\347\232\204\345\256\214\346\225\264\347\232\204\345\237\272\346\234\254\346\265\201\347\250\213.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\345\244\215\345\210\266\347\232\204\345\256\214\346\225\264\347\232\204\345\237\272\346\234\254\346\265\201\347\250\213.png" new file mode 100644 index 0000000000000000000000000000000000000000..b930702c13017881ec1f43fbc2e5c7fedd1ddec0 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\345\244\215\345\210\266\347\232\204\345\256\214\346\225\264\347\232\204\345\237\272\346\234\254\346\265\201\347\250\213.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\345\274\202\346\255\245\345\244\215\345\210\266\345\257\274\350\207\264\346\225\260\346\215\256\344\270\242\345\244\261\345\246\202\344\275\225\351\231\215\344\275\216\346\215\237\345\244\261.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\345\274\202\346\255\245\345\244\215\345\210\266\345\257\274\350\207\264\346\225\260\346\215\256\344\270\242\345\244\261\345\246\202\344\275\225\351\231\215\344\275\216\346\215\237\345\244\261.png" new file mode 100644 index 0000000000000000000000000000000000000000..8d33c5ef4bc8e2cfc46d2607b391e60e88191715 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\345\274\202\346\255\245\345\244\215\345\210\266\345\257\274\350\207\264\346\225\260\346\215\256\344\270\242\345\244\261\345\246\202\344\275\225\351\231\215\344\275\216\346\215\237\345\244\261.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\345\274\202\346\255\245\345\244\215\345\210\266\345\257\274\350\207\264\347\232\204\346\225\260\346\215\256\344\270\242\345\244\261\351\227\256\351\242\230.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\345\274\202\346\255\245\345\244\215\345\210\266\345\257\274\350\207\264\347\232\204\346\225\260\346\215\256\344\270\242\345\244\261\351\227\256\351\242\230.png" new file mode 100644 index 0000000000000000000000000000000000000000..80bd13ccd1da01f16866f19b15fbce21ea7d3087 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\345\274\202\346\255\245\345\244\215\345\210\266\345\257\274\350\207\264\347\232\204\346\225\260\346\215\256\344\270\242\345\244\261\351\227\256\351\242\230.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\347\263\273\347\273\237\345\244\204\344\272\216\344\270\215\345\217\257\347\224\250\346\230\257\344\273\200\344\271\210\346\204\217\346\200\235.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\347\263\273\347\273\237\345\244\204\344\272\216\344\270\215\345\217\257\347\224\250\346\230\257\344\273\200\344\271\210\346\204\217\346\200\235.png" new file mode 100644 index 0000000000000000000000000000000000000000..7d1b0625cea9e7f47197891822b388364c7d13b1 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\347\263\273\347\273\237\345\244\204\344\272\216\344\270\215\345\217\257\347\224\250\346\230\257\344\273\200\344\271\210\346\204\217\346\200\235.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\350\204\221\350\243\202\345\257\274\350\207\264\346\225\260\346\215\256\344\270\242\345\244\261\347\232\204\351\227\256\351\242\230\345\246\202\344\275\225\351\231\215\344\275\216\346\215\237\345\244\261.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\350\204\221\350\243\202\345\257\274\350\207\264\346\225\260\346\215\256\344\270\242\345\244\261\347\232\204\351\227\256\351\242\230\345\246\202\344\275\225\351\231\215\344\275\216\346\215\237\345\244\261.png" new file mode 100644 index 0000000000000000000000000000000000000000..5cf1e8ac76df1bcd3c64a2fec66d88d252792485 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\350\204\221\350\243\202\345\257\274\350\207\264\346\225\260\346\215\256\344\270\242\345\244\261\347\232\204\351\227\256\351\242\230\345\246\202\344\275\225\351\231\215\344\275\216\346\215\237\345\244\261.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\351\233\206\347\276\244\350\204\221\350\243\202\345\257\274\350\207\264\347\232\204\346\225\260\346\215\256\344\270\242\345\244\261\351\227\256\351\242\230.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\351\233\206\347\276\244\350\204\221\350\243\202\345\257\274\350\207\264\347\232\204\346\225\260\346\215\256\344\270\242\345\244\261\351\227\256\351\242\230.png" new file mode 100644 index 0000000000000000000000000000000000000000..9097ac6ef9e97703993c4776203d992df71234ec Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/4_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/\351\233\206\347\276\244\350\204\221\350\243\202\345\257\274\350\207\264\347\232\204\346\225\260\346\215\256\344\270\242\345\244\261\351\227\256\351\242\230.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..1777dea801542d8633ded7183a1bc88fa91c4219 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/README.md" @@ -0,0 +1,555 @@ + + +# Redis集群模式 + +## 面试题 + +- Redis集群模式的工作原理? +- 在集群模式下,redis的key是如何寻址的? +- 分布式寻址都有哪些算法? +- 了解一致性Hash算法么? +- 如何应对缓存雪崩以及缓存穿透问题? +- 如何保证缓存与数据库双写时的数据一致性? +- Redis的并发竞争问题是什么?怎么解决? +- 了解Redis事务的CAS方案? + +## 剖析 + +在以前,如果前几年的时候,一般来说,redis如果要搞几个节点,每个节点存储一部分的数据,得借助一些中间件来实现,比如说有codis,或者twemproxy,都有。有一些redis中间件,你读写redis中间件,redis中间件负责将你的数据分布式存储在多台机器上的redis实例中。 + +这两年,redis不断在发展,redis也不断的有新的版本,redis cluster,redis集群模式,你可以做到在多台机器上,部署多个redis实例,每个实例存储一部分的数据,同时每个redis实例可以挂redis从实例,自动确保说,如果redis主实例挂了,会自动切换到redis从实例顶上来。 + +现在redis的新版本,大家都是用redis cluster的,也就是redis原生支持的redis集群模式,那么面试官肯定会就redis cluster对你来个几连炮。要是你没用过redis cluster,正常,以前很多人用codis之类的客户端来支持集群,但是起码你得研究一下redis cluster吧。 + + + +## Redis集群模式的工作原理 + +### 单机瓶颈 + +Redis在单机架构下的瓶颈:master节点的数据和slave节点的数据量一样,也就是master容纳多少,slave也只能容纳多少,如果需要放1T数据,在缓存中,那么就遇到的性能瓶颈了。 + +![redis单master架构的容量的瓶颈问题](images/redis单master架构的容量的瓶颈问题.png) + +### 集群模式 + +支撑N个redis master node,每个master node都可以挂载多个slave node,读写分离的架构,对于每个master来说,写就写到master,然后读就从mater对应的slave去读,高可用,因为每个master都有salve节点,那么如果mater挂掉,redis cluster这套机制,就会自动将某个slave切换成master,redis cluster(多master + 读写分离 + 高可用),我们只要基于redis cluster去搭建redis集群即可,不需要手工去搭建replication复制+主从架构+读写分离+哨兵集群+高可用 + +![redis如何通过master横向扩容支撑1T+数据量](images/redis如何通过master横向扩容支撑1T+数据量.png) + +### Redis cluster 和 Replication + sentinel + +#### Redis Cluster + +是Redis的集群模式 + +- 自动将数据进行分片,每个master上放一部分数据 +- 提供内置的高可用支持,部分master不可用时,还是可以继续工作的 + +在redis cluster架构下,每个redis要放开两个端口号,比如一个是6379,另外一个就是加10000的端口号,比如16379端口号是用来进行节点间通信的,也就是cluster bus的东西,集群总线。cluster bus的通信,用来进行故障检测,配置更新,故障转移授权 + +#### Redis replication + sentinel:高可用模式 + +如果你的数据量很少,主要是承载高并发高性能的场景,比如你的缓存一般就几个G,单机足够了,replication,一个mater,多个slave,要几个slave跟你的要求的读吞吐量有关系,然后自己搭建一个sentinal集群,去保证redis主从架构的高可用性,就可以了 + +redis cluster,主要是针对海量数据+高并发+高可用的场景,海量数据,如果你的数据量很大,那么建议就用redis cluster + + + +## 分布式数据存储的核心算法,数据分布的算法 + +hash算法 -> 一致性hash算法(memcached) -> redis cluster,hash slot 算法 + +用不同的算法,就决定了在多个master节点的时候,数据如何分布到这些节点上去,解决这个问题 + +### Hash算法 + +最老土的hash算法和弊端(大量缓存重建),属于最简单的数据分布算法 + +但是如果某一台master宕机了,会导致 1/3的数据全部失效,从而大量的数据将会进入MySQL + +![最老土的hash算法以及弊端](images/最老土的hash算法以及弊端.png) + +### 一致性Hash算法 + +Memcache中使用的是一致性Hash算法 + +![一致性hash算法的讲解和优点](images/一致性hash算法的讲解和优点.png) + +### 缓存热点问题 + +因为上面的一致性Hash环,不能解决缓存热点问题,即集中在某个Hash区间内的值特别多,这样就会导致大量的请求同时涌入一个master节点,而其它的节点处于空闲状态,从而造成master热点问题。 + +这个时候就引入了虚拟环(虚拟节点)的概念,目的是为了让每个master都做了均匀分布,这样每个区间内的数据都能够 均衡的分布到不同的节点中,而不是按照顺时针去查找,从而造成涌入一个master上的问题。 + +![一致性hash算法的虚拟节点实现负载均衡](images/一致性hash算法的虚拟节点实现负载均衡.png) + +### Redis Cluster + +Redis Cluster有固定的16384个Hash slot,对每个key计算CRC16值,然后对16384取模,可以获取key对应的hash slot,redis cluster中每个master都会持有部分slot,比如有3个master,那么可能每个master持有5000多个hash slot,hash slot让node的增加和移除很简单,增加一个master,就将其他master的hash slot移动部分过去,减少一个master,就将它的hash slot移动到其他master上去,移动hash slot的成本是非常低的,客户端的api,可以对指定的数据,让他们走同一个hash slot,通过hash tag来实现 + +如果有一台master宕机了,其它节点上的缓存几乎不受影响,因为它取模运算是根据 Hash slot来的,也就是 16384,而不是根据Redis的机器数。 + +![redis cluster hash slot算法](images/redis cluster hash slot算法.png) + +### Redis Cluster节点通信 + +![集中式的集群元数据存储和维护](images/集中式的集群元数据存储和维护.png) + +#### 基础通信原理 + +(1)redis cluster节点间采取gossip协议进行通信 + +跟集中式不同,不是将集群元数据(节点信息,故障,等等)集中存储在某个节点上,而是互相之间不断通信,保持整个集群所有节点的数据是完整的 + +维护集群的元数据用得,集中式,一种叫做gossip + +集中式:好处在于,元数据的更新和读取,时效性非常好,一旦元数据出现了变更,立即就更新到集中式的存储中,其他节点读取的时候立即就可以感知到; 不好在于,所有的元数据的跟新压力全部集中在一个地方,可能会导致元数据的存储有压力 + +gossip:好处在于,元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续,打到所有节点上去更新,有一定的延时,降低了压力; 缺点,元数据更新有延时,可能导致集群的一些操作会有一些滞后 + +我们刚才做reshard,去做另外一个操作,会发现说,configuration error,达成一致 + +![gossip协议维护集群元数据](images/gossip协议维护集群元数据.png) + +(2)10000端口 + +每个节点都有一个专门用于节点间通信的端口,就是自己提供服务的端口号+10000,比如7001,那么用于节点间通信的就是17001端口 + +每隔节点每隔一段时间都会往另外几个节点发送ping消息,同时其他几点接收到ping之后返回pong + +(3)交换的信息 + +故障信息,节点的增加和移除,hash slot信息,等等 + +#### gossip协议 + +gossip协议包含多种消息,包括ping,pong,meet,fail,等等 + +meet: 某个节点发送meet给新加入的节点,让新节点加入集群中,然后新节点就会开始与其他节点进行通信 + +``` +redis-trib.rb add-node +``` + +其实内部就是发送了一个gossip meet消息,给新加入的节点,通知那个节点去加入我们的集群 + +ping: 每个节点都会频繁给其他节点发送ping,其中包含自己的状态还有自己维护的集群元数据,互相通过ping交换元数据,每个节点每秒都会频繁发送ping给其他的集群,频繁的互相之间交换数据,互相进行元数据的更新 + +pong: 返回ping和meet,包含自己的状态和其他信息,也可以用于信息广播和更新 + +fail: 某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点,指定的节点宕机了 + +#### ping消息深入 + +ping很频繁,而且要携带一些元数据,所以可能会加重网络负担,每个节点每秒会执行10次ping,每次会选择5个最久没有通信的其他节点,当然如果发现某个节点通信延时达到了cluster_node_timeout / 2,那么立即发送ping,避免数据交换延时过长,落后的时间太长了 + +比如说,两个节点之间都10分钟没有交换数据了,那么整个集群处于严重的元数据不一致的情况,就会有问题,所以cluster_node_timeout可以调节,如果调节比较大,那么会降低发送的频率,每次ping,一个是带上自己节点的信息,还有就是带上1/10其他节点的信息,发送出去,进行数据交换,至少包含3个其他节点的信息,最多包含总节点-2个其他节点的信息 + + + +#### 面向集群的Jedis内部实现原理 + +开发,jedis,redis的java client客户端,redis cluster,jedis cluster api + +jedis cluster api与redis cluster集群交互的一些基本原理 + +1、基于重定向的客户端 + +redis-cli -c,自动重定向 + +(1)请求重定向 + +客户端可能会挑选任意一个redis实例去发送命令,每个redis实例接收到命令,都会计算key对应的hash slot + +如果在本地就在本地处理,否则返回moved给客户端,让客户端进行重定向 + +cluster keyslot mykey,可以查看一个key对应的hash slot是什么 + +用redis-cli的时候,可以加入-c参数,支持自动的请求重定向,redis-cli接收到moved之后,会自动重定向到对应的节点执行命令 + +(2)计算hash slot + +计算hash slot的算法,就是根据key计算CRC16值,然后对16384取模,拿到对应的hash slot + +用hash tag可以手动指定key对应的slot,同一个hash tag下的key,都会在一个hash slot中,比如set mykey1:{100}和set mykey2:{100} + +(3)hash slot查找 + +节点间通过gossip协议进行数据交换,就知道每个hash slot在哪个节点上 + +2、smart jedis + +(1)什么是smart jedis + +基于重定向的客户端,很消耗网络IO,因为大部分情况下,可能都会出现一次请求重定向,才能找到正确的节点 + +所以大部分的客户端,比如java redis客户端,就是jedis,都是smart的 + +本地维护一份hashslot -> node的映射表,缓存,大部分情况下,直接走本地缓存就可以找到hashslot -> node,不需要通过节点进行moved重定向 + +(2)JedisCluster的工作原理 + +在JedisCluster初始化的时候,就会随机选择一个node,初始化hashslot -> node映射表,同时为每个节点创建一个JedisPool连接池 + +每次基于JedisCluster执行操作,首先JedisCluster都会在本地计算key的hashslot,然后在本地映射表找到对应的节点 + +如果那个node正好还是持有那个hashslot,那么就ok; 如果说进行了reshard这样的操作,可能hashslot已经不在那个node上了,就会返回moved + +如果JedisCluter API发现对应的节点返回moved,那么利用该节点的元数据,更新本地的hashslot -> node映射表缓存 + +重复上面几个步骤,直到找到对应的节点,如果重试超过5次,那么就报错,JedisClusterMaxRedirectionException + +jedis老版本,可能会出现在集群某个节点故障还没完成自动切换恢复时,频繁更新hash slot,频繁ping节点检查活跃,导致大量网络IO开销 + +jedis最新版本,对于这些过度的hash slot更新和ping,都进行了优化,避免了类似问题 + +(3)hashslot迁移和ask重定向 + +如果hash slot正在迁移,那么会返回ask重定向给jedis + +jedis接收到ask重定向之后,会重新定位到目标节点去执行,但是因为ask发生在hash slot迁移过程中,所以JedisCluster API收到ask是不会更新hashslot本地缓存 + +已经可以确定说,hashslot已经迁移完了,moved是会更新本地hashslot->node映射表缓存的 + + + +#### 高可用性与主备切换原理 + +redis cluster的高可用的原理,几乎跟哨兵是类似的 + +1、判断节点宕机 + +如果一个节点认为另外一个节点宕机,那么就是pfail,主观宕机,如果多个节点都认为另外一个节点宕机了,那么就是fail,客观宕机,跟哨兵的原理几乎一样,sdown,odown,在cluster-node-timeout内,某个节点一直没有返回pong,那么就被认为pfail,如果一个节点认为某个节点pfail了,那么会在gossip ping消息中,ping给其他节点,如果超过半数的节点都认为pfail了,那么就会变成fail + +2、从节点过滤 + +对宕机的master node,从其所有的slave node中,选择一个切换成master node,检查每个slave node与master node断开连接的时间,如果超过了cluster-node-timeout * cluster-slave-validity-factor,那么就没有资格切换成master,这个也是跟哨兵是一样的,从节点超时过滤的步骤 + +3、从节点选举 + +哨兵:对所有从节点进行排序,slave priority,offset,run id,每个从节点,都根据自己对master复制数据的offset,来设置一个选举时间,offset越大(复制数据越多)的从节点,选举时间越靠前,优先进行选举,所有的master node开始slave选举投票,给要进行选举的slave进行投票,如果大部分master node(N/2 + 1)都投票给了某个从节点,那么选举通过,那个从节点可以切换成master,从节点执行主备切换,从节点切换为主节点 + +4、与哨兵比较 + +整个流程跟哨兵相比,非常类似,所以说,redis cluster功能强大,直接集成了replication和sentinal的功能 + + + +## 缓存雪崩和缓存穿透? + +### 面试题 + +了解什么是redis的雪崩和穿透?redis崩溃之后会怎么样?系统该如何应对这种情况?如何处理redis的穿透? + +### 剖析 + +其实这是问到缓存必问的,因为缓存雪崩和穿透,那是缓存最大的两个问题,要么不出现,一旦出现就是致命性的问题。所以面试官一定会问你 + +### 缓存雪崩发生的现象 + +因为缓存宕机,大量的请求打入数据库,导致整个系统宕机 + +![01_缓存雪崩现象](images/01_缓存雪崩现象.png) + +### 如何解决缓存雪崩 + +缓存雪崩的事前事中事后的解决方案 + +事前:redis高可用,主从+哨兵,redis cluster,避免全盘崩溃 + +事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL被打死 + +事后:redis持久化,快速恢复缓存数据,一般重启,自动从磁盘上加载数据恢复内存中的数据。 + + ![02_如何解决缓存雪崩](images/02_如何解决缓存雪崩.png) + + + +### 缓存穿透的现象 + +缓存穿透也就是,由黑客发出的非法请求,请求大量的无效key,导致无法命中缓存,同时数据库也查询不到,最终导致缓存穿透把数据库打死了。 + +![03_缓存穿透现象以及解决方案](images/03_缓存穿透现象以及解决方案.png) + +### 如何解决缓存穿透 + +解决方案,每次系统从系统库只要没有查询到,就写一个空值到缓存中查找。 + + + +## 如何保证缓存与数据库的双写一致性? + +只要用到了缓存,就可能会涉及到缓存与数据库双存储双写,就一定会有数据一致性的问题,那么你如何解决一致性问题呢 + +### Cache Aside Pattern + +最经典的缓存+数据库读写的模式,cache aside pattern + +(1)读的时候,先读缓存,缓存没有的话,那么就读数据库,然后取出数据后放入缓存,同时返回响应 + +(2)更新的时候,先删除缓存,然后再更新数据库 + +![cache aside pattern](images/cache aside pattern.png) + +### 为什么是删除缓存,而不是更新缓存呢? + +原因很简单,很多时候,复杂点的缓存的场景,因为缓存有的时候,不简单是数据库中直接取出来的值 + +商品详情页的系统,修改库存,只是修改了某个表的某些字段,但是要真正把这个影响的最终的库存计算出来,可能还需要从其他表查询一些数据,然后进行一些复杂的运算,才能最终计算出 + +现在最新的库存是多少,然后才能将库存更新到缓存中去,比如可能更新了某个表的一个字段,然后其对应的缓存,是需要查询另外两个表的数据,并进行运算,才能计算出缓存最新的值的 + +更新缓存的代价是很高的,是不是说,每次修改数据库的时候,都一定要将其对应的缓存去更新一份?也许有的场景是这样的,但是对于比较复杂的缓存数据计算的场景,就不是这样了 + +如果你频繁修改一个缓存涉及的多个表,那么这个缓存会被频繁的更新,频繁的更新缓存,但是问题在于,这个缓存到底会不会被频繁访问到??? + +举个例子,一个缓存涉及的表的字段,在1分钟内就修改了20次,或者是100次,那么缓存更新20次,100次; 但是这个缓存在1分钟内就被读取了1次,有大量的冷数据 + +28法则,黄金法则,20%的数据,占用了80%的访问量 + +实际上,如果你只是删除缓存的话,那么1分钟内,这个缓存不过就重新计算一次而已,开销大幅度降低 + +每次数据过来,就只是删除缓存,然后修改数据库,如果这个缓存,在1分钟内只是被访问了1次,那么只有那1次,缓存是要被重新计算的,用缓存才去算缓存 + +其实删除缓存,而不是更新缓存,就是一个lazy计算的思想,不要每次都重新做复杂的计算,不管它会不会用到,而是让它到需要被使用的时候再重新计算 + +mybatis,hibernate,懒加载,思想 + +查询一个部门,部门带了一个员工的list,没有必要说每次查询部门,都里面的1000个员工的数据也同时查出来啊 + +80%的情况,查这个部门,就只是要访问这个部门的信息就可以了 + +先查部门,同时要访问里面的员工,那么这个时候只有在你要访问里面的员工的时候,才会去数据库里面查询1000个员工 + + + +### 数据库双写不一致问题分析与解决方案设计 + +从哪一步开始做,从比较简单的那一块开始做,实时性要求比较高的那块数据的缓存去做,实时性比较高的数据缓存,选择的就是库存的服务,库存可能会修改,每次修改都要去更新这个缓存数据; 每次库存的数据,在缓存中一旦过期,或者是被清理掉了,前端的nginx服务都会发送请求给库存服务,去获取相应的数据,库存这一块,写数据库的时候,直接更新redis缓存,实际上没有这么的简单,这里,其实就涉及到了一个问题,数据库与缓存双写,数据不一致的问题,围绕和结合实时性较高的库存服务,把数据库与缓存双写不一致问题以及其解决方案 + +### 最初级的缓存不一致问题 + +问题:先修改数据库,再删除缓存,如果删除缓存失败了,那么会导致数据库中是新数据,缓存中是旧数据,数据出现不一致,解决思路是:先删除缓存,再修改数据库,如果删除缓存成功了,如果修改数据库失败了,那么数据库中是旧数据,缓存中是空的,那么数据不会不一致,因为读的时候缓存没有,则读数据库中旧数据,然后更新到缓存中 + +![最初级的数据库+缓存双写不一致问题](images/最初级的数据库+缓存双写不一致问题.png) + +假设删除缓存成功,但是更新数据库失败了,那么不会出现双写不一致的问题 + +![最初级的数据库+缓存双写不一致问题的解决方案](images/最初级的数据库+缓存双写不一致问题的解决方案.png) + +### 复杂的数据不一致问题 + +数据发生了变更,先删除了缓存,然后要去修改数据库,此时还没修改 + +一个请求过来,去读缓存,发现缓存空了,去查询数据库,查到了修改前的旧数据,放到了缓存中 + +数据变更的程序完成了数据库的修改 + +完了,数据库和缓存中的数据不一样了。。。。 + +![读写并发的时候复杂的数据库+缓存双写不一致的场景](images/读写并发的时候复杂的数据库+缓存双写不一致的场景.png) + +### 上亿流量高并发场景下,缓存会出现这个问题? + +只有在对一个数据在并发的进行读写的时候,才可能会出现这种问题 + +其实如果说你的并发量很低的话,特别是读并发很低,每天访问量就1万次,那么很少的情况下,会出现刚才描述的那种最初不一致的场景。 + +但是问题是,如果每天的是上亿的流量,每秒并发读是几万,每秒只要有数据更新的请求,就可能会出现上述的数据库+缓存不一致的情况。 + +### 数据库与缓存更新与读取操作进行异步串行化 + +更新数据的时候,根据数据的唯一标识,将操作路由之后,发送到一个jvm内部的队列中,读取数据的时候,如果发现数据不在缓存中,那么将重新读取数据+更新缓存的操作,根据唯一标识路由之后,也发送同一个jvm内部的队列中,一个队列对应一个工作线程,每个工作线程串行拿到对应的操作,然后一条一条的执行 + +这样的话,一个数据变更的操作,先执行,删除缓存,然后再去更新数据库,但是还没完成更新 + +此时如果一个读请求过来,读到了空的缓存,那么可以先将缓存更新的请求发送到队列中,此时会在队列中积压,然后同步等待缓存更新完成 + +这里有一个优化点,一个队列中,其实多个更新缓存请求串在一起是没意义的,因此可以做过滤,如果发现队列中已经有一个更新缓存的请求了,那么就不用再放个更新请求操作进去了,直接等待前面的更新操作请求完成即可 + +待那个队列对应的工作线程完成了上一个操作的数据库的修改之后,才会去执行下一个操作,也就是缓存更新的操作,此时会从数据库中读取最新的值,然后写入缓存中 + +如果请求还在等待时间范围内,不断轮询发现可以取到值了,那么就直接返回; 如果请求等待的时间超过一定时长,那么这一次直接从数据库中读取当前的旧值![复杂的数据库+缓存双写一致保障方案](images/复杂的数据库+缓存双写一致保障方案.png) + +假设出现了数据库没有这条数据的场景时: + +这个时候需要判断一下,内存队列中有没有数据库更新操作,如果没有数据库更新操作,说明这条数据压根可能就是空的,那么不用hang住,直接就返回空。 + +### 更新与读取请求串行化缺点 + +一般来说,如果你的系统不是严格要求缓存 + 数据库必须一致性的话,缓存可以稍微的跟数据库偶尔有不一致的情况,最好不要使用这个方案,因为读请求 和 写请求 串行化,串到一个内存队列中去,这样就可以保证一定不会出现不一致的情况。 + +串行化之后,就会导致系统的吞吐量大幅度的降低,用比较正常情况下多几倍的机器去支撑线上的请求。 + +### 高并发的场景下,该解决方案要注意的问题 + +#### 读请求长时阻塞 + +由于读请求进行了非常轻度的异步化,所以一定要注意读超时的问题,每个读请求必须在超时时间范围内返回 + +该解决方案,最大的风险点在于说,可能数据更新很频繁,导致队列中积压了大量更新操作在里面,然后读请求会发生大量的超时,最后导致大量的请求直接走数据库 + +务必通过一些模拟真实的测试,看看更新数据的频繁是怎样的 + +另外一点,因为一个队列中,可能会积压针对多个数据项的更新操作,因此需要根据自己的业务情况进行测试,可能需要部署多个服务,每个服务分摊一些数据的更新操作 + +如果一个内存队列里居然会挤压100个商品的库存修改操作,每隔库存修改操作要耗费10ms区完成,那么最后一个商品的读请求,可能等待10 * 100 = 1000ms = 1s后,才能得到数据 + +这个时候就导致读请求的长时阻塞 + +一定要做根据实际业务系统的运行情况,去进行一些压力测试,和模拟线上环境,去看看最繁忙的时候,内存队列可能会挤压多少更新操作,可能会导致最后一个更新操作对应的读请求,会hang多少时间,如果读请求在200ms返回,如果你计算过后,哪怕是最繁忙的时候,积压10个更新操作,最多等待200ms,那还可以的 + +如果一个内存队列可能积压的更新操作特别多,那么你就要加机器,让每个机器上部署的服务实例处理更少的数据,那么每个内存队列中积压的更新操作就会越少 + +其实根据之前的项目经验,一般来说数据的写频率是很低的,因此实际上正常来说,在队列中积压的更新操作应该是很少的 + +针对读高并发,读缓存架构的项目,一般写请求相对读来说,是非常非常少的,每秒的QPS能到几百就不错了 + +一秒,500的写操作,5份,每200ms,就100个写操作 + +单机器,20个内存队列,每个内存队列,可能就积压5个写操作,每个写操作性能测试后,一般在20ms左右就完成 + +那么针对每个内存队列中的数据的读请求,也就最多hang一会儿,200ms以内肯定能返回了 + +写QPS扩大10倍,但是经过刚才的测算,就知道,单机支撑写QPS几百没问题,那么就扩容机器,扩容10倍的机器,10台机器,每个机器20个队列,200个队列 + +大部分的情况下,应该是这样的,大量的读请求过来,都是直接走缓存取到数据的 + +少量情况下,可能遇到读跟数据更新冲突的情况,如上所述,那么此时更新操作如果先入队列,之后可能会瞬间来了对这个数据大量的读请求,但是因为做了去重的优化,所以也就一个更新缓存的操作跟在它后面 + +等数据更新完了,读请求触发的缓存更新操作也完成,然后临时等待的读请求全部可以读到缓存中的数据 + +#### 读请求并发量过高 + +这里还必须做好压力测试,确保恰巧碰上上述情况的时候,还有一个风险,就是突然间大量读请求会在几十毫秒的延时hang在服务上,看服务能不能抗的住,需要多少机器才能抗住最大的极限情况的峰值 + +但是因为并不是所有的数据都在同一时间更新,缓存也不会同一时间失效,所以每次可能也就是少数数据的缓存失效了,然后那些数据对应的读请求过来,并发量应该也不会特别大 + +按1:99的比例计算读和写的请求,每秒5万的读QPS,可能只有500次更新操作 + +如果一秒有500的写QPS,那么要测算好,可能写操作影响的数据有500条,这500条数据在缓存中失效后,可能导致多少读请求,发送读请求到库存服务来,要求更新缓存 + +一般来说,1:1,1:2,1:3,每秒钟有1000个读请求,会hang在库存服务上,每个读请求最多hang多少时间,200ms就会返回 + +在同一时间最多hang住的可能也就是单机200个读请求,同时hang住 + +单机hang200个读请求,还是ok的 + +1:20,每秒更新500条数据,这500秒数据对应的读请求,会有20 * 500 = 1万 + +1万个读请求全部hang在库存服务上,就死定了 + +#### 多服务实例部署的请求路由 + +可能这个服务部署了多个实例,那么必须保证说,执行数据更新操作,以及执行缓存更新操作的请求,都通过nginx服务器路由到相同的服务实例上 + +![机器级别的请求路由问题](images/机器级别的请求路由问题.png) + +#### 热点商品的路由问题,导致请求的倾斜 + +万一某个商品的读写请求特别高,全部打到相同的机器的相同的队列里面去了,可能造成某台机器的压力过大 + +就是说,因为只有在商品数据更新的时候才会清空缓存,然后才会导致读写并发,所以更新频率不是太高的话,这个问题的影响并不是特别大,但是的确可能某些机器的负载会高一些 + + + +## Redis并发竞争的问题是什么? + +这个也是线上非常常见的一个问题,就是多客户端同时并发写一个key,可能本来应该先到的数据后到了,导致数据版本错了。或者是多客户端同时获取一个key,修改值之后再写回去,只要顺序错了,数据就错了 + +如下图所示:我们有好几个系统同时取访问缓存,并且发起了一个写缓存的操作 + +- set V1、V2、V3、V4 +- 我们期望的是它是有顺序的去执行,但是最后却没有顺序了 +- 变成了:set V1、V3、V4、V2 +- 一般解决这种问题,就是使用分布式锁 + +![01_redis并发竞争问题以及解决方案](images/01_redis并发竞争问题以及解决方案.png) + +### 基于Zookeeper的分布式锁 + +分布式锁:确保同一时间,只有一个系统实例在操作某个key,别人都不需要读和写 + +这里修改的时候,就需要引入时间戳,因为写入缓存的数据,都是从mysql中查询出来的,都得写入mysql中,写入mysql的时候,是必须保存一个时间戳,同时查询的时候,也需要把时间戳也查询出来 + +``` +v1 10.00.00 +v2 10.00.01 +v3 10.00.02 +v4 10.00.03 +``` + +每次要写入之前,首先判断一下当前这个value的时间戳是否比缓存的value的时间戳大,如果比缓存中的时间戳更大,那么就执行写入操作,如果更小,就不能用旧的数据覆盖新的数据。 + + + +## Redis的事务 + +可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序串行化的执行而不会被其他命令插入。Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。 + +其中,Redis事务分为三个阶段 + +- 开始事务 +- 命令入队 +- 执行事务 + +### 正常执行 + +![image-20200529212239626](images/image-20200529212239626.png) + +### 放弃事务 + +![image-20200529212259619](images/image-20200529212259619.png) + +### 事务执行出错 - 命令错误 + +若在事务队列中存在命令性错误(类似于java编译性错误),则执行EXEC命令时,所有命令都不会执行 + +![image-20200529212336388](images/image-20200529212336388.png) + +### 事务执行出错 - 抛异常 + +若在事务队列中存在语法性错误(类似于java的1/0的运行时异常),则执行EXEC命令时,其他正确命令会被执行,错误命令抛出异常 + +![image-20200529212442082](images/image-20200529212442082.png) + +### Watch使用 + +使用watch检测balance,事务期间balance数据未变动,事务执行成功 + +![image-20200529212649282](images/image-20200529212649282.png) + +使用watch检测balance,在开启事务后(标注1处),在新窗口执行标注2中的操作,更改balance的值,模拟其他客户端在事务执行期间更改watch监控的数据,然后再执行标注1后命令,执行EXEC后,事务未成功执行。 + +![image-20200529212702162](images/image-20200529212702162.png) + +一但执行 EXEC 开启事务的执行后,无论事务使用执行成功, WARCH 对变量的监控都将被取消。故当事务执行失败后,需重新执行WATCH命令对变量进行监控,并开启新的事务进行操作 + +watch指令类似于乐观锁,在事务提交时,如果watch监控的多个KEY中任何KEY的值已经被其他客户端更改,则使用EXEC执行事务时,事务队列将不会被执行,同时返回Nullmulti-bulk应答以通知调用者事务执行失败。 + + + +## 线上生产环境的Redis是怎么部署的? + +看看你了解不了解你们公司的redis生产集群的部署架构,你的redis是主从架构?集群架构?用了哪种集群方案?有没有做高可用保证?有没有开启持久化机制确保可以进行数据恢复?线上redis给几个G的内存?设置了哪些参数?压测后你们redis集群承载多少QPS? + +### 剖析 + +redis cluster,10台机器,5台机器部署了redis主实例,另外5台机器部署了redis的从实例,每个主实例挂了一个从实例,5个节点对外提供读写服务,每个节点的读写高峰qps可能可以达到每秒5万,5台机器最多是25万读写请求/s。 + +机器是什么配置?32G内存+8核CPU+1T磁盘,但是分配给redis进程的是10g内存,一般线上生产环境,redis的内存尽量不要超过10g,超过10g可能会有问题。 + +5台机器对外提供读写,一共有50g内存。因为每个主实例都挂了一个从实例,所以是高可用的,任何一个主实例宕机,都会自动故障迁移,redis从实例会自动变成主实例继续提供读写服务 + +你往内存里写的是什么数据?每条数据的大小是多少?商品数据,每条数据是10kb。100条数据是1mb,10万条数据是1g。常驻内存的是200万条商品数据,占用内存是20g,仅仅不到总内存的50%。 + +目前高峰期每秒就是3500左右的请求量,比如我们吧,大型的公司,其实基础架构的team,会负责缓存集群的运维 + +## 总结 + + 说实话,这一套东西基本构成了缓存这块你必须知道的基础性的知识,如果你不知道,那么说明你有点失职,确实平时没好好积累。 + +因为这些问题确实不难,如果我往深了问,可以问的很细,结合项目扣的很细,比如你们公司线上系统高峰QPS 3000?那请求主要访问哪些接口?redis抗了多少请求?mysql抗了多少请求?你到底是怎么实现高并发的?咱们聊聊redis的内核吧,看看你对底层了解的多么?如果要缓存几百GB的数据会有什么坑该这么弄?如果缓存出现热点现象该这么处理?某个value特别大把网卡给打死了怎么办?等等等等,可以深挖的东西其实有很多。。。。。 + +但是如果你掌握好了这套东西的回答,那么你在面试的时候,如果面试官没有全都问到,你可以自己主动合盘脱出。比如你可以说,我们线上的缓存,做了啥啥机制,防止雪崩、防止穿透、保证双写时的数据一致性、保证并发竞争时的数据一致性,我们线上咋部署的,啥架构,怎么玩儿的。这套东西你可以自己说出来,展示一下你对缓存这块的掌握。 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/01_redis\345\271\266\345\217\221\347\253\236\344\272\211\351\227\256\351\242\230\344\273\245\345\217\212\350\247\243\345\206\263\346\226\271\346\241\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/01_redis\345\271\266\345\217\221\347\253\236\344\272\211\351\227\256\351\242\230\344\273\245\345\217\212\350\247\243\345\206\263\346\226\271\346\241\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..f7a3c8912e162ae3ad36969c29793334083b0c12 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/01_redis\345\271\266\345\217\221\347\253\236\344\272\211\351\227\256\351\242\230\344\273\245\345\217\212\350\247\243\345\206\263\346\226\271\346\241\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/01_\347\274\223\345\255\230\351\233\252\345\264\251\347\216\260\350\261\241.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/01_\347\274\223\345\255\230\351\233\252\345\264\251\347\216\260\350\261\241.png" new file mode 100644 index 0000000000000000000000000000000000000000..8d9e86e5c0a42dfa0f1e7e411bf53413740fada5 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/01_\347\274\223\345\255\230\351\233\252\345\264\251\347\216\260\350\261\241.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/02_\345\246\202\344\275\225\350\247\243\345\206\263\347\274\223\345\255\230\351\233\252\345\264\251.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/02_\345\246\202\344\275\225\350\247\243\345\206\263\347\274\223\345\255\230\351\233\252\345\264\251.png" new file mode 100644 index 0000000000000000000000000000000000000000..f8157b125a6fa8f225cc66cb6a367825a3a1d309 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/02_\345\246\202\344\275\225\350\247\243\345\206\263\347\274\223\345\255\230\351\233\252\345\264\251.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/03_\347\274\223\345\255\230\347\251\277\351\200\217\347\216\260\350\261\241\344\273\245\345\217\212\350\247\243\345\206\263\346\226\271\346\241\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/03_\347\274\223\345\255\230\347\251\277\351\200\217\347\216\260\350\261\241\344\273\245\345\217\212\350\247\243\345\206\263\346\226\271\346\241\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..edb40e2441c779ec16d5df6748092732d5fd246d Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/03_\347\274\223\345\255\230\347\251\277\351\200\217\347\216\260\350\261\241\344\273\245\345\217\212\350\247\243\345\206\263\346\226\271\346\241\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/cache aside pattern.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/cache aside pattern.png" new file mode 100644 index 0000000000000000000000000000000000000000..6753c7d9f63827749e46aadf20fe29f05d9f38c8 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/cache aside pattern.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/gossip\345\215\217\350\256\256\347\273\264\346\212\244\351\233\206\347\276\244\345\205\203\346\225\260\346\215\256.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/gossip\345\215\217\350\256\256\347\273\264\346\212\244\351\233\206\347\276\244\345\205\203\346\225\260\346\215\256.png" new file mode 100644 index 0000000000000000000000000000000000000000..27cb5175cd25a0e8ad40246687f620aa0af08776 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/gossip\345\215\217\350\256\256\347\273\264\346\212\244\351\233\206\347\276\244\345\205\203\346\225\260\346\215\256.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212239626.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212239626.png" new file mode 100644 index 0000000000000000000000000000000000000000..eea50b6b3683b8a893d76e9a51d3b7597882af73 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212239626.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212259619.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212259619.png" new file mode 100644 index 0000000000000000000000000000000000000000..acbda4831ad4f0edddcebff3294b269c1de4af49 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212259619.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212336388.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212336388.png" new file mode 100644 index 0000000000000000000000000000000000000000..46904824aef83607e4e6cb4cd99997532112afc5 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212336388.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212442082.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212442082.png" new file mode 100644 index 0000000000000000000000000000000000000000..f02a18785e8afab77c1b17de998ef11d0ea9896f Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212442082.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212649282.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212649282.png" new file mode 100644 index 0000000000000000000000000000000000000000..1cc95435a53a6f7a7f6e379b3778b9c0dd5372fa Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212649282.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212702162.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212702162.png" new file mode 100644 index 0000000000000000000000000000000000000000..459aa86f4f66eb9b5c55986cc6a9a8b92396d3c5 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/image-20200529212702162.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/redis cluster hash slot\347\256\227\346\263\225.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/redis cluster hash slot\347\256\227\346\263\225.png" new file mode 100644 index 0000000000000000000000000000000000000000..1fdea932ba568b7215bf084548bb57ac25a129c0 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/redis cluster hash slot\347\256\227\346\263\225.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/redis\345\215\225master\346\236\266\346\236\204\347\232\204\345\256\271\351\207\217\347\232\204\347\223\266\351\242\210\351\227\256\351\242\230.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/redis\345\215\225master\346\236\266\346\236\204\347\232\204\345\256\271\351\207\217\347\232\204\347\223\266\351\242\210\351\227\256\351\242\230.png" new file mode 100644 index 0000000000000000000000000000000000000000..42a629c0fcb2451d2c60403a0e80a82c1304e5f7 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/redis\345\215\225master\346\236\266\346\236\204\347\232\204\345\256\271\351\207\217\347\232\204\347\223\266\351\242\210\351\227\256\351\242\230.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/redis\345\246\202\344\275\225\351\200\232\350\277\207master\346\250\252\345\220\221\346\211\251\345\256\271\346\224\257\346\222\2211T+\346\225\260\346\215\256\351\207\217.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/redis\345\246\202\344\275\225\351\200\232\350\277\207master\346\250\252\345\220\221\346\211\251\345\256\271\346\224\257\346\222\2211T+\346\225\260\346\215\256\351\207\217.png" new file mode 100644 index 0000000000000000000000000000000000000000..0551bc56c8a48899a662f1b637c5e6bf6011dd60 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/redis\345\246\202\344\275\225\351\200\232\350\277\207master\346\250\252\345\220\221\346\211\251\345\256\271\346\224\257\346\222\2211T+\346\225\260\346\215\256\351\207\217.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\344\270\200\350\207\264\346\200\247hash\347\256\227\346\263\225\347\232\204\350\231\232\346\213\237\350\212\202\347\202\271\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\344\270\200\350\207\264\346\200\247hash\347\256\227\346\263\225\347\232\204\350\231\232\346\213\237\350\212\202\347\202\271\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241.png" new file mode 100644 index 0000000000000000000000000000000000000000..1a901c51413026745aed9fe5201d5fd8ffe55afa Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\344\270\200\350\207\264\346\200\247hash\347\256\227\346\263\225\347\232\204\350\231\232\346\213\237\350\212\202\347\202\271\345\256\236\347\216\260\350\264\237\350\275\275\345\235\207\350\241\241.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\344\270\200\350\207\264\346\200\247hash\347\256\227\346\263\225\347\232\204\350\256\262\350\247\243\345\222\214\344\274\230\347\202\271.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\344\270\200\350\207\264\346\200\247hash\347\256\227\346\263\225\347\232\204\350\256\262\350\247\243\345\222\214\344\274\230\347\202\271.png" new file mode 100644 index 0000000000000000000000000000000000000000..137183fb10f21ea239a1a1a5b1f15ec6a349d201 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\344\270\200\350\207\264\346\200\247hash\347\256\227\346\263\225\347\232\204\350\256\262\350\247\243\345\222\214\344\274\230\347\202\271.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\345\244\215\346\235\202\347\232\204\346\225\260\346\215\256\345\272\223+\347\274\223\345\255\230\345\217\214\345\206\231\344\270\200\350\207\264\344\277\235\351\232\234\346\226\271\346\241\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\345\244\215\346\235\202\347\232\204\346\225\260\346\215\256\345\272\223+\347\274\223\345\255\230\345\217\214\345\206\231\344\270\200\350\207\264\344\277\235\351\232\234\346\226\271\346\241\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..c9f7f4e6523b91fee72a386ce1109ec3afdfd0ef Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\345\244\215\346\235\202\347\232\204\346\225\260\346\215\256\345\272\223+\347\274\223\345\255\230\345\217\214\345\206\231\344\270\200\350\207\264\344\277\235\351\232\234\346\226\271\346\241\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\346\234\200\345\210\235\347\272\247\347\232\204\346\225\260\346\215\256\345\272\223+\347\274\223\345\255\230\345\217\214\345\206\231\344\270\215\344\270\200\350\207\264\351\227\256\351\242\230.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\346\234\200\345\210\235\347\272\247\347\232\204\346\225\260\346\215\256\345\272\223+\347\274\223\345\255\230\345\217\214\345\206\231\344\270\215\344\270\200\350\207\264\351\227\256\351\242\230.png" new file mode 100644 index 0000000000000000000000000000000000000000..14ec8c1584807e3bfe0ad64ad8127fc2bdacc4f0 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\346\234\200\345\210\235\347\272\247\347\232\204\346\225\260\346\215\256\345\272\223+\347\274\223\345\255\230\345\217\214\345\206\231\344\270\215\344\270\200\350\207\264\351\227\256\351\242\230.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\346\234\200\345\210\235\347\272\247\347\232\204\346\225\260\346\215\256\345\272\223+\347\274\223\345\255\230\345\217\214\345\206\231\344\270\215\344\270\200\350\207\264\351\227\256\351\242\230\347\232\204\350\247\243\345\206\263\346\226\271\346\241\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\346\234\200\345\210\235\347\272\247\347\232\204\346\225\260\346\215\256\345\272\223+\347\274\223\345\255\230\345\217\214\345\206\231\344\270\215\344\270\200\350\207\264\351\227\256\351\242\230\347\232\204\350\247\243\345\206\263\346\226\271\346\241\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..a0123e12b2e0567603d9ca19b66fc37201f4823b Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\346\234\200\345\210\235\347\272\247\347\232\204\346\225\260\346\215\256\345\272\223+\347\274\223\345\255\230\345\217\214\345\206\231\344\270\215\344\270\200\350\207\264\351\227\256\351\242\230\347\232\204\350\247\243\345\206\263\346\226\271\346\241\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\346\234\200\350\200\201\345\234\237\347\232\204hash\347\256\227\346\263\225\344\273\245\345\217\212\345\274\212\347\253\257.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\346\234\200\350\200\201\345\234\237\347\232\204hash\347\256\227\346\263\225\344\273\245\345\217\212\345\274\212\347\253\257.png" new file mode 100644 index 0000000000000000000000000000000000000000..c3801ddbc293ac80f5368fa12dbd9c094f0f1ba4 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\346\234\200\350\200\201\345\234\237\347\232\204hash\347\256\227\346\263\225\344\273\245\345\217\212\345\274\212\347\253\257.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\346\234\272\345\231\250\347\272\247\345\210\253\347\232\204\350\257\267\346\261\202\350\267\257\347\224\261\351\227\256\351\242\230.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\346\234\272\345\231\250\347\272\247\345\210\253\347\232\204\350\257\267\346\261\202\350\267\257\347\224\261\351\227\256\351\242\230.png" new file mode 100644 index 0000000000000000000000000000000000000000..82bc78c83b31b3302cb64338f4ac35a2811ebecf Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\346\234\272\345\231\250\347\272\247\345\210\253\347\232\204\350\257\267\346\261\202\350\267\257\347\224\261\351\227\256\351\242\230.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\350\257\273\345\206\231\345\271\266\345\217\221\347\232\204\346\227\266\345\200\231\345\244\215\346\235\202\347\232\204\346\225\260\346\215\256\345\272\223+\347\274\223\345\255\230\345\217\214\345\206\231\344\270\215\344\270\200\350\207\264\347\232\204\345\234\272\346\231\257.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\350\257\273\345\206\231\345\271\266\345\217\221\347\232\204\346\227\266\345\200\231\345\244\215\346\235\202\347\232\204\346\225\260\346\215\256\345\272\223+\347\274\223\345\255\230\345\217\214\345\206\231\344\270\215\344\270\200\350\207\264\347\232\204\345\234\272\346\231\257.png" new file mode 100644 index 0000000000000000000000000000000000000000..094c41c3b956e1bf4dd8caf11cf78ed4517980ff Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\350\257\273\345\206\231\345\271\266\345\217\221\347\232\204\346\227\266\345\200\231\345\244\215\346\235\202\347\232\204\346\225\260\346\215\256\345\272\223+\347\274\223\345\255\230\345\217\214\345\206\231\344\270\215\344\270\200\350\207\264\347\232\204\345\234\272\346\231\257.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\351\233\206\344\270\255\345\274\217\347\232\204\351\233\206\347\276\244\345\205\203\346\225\260\346\215\256\345\255\230\345\202\250\345\222\214\347\273\264\346\212\244.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\351\233\206\344\270\255\345\274\217\347\232\204\351\233\206\347\276\244\345\205\203\346\225\260\346\215\256\345\255\230\345\202\250\345\222\214\347\273\264\346\212\244.png" new file mode 100644 index 0000000000000000000000000000000000000000..48d2b59315f58916bfb4ece0d60013f483f22319 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/5_Redis\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\2562/images/\351\233\206\344\270\255\345\274\217\347\232\204\351\233\206\347\276\244\345\205\203\346\225\260\346\215\256\345\255\230\345\202\250\345\222\214\347\273\264\346\212\244.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..1c99fbcf5e0d7cb9cb85a852305f05df09495403 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/README.md" @@ -0,0 +1,453 @@ +# 分布式系统的面试连环炮 + +## 面试题 + +- 什么是分布式系统? +- 为什么要进行系统拆分?如何进行系统拆分?拆分后不用dubbo可以吗?dubbo和thrift有什么区别呢? +- 分布式服务框架 +- Dubbo的工作原理? +- Dubbo支持哪些通信协议? +- Dubbo负载均衡策略和集群容错策略? +- Dubbo的SPI思想是什么? + +## 什么是分布式系统 + +现在互联网公司,一般都是做分布式的系统,大家都不是做底层的分布式系统,分布式存储系统,hadoop hdfs,分布式计算系统,hadoop mapreduce,spark,分布式流式计算系统,storm。 + +分布式业务系统,把原来用java开发的一个大块系统,给拆分成多个子系统,多个子系统之间互相调用,形成一个大系统的整体。假设原来你做了一个OA系统,里面包含了权限模块、员工模块、请假模块、财务模块,一个工程,里面包含了一堆模块,模块与模块之间会互相去调用,1台机器部署。 + +现在如果你把他这个系统给拆开,权限系统,员工系统,请假系统,财务系统,4个系统,4个工程,分别在4台机器上部署 + +一个请求过来,完成这个请求,这个员工系统,调用权限系统,调用请假系统,调用财务系统,4个系统分别完成了一部分的事情,最后4个系统都干完了以后,才认为是这个请求已经完成了 + +单体架构与分布式架构: + +![01_什么是最简单的分布式系统](images/01_什么是最简单的分布式系统.png) + + + +## 为什么要把系统拆分成分布式?为什么要使用Dubbo? + +### 发展变迁 + +早些年,我印象中在2010年初的时候,整个IT行业,很少有人谈分布式,更不用说微服务,虽然很多BAT等大型公司,因为系统的复杂性,很早就是分布式架构,大量的服务,只不过微服务大多基于自己搞的一套框架来实现而已。 + +但是确实,那个年代,大家很重视ssh2,很多中小型公司几乎大部分都是玩儿struts2、spring、hibernate,稍晚一些,才进入了spring mvc、spring、mybatis的组合。那个时候整个行业的技术水平就是那样,当年oracle很火,oracle管理员很吃香,oracle性能优化啥的都是IT男的大杀招啊。连大数据都没人提,当年OCP、OCM等认证培训机构,火的不行。 + +但是确实随着时代的发展,慢慢的,很多公司开始接受分布式系统架构了,这里面尤为对行业有至关重要影响的,是阿里的dubbo,某种程度上而言,阿里在这里推动了行业技术的前进。 + +正是因为有阿里的dubbo,很多中小型公司才可以基于dubbo,来把系统拆分成很多的服务,每个人负责一个服务,大家的代码都没有冲突,服务可以自治,自己选用什么技术都可以,每次发布如果就改动一个服务那就上线一个服务好了,不用所有人一起联调,每次发布都是几十万行代码,甚至几百万行代码了。 + +直到今日,我很高兴的看到分布式系统都成行业面试标配了,任何一个普通的程序员都该掌握这个东西,其实这是行业的进步,也是所有IT码农的技术进步。所以既然分布式都成标配了,那么面试官当然会问了,因为很多公司现在都是分布式、微服务的架构,那面试官当然得考察考察你了。 + +### 为什么要将系统拆分成分布式? + +#### 假设不拆分 + +要是不拆分,一个大系统几十万行代码,20个人维护一份代码,简直是悲剧啊。代码经常改着改着就冲突了,各种代码冲突和合并要处理,非常耗费时间;经常我改动了我的代码,你调用了我,导致你的代码也得重新测试,麻烦的要死;然后每次发布都是几十万行代码的系统一起发布,大家得一起提心吊胆准备上线,几十万行代码的上线,可能每次上线都要做很多的检查,很多异常问题的处理,简直是又麻烦又痛苦;而且如果我现在打算把技术升级到最新的spring版本,还不行,因为这可能导致你的代码报错,我不敢随意乱改技术。 + +假设一个系统是20万行代码,其中小A在里面改了1000行代码,但是此时发布的时候是这个20万行代码的大系统一块儿发布。就意味着20万上代码在线上就可能出现各种变化,20个人,每个人都要紧张地等在电脑面前,上线之后,检查日志,看自己负责的那一块儿有没有什么问题。 + +小A就检查了自己负责的1万行代码对应的功能,确保ok就闪人了;结果不巧的是,小A上线的时候不小心修改了线上机器的某个配置,导致另外小B和小C负责的2万行代码对应的一些功能,出错了 + +几十个人负责维护一个几十万行代码的单块应用,每次上线,准备几个礼拜,上线 -> 部署 -> 检查自己负责的功能 + +最近从2013年到现在,5年的时间里,2013年以前,基本上都是BAT的天下;2013年开始,有几个小巨头开始快速的发展,上市,几百亿美金,估值都几百亿美金;2015年,出现了除了BAT以外,又有几个互联网行业的小巨头出现。 + +有某一个小巨头,现在估值几百亿美金的小巨头,5年前刚开始搞的时候,核心的业务,几十个人,维护一个单块的应用,维护单块的应用,在从0到1的环节里,是很合适的,因为那个时候,是系统都没上线,没什么技术挑战,大家有条不紊的开发。ssh + mysql + tomcat,可能会部署几台机器吧。 + +结果不行了,后来系统上线了,业务快速发展,10万用户 -> 100万用户 -> 1000万用户 -> 上亿用户了 + +#### 拆分后 + +拆分了以后,整个世界清爽了,几十万行代码的系统,拆分成20个服务,平均每个服务就1~2万行代码,每个服务部署到单独的机器上。20个工程,20个git代码仓库里,20个码农,每个人维护自己的那个服务就可以了,是自己独立的代码,跟别人没关系。再也没有代码冲突了,爽。每次就测试我自己的代码就可以了,爽。每次就发布我自己的一个小服务就可以了。技术上想怎么升级就怎么升级,保持接口不变就可以了 + +所以简单来说,一句话总结,如果是那种代码量多达几十万行的中大型项目,团队里有几十个人,那么如果不拆分系统,开发效率极其低下,问题很多。但是拆分系统之后,每个人就负责自己的一小部分就好了,可以随便玩儿随便弄。分布式系统拆分之后,可以大幅度提升复杂系统大型团队的开发效率。 + +但是同时,也要提醒的一点是,系统拆分成分布式系统之后,大量的分布式系统面临的问题也是接踵而来,所以后面的问题都是在围绕分布式系统带来的复杂技术挑战在说。 + +### 如何进行系统的拆分 + +这个问题说大可以很大,可以扯到领域驱动模型设计上去,说小了也很小,我不太想给大家太过于学术的说法,因为你也不可能背这个答案,过去了直接说吧。还是说的简单一点,大家自己到时候知道怎么回答就行了。 + +系统拆分分布式系统,拆成多个服务,拆成微服务的架构,拆很多轮的。上来一个架构师第一轮就给拆好了,第一轮;团队继续扩大,拆好的某个服务,刚开始是1个人维护1万行代码,后来业务系统越来越复杂,这个服务是10万行代码,5个人;第二轮,1个服务 -> 5个服务,每个服务2万行代码,每人负责一个服务 + +如果是多人维护一个服务,<=3个人维护这个服务;最理想的情况下,几十个人,1个人负责1个或2~3个服务;某个服务工作量变大了,代码量越来越多,某个同学,负责一个服务,代码量变成了10万行了,他自己不堪重负,他现在一个人拆开,5个服务,1个人顶着,负责5个人,接着招人,2个人,给那个同学带着,3个人负责5个服务,其中2个人每个人负责2个服务,1个人负责1个服务 + +我个人建议,一个服务的代码不要太多,1万行左右,两三万撑死了吧 + +大部分的系统,是要进行多轮拆分的,第一次拆分,可能就是将以前的多个模块该拆分开来了,比如说将电商系统拆分成订单系统、商品系统、采购系统、仓储系统、用户系统,等等吧。 + +但是后面可能每个系统又变得越来越复杂了,比如说采购系统里面又分成了供应商管理系统、采购单管理系统,订单系统又拆分成了购物车系统、价格系统、订单管理系统。 + +扯深了实在很深,所以这里先给大家举个例子,你自己感受一下,核心意思就是根据情况,先拆分一轮,后面如果系统更复杂了,可以继续分拆。你根据自己负责系统的例子,来考虑一下就好了。 + +#### 拆分后不用dubbo可以吗? + +当然可以了,大不了最次,就是各个系统之间,直接基于spring mvc,就纯http接口互相通信呗,还能咋样。但是这个肯定是有问题的,因为http接口通信维护起来成本很高,你要考虑超时重试、负载均衡等等各种乱七八糟的问题,比如说你的订单系统调用商品系统,商品系统部署了5台机器,你怎么把请求均匀地甩给那5台机器?这不就是负载均衡?你要是都自己搞那是可以的,但是确实很痛苦。 + +所以dubbo说白了,是一种rpc框架,就是本地就是进行接口调用,但是dubbo会代理这个调用请求,跟远程机器网络通信,给你处理掉负载均衡了、服务实例上下线自动感知了、超时重试了,等等乱七八糟的问题。那你就不用自己做了,用dubbo就可以了。 + + + +## Dubbo的工作原理是啥? + +### 工作原理 + +![01_dubbo的工作原理](images/01_dubbo的工作原理.png) + +- 第一层:service层,接口层,给服务提供者和消费者来实现的 +- 第二层:config层,配置层,主要是对dubbo进行各种配置的 +- 第三层:proxy层,服务代理层,透明生成客户端的stub和服务单的skeleton +- 第四层:registry层,服务注册层,负责服务的注册与发现 +- 第五层:cluster层,集群层,封装多个服务提供者的路由以及负载均衡,将多个实例组合成一个服务 +- 第六层:monitor层,监控层,对rpc接口的调用次数和调用时间进行监控 +- 第七层:protocol层,远程调用层,封装rpc调用 +- 第八层:exchange层,信息交换层,封装请求响应模式,同步转异步 +- 第九层:transport层,网络传输层,抽象mina和netty为统一接口 +- 第十层:serialize层,数据序列化层 + +### 工作流程 + +- 第一步,provider向注册中心去注册 +- 第二步,consumer从注册中心订阅服务,注册中心会通知consumer注册好的服务 +- 第三步,consumer调用provider +- 第四步,consumer和provider都异步的通知监控中心 + +### 注册中心宕机了后可以继续通信么? + +可以,因为刚开始初始化的时候,消费者会将提供者的地址等信息拉取到本地缓存,所以注册中心挂了可以继续通信 + +## Dubbo支持哪些通信协议?支持哪些序列化协议? + +![01_dubbo的网络通信协议](images/01_dubbo的网络通信协议.png) + +### Dubbo通信协议 + +#### dubbo协议 + +dubbo://192.168.0.1:20188 + +默认就是走dubbo协议的,单一长连接,NIO异步通信,基于hessian作为序列化协议 + +适用的场景就是:传输数据量很小(每次请求在100kb以内),但是并发量很高 + +为了要支持高并发场景,一般是服务提供者就几台机器,但是服务消费者有上百台,可能每天调用量达到上亿次!此时用长连接是最合适的,就是跟每个服务消费者维持一个长连接就可以,可能总共就100个连接。然后后面直接基于长连接NIO异步通信,可以支撑高并发请求。 + +否则如果上亿次请求每次都是短连接的话,服务提供者会扛不住。 + +而且因为走的是单一长连接,所以传输数据量太大的话,会导致并发能力降低。所以一般建议是传输数据量很小,支撑高并发访问。 + +#### rmi协议 + +走java二进制序列化,多个短连接,适合消费者和提供者数量差不多,适用于文件的传输,一般较少用 + +#### hessian协议 + +走hessian序列化协议,多个短连接,适用于提供者数量比消费者数量还多,适用于文件的传输,一般较少用 + +#### http议 + +走json序列化 + +#### webservice + +走SOAP文本序列化 + +### dubbo支持的序列化协议 + +所以dubbo实际基于不同的通信协议,支持hessian、java二进制序列化、json、SOAP文本序列化多种序列化协议。但是hessian是其默认的序列化协议。 + +## dubbo负载均衡策略和集群容错策略都有哪些? + +![01_dubbo负载均衡](images/01_dubbo负载均衡.png) + +### dubbo负载均衡策略 + +#### random loadbalance + +默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重,会按照权重来负载均衡,权重越大分配流量越高,一般就用这个默认的就可以了。 + +#### roundrobin loadbalance + +还有roundrobin loadbalance,这个的话默认就是均匀地将流量打到各个机器上去,但是如果各个机器的性能不一样,容易导致性能差的机器负载过高。所以此时需要调整权重,让性能差的机器承载权重小一些,流量少一些。 + +跟运维同学申请机器,有的时候,我们运气,正好公司资源比较充足,刚刚有一批热气腾腾,刚刚做好的一批虚拟机新鲜出炉,配置都比较高。8核+16g,机器,2台。过了一段时间,我感觉2台机器有点不太够,我去找运维同学,哥儿们,你能不能再给我1台机器,4核+8G的机器。我还是得要。 + +#### leastactive loadbalance + +这个就是自动感知一下,如果某个机器性能越差,那么接收的请求越少,越不活跃,此时就会给不活跃的性能差的机器更少的请求 + +#### consistanthash loadbalance + +一致性Hash算法,相同参数的请求一定分发到一个provider上去,provider挂掉的时候,会基于虚拟节点均匀分配剩余的流量,抖动不会太大。如果你需要的不是随机负载均衡,是要一类请求都到一个节点,那就走这个一致性hash策略。 + +### dubbo集群容错策略 + +#### failover cluster模式 + +失败自动切换,自动重试其他机器,默认就是这个,常见于读操作 + +#### failfast cluster模式 + +一次调用失败就立即失败,常见于写操作 + +#### failsafe cluster模式 + +出现异常时忽略掉,常用于不重要的接口调用,比如记录日志 + +#### failbackc cluster模式 + +失败了后台自动记录请求,然后定时重发,比较适合于写消息队列这种 + +#### forking cluster + +并行调用多个provider,只要一个成功就立即返回 + +#### broadcacst cluster + +逐个调用所有的provider + +### dubbo动态代理策略 + +默认使用javassist动态字节码生成,创建代理类 + +但是可以通过spi扩展机制配置自己的动态代理策略 + + + +## Dubbo的SPI思想是什么? + +![01_dubbo的SPI原理](images/01_dubbo的SPI原理.png) + +spi,简单来说,就是service provider interface,说白了是什么意思呢,比如你有个接口,现在这个接口有3个实现类,那么在系统运行的时候对这个接口到底选择哪个实现类呢?这就需要spi了,需要根据指定的配置或者是默认的配置,去找到对应的实现类加载进来,然后用这个实现类的实例对象。 + +接口A -> 实现A1,实现A2,实现A3 + +配置一下,接口A = 实现A2 + +在系统实际运行的时候,会加载你的配置,用实现A2实例化一个对象来提供服务 + +比如说你要通过jar包的方式给某个接口提供实现,然后你就在自己jar包的META-INF/services/目录下放一个跟接口同名的文件,里面指定接口的实现里是自己这个jar包里的某个类。ok了,别人用了一个接口,然后用了你的jar包,就会在运行的时候通过你的jar包的那个文件找到这个接口该用哪个实现类。 + +这是jdk提供的一个功能。 + +比如说你有个工程A,有个接口A,接口A在工程A里是没有实现类的 -> 系统在运行的时候,怎么给接口A选择一个实现类呢? + +你就可以自己搞一个jar包,META-INF/services/,放上一个文件,文件名就是接口名,接口A,接口A的实现类=com.zhss.service.实现类A2。让工程A来依赖你的这个jar包,然后呢在系统运行的时候,工程A跑起来,对接口A,就会扫描自己依赖的所有的jar包,在每个jar里找找,有没有META-INF/services文件夹,如果有,在里面找找,有没有接口A这个名字的文件,如果有在里面找一下你指定的接口A的实现是你的jar包里的哪个类? + +SPI机制,一般来说用在哪儿?插件扩展的场景,比如说你开发的是一个给别人使用的开源框架,如果你想让别人自己写个插件,插到你的开源框架里面来,扩展某个功能。 + +经典的思想体现,大家平时都在用,比如说jdbc + +java定义了一套jdbc的接口,但是java是没有提供jdbc的实现类 + +但是实际上项目跑的时候,要使用jdbc接口的哪些实现类呢?一般来说,我们要根据自己使用的数据库,比如msyql,你就将mysql-jdbc-connector.jar,引入进来;oracle,你就将oracle-jdbc-connector.jar,引入进来。 + +在系统跑的时候,碰到你使用jdbc的接口,他会在底层使用你引入的那个jar中提供的实现类 + +但是dubbo也用了spi思想,不过没有用jdk的spi机制,是自己实现的一套spi机制。 + +``` +Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); +``` + +Protocol接口,dubbo要判断一下,在系统运行的时候,应该选用这个Protocol接口的哪个实现类来实例化对象来使用呢? + +他会去找一个你配置的Protocol,他就会将你配置的Protocol实现类,加载到jvm中来,然后实例化对象,就用你的那个Protocol实现类就可以了 + +微内核,可插拔,大量的组件,Protocol负责rpc调用的东西,你可以实现自己的rpc调用组件,实现Protocol接口,给自己的一个实现类即可。 + +这行代码就是dubbo里大量使用的,就是对很多组件,都是保留一个接口和多个实现,然后在系统运行的时候动态根据配置去找到对应的实现类。如果你没配置,那就走默认的实现好了,没问题。 + +``` +@SPI("dubbo") + +public interface Protocol { + + int getDefaultPort(); + + @Adaptive + + Exporter export(Invoker invoker) throws RpcException; + + @Adaptive + + Invoker refer(Class type, URL url) throws RpcException; + + void destroy(); + +} +``` + + + +在dubbo自己的jar里,在/META_INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol文件中: + +``` +dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol +http=com.alibaba.dubbo.rpc.protocol.http.HttpProtocol +hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol +``` + +所以说,这就看到了dubbo的spi机制默认是怎么玩儿的了,其实就是Protocol接口,@SPI(“dubbo”)说的是,通过SPI机制来提供实现类,实现类是通过dubbo作为默认key去配置文件里找到的,配置文件名称与接口全限定名一样的,通过dubbo作为key可以找到默认的实现了就是com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol。 + +dubbo的默认网络通信协议,就是dubbo协议,用的DubboProtocol + +如果想要动态替换掉默认的实现类,需要使用@Adaptive接口,Protocol接口中,有两个方法加了@Adaptive注解,就是说那俩接口会被代理实现。 + +比如这个Protocol接口搞了俩@Adaptive注解标注了方法,在运行的时候会针对Protocol生成代理类,这个代理类的那俩方法里面会有代理代码,代理代码会在运行的时候动态根据url中的protocol来获取那个key,默认是dubbo,你也可以自己指定,你如果指定了别的key,那么就会获取别的实现类的实例了。 + +通过这个url中的参数不通,就可以控制动态使用不同的组件实现类 + +好吧,那下面来说说怎么来自己扩展dubbo中的组件 + +自己写个工程,要是那种可以打成jar包的,里面的src/main/resources目录下,搞一个META-INF/services,里面放个文件叫:com.alibaba.dubbo.rpc.Protocol,文件里搞一个my=com.zhss.MyProtocol。自己把jar弄到nexus私服里去。 + +然后自己搞一个dubbo provider工程,在这个工程里面依赖你自己搞的那个jar,然后在spring配置文件里给个配置: + +``` + +``` + +这个时候provider启动的时候,就会加载到我们jar包里的my=com.zhss.MyProtocol这行配置里,接着会根据你的配置使用你定义好的MyProtocol了,这个就是简单说明一下,你通过上述方式,可以替换掉大量的dubbo内部的组件,就是扔个你自己的jar包,然后配置一下即可。 + +dubbo里面提供了大量的类似上面的扩展点,就是说,你如果要扩展一个东西,只要自己写个jar,让你的consumer或者是provider工程,依赖你的那个jar,在你的jar里指定目录下配置好接口名称对应的文件,里面通过key=实现类。 + +然后对对应的组件,用类似用你的哪个key对应的实现类来实现某个接口,你可以自己去扩展dubbo的各种功能,提供你自己的实现。 + + + +## 基于Dubbo如何做服务治理、服务降级和重试 + +服务治理,这个问题如果问你,其实就是看看你有没有服务治理的思想,因为这个是做过复杂微服务的人肯定会遇到的一个问题。 + +服务降级,这个是涉及到复杂分布式系统中必备的一个话题,因为分布式系统互相来回调用,任何一个系统故障了,你不降级,直接就全盘崩溃?那就太坑爹了吧 + +失败重试,分布式系统中网络请求如此频繁,要是因为网络问题不小心失败了一次,是不是要重试? + +超时重试,同上,如果不小心网络慢一点,超时了,如何重试? + +- dubbo工作原理:服务注册,注册中心,消费者,代理通信,负载均衡 +- 网络通信、序列化:dubbo协议,长连接,NIO,hessian序列化协议 +- 负载均衡策略,集群容错策略,动态代理策略:dubbo跑起来的时候一些功能是如何运转的,怎么做负载均衡?怎么做集群容错?怎么生成动态代理? +- dubbo SPI机制:你了解不了解dubbo的SPI机制?如何基于SPI机制对dubbo进行扩展? +- dubbo的服务治理、降级、重试 + +### 服务治理 + +#### 调用链路自动生成 + +一个大型的分布式系统,或者说是用现在流行的微服务架构来说吧,分布式系统由大量的服务组成。那么这些服务之间互相是如何调用的?调用链路是啥?说实话,几乎到后面没人搞的清楚了,因为服务实在太多了,可能几百个甚至几千个服务。 + +那就需要基于dubbo做的分布式系统中,对各个服务之间的调用自动记录下来,然后自动将各个服务之间的依赖关系和调用链路生成出来,做成一张图,显示出来,大家才可以看到对吧。 + +服务A -> 服务B -> 服务C + +​ -> 服务E + + -> 服务D + +​ -> 服务F + + -> 服务W + +#### 服务访问压力以及时长统计 + +需要自动统计各个接口和服务之间的调用次数以及访问延时,而且要分成两个级别。一个级别是接口粒度,就是每个服务的每个接口每天被调用多少次,TP50,TP90,TP99,三个档次的请求延时分别是多少;第二个级别是从源头入口开始,一个完整的请求链路经过几十个服务之后,完成一次请求,每天全链路走多少次,全链路请求延时的TP50,TP90,TP99,分别是多少。 + +这些东西都搞定了之后,后面才可以来看当前系统的压力主要在哪里,如何来扩容和优化啊 + +#### 其他的 + +服务分层(避免循环依赖),调用链路失败监控和报警,服务鉴权,每个服务的可用性的监控(接口调用成功率?几个9)99.99%,99.9%,99% + +### 服务降级 + +比如说服务A调用服务B,结果服务B挂掉了,服务A重试几次调用服务B,还是不行,直接降级,走一个备用的逻辑,给用户返回响应 + + ``` +public interface HelloService { + void sayHello(); +} + +public class HelloServiceImpl implements HelloService { + + public void sayHello() { +​ System.out.println("hello world......"); + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ``` + +现在就是mock,如果调用失败统一返回null + +但是可以将mock修改为true,然后在跟接口同一个路径下实现一个Mock类,命名规则是接口名称加Mock后缀。然后在Mock类里实现自己的降级逻辑。 + +``` +public class HelloServiceMock implements HelloService { + public void sayHello() { + + // 降级逻辑 + + } +} +``` + +### 失败重试和超时重试 + +所谓失败重试,就是consumer调用provider要是失败了,比如抛异常了,此时应该是可以重试的,或者调用超时了也可以重试。 + +``` + +``` + +某个服务的接口,要耗费5s,你这边不能干等着,你这边配置了timeout之后,我等待2s,还没返回,我直接就撤了,不能等你 + +如果是超时了,timeout就会设置超时时间;如果是调用失败了自动就会重试指定的次数 + +你就结合你们公司的具体的场景来说说你是怎么设置这些参数的,timeout,一般设置为200ms,我们认为不能超过200ms还没返回 + +retries,3次,设置retries,还一般是在读请求的时候,比如你要查询个数据,你可以设置个retries,如果第一次没读到,报错,重试指定的次数,尝试再次读取2次 + + \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_dubbo\347\232\204SPI\345\216\237\347\220\206.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_dubbo\347\232\204SPI\345\216\237\347\220\206.png" new file mode 100644 index 0000000000000000000000000000000000000000..3f18eff0a2b92a835ceef07b667ecc0afb908d6a Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_dubbo\347\232\204SPI\345\216\237\347\220\206.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_dubbo\347\232\204\345\267\245\344\275\234\345\216\237\347\220\206.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_dubbo\347\232\204\345\267\245\344\275\234\345\216\237\347\220\206.png" new file mode 100644 index 0000000000000000000000000000000000000000..2be41e12e0088dc42df140a7170058efc202ff42 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_dubbo\347\232\204\345\267\245\344\275\234\345\216\237\347\220\206.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_dubbo\347\232\204\347\275\221\347\273\234\351\200\232\344\277\241\345\215\217\350\256\256.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_dubbo\347\232\204\347\275\221\347\273\234\351\200\232\344\277\241\345\215\217\350\256\256.png" new file mode 100644 index 0000000000000000000000000000000000000000..ff032a936f0615ba4c44984bac2c576cdede00b9 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_dubbo\347\232\204\347\275\221\347\273\234\351\200\232\344\277\241\345\215\217\350\256\256.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_dubbo\350\264\237\350\275\275\345\235\207\350\241\241.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_dubbo\350\264\237\350\275\275\345\235\207\350\241\241.png" new file mode 100644 index 0000000000000000000000000000000000000000..7480d770e975bea17c85b54871f07edf51954af8 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_dubbo\350\264\237\350\275\275\345\235\207\350\241\241.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\344\273\200\344\271\210\346\230\257\346\234\200\347\256\200\345\215\225\347\232\204\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\344\273\200\344\271\210\346\230\257\346\234\200\347\256\200\345\215\225\347\232\204\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237.png" new file mode 100644 index 0000000000000000000000000000000000000000..6335960294de7c564dff7ac9e1eec2c7f826dc83 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/6_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\347\232\204\351\235\242\350\257\225\350\277\236\347\216\257\347\202\256/images/01_\344\273\200\344\271\210\346\230\257\346\234\200\347\256\200\345\215\225\347\232\204\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..2ed8d6dae2eec971807909d56d050d64a782f241 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/README.md" @@ -0,0 +1,343 @@ + + +# 分布式系统幂等性与顺序性及分布式锁 + +## 分布式服务接口的幂等性如何设计 + +### 什么是幂等性 + +一个分布式系统中的某个接口,要保证幂等性,该如何保证?这个事儿其实是你做分布式系统的时候必须要考虑的一个生产环境的技术问题。啥意思呢? + +你看,假如你有个服务提供一个接口,结果这服务部署在了5台机器上,接着有个接口就是付款接口。然后人家用户在前端上操作的时候,不知道为啥,总之就是一个订单不小心发起了两次支付请求,然后这俩请求分散在了这个服务部署的不同的机器上,好了,结果一个订单扣款扣两次?尴尬了。。。 + +或者是订单系统调用支付系统进行支付,结果不小心因为网络超时了,然后订单系统走了前面我们看到的那个重试机制,咔嚓给你重试了一把,好,支付系统收到一个支付请求两次,而且因为负载均衡算法落在了不同的机器上,尴尬了。。。 + +所以你肯定得知道这事儿,否则你做出来的分布式系统恐怕容易埋坑 + +网络问题很常见,100次请求,都ok;1万次,可能1次是超时会重试;10万,10次;100万,100次;如果有100个请求重复了,你没处理,导致订单扣款2次,100个订单都扣错了;每天被100个用户投诉;一个月被3000个用户投诉 + +我们之前生产就遇到过,是往数据库里写入数据,重复的请求,就导致我们的数据经常会错,出现一些重复数据,就会导致一些问题 + +![01_分布式系统接口的幂等性问题](images/01_分布式系统接口的幂等性问题.png) + +如果是单机的环境,只需要维护一个map或者set即可,每次判断订单ID是否被支付过。 + +这个不是技术问题,这个没有通用的一个方法,这个是结合业务来看应该如何保证幂等性的,你的经验。 + + 所谓幂等性,就是说一个接口,多次发起同一个请求,你这个接口得保证结果是准确的,比如不能多扣款,不能多插入一条数据,不能将统计值多加了1。这就是幂等性,不给大家来学术性词语了。 + +### 保证幂等性 + +其实保证幂等性主要是三点: + +- 对于每个请求必须有一个唯一的标识,举个例子:订单支付请求,肯定得包含订单id,一个订单id最多支付一次,对吧 +- 每次处理完请求之后,必须有一个记录标识这个请求处理过了,比如说常见的方案是在mysql中记录个状态啥的,比如支付之前记录一条这个订单的支付流水,而且支付流水采 +- 每次接收请求需要进行判断之前是否处理过的逻辑处理,比如说,如果有一个订单已经支付了,就已经有了一条支付流水,那么如果重复发送这个请求,则此时先插入支付流水,orderId已经存在了,唯一键约束生效,报错插入不进去的。然后你就不用再扣款了。 +- 上面只是给大家举个例子,实际运作过程中,你要结合自己的业务来,比如说用redis用orderId作为唯一键。只有成功插入这个支付流水,才可以执行实际的支付扣款。 + +要求是支付一个订单,必须插入一条支付流水,order_id建一个唯一键,unique key + +所以你在支付一个订单之前,先插入一条支付流水,order_id就已经进去了 + +你就可以写一个标识到redis里面去,set order_id payed,下一次重复请求过来了,先查redis的order_id对应的value,如果是payed就说明已经支付过了,你就别重复支付了 + +然后呢,你再重复支付这个订单的时候,你写尝试插入一条支付流水,数据库给你报错了,说unique key冲突了,整个事务回滚就可以了 + +来保存一个是否处理过的标识也可以,服务的不同实例可以一起操作redis。 + + + +## 分布式服务接口请求的顺序如何保证? + +其实分布式系统接口的调用顺序,也是个问题,一般来说是不用保证顺序的。但是有的时候可能确实是需要严格的顺序保证。给大家举个例子,你服务A调用服务B,先插入再删除。好,结果俩请求过去了,落在不同机器上,可能插入请求因为某些原因执行慢了一些,导致删除请求先执行了,此时因为没数据所以啥效果也没有;结果这个时候插入请求过来了,好,数据插入进去了,那就尴尬了。 + + 本来应该是先插入 -> 再删除,这条数据应该没了,结果现在先删除 -> 再插入,数据还存在,最后你死都想不明白是怎么回事。所以这都是分布式系统一些很常见的问题 + +![01_分布式系统接口调用顺序性](images/01_分布式系统接口调用顺序性.png) + +首先,一般来说,我个人给你的建议是,你们从业务逻辑上最好设计的这个系统不需要这种顺序性的保证,因为一旦引入顺序性保障,会导致系统复杂度上升,而且会带来效率低下,热点数据压力过大,等问题。 + +下面我给个我们用过的方案吧,简单来说,首先你得用dubbo的一致性hash负载均衡策略,将比如某一个订单id对应的请求都给分发到某个机器上去,接着就是在那个机器上因为可能还是多线程并发执行的,你可能得立即将某个订单id对应的请求扔一个内存队列里去,强制排队,这样来确保他们的顺序性。 + +但是这样引发的后续问题就很多,比如说要是某个订单对应的请求特别多,造成某台机器成热点怎么办?解决这些问题又要开启后续一连串的复杂技术方案。。。曾经这类问题弄的我们头疼不已,所以,还是建议什么呢? + +最好是比如说刚才那种,一个订单的插入和删除操作,能不能合并成一个操作,就是一个删除,或者是什么,避免这种问题的产生。 + +### 采用MQ以及内存队列来解决 + +方式1,也是最友好的方式就是使用消息队列和内存队列来解决,首先我们需要做的就是把需要保证顺序的请求,通过Hash算法分发到特定的同一台机器上,然后机器内部在把请求放到内存队列中,线程从内存队列中获取消费,保证线程的顺序性 + +但是这种方式能解决99%的顺序性,但是接入服务还是可能存在问题,比如把请求 123,弄成231,导致送入MQ队列中顺序也不一致 + +### 采用分布式锁来解决 + +分布式锁能够保证强一致性,但是因为引入这种重量级的同步机制,会导致并发量急剧降低,因为需要频繁的获取锁,释放锁的操作。 + + + +## 如何设计一个类似Dubbo的RPC框架 + +遇到这类问题,起码从你了解的类似框架的原理入手,自己说说参照dubbo的原理,你来设计一下,举个例子,dubbo不是有那么多分层么?而且每个分层是干啥的,你大概是不是知道?那就按照这个思路大致说一下吧。 + +- 上来你的服务就得去注册中心注册吧,你是不是得有个注册中心,保留各个服务的信息,可以用zookeeper来做,对吧 +- 然后你的消费者需要去注册中心拿对应的服务信息吧,对吧,而且每个服务可能会存在于多台机器上 +- 接着你就该发起一次请求了,咋发起?蒙圈了是吧。当然是基于动态代理了,你面向接口获取到一个动态代理,这个动态代理就是接口在本地的一个代理,然后这个代理会找到服务对应的机器地址 +- 然后找哪个机器发送请求?那肯定得有个负载均衡算法了,比如最简单的可以随机轮询是不是 +- 接着找到一台机器,就可以跟他发送请求了,第一个问题咋发送?你可以说用netty了,nio方式;第二个问题发送啥格式数据?你可以说用hessian序列化协议了,或者是别的,对吧。然后请求过去了。。 +- 服务器那边一样的,需要针对你自己的服务生成一个动态代理,监听某个网络端口了,然后代理你本地的服务代码。接收到请求的时候,就调用对应的服务代码,对吧。 + + + +## 说说Zookeeper的使用场景有哪些? + +分布式锁这个东西,很常用的,你做java系统开发,分布式系统,可能会有一些场景会用到。最常用的分布式锁就是zookeeper来做分布式锁。 + +其实说实话,问这个问题,一般就是看看你是否了解zk,因为zk是分布式系统中很常见的一个基础系统。而且问的话常问的就是说zk的使用场景是什么?看你知道不知道一些基本的使用场景。但是其实zk挖深了自然是可以问的很深很深的。 + +### 分布式协调 + +这个其实是zk很经典的一个用法,简单来说,就好比,你A系统发送个请求到mq,然后B消息消费之后处理了。那A系统如何知道B系统的处理结果?用zk就可以实现分布式系统之间的协调工作。A系统发送请求之后可以在zk上对某个节点的值注册个监听器,一旦B系统处理完了就修改zk那个节点的值,A立马就可以收到通知,完美解决。 + +![01_zookeeper的分布式协调场景](images/01_zookeeper的分布式协调场景.png) + +### 分布式锁 + +对某一个数据连续发出两个修改操作,两台机器同时收到了请求,但是只能一台机器先执行另外一个机器再执行。那么此时就可以使用zk分布式锁,一个机器接收到了请求之后先获取zk上的一把分布式锁,就是可以去创建一个znode,接着执行操作;然后另外一个机器也尝试去创建那个znode,结果发现自己创建不了,因为被别人创建了。。。。那只能等着,等第一个机器执行完了自己再执行。 + +![02_zookeeper的分布式锁场景](images/02_zookeeper的分布式锁场景.png) + +### 元数据/配置信息管理 + +zk可以用作很多系统的配置信息的管理,比如kafka、storm等等很多分布式系统都会选用zk来做一些元数据、配置信息的管理,包括dubbo注册中心不也支持zk + +![03_zookeeper的元数据_配置管理场景](images/03_zookeeper的元数据_配置管理场景.png) + +### HA高可用性 + +这个应该是很常见的,比如hadoop、hdfs、yarn等很多大数据系统,都选择基于zk来开发HA高可用机制,就是一个重要进程一般会做主备两个,主进程挂了立马通过zk感知到切换到备用进程![04_zookeeper的HA高可用性场景](images/04_zookeeper的HA高可用性场景.png) + +## 分布式锁 + +### 面试题 + +- 一般实现分布式锁都有哪些方式? +- 使用redis如何设计分布式锁? +- 使用zk来设计分布式锁可以吗? +- 这两种分布式锁的实现方式哪种效率比较高? + +### Redis实现分布式锁 + +官方叫做RedLock算法,是redis官方支持的分布式锁算法。 + +这个分布式锁有3个重要的考量点,互斥(只能有一个客户端获取锁),不能死锁,容错(大部分redis节点或者这个锁就可以加可以释放) + +第一个最普通的实现方式,如果就是在redis里创建一个key算加锁 + +SET my:lock 随机值 NX PX 30000,这个命令就ok,这个的NX的意思就是只有key不存在的时候才会设置成功,PX 30000的意思是30秒后锁自动释放。别人创建的时候如果发现已经有了就不能加锁了。 + +释放锁就是删除key,但是一般可以用lua脚本删除,判断value一样才删除: + +![01_redis最普通的分布式锁的实现原理](images/01_redis最普通的分布式锁的实现原理.png) + +关于redis如何执行lua脚本,自行百度 + +``` +if redis.call("get",KEYS[1]) == ARGV[1] then + +return redis.call("del",KEYS[1]) + +else + + return 0 + +end +``` + +为啥要用随机值呢?因为如果某个客户端获取到了锁,但是阻塞了很长时间才执行完,此时可能已经自动释放锁了,此时可能别的客户端已经获取到了这个锁,要是你这个时候直接删除key的话会有问题,所以得用随机值加上面的lua脚本来释放锁。 + +但是这样是肯定不行的。因为如果是普通的redis单实例,那就是单点故障。或者是redis普通主从,那redis主从异步复制,如果主节点挂了,key还没同步到从节点,此时从节点切换为主节点,别人就会拿到锁。 + + + +第二个问题,RedLock算法 + +- 这个场景是假设有一个redis cluster,有5个redis master实例。然后执行如下步骤获取一把锁: +- 获取当前时间戳,单位是毫秒 +- 跟上面类似,轮流尝试在每个master节点上创建锁,过期时间较短,一般就几十毫秒 +- 尝试在大多数节点上建立一个锁,比如5个节点就要求是3个节点(n / 2 +1) +- 客户端计算建立好锁的时间,如果建立锁的时间小于超时时间,就算建立成功了 +- 要是锁建立失败了,那么就依次删除这个锁 +- 只要别人建立了一把分布式锁,你就得不断轮询去尝试获取锁 + + ![02_RedLock算法](images/02_RedLock算法.png) + +### ZK实现分布式锁 + +zk分布式锁,其实可以做的比较简单,就是某个节点尝试创建临时znode,此时创建成功了就获取了这个锁;这个时候别的客户端来创建锁会失败,只能注册个监听器监听这个锁。释放锁就是删除这个znode,一旦释放掉就会通知客户端,然后有一个等待着的客户端就可以再次重新加锁。 + +![03_zookeeper的分布式锁原理](images/03_zookeeper的分布式锁原理.png) + +ZK实现分布式锁,就是不需要执行轮询算法,而是注册监听器,但有人释放锁的时候,会通知需要获取锁的进程。 + +同时ZK获取锁的时候,其实就是创建了一个临时节点,如果这个临时节点之前不存在,那么就创建成功,也就是说这个锁就是属于该线程的。 + +同时其它的线程会尝试创建相同名称的一个临时节点,如果已经存在,说明别人已经占有了这把锁,那么就创建失败。 + +一旦临时节点被删除,zk就通知别人这个锁已经被释放掉了,相当于锁被释放掉了。 + +假设这个时候,持有锁的服务器宕机了,那么Zookeeper会自动将该锁给释放掉。 + + + +### ZK实现分布式锁代码 + +``` +/** + * ZooKeeperSession + * @author Administrator + * + */ +public class ZooKeeperSession { + + private static CountDownLatch connectedSemaphore = new CountDownLatch(1); + + private ZooKeeper zookeeper; +private CountDownLatch latch; + + public ZooKeeperSession() { + try { + this.zookeeper = new ZooKeeper( + "192.168.31.187:2181,192.168.31.19:2181,192.168.31.227:2181", + 50000, + new ZooKeeperWatcher()); + try { + connectedSemaphore.await(); + } catch(InterruptedException e) { + e.printStackTrace(); + } + + System.out.println("ZooKeeper session established......"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 获取分布式锁 + * @param productId + */ + public Boolean acquireDistributedLock(Long productId) { + String path = "/product-lock-" + productId; + + try { + zookeeper.create(path, "".getBytes(), + Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); +return true; + } catch (Exception e) { +while(true) { + try { +Stat stat = zk.exists(path, true); // 相当于是给node注册一个监听器,去看看这个监听器是否存在 +if(stat != null) { +this.latch = new CountDownLatch(1); +this.latch.await(waitTime, TimeUnit.MILLISECONDS); +this.latch = null; +} +zookeeper.create(path, "".getBytes(), + Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); +return true; +} catch(Exception e) { +continue; +} +} + +// 很不优雅,我呢就是给大家来演示这么一个思路 +// 比较通用的,我们公司里我们自己封装的基于zookeeper的分布式锁,我们基于zookeeper的临时顺序节点去实现的,比较优雅的 + } +return true; + } + + /** + * 释放掉一个分布式锁 + * @param productId + */ + public void releaseDistributedLock(Long productId) { + String path = "/product-lock-" + productId; + try { + zookeeper.delete(path, -1); + System.out.println("release the lock for product[id=" + productId + "]......"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 建立zk session的watcher + * @author Administrator + * + */ + private class ZooKeeperWatcher implements Watcher { + + public void process(WatchedEvent event) { + System.out.println("Receive watched event: " + event.getState()); + + if(KeeperState.SyncConnected == event.getState()) { + connectedSemaphore.countDown(); + } + +if(this.latch != null) { +this.latch.countDown(); +} + } + + } + + /** + * 封装单例的静态内部类 + * @author Administrator + * + */ + private static class Singleton { + + private static ZooKeeperSession instance; + + static { + instance = new ZooKeeperSession(); + } + + public static ZooKeeperSession getInstance() { + return instance; + } + + } + + /** + * 获取单例 + * @return + */ + public static ZooKeeperSession getInstance() { + return Singleton.getInstance(); + } + + /** + * 初始化单例的便捷方法 + */ + public static void init() { + getInstance(); + } + +} +``` + + + +### Redis分布式锁和ZK分布式锁 + +redis分布式锁,其实需要自己不断去尝试获取锁,比较消耗性能 + + zk分布式锁,获取不到锁,注册个监听器即可,不需要不断主动尝试获取锁,性能开销较小 + + 另外一点就是,如果是redis获取锁的那个客户端bug了或者挂了,那么只能等待超时时间之后才能释放锁;而zk的话,因为创建的是临时znode,只要客户端挂了,znode就没了,此时就自动释放锁 + + redis分布式锁大家每发现好麻烦吗?遍历上锁,计算时间等等。。。zk的分布式锁语义清晰实现简单 + + 所以先不分析太多的东西,就说这两点,我个人实践认为zk的分布式锁比redis的分布式锁牢靠、而且模型简单易用 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/01_redis\346\234\200\346\231\256\351\200\232\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/01_redis\346\234\200\346\231\256\351\200\232\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.png" new file mode 100644 index 0000000000000000000000000000000000000000..720375842db364578065c095df5f4725a89154d7 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/01_redis\346\234\200\346\231\256\351\200\232\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\347\232\204\345\256\236\347\216\260\345\216\237\347\220\206.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/01_zookeeper\347\232\204\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\345\234\272\346\231\257.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/01_zookeeper\347\232\204\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\345\234\272\346\231\257.png" new file mode 100644 index 0000000000000000000000000000000000000000..52646964b35303e5c8b8477d3e744d75cea7b58c Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/01_zookeeper\347\232\204\345\210\206\345\270\203\345\274\217\345\215\217\350\260\203\345\234\272\346\231\257.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/01_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\346\216\245\345\217\243\347\232\204\345\271\202\347\255\211\346\200\247\351\227\256\351\242\230.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/01_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\346\216\245\345\217\243\347\232\204\345\271\202\347\255\211\346\200\247\351\227\256\351\242\230.png" new file mode 100644 index 0000000000000000000000000000000000000000..11a10b5736bab4914e45b23b8ed04afa0035324e Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/01_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\346\216\245\345\217\243\347\232\204\345\271\202\347\255\211\346\200\247\351\227\256\351\242\230.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/01_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\346\216\245\345\217\243\350\260\203\347\224\250\351\241\272\345\272\217\346\200\247.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/01_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\346\216\245\345\217\243\350\260\203\347\224\250\351\241\272\345\272\217\346\200\247.png" new file mode 100644 index 0000000000000000000000000000000000000000..6b0bbd6cb9c16b4f47e3af871f616eb67ea30640 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/01_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\346\216\245\345\217\243\350\260\203\347\224\250\351\241\272\345\272\217\346\200\247.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/02_RedLock\347\256\227\346\263\225.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/02_RedLock\347\256\227\346\263\225.png" new file mode 100644 index 0000000000000000000000000000000000000000..9c49c7763b92146e880c1b1827e85d197453d653 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/02_RedLock\347\256\227\346\263\225.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/02_zookeeper\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\345\234\272\346\231\257.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/02_zookeeper\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\345\234\272\346\231\257.png" new file mode 100644 index 0000000000000000000000000000000000000000..0842f6874fee451242d2182b8f43fc583f35925a Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/02_zookeeper\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\345\234\272\346\231\257.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/03_zookeeper\347\232\204\345\205\203\346\225\260\346\215\256_\351\205\215\347\275\256\347\256\241\347\220\206\345\234\272\346\231\257.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/03_zookeeper\347\232\204\345\205\203\346\225\260\346\215\256_\351\205\215\347\275\256\347\256\241\347\220\206\345\234\272\346\231\257.png" new file mode 100644 index 0000000000000000000000000000000000000000..82b2b406218c2528c1a2479921d8ed15047ee308 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/03_zookeeper\347\232\204\345\205\203\346\225\260\346\215\256_\351\205\215\347\275\256\347\256\241\347\220\206\345\234\272\346\231\257.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/03_zookeeper\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\345\216\237\347\220\206.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/03_zookeeper\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\345\216\237\347\220\206.png" new file mode 100644 index 0000000000000000000000000000000000000000..c1b1b05354c923acafbeb52efc852cb53ea14678 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/03_zookeeper\347\232\204\345\210\206\345\270\203\345\274\217\351\224\201\345\216\237\347\220\206.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/04_zookeeper\347\232\204HA\351\253\230\345\217\257\347\224\250\346\200\247\345\234\272\346\231\257.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/04_zookeeper\347\232\204HA\351\253\230\345\217\257\347\224\250\346\200\247\345\234\272\346\231\257.png" new file mode 100644 index 0000000000000000000000000000000000000000..cf6e1ae1209a9a6bf3f2ef5709358a25d3c4b5c6 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/7_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\345\271\202\347\255\211\346\200\247\344\270\216\351\241\272\345\272\217\346\200\247\345\217\212\345\210\206\345\270\203\345\274\217\351\224\201/images/04_zookeeper\347\232\204HA\351\253\230\345\217\257\347\224\250\346\200\247\345\234\272\346\231\257.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/8_\345\210\206\345\270\203\345\274\217Session\350\247\243\345\206\263\346\226\271\346\241\210/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/8_\345\210\206\345\270\203\345\274\217Session\350\247\243\345\206\263\346\226\271\346\241\210/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..9a3534356d58245fbf73044f279890987559a66f --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/8_\345\210\206\345\270\203\345\274\217Session\350\247\243\345\206\263\346\226\271\346\241\210/README.md" @@ -0,0 +1,192 @@ +# 分布式Session方案 + +## 什么是Session + +![01_分布式会话是什么](images/01_分布式会话是什么.png) + +session是啥?浏览器有个cookie,在一段时间内这个cookie都存在,然后每次发请求过来都带上一个特殊的jsessionid cookie,就根据这个东西,在服务端可以维护一个对应的session域,里面可以放点儿数据。 + +一般只要你没关掉浏览器,cookie还在,那么对应的那个session就在,但是cookie没了,session就没了。常见于什么购物车之类的东西,还有登录状态保存之类的。 + + 但是你单块系统的时候这么玩儿session没问题啊,但是你要是分布式系统了呢,那么多的服务,session状态在哪儿维护啊? + +其实方法很多,但是常见常用的是两种 + +## tomcat + redis + +这个其实还挺方便的,就是使用session的代码跟以前一样,还是基于tomcat原生的session支持即可,然后就是用一个叫做Tomcat RedisSessionManager的东西,让所有我们部署的tomcat都将session数据存储到redis即可。 + +在tomcat的配置文件中,配置一下 + + ``` + + + + ``` + +搞一个类似上面的配置即可,你看是不是就是用了RedisSessionManager,然后指定了redis的host和 port就ok了。 + + ``` + + + + ``` + +还可以用上面这种方式基于redis哨兵支持的redis高可用集群来保存session数据,都是ok的 + +但我们从Session获取数据,其实tomcat就是会从redis中获取到session了。 + +但是存在的问题,就是严重依赖于Web容器 + +## Spring Session + redis + +分布式会话的这个东西重耦合在tomcat中,如果我要将web容器迁移成jetty,难道你重新把jetty都配置一遍吗? + + 因为上面那种tomcat + redis的方式好用,但是会严重依赖于web容器,不好将代码移植到其他web容器上去,尤其是你要是换了技术栈咋整?比如换成了spring cloud或者是spring boot之类的。还得好好思忖思忖。 + + 所以现在比较好的还是基于java一站式解决方案,spring了。人家spring基本上包掉了大部分的我们需要使用的框架了,spirng cloud做微服务了,spring boot做脚手架了,所以用sping session是一个很好的选择。 + +### pom.xml + +``` + + + org.springframework.session + + spring-session-data-redis + + 1.2.1.RELEASE + + + + + + redis.clients + + jedis + + 2.8.1 + + +``` + +### spring配置文件 + +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +### web.xml + +``` + + + springSessionRepositoryFilter + + org.springframework.web.filter.DelegatingFilterProxy + + + + + + springSessionRepositoryFilter + + /* + + +``` + +### 示例代码 + +``` +@Controller + +@RequestMapping("/test") + +public class TestController { + + +@RequestMapping("/putIntoSession") + +@ResponseBody + + public String putIntoSession(HttpServletRequest request, String username){ + + request.getSession().setAttribute("name", “leo”); + + return "ok"; + + } + + + +@RequestMapping("/getFromSession") + +@ResponseBody + + public String getFromSession(HttpServletRequest request, Model model){ + + String name = request.getSession().getAttribute("name"); + + return name; + + } + +} +``` + +上面的代码就是ok的,给sping session配置基于redis来存储session数据,然后配置了一个spring session的过滤器,这样的话,session相关操作都会交给spring session来管了。接着在代码中,就用原生的session操作,就是直接基于spring sesion从redis中获取数据了。 + + 实现分布式的会话,有很多种很多种方式,我说的只不过比较常见的两种方式,tomcat + redis早期比较常用;近些年,重耦合到tomcat中去,通过spring session来实现。 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/8_\345\210\206\345\270\203\345\274\217Session\350\247\243\345\206\263\346\226\271\346\241\210/images/01_\345\210\206\345\270\203\345\274\217\344\274\232\350\257\235\346\230\257\344\273\200\344\271\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/8_\345\210\206\345\270\203\345\274\217Session\350\247\243\345\206\263\346\226\271\346\241\210/images/01_\345\210\206\345\270\203\345\274\217\344\274\232\350\257\235\346\230\257\344\273\200\344\271\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..820f96dae2297c153f70f8781669ebd0339e5fb4 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/8_\345\210\206\345\270\203\345\274\217Session\350\247\243\345\206\263\346\226\271\346\241\210/images/01_\345\210\206\345\270\203\345\274\217\344\274\232\350\257\235\346\230\257\344\273\200\344\271\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..753b86b9b145b8cb44bf0366303152763c2890bc --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/README.md" @@ -0,0 +1,309 @@ +# Spring中的事务 + +来源:https://www.bilibili.com/video/BV1EE411p7dD + +## 什么是事务 + +事务:是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作,这些操作作为一个整体像系统提交,要么都执行,要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元) + +通俗点说就是为了达到某个目的而做的一系列的操作要么一起成功(事务提交),要么一起失败(事务回滚) + +最常见的例子就是转账: + +小明给如花转账: + +``` +开启事务------- +① 从小明的账户扣除1000元 +② 给如花的账户增加1000元 +事务提交------- +``` + +从上面的例子的任何步骤一旦出现问题,都会导致事务回滚。 + +![image-20200503101957103](images/image-20200503101957103.png) + +从搭讪到结婚就是事务提交,女方要求男方重新追求她一次就是事务回滚~ + +## 事务的四大特征 + +ACID是事务的基本特征:口诀(一原持久隔离) + +- 原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。 +- 一致性(Consistency):事务执行后,数据库状态与其它业务规则保持一致,如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的 +- 隔离性(Isolation):隔离性指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。 +- 持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须保证通过某种机制恢复数据。 + +## 原生JDBC事务操作 + +``` +try { + // 设置是否自动提交 + connection.setAutoCommit(false) + + // 数据库操作 insert,update,delete + + connection.commit() +} catch(Exception ex) { + // 回滚 + connection.rollback() +} finally { + connection.setAutoCommit(true) +} +``` + +## 事务隔离级别 + +数据库事务的隔离级别有4中,由低到高分别是:`Read uncomomitted(读取未被提交的数据)`、`Read committed(读取以被提交的数据)`、`Repeatable read(可重复读)`、`Serializable(完全隔离)`。而且,在事务的并发操作中,可能出现脏读、不可重复读、幻读、事务丢失 + +### 四种隔离级别 + +#### Read UnCommitted + +读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据,会产生脏读 + +#### Read Committed + +`这种使用的概率比较高,因为很多时候我们就以最后一次读取的为准` + +读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据,会产生不可重复读。 + +#### Repeatable Read + +`相当于加锁,MySQL的默认级别` + +重复读,就是在开始读取数据(事务开启)时,不在允许修改操作,可能会产生幻读。 + +#### Serializable + +最高的事务隔离级别,在改级别下,事务串行化顺序执行,可以避免脏读,不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用 + +#### 总结 + +大多数数据库默认的事务隔离级别是:`Read Committed`,比如SqlServer,Oracle + +MySQL的默认隔离级别是Repeatable Read + +### 可能出现的问题 + +#### 脏读 + +`读取了未提交的新事务,然后被回滚了` + +事务A读取了事务B中尚未提交的数据,如果事务B回滚,则A读取使用了错误的数据 + +![image-20200503111507422](images/image-20200503111507422.png) + +#### 不可重复读 + +`读取了提交的新事物,指更新操作` + +不可重复读是指对于数据库中某个数据,一个事务范围内多次查询却反悔不同的数值,这是由于在查询间隔,被另一个事务修改并提交了 + +![image-20200503114507968](images/image-20200503114507968.png) + +解决不可重复读的一个解决方案,就是调整隔离级别。 + +#### 幻读 + +`读取了提交的新事物,指增删操作` + +在事务A多次读取构成中,事务B对数据进行了新增操作,导致事务A多次读取的数据不一致 + +![image-20200503114709457](images/image-20200503114709457.png) + +对于幻读的另外一个理解,可以为: + +`幻读就是指新增了数据记录条数,第一次查询数据记录数为1000,再次查询的时候,变成了1001,这个就是幻读` + +#### 不可重复读和幻读的区别 + +很多人容易搞混不可重复读和幻读,确实这两者有些相似。但不可重复读重点在于update和delete,而幻读的重点在于insert + +- 不可重复读, 只需要锁住满足条件的记录 `避免不可重复读需要锁行就行` +- 幻读 要锁住满足条件及其相近的记录 `避免幻读则需要锁表` + +所以说不可重复读和幻读最大的区别,就在于如何通过锁机制来解决他们产生的问题 + +## 事务丢失 + +### 第一类事务丢失 + +`称为:回滚丢失` + +对于第一类事务丢失,就是比如A和B同时在执行一个数据,然后B事务已经提交了,然后A事务回滚了,这样B事务的操作就因A事务回滚而丢失了。 + +![image-20200503115622743](images/image-20200503115622743.png) + +### 第二类事务丢失 + +`称为:覆盖丢失` + +对于第二类事务丢失,也称为覆盖丢失,就是A和B一起执行一个数据,两个同时取到一个数据,然后B事务首先提交,但是A事务接下来又提交,这样就覆盖了B事务 + +![image-20200503121151996](images/image-20200503121151996.png) + +## Spring怎么配置事务 + +`具体说出一些关键的xml元素` + +准备数据表: + +![image-20200503212336011](images/image-20200503212336011.png) + +实体类: + +``` +public class User { + private Integer id; + private String name; + private Integer money; +} +``` + +Dao: + +![image-20200503213406622](images/image-20200503213406622.png) + +Service:默认一个出错的场景 + +![image-20200503221133377](images/image-20200503221133377.png) + + + +### 编程式事务 + +XML配置事务:在applicationContext.xml中添加事务管理器和事务管理器模板的配置 + +![image-20200503222130639](images/image-20200503222130639.png) + +注解方式配置事务管理器和事务管理器模板 + +![image-20200503222459984](images/image-20200503222459984.png) + +### 声明式事务 + +`基于AspectJ XML方式` + +注:基于TransactionProxyFactoryBean,代理的方式是比较古老的方式,我们这里就不叙述了 + +删除applicationContext.xml中的事务管理模版的配置,就是下面的配置: + +``` + + + + +``` + +添加事务定义和AOP配置 + +``` + + + + + + + + + + + + + + + + +``` + +业务类改成原来的方式 + +``` +/** +* 沒有事務的转账的业务 +* @param fromName +* @param toName +* @param money +*/ +public void transfer(String fromName, String toName, Integer money) { + userDAO.out(fromName, money);// 转出钱 + int x = 10; + if(x == 10) + throw new RuntimeException("出错啦!"); + userDAO.in(toName, money);// 收入钱 +} +``` + +基于注解的申明式事务: +在配置类上配置@EnableTransactionManagement开启事务。删除注解类中和事务相关的@Bane + +在UserService类上方或者方法上方通过@Transactional完成事务配置: + +``` +@Service +@Transactional +public class UserService { + +} +``` + +申明式事务可以按照对应什么开头的方法 给配置事务 + +``` + + +``` + + + +### Spring事务传播特性 + +指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。举例子 + +``` +public class PersonService { + @Transactional + public void laoda(){ + System.out.println("老大的方法"); + xiaodi(); + } + @Transactional + public void xiaodi(){ + System.out.println("小弟方法"); + } +} +``` + +也就是当老大的方法,调用小弟的方法时,小弟的事务该怎么办? + +假设老大的方法出现异常,那么小弟的需不需要回滚? + +假设小弟的方法出现异常,那么老大的放法需不需要回滚? + +#### 死活不要事务的 + +- PROPAGATION_NEVER:没有就非事务执行,有就抛出异常 +- PROPAGATION_NOT_SUPPORTED:没有就非事务执行,有就直接挂起,然后非事务执行 + - 这个容易出现死锁 + +#### 可有可无的 + +- PROPAGATION_SUPPORTS: 有就用,没有就算了 + +#### 必须有事务的 + +- PROPAGATION_REQUIRES_NEW:有没有都新建事务,如果原来有,就将原来的挂起。也就是说事务之间完全隔离,一个事务不影响其它的事务 +- PROPAGATION_NESTED: 如果没有,就新建一个事务;如果有,就在当前事务中嵌套其他事务。嵌套事务就是外面的事务出异常,里面的事务全部回滚 +- PROPAGATION_REQUIRED: (默认的配置)如果没有,就新建一个事务;如果有,就加入当前事务 +- PROPAGATION_MANDATORY: 如果没有,就抛出异常;如果有,就使用当前事务。 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503101957103.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503101957103.png" new file mode 100644 index 0000000000000000000000000000000000000000..db241a0d04d6e5bb31a92541900f6d4596d2af90 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503101957103.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503111507422.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503111507422.png" new file mode 100644 index 0000000000000000000000000000000000000000..4171b298f01b95a55f48768994a3f1c92eb3757b Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503111507422.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503112154581.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503112154581.png" new file mode 100644 index 0000000000000000000000000000000000000000..58078687a6edaff3320bf910f42193ca1f361ff9 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503112154581.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503112529364.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503112529364.png" new file mode 100644 index 0000000000000000000000000000000000000000..728a094b764879ae52fb60449278624d4655d34e Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503112529364.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503114507968.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503114507968.png" new file mode 100644 index 0000000000000000000000000000000000000000..00e31314c79960bce65b608f45ec229bb1739baf Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503114507968.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503114709457.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503114709457.png" new file mode 100644 index 0000000000000000000000000000000000000000..8bc5bfcb283f7ecd1c511f1cb211ff472a386e3a Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503114709457.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503115622743.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503115622743.png" new file mode 100644 index 0000000000000000000000000000000000000000..ff2a14b24c7ae33c8545451e9d28ee49fd01a68d Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503115622743.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503121151996.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503121151996.png" new file mode 100644 index 0000000000000000000000000000000000000000..9b063ef2b4ce0362044e1adb3670e41cbb9a37d9 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503121151996.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503212336011.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503212336011.png" new file mode 100644 index 0000000000000000000000000000000000000000..9ee64e35052c107c44641915378f0ce50a540eff Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503212336011.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503213406622.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503213406622.png" new file mode 100644 index 0000000000000000000000000000000000000000..c8aea3602475503f7142d1447fa978f7235ae1e6 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503213406622.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503221133377.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503221133377.png" new file mode 100644 index 0000000000000000000000000000000000000000..c227d2d4aca33238a9519deb0b0624116fa171a6 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503221133377.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503222130639.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503222130639.png" new file mode 100644 index 0000000000000000000000000000000000000000..7b08a78de415bc15cc6dea81cec96776dd78ba31 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503222130639.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503222459984.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503222459984.png" new file mode 100644 index 0000000000000000000000000000000000000000..23054e143ac7095e96d8eeb88db4405e4f063630 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_Spring\344\270\255\347\232\204\344\272\213\345\212\241/images/image-20200503222459984.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..f5207a05dbd1fe96e41b1830c4659da876b444eb --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/README.md" @@ -0,0 +1,153 @@ +# 分布式事务解决方案 + +- 分布式事务了解吗 +- 你如何解决分布式事务问题 + - 两阶段提交方案/XA方案 + - TCC方案 + - 本地消费表 + - 可靠消息最终一致性方案 + - 最大努力通知方案 +- 公司如何处理分布式事务 + +## 分布式事务 + +只要聊到你做了分布式系统,必问分布式事务,你对分布式事务一无所知的话,确实会很坑,你起码得知道有哪些方案,一般怎么来做,每个方案的优缺点是什么。 + +现在面试,分布式系统成了标配,而分布式系统带来的分布式事务也成了标配了。因为你做系统肯定要用事务吧,那你用事务的话,分布式系统之后肯定要用分布式事务吧。先不说你搞过没有,起码你得明白有哪几种方案,每种方案可能有啥坑?比如TCC方案的网络问题、XA方案的一致性问题 + +### 单机系统下的事务 + +![01_单块系统里的事务](images/01_单块系统里的事务.png) + +### 分布式系统下的事务 + +![02_分布式系统里的事务](images/02_分布式系统里的事务.png) + + + +## 两阶段提交方案/XA方案 + + 也叫做两阶段提交事务方案,这个举个例子,比如说咱们公司里经常tb是吧(就是团建),然后一般会有个tb主席(就是负责组织团建的那个人)。 + +tb,team building,团建 + +第一个阶段,一般tb主席会提前一周问一下团队里的每个人,说,大家伙,下周六我们去滑雪+烧烤,去吗?这个时候tb主席开始等待每个人的回答,如果所有人都说ok,那么就可以决定一起去这次tb。如果这个阶段里,任何一个人回答说,我有事不去了,那么tb主席就会取消这次活动。 + +第二个阶段,那下周六大家就一起去滑雪+烧烤了 + +所以这个就是所谓的XA事务,两阶段提交,有一个事务管理器的概念,负责协调多个数据库(资源管理器)的事务,事务管理器先问问各个数据库你准备好了吗?如果每个数据库都回复ok,那么就正式提交事务,在各个数据库上执行操作;如果任何一个数据库回答不ok,那么就回滚事务。 + +这种分布式事务方案,比较适合单块应用里,跨多个库的分布式事务,而且因为严重依赖于数据库层面来搞定复杂的事务,效率很低,绝对不适合高并发的场景。如果要玩儿,那么基于spring + JTA就可以搞定,自己随便搜个demo看看就知道了。 + +![03_两阶段提交方案](images/03_两阶段提交方案.png) + +这个方案,我们很少用,一般来说某个系统内部如果出现跨多个库的这么一个操作,是不合规的。我可以给大家介绍一下, 现在微服务,一个大的系统分成几百个服务,几十个服务。一般来说,我们的规定和规范,是要求说每个服务只能操作自己对应的一个数据库。 + +如果你要操作别的服务对应的库,不允许直连别的服务的库,违反微服务架构的规范,你随便交叉胡乱访问,几百个服务的话,全体乱套,这样的一套服务是没法管理的,没法治理的,经常数据被别人改错,自己的库被别人写挂。 + +如果你要操作别人的服务的库,你必须是通过调用别的服务的接口来实现,绝对不允许你交叉访问别人的数据库! + +## TCC方案 + +TCC的全程是:Try、Confirm、Cancel。 + +这个其实是用到了补偿的概念,分为了三个阶段: + +- Try阶段:这个阶段说的是对各个服务的资源做检测以及对资源进行锁定或者预留 + +- Confirm阶段:这个阶段说的是在各个服务中执行实际的操作 + +- Cancel阶段:如果任何一个服务的业务方法执行出错,那么这里就需要进行补偿,就是执行已经执行成功的业务逻辑的回滚操作 + + +给大家举个例子吧,比如说跨银行转账的时候,要涉及到两个银行的分布式事务,如果用TCC方案来实现,思路是这样的: + +- Try阶段:先把两个银行账户中的资金给它冻结住就不让操作了 +- Confirm阶段:执行实际的转账操作,A银行账户的资金扣减,B银行账户的资金增加 +- Cancel阶段:如果任何一个银行的操作执行失败,那么就需要回滚进行补偿,就是比如A银行账户如果已经扣减了,但是B银行账户资金增加失败了,那么就得把A银行账户资金给加回去 + + +这种方案说实话几乎很少用人使用,我们用的也比较少,但是也有使用的场景。因为这个事务回滚实际上是严重依赖于你自己写代码来回滚和补偿了,会造成补偿代码巨大,非常之恶心。 + +比如说我们,一般来说跟钱相关的,跟钱打交道的,支付、交易相关的场景,我们会用TCC,严格严格保证分布式事务要么全部成功,要么全部自动回滚,严格保证资金的正确性,在资金上出现问题 + +比较适合的场景:这个就是除非你是真的一致性要求太高,是你系统中核心之核心的场景,比如常见的就是资金类的场景,那你可以用TCC方案了,自己编写大量的业务逻辑,自己判断一个事务中的各个环节是否ok,不ok就执行补偿/回滚代码。 + +而且最好是你的各个业务执行的时间都比较短。 + +但是说实话,一般尽量别这么搞,自己手写回滚逻辑,或者是补偿逻辑,实在太复杂了,那个业务代码很难维护。 + +![04_TCC方案](images/04_TCC方案.png) + +## 本地消费表 + +这个大概意思是这样的 + +- A系统在自己本地一个事务里操作同时,插入一条数据到消息表 +- 接着A系统将这个消息发送到MQ中去 +- B系统接收到消息之后,在一个事务里,往自己本地消息表里插入一条数据,同时执行其他的业务操作,如果这个消息已经被处理过了,那么此时这个事务会回滚,这样保证不会重复处理消息 +- B系统执行成功之后,就会更新自己本地消息表的状态以及A系统消息表的状态 +- 如果B系统处理失败了,那么就不会更新消息表状态,那么此时A系统会定时扫描自己的消息表,如果有没处理的消息,会再次发送到MQ中去,让B再次处理 +- 这个方案保证了最终一致性,哪怕B事务失败了,但是A会不断重发消息,直到B那边成功为止 + +这个方案说实话最大的问题就在于严重依赖于数据库的消息表来管理事务啥的???这个会导致如果是高并发场景咋办呢?咋扩展呢?所以一般确实很少用![05_本地消息表方案](images/05_本地消息表方案.png) + +## 可靠消息最终一致性方案 + +这个的意思,就是干脆不要用本地的消息表了,直接基于MQ来实现事务。比如阿里的RocketMQ就支持消息事务。 + +大概的意思就是: + +- A系统先发送一个prepared消息到mq,如果这个prepared消息发送失败那么就直接取消操作别执行了 +- 如果这个消息发送成功过了,那么接着执行本地事务,如果成功就告诉mq发送确认消息,如果失败就告诉mq回滚消息 +- 如果发送了确认消息,那么此时B系统会接收到确认消息,然后执行本地的事务 +- mq会自动定时轮询所有prepared消息回调你的接口,问你,这个消息是不是本地事务处理失败了,所有没发送确认消息?那是继续重试还是回滚?一般来说这里你就可以查下数据库看之前本地事务是否执行,如果回滚了,那么这里也回滚吧。这个就是避免可能本地事务执行成功了,别确认消息发送失败了。 +- 这个方案里,要是系统B的事务失败了咋办?重试咯,自动不断重试直到成功,如果实在是不行,要么就是针对重要的资金类业务进行回滚,比如B系统本地回滚后,想办法通知系统A也回滚;或者是发送报警由人工来手工回滚和补偿 + +这个还是比较合适的,目前国内互联网公司大都是这么玩儿的,要不你举用RocketMQ支持的,要不你就自己基于类似ActiveMQ?RabbitMQ?自己封装一套类似的逻辑出来,总之思路就是这样子的![06_可靠消息最终一致性方案](images/06_可靠消息最终一致性方案.png) + +最终一致性的解决方案:就是生产把消息发送到消息队列中,然后消息队列对消息进行持久化操作,但消费者没有进行处理的时候,就会不断的重试,知道最终处理完成,这就保证了一致性。 + +## 最大努力通知方案 + +这个方案的大致意思就是: + +- 系统A本地事务执行完之后,发送个消息到MQ + +- 这里会有个专门消费MQ的最大努力通知服务,这个服务会消费MQ然后写入数据库中记录下来,或者是放入个内存队列也可以,接着调用系统B的接口 + +- 要是系统B执行成功就ok了;要是系统B执行失败了,那么最大努力通知服务就定时尝试重新调用系统B,反复N次,最后还是不行就放弃 + + ![07_最大努力通知方案](images/07_最大努力通知方案.png) + + + +可以在一定程度上允许是少数的分布式事务失败,一般用在对分布式要求不严格的情况下,比如说记录日志或状态 + +## 公司如何处理分布式事务 + +我们某某特别严格的场景,用的是TCC来保证强一致性;然后其他的一些场景基于了阿里的RocketMQ来实现了分布式事务。你找一个严格资金要求绝对不能错的场景,你可以说你是用的TCC方案;如果是一般的分布式事务场景,订单插入之后要调用库存服务更新库存,库存数据没有资金那么的敏感,可以用可靠消息最终一致性方案 + + 友情提示一下,rocketmq 3.2.6之前的版本,是可以按照上面的思路来的,但是之后接口做了一些改变,我这里不再赘述了。 + + 当然如果你愿意,你可以参考可靠消息最终一致性方案来自己实现一套分布式事务,比如基于rabbitmq来玩儿。 + + + +老师,我们现在想保证我们的某个系统非常的可靠,任何一个数据都不能错,我们用的是微服务架构,几十个服务。结果我们一盘点,发现,如果到处都要搞的话,一个系统要做几十个分布式事务出来。 + + 我们的经验,我带几十人的team,最大的一个项目,起码几百个服务,复杂的分布式大型系统,里面其实也没几个分布式事务。 + + 你其实用任何一个分布式事务的这么一个方案,都会导致你那块儿代码会复杂10倍。很多情况下,系统A调用系统B、系统C、系统D,我们可能根本就不做分布式事务。如果调用报错会打印异常日志。 + + 每个月也就那么几个bug,很多bug是功能性的,体验性的,真的是涉及到数据层面的一些bug,一个月就几个,两三个?如果你为了确保系统自动保证数据100%不能错,上了几十个分布式事务,代码太复杂;性能太差,系统吞吐量、性能大幅度下跌。 + + 99%的分布式接口调用,不要做分布式事务,直接就是监控(发邮件、发短信)、记录日志(一旦出错,完整的日志)、事后快速的定位、排查和出解决方案、修复数据。 + +每个月,每隔几个月,都会对少量的因为代码bug,导致出错的数据,进行人工的修复数据,自己临时动手写个程序,可能要补一些数据,可能要删除一些数据,可能要修改一些字段的值。 + + 比你做50个分布式事务,成本要来的低上百倍,低几十倍 + + trade off,权衡,要用分布式事务的时候,一定是有成本,代码会很复杂,开发很长时间,性能和吞吐量下跌,系统更加复杂更加脆弱反而更加容易出bug;好处,如果做好了,TCC、可靠消息最终一致性方案,一定可以100%保证你那快数据不会出错。 + + 1%,0.1%,0.01%的业务,资金、交易、订单,我们会用分布式事务方案来保证,会员积分、优惠券、商品信息,其实不要这么搞了 \ No newline at end of file diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/01_\345\215\225\345\235\227\347\263\273\347\273\237\351\207\214\347\232\204\344\272\213\345\212\241.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/01_\345\215\225\345\235\227\347\263\273\347\273\237\351\207\214\347\232\204\344\272\213\345\212\241.png" new file mode 100644 index 0000000000000000000000000000000000000000..a622b80598446e9443dc5bcf0fe1126a851df82b Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/01_\345\215\225\345\235\227\347\263\273\347\273\237\351\207\214\347\232\204\344\272\213\345\212\241.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/02_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\351\207\214\347\232\204\344\272\213\345\212\241.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/02_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\351\207\214\347\232\204\344\272\213\345\212\241.png" new file mode 100644 index 0000000000000000000000000000000000000000..9338e051acf1a002e5fb6b5f89df59d312b82a55 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/02_\345\210\206\345\270\203\345\274\217\347\263\273\347\273\237\351\207\214\347\232\204\344\272\213\345\212\241.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/03_\344\270\244\351\230\266\346\256\265\346\217\220\344\272\244\346\226\271\346\241\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/03_\344\270\244\351\230\266\346\256\265\346\217\220\344\272\244\346\226\271\346\241\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..8d6e1050a26f593de6c31dbd426a9c2c8dfbe614 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/03_\344\270\244\351\230\266\346\256\265\346\217\220\344\272\244\346\226\271\346\241\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/04_TCC\346\226\271\346\241\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/04_TCC\346\226\271\346\241\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..d8b64243ae57dc51d2399531a21795425f146381 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/04_TCC\346\226\271\346\241\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/05_\346\234\254\345\234\260\346\266\210\346\201\257\350\241\250\346\226\271\346\241\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/05_\346\234\254\345\234\260\346\266\210\346\201\257\350\241\250\346\226\271\346\241\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..597e5d11a718d3383ee5019dea2e013dc9091783 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/05_\346\234\254\345\234\260\346\266\210\346\201\257\350\241\250\346\226\271\346\241\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/06_\345\217\257\351\235\240\346\266\210\346\201\257\346\234\200\347\273\210\344\270\200\350\207\264\346\200\247\346\226\271\346\241\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/06_\345\217\257\351\235\240\346\266\210\346\201\257\346\234\200\347\273\210\344\270\200\350\207\264\346\200\247\346\226\271\346\241\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..7c8c2c7144e8d9dfaa80b8af9bf1e31ebaea536a Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/06_\345\217\257\351\235\240\346\266\210\346\201\257\346\234\200\347\273\210\344\270\200\350\207\264\346\200\247\346\226\271\346\241\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/07_\346\234\200\345\244\247\345\212\252\345\212\233\351\200\232\347\237\245\346\226\271\346\241\210.png" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/07_\346\234\200\345\244\247\345\212\252\345\212\233\351\200\232\347\237\245\346\226\271\346\241\210.png" new file mode 100644 index 0000000000000000000000000000000000000000..989c81853678f198bc82ee763e527717355afd57 Binary files /dev/null and "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/9_\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\350\247\243\345\206\263\346\226\271\346\241\210/images/07_\346\234\200\345\244\247\345\212\252\345\212\233\351\200\232\347\237\245\346\226\271\346\241\210.png" differ diff --git "a/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/README.md" "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..4abbcd3ecc4701b4239253e729ae3e1547639d48 --- /dev/null +++ "b/\346\240\241\346\213\233\351\235\242\350\257\225/\351\235\242\350\257\225\346\211\253\347\233\262\345\255\246\344\271\240/README.md" @@ -0,0 +1,16 @@ +## 中间件 + +>来源Bilibili中华石杉老师学习视频:[Java工程师面试突击](https://www.bilibili.com/video/BV1UJ411X7M1) + +- [消息队列的面试连环炮](./1_消息队列的面试连环炮)  [传送门](http://www.moguit.cn/#/info?blogUid=f0860e8c55a378eca6ff1d25d7949c59) +- [分布式搜索引擎的面试连环炮](./2_分布式搜索引擎的面试连环炮)  [传送门](http://www.moguit.cn/#/info?blogUid=83c9c2b73ab286e5239923513553b897) +- [分布式缓存](./3_分布式缓存) +- [Redis的面试连环炮](./4_Redis的面试连环炮)  [传送门](http://www.moguit.cn/#/info?blogUid=91cb882ae856366b60cd8f0017e0c17f) +- [Redis的面试连环炮2](./5_Redis的面试连环炮2)  [传送门](http://www.moguit.cn/#/info?blogUid=68020f4cff4a2028253440b34c5e079b) +- [分布式系统的面试连环炮](./6_分布式系统的面试连环炮)  [传送门](http://www.moguit.cn/#/info?blogUid=b1fe926b5a626abf25d0df6d173e2d37) +- [分布式系统幂等性与顺序性及分布式锁](./7_分布式系统幂等性与顺序性及分布式锁)   [传送门](http://www.moguit.cn/#/info?blogUid=b1fe926b5a626abf25d0df6d173e2d37) +- [分布式Session解决方案](./8_分布式Session解决方案)  [传送门](http://www.moguit.cn/#/info?blogUid=33e8b256524b8fdb7963516befe369d5) +- [Spring中的事务](./9_Spring中的事务)  [传送门](http://www.moguit.cn/#/info?blogUid=471e9c19a8ca4efd41a6b1ec89b0b693) +- [设计一个高并发系统](./10_设计一个高并发系统)  [传送门](http://www.moguit.cn/#/info?blogUid=0b24643d8a538eb9a996e62d2aba5aa9) +- [数据库分库分表的面试连环炮](./11_数据库分库分表的面试连环炮)  [传送门](http://www.moguit.cn/#/info?blogUid=35b290e228106bea20ba9cd93408abe9) +- [MySQL读写复制及主从同步时延](./12_MySQL读写复制及主从同步时延) \ No newline at end of file diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/1_\344\270\211\346\254\241\346\217\241\346\211\213\345\222\214\345\233\233\346\254\241\346\214\245\346\211\213/README.md" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/1_\344\270\211\346\254\241\346\217\241\346\211\213\345\222\214\345\233\233\346\254\241\346\214\245\346\211\213/README.md" index d8cad2abd3fe9853edbd71695080c7c64e806e1a..87cabb838550f7a7e4680ac7f8a0984bcdb5465c 100644 --- "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/1_\344\270\211\346\254\241\346\217\241\346\211\213\345\222\214\345\233\233\346\254\241\346\214\245\346\211\213/README.md" +++ "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/1_\344\270\211\346\254\241\346\217\241\346\211\213\345\222\214\345\233\233\346\254\241\346\214\245\346\211\213/README.md" @@ -32,12 +32,14 @@ TCP建立连接的过程:被称为握手 - SYN = 1:表示该报文不能携带数据,但是需要消耗一个SEQ(序号),可以想象成我们对消息编号 - seq:TCP的每个字节发送的时候,都有一个序号,主要是为了保证可靠性,比如当我服务器通过TCP报文得到了有N个字节需要接受,但是最后只接受到了N-1个,我们通过序号就知道哪个没有被接收到。 +- 客户端进入SYN_SENT状态,即同步已发送 ② 当服务器接受到我们的握手请求时,会回复一个确认报文 - SYN:表示不携带数据,同时消耗一个SEQ = y(这里的y是任意数字,可以是1,2,3,4) - ACK:=1 表示这是一条确定报文 - ack:x+1,其中x是刚刚客户端发送过来的 +- 服务器进入SYN_RECVD状态,即同步已收到 ③ 当客户端收到确认报文的时候,客户端需要对这个确认报文进行回复 @@ -85,6 +87,42 @@ TCP建立连接的过程:被称为握手 ## 四次挥手 +所谓的四次挥手,就是关闭TCP连接的过程,指的是断开一个TPC连接,需要客户端和服务端总共发送4个包,以确定双方连接的断开。 + +主要目的:保证TCP连接的全双工连接 + +### 四次挥手示意图 + +![img](images/20181120162254477.png) + +由于TCP连接是全双工的,因此每个方向都必须单独关闭,这个原则是当以防完成它的数据发送任务后,就能发送一个FIN包来终止这个方向的连接。 + +收到一个FIN包只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后,仍然能发送数据,首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。 + +### 四次挥手过程 + +- **第一次挥手**:客户端发送一个FIN包(FIN=1,seq=U)给服务器,用来关闭客户端到服务器端的数据传输,客户端进入FIN_WAIT_1状态(终止等待) +- **第二次挥手**:服务器端收到FIN包后,发送一个ACK包(ACK=1,ack=u+1,在随机产生一个值v 给seq)给客户端,服务器进入了CLOSE_WAIT状态(关闭等待) +- **第三次挥手**:服务器端发送一个FIN包(FIN=1,ACK=1,ack=u+1,在随机产生 一个w值给seq)给客户端,用来关闭服务器到客户端的数据传输,服务端进入了LAST_ACK(最后确定)状态 +- **第四次挥手**:客户端接收FIN包,然后进入TIME_WAIT状态,接着发送一个ACK包(ACK=1,seq=u+1, ack = w+1) 给服务端,服务端确定序号,进入CLOSe状态,完成了四次挥手。 + +### 挥手中的状态 + +- CLOSED:表示初始状态 +- ESTABLISHED:表示连接已经连接 +- FIN_WAIT:状态FIN_WAIT_1和FIN_WAIT_2都表示等待对方的FIN报文,这两个状态的区别是,当主动发送方给对方发送了断开请求时,就进入了FIN_WAIT_1状态,而到被动方在回应后,主动发送方就进入了FIN_WAIT_2。 +- **FIN_WAIT_2**:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接 +- CLOSE_WAIT:这个状态的含义是 表示在等待关闭 +- LAST_ACK:在被动关闭放发送FIN报文后,最后等待对方的ACK报文,当收到了ACK报文后,就进入了CLOSE状态。 + +### 为什么TIME_WAIT状态还需要等待2MSL后才能返回CLOSE + +这是因为虽然双方都同意了关闭连接,而且握手的4个报文也都协调和发送完毕,按道理可以直接回到CLOSE状态 + +但是因为我们需要假设网络是不可靠的,你无法保证你最后发送的ACK报文是会一定被对方收到,因此处于LAST_ACK状态下的socket可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的报文。 + +### 中国机长版四次挥手 + 当客户端与服务器在规定的时间内没有得到应答 会发送报文进行探测,假设没有应答,那么就会关闭连接 diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/1_\344\270\211\346\254\241\346\217\241\346\211\213\345\222\214\345\233\233\346\254\241\346\214\245\346\211\213/images/20181120162254477.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/1_\344\270\211\346\254\241\346\217\241\346\211\213\345\222\214\345\233\233\346\254\241\346\214\245\346\211\213/images/20181120162254477.png" new file mode 100644 index 0000000000000000000000000000000000000000..40e81345116267f49fbe0f869104f3174456b66b Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/1_\344\270\211\346\254\241\346\217\241\346\211\213\345\222\214\345\233\233\346\254\241\346\214\245\346\211\213/images/20181120162254477.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/README.md" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..7ae98fde081dd8e84ab1235fcd8c246b3ff19582 --- /dev/null +++ "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/README.md" @@ -0,0 +1,91 @@ +# TCP中的流量控制和拥塞控制 + +## 流量控制 + +### 什么是流量控制 + +如果发送者发送数据过快,接收者来不及接收,那么就会出现分组丢失,为了避免分组丢失,控制发送者的发送速度,使得接收者来得及接收,这就是流量控制。 + +流量控制的目的是:防止分组丢失,是构成TCP可靠性的一方面。 + +### 如何实现流量控制 + +由滑动窗口协议(连续ARQ协议)实现,滑动窗口协议即保证了分组无差错,有序接收,也实现了流量控制。主要的方式就是接收方返回的ACK会包含自己的接受窗口大小,并利用大小来控制发送方的数据发送。 + +## 拥塞控制 + +### 什么是拥塞控制 + +拥塞控制是作用于网络的,它是防止过多的数据注入网络,避免出现网络负载过大的情况,常见的方法就是 + +- 慢开始,避免拥塞 +- 快重传、快恢复 + +### 拥塞控制算法 + +我们首先添加几个限定条件 + +- 数据是单方向传递,另一个窗口只发送确认 +- 接收方的缓存足够大,因此发送方的大小由网络的拥塞程度来决定 + +#### 慢开始算法 + +发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量,拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化,发送方让自己的发送窗口等于拥塞窗口,另外考虑到接收方的接受能力,发送窗口可能小于拥塞窗口。 + +慢开始算法的思路就是:不要一开始就发送大量的数据,先测探一下网络的拥塞程度,也就是说从小到大主键增加拥塞窗口的大小。 + +这里用报文段的个数作为拥塞窗口的大小举例说明慢开始算法,实际的拥塞窗口大小是以字节为单位的。如下图所示: + +![image-20200623214100440](images/image-20200623214100440.png) + +> 发送方没收到一个确认窗口,就把窗口cwnd加1 + +从上图可以看到,一个传输轮次所经历的时间其实就是往返时间RTT,而且每经过一个传输轮次,拥塞窗口cwnd就加倍 + +为了防止cwnd增长过大引起网络拥塞,还需设置一个慢开始门限ssthresh状态变量,ssthresh的用法如下: + +- 当 cwnd > ssthresh时:使用慢开始算法 +- 当cwnd = ssthresh时:采用 慢开始或拥塞避免中的任意一种 +- 当 cwnd > ssthresh时:采用拥塞避免算法 + +#### 拥塞避免算法 + +拥塞避免算法让拥塞窗口缓慢增长,即没经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍,这样能够让拥塞窗口按线性规律增长。 + +无论是在慢开始阶段,还是在拥塞控制阶段,只要发送方判断网络出现拥塞,就把慢开始门限 ssthressh设置为当前出现拥塞时发送窗口大小的一半(不能小于2),然后将拥塞窗口cwnd设置为1,执行慢开始算法。 + +这样做的目的是迅速减少主机发送到网络中的分组数,使得发送拥塞的路由器有足够时间把队列中积压的分组处理完毕。 + +整个拥塞控制的流程图如下图所示: + +![image-20200623220009542](images/image-20200623220009542.png) + +- 拥塞窗口cwnd初始化为1个报文段,慢开始门限初始值为16 +- 执行慢开始算法,指数规律增长到第4轮,即cwnd=16=ssthresh,改为执行拥塞避免算法,拥塞窗口按线性规律增长 +- 假定cwnd=24时,网络出现超时(拥塞),则更新后的ssthresh=12,cwnd重新设置为1,并执行慢开始算法。当cwnd=12=ssthresh时,改为执行拥塞避免算法 + +**乘法减小和加法增大** + +- 乘法减小”指的是无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞,就把慢开始门限ssthresh设置为出现拥塞时的发送窗口大小的一半,并执行慢开始算法,所以当网络频繁出现拥塞时,ssthresh下降的很快,以大大减少注入到网络中的分组数。 +- 加法增大”是指执行拥塞避免算法后,使拥塞窗口缓慢增大,以防止过早出现拥塞。常合起来成为AIMD算法。 + +#### 快重传算法 + +快重传要求接收方在收到一个失序的报文段后,就立即发出重复确定(为的是使发送方及早知道有报文段没有达到对方,可提高网络吞吐量约20%)而不要等到自己发送数据时捎带确定。快重传算法规定,发送方只要一连收到三个重复确定就应当立即重传对方尚为收到的报文段,而不必继续等待设置的重传计时器时间到期,如下所示 + +![image-20200623221705052](images/image-20200623221705052.png) + +#### 快恢复 + +快重传配合使用的还有快恢复算法,有以下两点要求 + +- 当发送方连续收到三个重复确认时,就执行乘法减小算法,把ssthresh门限减半(为了预防发送拥塞),但是接下来并不执行慢开始算法 +- 考虑到如果网络出现拥塞的话,就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞,所以此时不执行慢开始算法,而是将cwnd设置为ssthresh减半后的值,然后执行拥塞避免算法,使cwnd缓慢增大,如下图所示:TCP Reno版本是目前使用最广泛的版本。 + +![image-20200623222155538](images/image-20200623222155538.png) + +> 在采用快恢复算法时,慢开始算法只是在TCP连接建立时和网络出现超时时才使用 + +## 来源 + +https://zhuanlan.zhihu.com/p/37379780 \ No newline at end of file diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/images/image-20200623214100440.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/images/image-20200623214100440.png" new file mode 100644 index 0000000000000000000000000000000000000000..50a482787f4bef0fc51c9cb667a4849fbca65ce7 Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/images/image-20200623214100440.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/images/image-20200623220009542.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/images/image-20200623220009542.png" new file mode 100644 index 0000000000000000000000000000000000000000..e09fe29a0aab6352e4ce6d17b57fe3be6772b175 Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/images/image-20200623220009542.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/images/image-20200623221705052.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/images/image-20200623221705052.png" new file mode 100644 index 0000000000000000000000000000000000000000..4c85af50bfb337dc8dea7f961aa2c88eda83db1c Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/images/image-20200623221705052.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/images/image-20200623222155538.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/images/image-20200623222155538.png" new file mode 100644 index 0000000000000000000000000000000000000000..d1af88f1be5e7c9a8cb997b31a5ff0126fed085e Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/3_TCP\344\270\255\347\232\204\346\213\245\345\241\236\346\216\247\345\210\266\345\222\214\346\265\201\351\207\217\346\216\247\345\210\266/images/image-20200623222155538.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/README.md" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..c6205845396576d94eba6e674562c369021aa7e9 --- /dev/null +++ "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/README.md" @@ -0,0 +1,160 @@ +# 计算机网络分层结构 - 物理层 + +## 两种分层结构 + +### OSI体系结构 + +- 应用层 +- 表示层 +- 会话层 +- 运输层 +- 网络层 +- 数据链路层 +- 物理层 + +### TCP/IP体系结构 + +- 应用层 +- 运输层(TCP、UDP) +- 网络层(IP) +- 数据链路层 +- 物理层 + + + +## 物理层 + +### 基本概念 + +物理层解决如何在连接各种计算机的传输媒体上传输数据比特流,而不是指具体的传输媒体,尽可能的屏蔽掉传输媒体和通信手段的差异。 + +物理层的主要任务描述为:确定传输媒体的接口的一些特性 + +- 机械特性:接口形状,引线数目 +- 电气特性:规定电压的范围(-5V 到 +5V) +- 功能特性:例:规定 -5V表示0,+5V表示1 +- 过程特性:各个相关部件的工作步骤 + +### 数据通信模型 + +![image-20200627152502661](images/image-20200627152502661.png) + +### 与通信相关的术语 + +- 数据:运送消息的实体 +- 信号:数据电器或电磁的表现 + - 模拟信号:代表消息的参数的取值是连续的 + - 数字信息:代表消息的参数的取值是离散的 +- 码元:在使用时间域的波形表示数字信号时,则代表不同离散数值的基本波形就成为了码元 + +### 有关信道的基本概念 + +信道一般表示向一个方向上传递信息的媒体,我们平时说的通信线路往往包含一条发送信息的信道和一个接受信息的信道 + +- 单工通道:只有一个方向上的通信,而没有反方向的交互 +- 半双工通信:不能同时发送,只能一个发送,一个接受(例如:对讲机) +- 全双工通信:通信双方可以同时发送和接受(例如:手机) + +### 基带信号和带通信号 + +- 基带信号:来自信源的信号 +- 带通信号:是通过将基带信号进行载波调制后,把信号的频率搬到较高的频段 + +对基带信号的几种调制方式:调幅、调频、调相 + +### 曼切斯特编码 + + + +![image-20200627154025723](images/image-20200627154025723.png) + +利用曼彻斯特编码,一个时钟周期只可以表示一个bit,并且必须通过两次采样才能得到一个bit,但它能携带时钟信号,且可表示没有数据传输 + +### 差分曼彻斯特编码 + +![image-20200627154623354](images/image-20200627154623354.png) + +- bit中间有信号跳变,bit与bit之间也有信号跳变,表示下一个bit为 0 +- bit中间有信号跳变,bit与bit之间没有信号跳变,表示下一个bit为 1 + +差分曼切斯特编码和曼彻斯特编码相同,但是抗干扰性强于曼切斯特编码,例如 + +![image-20200627155008442](images/image-20200627155008442.png) + +### 信道极限容量 + +#### 奈氏准则 + +任何信道中,码元的传输速率是有上限的,否则就会出现码间串扰的问题,使得接收端对码元的判决成为不可能。 + +#### 信噪比:香农定理 + +香农用信息论的理论,推导出带宽首先且有高斯白噪声干扰的信道的极限,无差错的信息传输速率 + +信道的极限信息传输传输速度 $c$ 可以表示为 +$$ +c=w \log _{2}(1 + s / N) \quad b / s (有噪声干扰的传输速率) +$$ +其中: + +- w:信道的带宽,以HZ为单位 +- S:信道内所传信号的平均功率 +- N:信道内部的高斯噪声功率 + +**结论**:香农公式表明,信道的带宽或信道内 的信噪比越大,则信息的极限传输速率就越高。 + +### 物理层下面的传输媒体 + +- 导向传输媒体:导向传输媒体中,电磁波沿着固体媒体传播 + - 屏蔽双绞线:STP + - 非屏蔽双绞线:UTP + - 同轴电缆:有线电视 + - 光缆 +- 非导向传播媒体:无线传输 + +其中,我们常常说的网线,就是双绞线。 + +![image-20200627155959991](images/image-20200627155959991.png) + +10M 和 100M带宽的网络,只需要使用 1,2,3,6 四根线 + +而 1000M带宽的网络,8根线都需要使用 + +### 信道复用技术 + +信道复用指的就是多个用户共用同一信道进行传输 + +#### 频分复用 + +用户 分配到一定的频带后,在通信过程中自始至终都占用这个频带,频分复用的所有用户在同样的时间,占用不同的带宽资源 + +![image-20200627160528043](images/image-20200627160528043.png) + +#### 时分复用 + +时分复用,指的是每个数据占用一个时间片,时分复用可能会导致线路资源的浪费 + +![image-20200627160623176](images/image-20200627160623176.png) + +#### 波分复用 + +波分复用就是光的频分复用 + +![image-20200627160651311](images/image-20200627160651311.png) + +#### 数字传输系统 + +主要用于广域网上的传输,脉码调制PCM体制最初是为了在电话局之间的中继线上传送多路的电话,由于历史的原因,PCM有两个互不兼容的国际标准: + +- 欧洲标准:(EI),我国目前采用广度 +- 北美标准:(TI) + +#### 宽带接入技术 + +- XDSL:用数字技术对现有的模拟电话用户线进行改造 + - 电话信号频率:300~3400HZ + - 然后把更高频率用于用户上网,使用的就是频分复用技术 +- DMT技术:把更多的信道用于下行,少数信道用户上行 + - 这是因为上传流量远远小于下载流量 + +![image-20200627161209527](images/image-20200627161209527.png) \ No newline at end of file diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627152502661.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627152502661.png" new file mode 100644 index 0000000000000000000000000000000000000000..3e95424d668f7e5b1f1ec905df7e698d918bb30f Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627152502661.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627154025723.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627154025723.png" new file mode 100644 index 0000000000000000000000000000000000000000..0805f015a6f3d2f462fdfdcf8e76b7761e9085f9 Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627154025723.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627154623354.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627154623354.png" new file mode 100644 index 0000000000000000000000000000000000000000..cc3e4e506ada41343f66073bb64ea41392583012 Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627154623354.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627155008442.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627155008442.png" new file mode 100644 index 0000000000000000000000000000000000000000..ce12fd6c5bc653881d14505cd16fc22616c1deff Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627155008442.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627155959991.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627155959991.png" new file mode 100644 index 0000000000000000000000000000000000000000..ba23f50acc3ba7b82e865f3e107538c8ddc542a4 Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627155959991.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627160528043.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627160528043.png" new file mode 100644 index 0000000000000000000000000000000000000000..7c5cef2ab4c007f85260d2cbeb385520b87a2092 Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627160528043.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627160623176.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627160623176.png" new file mode 100644 index 0000000000000000000000000000000000000000..301780786314b335304860f5315f7cadc2ba1d0d Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627160623176.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627160651311.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627160651311.png" new file mode 100644 index 0000000000000000000000000000000000000000..94ab84267bf77dc42f9816283180c808b4a816b3 Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627160651311.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627161209527.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627161209527.png" new file mode 100644 index 0000000000000000000000000000000000000000..c11031734b731a1ccd2690ed43d36741321b8565 Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/4_\347\211\251\347\220\206\345\261\202/images/image-20200627161209527.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/README.md" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..75269be33ca99fe5bdfee13a0e79d4e09da4eee8 --- /dev/null +++ "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/README.md" @@ -0,0 +1,157 @@ +# 数据链路层 + +## 链路和数据链路 + +### 链路 + +一条点到点的物理线路段,中间没有其它的交换节点,一条链路只是一条通路的一个组成部分 + +### 数据链路 + +除物理链路外,还必须有通信协议来控制这些数据的传输,若把实现这些协议的硬件和软件加到链路上,就构成了数据链路。现常见的方法就是使用适配器(网卡)来实现这些协议的硬件和软件。 + +数据链路层相当于一个管道,传输的是一条条的帧信息 + +![image-20200627162011689](images/image-20200627162011689.png) + +## 数据链路层的主要功能 + +- 封装成帧 +- 透明传输 +- 差错控制 + +## 封装成帧 + +封装成帧就是一段数据的前后分别添加首部和尾部,然后构成一个帧,确定帧的界限 + +首部和尾部的一个重要作用就是进行帧定界 + +![image-20200627162616750](images/image-20200627162616750.png) + +下图是使用控制字符进行帧定界的方法举例 + +![image-20200627162720414](images/image-20200627162720414.png) + +若帧数据部分有 开始标记 和 结束标记怎么办? + +发送端的数据链路层在数据中出现控制字符 “SOH” 或 “EOT”的前面插入一个转移字符 “ESC” + +这个时候就需要用到字节填充 或 字符填充,也就是接收端的数据链路层在数据送往网络层之间删除插入的转义字符。 + +如果转移字符也出现在数据中,那么应该在转义字符的前面在插入一个转义字符。当接收端连续收到两个转义字符的时候,就删除掉前面的一个 + +![image-20200627163044943](images/image-20200627163044943.png) + +## 差错控制 + +传输的过程中可能会产生比特差错,1可能变成0,而0也可能变成1。 + +在一段时间内,传输错误的比特占所传输比特总数的比率称为 误码率 BER(Bit error Rate),其中误码率和信噪比有很大的关系。 + +### CPC循环冗余检验 + +CRC是一种常用的检错方法,而FCS是添加在数据后面的冗余码 + +FCS可以用CRC这种方法得出,并且CRC是用来获取FCS的唯一方法 + +![image-20200627164926128](images/image-20200627164926128.png) + +我们得到 FCS后,将其拼接到我们传送数据的末端 + +![image-20200627164944182](images/image-20200627164944182.png) + +接收端对收到的每一帧进行CRC检验 + +- 若得出的余数 R = 0,则判定这个帧没有差错,就接受 +- 若余数不为0,则判定有差错,丢弃 + +特点 + +- 这种差错检测的方法不能确定是哪一位出现了问题 +- 只需使用足够的余数,就能检测出来 + +## 两种情况的数据链路 + +- 点到点:PPP协议(全世界使用最多的),只实现无差错接收 +- 零比特填充:5个连续的1,后面添加一个0 + +## 局域网的拓扑结构 + +![image-20200627181830249](images/image-20200627181830249.png) + +## CSMA/CD + +- 多点接入:表示许多计算机以多点接入的方式连接在一根总线上 +- 载波监听:是指每一站在发送数据之前,先检测一下总线上是否有其它数据 + +## 碰撞检测 + +碰撞检测就是计算机发送数据时,检测链路上信号电压的大小 + +使用CSMA/CD协议的以太网不能进行全双工通信,而只能进行双向交替通信(半双工通信),每个站发送数据之后一小段时间,可能会遭遇碰撞的可能性。 + +发生碰撞的站停止发送数据后,需要延迟一个随机时间 才能再发送数据,确定基本退避时间,一般是取2T,当重传16次后,仍然不成功,即丢弃该帧,并向高层报告。 + +## 以太网 + +只要满足载波监听,多路访问的都是以太网。 + +同时局域网数据链路层拆分成了两个子层 + +- 逻辑链路控制LLC子层 +- 媒体接入控制MAC子层,现在的网卡只有MAC子层 + +以太网提供的服务是不可靠的交付,即尽最大努力的交付。 + +## 信道利用率 + +$$ +\partial=\frac{\tau}{T_{0}} +$$ + +## 流量控制协议 + +### 单工停等协议 + +stop and wait,链路不出错,但有可能出现流量不匹配的情况,发送方每发一帧停下来,每收到一帧后,上交网络层,再发一个确认给发送方,表示收到。发送方收到确认在发送下一个。 + +### 连续ARQ + +自动请求重发协议。 + +- 发送端:在发送完一个数据帧后,不是停下来等待应答帧,而是可以连接再发送下面的数据帧。如果这时收到了接收端发来的确认帧,那么还可以接着再发送下面的数据帧。如果超时时间到,仍然没有收到相应的确认帧,则重新从这个帧开始重传。(go back N ARQ) +- 接收端:连续接收帧,当接收到一个坏帧时,简单丢弃这个帧和这个帧以后的所有帧,让他们在发送端超时,这道收到这个帧为止。 + +### 停止等待协议和连续ARQ协议的问题 + +#### 停止等待协议 + +发送 - 停止 - 等待,效率较低,当传播时间比发送时间大得多时,性能变得不可接受 + +#### 连续ARQ协议 + +- 未经确定的帧一次传送过多,如果出错,重传的代价太大 +- 序号站的位数过多,影响效率,一次能传送1024个帧,10位编号 +- 实际协议中,一次连续传输的帧的个数是有限的 + +### 滑动窗口协议 + +它是停止等待协议 和 连续ARQ协议的折中 + +一次发送为确定的帧的个数是有限的 + +- 发送端:一次发送未经确定的帧是收到发送窗口的控制的,只有落在发送窗口的帧才是可以发送的 +- 接收端:只有落在接收窗口的帧才是可以接收的。 + +出现差错的处理办法 + +一段收到出错的帧后进行丢弃,不发送确定报文,让发送方超时重发。对后面陆续到达的正确的帧进行同样的处理办法 + +- 当wr = 1时 + - 接收方:全部丢弃(drop),链路层只按顺序接收帧 + - 发送方:2号帧超时后,从2号帧开始发送 + - 回退n帧,(go back N protocol) +- 当 wr > 1时 + - 接收方:陆续接收出错的后续各个帧,但不提交给网络层,知道接收到2号帧以后,加上以后存储的各帧,按顺序交给网络层 + - 发送方:2号帧超时后,发完2号帧之后,从第6号帧开始,选择性重传 + diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/01C1D44F.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/01C1D44F.png" new file mode 100644 index 0000000000000000000000000000000000000000..2f5a0909e69c926b7f5da44494b396d0e9c4686a Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/01C1D44F.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627162011689.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627162011689.png" new file mode 100644 index 0000000000000000000000000000000000000000..37d0aa8d190ea7012e5bf4671427ead62d19224e Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627162011689.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627162616750.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627162616750.png" new file mode 100644 index 0000000000000000000000000000000000000000..5f4d207356cf59654b8881197ebc70a014595f0e Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627162616750.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627162720414.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627162720414.png" new file mode 100644 index 0000000000000000000000000000000000000000..b2bb06ae4390f77e0e87b78d05af05eba95a8664 Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627162720414.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627163044943.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627163044943.png" new file mode 100644 index 0000000000000000000000000000000000000000..092ad5e33270f487c534c0c03ab2e43114dd5805 Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627163044943.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627164926128.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627164926128.png" new file mode 100644 index 0000000000000000000000000000000000000000..0c397eec45985f9352bab64c953534eb5e6555e5 Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627164926128.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627164944182.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627164944182.png" new file mode 100644 index 0000000000000000000000000000000000000000..5401d074f5b8c2250dd97af117498278b1a5fdfb Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627164944182.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627181830249.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627181830249.png" new file mode 100644 index 0000000000000000000000000000000000000000..367f3e451d84c0dca3270d39d2a1ac1a6c62af7c Binary files /dev/null and "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/5_\346\225\260\346\215\256\351\223\276\350\267\257\345\261\202/images/image-20200627181830249.png" differ diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/http\344\270\255\347\232\204\347\212\266\346\200\201\347\240\201/README.md" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/http\344\270\255\347\232\204\347\212\266\346\200\201\347\240\201/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..4696df0b1a4d0b86fe62a23b6f7c3eb8dbe58027 --- /dev/null +++ "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/http\344\270\255\347\232\204\347\212\266\346\200\201\347\240\201/README.md" @@ -0,0 +1,73 @@ +# HTTP中的状态码 + +## 状态码的作用 + +状态码的职责是当客户端向服务器发送请求时,描述返回的请求结果,借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。 + +| | 类别 | 原因 | +| ---- | ------------ | ---------------------- | +| 1XX | 信息性状态码 | 接收到的请求正在处理中 | +| 2XX | 成功状态码 | 请求正常处理完毕 | +| 3XX | 重定向状态码 | 需要附加操作以完成请求 | +| 4XX | 客户端错误码 | 服务器无法处理请求 | +| 5XX | 服务器错误码 | 服务器处理请求出错 | + +## 2XX成功 + +### 200 OK + +表示客户端发送来的请求服务端正在处理了 + +### 204 No Content + +该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含Content-Range指定范围的实体内容 + +## 3XX重定向 + +### 301 Moved Permanently + +永久性重定向,该状态码表示请求的资源已经被分配了新的URI,以后应使用资源现在所指的URI + +### 302 Found + +临时重定向,该状态码表示请求的资源已经分配了新的URI,希望用户本次使用新的URI访问。和301类似,但是该状态码表示资源不是永久性被移动,只是短暂的 + +### 303 See other + +该状态码表示由于请求对应的资源存在另一个URI,应使用GET方法定向获取请求的资源 + +### 304 Not Modified + +该状态码表示客户端发送附带条件的请求时,服务端允许访问资源,但未满足条件的情况。虽然被划分在3XX中,但是和重定向没有任何关系。 + +## 4XX客户端错误 + +### 400 Bad Request + +该状态码表示请求报文中存在语法错误,需要修改请求的内容后再次发送请求 + +### 401 Unauthorized + +该状态码表示发送的请求需要HTTP认真信息或者用户认证失败 + +### 403 Forbidden + +该状态码表示请求资源的访问被服务器拒绝了 + +### 404 Not Found + +该状态码表示服务器上无法找到请求的资源 + +### 405 Method Not Allowed + +该状态码表示请求的方法不被允许 + +## 5XX服务器错误 + +### 500 Internal Server Error + +该状态码表示服务器在执行请求时发生了错误,也可能是web应用存在BUG和某些临时的故障 + +### 503 Service Unavailable + +该状态码表示服务器暂时处于超负荷或正在停机维护,现在无法处理请求。 \ No newline at end of file diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\270\270\350\247\201\351\242\230\347\233\256/README.md" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\270\270\350\247\201\351\242\230\347\233\256/README.md" deleted file mode 100644 index db3f649f980f422daf8f35d2b67ab15aeed1812b..0000000000000000000000000000000000000000 --- "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\270\270\350\247\201\351\242\230\347\233\256/README.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 计算机网络常见题型 - -## 能否简单介绍下HTTP协议中缓存的处理流程 - -![image-20200412200410989](images/image-20200412200410989.png) - -缓存的应用流程是什么? - -与缓存相关的HTTP头部是什么? \ No newline at end of file diff --git "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\270\270\350\247\201\351\242\230\347\233\256/images/image-20200412200410989.png" "b/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\270\270\350\247\201\351\242\230\347\233\256/images/image-20200412200410989.png" deleted file mode 100644 index e418a345322c7ae34c079f3d18b2b0a6121cc8fb..0000000000000000000000000000000000000000 Binary files "a/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\345\270\270\350\247\201\351\242\230\347\233\256/images/image-20200412200410989.png" and /dev/null differ diff --git "a/\350\256\276\350\256\241\346\250\241\345\274\217/\350\256\276\350\256\241\346\250\241\345\274\217/README.md" "b/\350\256\276\350\256\241\346\250\241\345\274\217/\350\256\276\350\256\241\346\250\241\345\274\217/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..523f638c0d24d03afa8c637f2435b0843d021999 --- /dev/null +++ "b/\350\256\276\350\256\241\346\250\241\345\274\217/\350\256\276\350\256\241\346\250\241\345\274\217/README.md" @@ -0,0 +1,364 @@ +# 设计模式 + +## 前言 + +有一些重要的设计原则在开篇和大家分享下,这些原则将贯通全文: + +- 面向接口编程,而不是面向实现。这个很重要,也是优雅的、可扩展的代码的第一步,这就不需要多说了吧。 + +- 职责单一原则。每个类都应该只有一个单一的功能,并且该功能应该由这个类完全封装起来。 + +- 对修改关闭,对扩展开放。对修改关闭是说,我们辛辛苦苦加班写出来的代码,该实现的功能和该修复的 bug 都完成了,别人可不能说改就改;对扩展开放就比较好理解了,也就是说在我们写好的代码基础上,很容易实现扩展。 + +创建型模式比较简单,但是会比较没有意思,结构型和行为型比较有意思 + +每个代理模式的代码都必须自己手动完成一遍。 + +## 创建型模式 + +创建型模式的作用就是创建对象,说到创建一个对象,最熟悉的就是 new 一个对象,然后 set 相关属性。但是,在很多场景下,我们需要给客户端提供更加友好的创建对象的方式,尤其是那种我们定义了类,但是需要提供给其他开发者用的时候。 + +工厂模式分为简单工厂模式,工厂模式,抽象工厂模式 + +在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。**本质就是使用工厂方法代替new操作。** + +### 简单工厂模式 + +```java +public class FoodFactory { + public static Food makeFood(String name) { + if (name.equals("兰州拉面")) { + Food noodle = new LanZhouNoodle(); + System.out.println("兰州拉面"+noodle+"出锅啦"); + return noodle; + } else if (name.equals("黄焖鸡")) { + Food chicken = new HuangMenChicken(); + System.out.println("黄焖鸡"+ chicken +"出锅啦"); + return chicken; + } else { + System.out.println("不知道你做的什么哦~"); + return null; + } + } +} +``` + +其中,LanZhouNoodle 和 HuangMenChicken 都继承自 Food。 + +```java +public class Cook { + public static void main(String[] args) { + Food food = FoodFactory.makeFood("黄焖鸡"); + FoodFactory.makeFood("jaja"); + } +} +``` + +简单地说,**简单工厂模式通常就是这样,一个工厂类 XxxFactory,里面有一个静态方法,根据我们不同的参数,返回不同的派生自同一个父类(或实现同一接口)的实例对象。** + +> 我们强调**职责单一**原则,一个类只提供一种功能,FoodFactory 的功能就是只要负责生产各种 Food。 + +在此例中可以看出,Cook 类在使用 FoodFactory 时就不需要 new 任何一个对象,这就是简单工厂模式的好处,封装了 new 的部分,做到的代码易用性。 + +### 工厂模式 + +简单工厂模式很简单,如果它能满足我们的需要,我觉得就不要折腾了。之所以需要引入工厂模式,是因为我们往往需要使用两个或两个以上的工厂。 + +```java +public interface FoodFactory { + Food makeFood(String name); +} +public class ChineseFoodFactory implements FoodFactory { + + @Override + public Food makeFood(String name) { + if (name.equals("A")) { + return new ChineseFoodA(); + } else if (name.equals("B")) { + return new ChineseFoodB(); + } else { + return null; + } + } +} +public class AmericanFoodFactory implements FoodFactory { + + @Override + public Food makeFood(String name) { + if (name.equals("A")) { + return new AmericanFoodA(); + } else if (name.equals("B")) { + return new AmericanFoodB(); + } else { + return null; + } + } +} +``` + +其中,ChineseFoodA、ChineseFoodB、AmericanFoodA、AmericanFoodB 都派生自 Food。 + +客户端调用: + +```java +public class APP { + public static void main(String[] args) { + // 先选择一个具体的工厂 + FoodFactory factory = new ChineseFoodFactory(); + // 由第一步的工厂产生具体的对象,不同的工厂造出不一样的对象 + Food food = factory.makeFood("A"); + } +} +``` + +虽然都是调用 makeFood("A") 制作 A 类食物,但是,不同的工厂生产出来的完全不一样。 + +第一步,我们需要选取合适的工厂,然后第二步基本上和简单工厂一样。 + +**核心在于,我们需要在第一步选好我们需要的工厂**。比如,我们有 LogFactory 接口,实现类有 FileLogFactory 和 KafkaLogFactory,分别对应将日志写入文件和写入 Kafka 中,显然,我们客户端第一步就需要决定到底要实例化 FileLogFactory 还是 KafkaLogFactory,这将决定之后的所有的操作。 + +### 抽象工厂模式 + +当涉及到**产品族**的时候,就需要引入抽象工厂模式了。 一个经典的例子是造一台电脑 。 + +当涉及到这种产品族的问题的时候,就需要抽象工厂模式来支持了。我们不再定义 CPU 工厂、主板工厂、硬盘工厂、显示屏工厂等等,我们直接定义电脑工厂,每个电脑工厂负责生产所有的设备,这样能保证肯定不存在兼容问题。 + +当然,抽象工厂的问题也是显而易见的,比如我们要加个显示器,就需要修改所有的工厂,给所有的工厂都加上制造显示器的方法。这有点违反了**对修改关闭,对扩展开放**这个设计原则。 + +本节要介绍的抽象工厂模式将考虑多等级产品的生产,将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族,图 1 所示的是海尔工厂和 TCL 工厂所生产的电视机与空调对应的关系图。 + +![电器工厂的产品等级与产品族](images/3-1Q1141559151S.gif) + +抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。 + +抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。 + +使用抽象工厂模式一般要满足以下条件。 + +- 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。 +- 系统一次只可能消费其中某一族产品,即同族的产品一起使用。 + +抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。 + +- 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。 +- 当增加一个新的产品族时不需要修改原代码,满足开闭原则。 + + +其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。 + + + +### 单例模式 + +简单点说,就是一个应用程序中,某个类的实例对象只有一个,你没有办法去new,因为构造器是被private修饰的,一般通过getInstance()的方法来获取它们的实例。 + +getInstance()的返回值是一个对象的引用,并不是一个新的实例,所以不要错误的理解成多个对象。 + +**特点** + +- 类构造器私有 +- 持有自己类型的属性 +- 对外提供获取实例的静态方法 + +**饿汉式写法** + +``` +public class Singleton { + private static Singleton instance = new Singleton(); + private Singleton (){} + public static Singleton getInstance() { + return instance; + } +} +``` + +弊端:因为类加载的时候就会创建对象,所以有的时候还不需要使用对象,就会创建对象,造成内存的浪费; + +**饱汉模式最容易出错:** + +``` +public class Singleton { + // 首先,也是先堵死 new Singleton() 这条路 + private Singleton() {} + // 和饿汉模式相比,这边不需要先实例化出来,注意这里的 volatile,它是必须的 + private static volatile Singleton instance = null; + + public static Singleton getInstance() { + if (instance == null) { + // 加锁 + synchronized (Singleton.class) { + // 这一次判断也是必须的,不然会有并发问题 + if (instance == null) { + instance = new Singleton(); + } + } + } + return instance; + } +} +``` + +> 双重检查,指的是两次检查 instance 是否为 null。 +> +> volatile 在这里是需要的,希望能引起读者的关注。 +> +> 很多人不知道怎么写,直接就在 getInstance() 方法签名上加上 synchronized,这就不多说了,性能太差。 + +嵌套类最经典,以后大家就用它吧: + +``` +public class Singleton { + + private Singleton() {} + // 主要是使用了 嵌套类可以访问外部类的静态属性和静态方法 的特性 + private static class Holder { + private static Singleton instance = new Singleton(); + } + public static Singleton getInstance() { + return Holder.instance; + } +} +``` + +> 注意,很多人都会把这个**嵌套类**说成是**静态内部类**,严格地说,内部类和嵌套类是不一样的,它们能访问的外部类权限也是不一样的。 + +最后,我们说一下枚举,枚举很特殊,它在类加载的时候会初始化里面的所有的实例,而且 JVM 保证了它们不会再被实例化,所以它天生就是单例的。 + +**TODO:** + +建造者模式 + +原型模式 + +## 结构型模式 + +前面创建型模式介绍了创建对象的一些设计模式,这节介绍的结构型模式旨在通过改变代码结构来达到解耦的目的,使得我们的代码容易维护和扩展。 + +### 代理模式 + +第一个要介绍的代理模式是最常使用的模式之一了,用一个代理来隐藏具体实现类的实现细节,通常还用于在真实的实现的前后添加一部分逻辑。 + +既然说是**代理**,那就要对客户端隐藏真实实现,由代理来负责客户端的所有请求。当然,代理只是个代理,它不会完成实际的业务逻辑,而是一层皮而已,但是对于客户端来说,它必须表现得就是客户端需要的真实实现。 + +理解**代理**这个词,这个模式其实就简单了。 下面上代码理解。 代理接口: + +``` +//要有一个代理接口让实现类和代理实现类来实现。 +public interface FoodService { + Food makeChicken(); +} +``` + +被代理的实现类: + +``` +public class FoodServiceImpl implements FoodService { + @Override + public Food makeChicken() { + Food f = new Chicken(); + f.setChicken("1kg"); + f.setSpicy("1g"); + f.setSalt("3g"); + System.out.println("鸡肉加好佐料了"); + return f; + } +} +``` + +被代理实现类就只需要做自己该做的事情就好了,不需要管别的。 + +代理实现类: + +``` +public class FoodServiceProxy implements FoodService { + // 内部一定要有一个真实的实现类,当然也可以通过构造方法注入 + private FoodService foodService = new FoodServiceImpl(); + + @Override + public Food makeChicken() { + System.out.println("开始制作鸡肉"); + + // 如果我们定义这句为核心代码的话,那么,核心代码是真实实现类做的, + // 代理只是在核心代码前后做些“无足轻重”的事情 + Food food = foodService.makeChicken(); + + System.out.println("鸡肉制作完成啦,加点胡椒粉"); + food.addCondiment("pepper"); + System.out.println("上锅咯"); + return food; + } +} +``` + +客户端调用,注意,我们要用代理来实例化接口: + +``` +// 这里用代理类来实例化 +FoodService foodService = new FoodServiceProxy(); +foodService.makeChicken(); +``` + +所谓代理模式,**就是对被代理方法包装或者叫增强, 在面向切面编程(AOP)中,其实就是动态代理的过程。比如 Spring 中,我们自己不定义代理类,但是 Spring 会帮我们动态来定义代理,然后把我们定义在 @Before、@After、@Around 中的代码逻辑动态添加到代理中。** + +待续。。。 + +## 行为型模式 + +### 模板模式 + +在含有继承结构的代码中,模板方法模式是非常常用的。 + +**父类定义了骨架(调用哪些方法及顺序),某些特定方法由子类实现** + +模板方法只负责定义第一步应该要做什么,第二步应该做什么,第三步应该做什么,至于怎么做,由子类来实现。 + +好处:代码复用,减少重复代码。除了子类要实现的特定方法,其他方法及方法调用顺序都在父类中预先写好 + +缺点: 每一个不同的实现都需要一个子类来实现,导致类个数增加,使系统更加庞大 + +**模板模式的关键点:** + +    1、使用抽象类定义模板类,并在其中定义所有的基本方法、模板方法,钩子方法,不限数量,以实现功能逻辑为主。其中基本方法使用final修饰,其中要调用基本方法和钩子方法,基本方法和钩子方法可以使用protected修饰,表明可被子类修改。 + +    2、定义实现抽象类的子类,重写其中的模板方法,甚至钩子方法,完善具体的逻辑。 + +  使用场景: + +    1、在多个子类中拥有相同的方法,而且逻辑相同时,可以将这些方法抽出来放到一个模板抽象类中。 + +    2、程序主框架相同,细节不同的情况下,也可以使用模板方法。 + +#### 架构方法介绍 + +模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。其主要分为两大类:模版方法和基本方法,而基本方法又分为:抽象方法(Abstract Method),具体方法(Concrete Method),钩子方法(Hook Method)。 + +四种方法的基本定义(前提:在抽象类中定义): + +(1)抽象方法:由抽象类声明,由具体子类实现,并以abstract关键字进行标识。 + +(2)具体方法:由抽象类声明并且实现,子类并不实现或者做覆盖操作。其实质就是普遍适用的方法,不需要子类来实现。 + +(3)钩子方法:由抽象类声明并且实现,子类也可以选择加以扩展。通常抽象类会给出一个空的钩子方法,也就是没有实现的扩展。**它和具体方法在代码上没有区别,不过是一种意识的区别**;而它和抽象方法有时候也是没有区别的,就是在子类都需要将其实现的时候。而不同的是抽象方法必须实现,而钩子方法可以不实现。也就是说钩子方法为你在实现某一个抽象类的时候提供了可选项,**相当于预先提供了一个默认配置。** + +(4)模板方法:定义了一个方法,其中定义了整个逻辑的基本骨架。 + +``` +public abstract class AbstractTemplate { + // 这就是模板方法 + public void templateMethod() { + init(); + apply(); // 这个是重点 + end(); // 可以作为钩子方法 + } + //这是具体方法 + protected void init() { + System.out.println("init 抽象层已经实现,子类也可以选择覆写"); + } + + // 这是抽象方法,留给子类实现 + protected abstract void apply(); + //这是钩子方法,可定义一个默认操作,或者为空 + protected void end() { + } +} +``` \ No newline at end of file diff --git "a/\350\256\276\350\256\241\346\250\241\345\274\217/\350\256\276\350\256\241\346\250\241\345\274\217/images/3-1Q1141559151S.gif" "b/\350\256\276\350\256\241\346\250\241\345\274\217/\350\256\276\350\256\241\346\250\241\345\274\217/images/3-1Q1141559151S.gif" new file mode 100644 index 0000000000000000000000000000000000000000..bd4ac77f5bc5124f8fd5d5e61952e5de01175ed2 Binary files /dev/null and "b/\350\256\276\350\256\241\346\250\241\345\274\217/\350\256\276\350\256\241\346\250\241\345\274\217/images/3-1Q1141559151S.gif" differ