├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .prettierrc.js ├── README.md ├── docs ├── assets │ ├── About.2402b6c4.js │ ├── About.7ebd9f83.css │ ├── Home.5fbcc04f.css │ ├── Home.d325a6a4.js │ ├── image-icon.63fadd7f.png │ ├── index.0f0c491a.js │ ├── index.dd263ccb.css │ ├── text-icon.83d569a1.png │ └── video-icon.b22a29fa.png ├── favicon.ico └── index.html ├── index.html ├── package-lock.json ├── package.json ├── public └── favicon.ico ├── server ├── .gitignore ├── app.js ├── package-lock.json ├── package.json └── uploader-node.js ├── src ├── App.vue ├── api │ └── index.js ├── assets │ └── logo.png ├── auto-imports.d.ts ├── components.d.ts ├── components │ └── GlobalUploader │ │ ├── GlobalUploader.vue │ │ ├── images │ │ ├── audio-icon.png │ │ ├── image-icon.png │ │ ├── text-icon.png │ │ ├── video-icon.png │ │ └── zip.png │ │ └── utils │ │ ├── bus.js │ │ └── md5.js ├── main.js ├── router │ └── index.js ├── styles │ ├── index.scss │ └── variable.scss └── views │ ├── About.vue │ └── Home.vue └── vite.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = crlf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | max_line_length = 100 11 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | src/assets 2 | src/icons 3 | dist 4 | public 5 | index.html 6 | *.sh 7 | node_modules 8 | *.md 9 | *.woff 10 | *.ttf 11 | .vscode 12 | .idea 13 | /docs 14 | *.d.ts 15 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | node: true, 4 | browser: true, 5 | es2021: true 6 | }, 7 | extends: [ 8 | // 'plugin:vue/vue3-essential', // 基础错误级别的检测 9 | 'plugin:vue/vue3-recommended', // 提升代码可读性和开发体验级的检测 10 | 'plugin:prettier/recommended' 11 | ], 12 | parser: 'vue-eslint-parser', 13 | plugins: ['vue'], 14 | rules: { 15 | 'linebreak-style': 'off', 16 | 'no-unused-vars': 'off', 17 | 'no-undef': 'off', 18 | // prop需要定义默认值 19 | 'vue/require-default-prop': 'off', 20 | // 组件名称必须有多个单词组成 21 | 'vue/multi-word-component-names': 'off' 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "printWidth": 100, //一行的字符数,如果超过会进行换行,默认为80 3 | "tabWidth": 2, //一个tab代表几个空格数 4 | "useTabs": false, //是否使用tab进行缩进,默认为false,表示用空格进行缩减 5 | "singleQuote": true, //字符串是否使用单引号,默认为false,使用双引号 6 | "semi": false, //行位是否使用分号,默认为true 7 | "trailingComma": "none", //是否使用尾逗号,有三个可选值"" 8 | "bracketSpacing": true, //对象大括号直接是否有空格,默认为true,效果:{ foo: bar } 9 | "arrowFunctionParentheses": true, // 箭头函数的参数是否需要被括号包裹 10 | } 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-uploader-solutions-next 2 | 3 | Vue uploader solutions 的 vue 3.0 版本 4 | 5 | 基于 `vue-simple-uploader` ,封装可以分片、秒传及断点续传的vue3上传插件 6 | 7 | 预览:[https://shady-xia.github.io/vue-uploader-solutions-next](https://shady-xia.github.io/vue-uploader-solutions-next) 8 | 9 | ## 本地调试 10 | 11 | **前端服务**: 12 | ```bash 13 | npm install 14 | 15 | npm start 16 | # or 17 | npm run serve 18 | ``` 19 | 20 | 前端服务默认打开8000端口 21 | 22 | **node服务端** 23 | 24 | ```bash 25 | cd server 26 | npm install 27 | npm run server 28 | ``` 29 | 30 | node服务会打开3000端口,临时文件存在 tmp 目录下,上传成功的文件存在 uploads 目录下 31 | 32 | 33 | ## 插件的封装及使用 34 | 35 | ### GlobalUploader 36 | 37 | `GlobalUploader.vue` 为基于 `vue-simple-uploader` 二次封装的上传插件 38 | 39 | 它有两种使用方式: 40 | 41 | ### 通过bus作为全局组件使用 42 | 43 | 作为全局上传组件使用时,将组件注册在`App.vue`中,通过 `Bus` 的方式调用插件。 44 | 45 | 使用场景为:上传器为整个网站级别的,切换路由时不打断上传流程,上传窗口始终存在于网站右下角。 46 | 47 | **打开上传器** 48 | 49 | 调用`Bus.emit('openUploader')`,打开上传器,弹出选择文件窗口,该函数有两个参数: 50 | 51 | * params:传给服务端的额外参数 52 | * options:上传选项,目前支持 target、testChunks、mergeFn、accept 53 | 54 | ```js 55 | Bus.emit('openUploader', { 56 | params: { 57 | page: 'home' 58 | }, 59 | options: { 60 | target: 'http://10.0.0.10' 61 | } 62 | }) 63 | ``` 64 | 65 | **Bus Events** 66 | 67 | * fileAdded:文件选择后的回调 68 | * fileSuccess:文件上传成功的回调 69 | 70 | ```js 71 | // 文件选择后的回调 72 | Bus.on('fileAdded', () => { 73 | console.log('文件已选择') 74 | }) 75 | 76 | // 文件上传成功的回调 77 | Bus.on('fileSuccess', () => { 78 | console.log('文件上传成功') 79 | }) 80 | ``` 81 | 82 | ### 作为普通组件在单个页面中使用 83 | 84 | 使用场景为:在单个页面中使用上传器 85 | 86 | props: 87 | * global:请务必设置为 `false`,代表非全局 88 | * params:(同用法一)传给服务端的额外参数 89 | * options:(同用法一)上传选项,目前支持 target、testChunks、mergeFn、accept 90 | 91 | events: 92 | * fileAdded:文件选择后的回调 93 | * fileSuccess:文件上传成功的回调 94 | 95 | ```html 96 | 102 | ``` 103 | -------------------------------------------------------------------------------- /docs/assets/About.2402b6c4.js: -------------------------------------------------------------------------------- 1 | import{l as t,o,e as a,s as c,v as _,f as s}from"./index.0f0c491a.js";const d={},p=e=>(c("data-v-e2e9fc40"),e=e(),_(),e),r={class:"page page-about"},n=p(()=>s("div",{class:"about"},[s("h1",null,"\u8FD9\u662F\u5173\u4E8E\u9875\u9762"),s("p",{class:"text"},"\u53EA\u662F\u4E3A\u4E86\u6A21\u62DF\u4E0A\u4F20\u5668\u7684\u5168\u5C40\u6548\u679C\u800C\u5DF2")],-1)),l=[n];function u(e,i){return o(),a("div",r,l)}var v=t(d,[["render",u],["__scopeId","data-v-e2e9fc40"]]);export{v as default}; 2 | -------------------------------------------------------------------------------- /docs/assets/About.7ebd9f83.css: -------------------------------------------------------------------------------- 1 | .text[data-v-e2e9fc40]{margin-top:20px} 2 | -------------------------------------------------------------------------------- /docs/assets/Home.5fbcc04f.css: -------------------------------------------------------------------------------- 1 | .el-empty{--el-empty-padding: 40px 0;--el-empty-image-width: 160px;--el-empty-description-margin-top: 20px;--el-empty-bottom-margin-top: 20px;--el-empty-fill-color-0: var(--el-color-white);--el-empty-fill-color-1: #fcfcfd;--el-empty-fill-color-2: #f8f9fb;--el-empty-fill-color-3: #f7f8fc;--el-empty-fill-color-4: #eeeff3;--el-empty-fill-color-5: #edeef2;--el-empty-fill-color-6: #e9ebef;--el-empty-fill-color-7: #e5e7e9;--el-empty-fill-color-8: #e0e3e9;--el-empty-fill-color-9: #d5d7de;display:flex;justify-content:center;align-items:center;flex-direction:column;text-align:center;box-sizing:border-box;padding:var(--el-empty-padding)}.el-empty__image{width:var(--el-empty-image-width)}.el-empty__image img{user-select:none;width:100%;height:100%;vertical-align:top;object-fit:contain}.el-empty__image svg{color:var(--el-svg-monochrome-grey);fill:currentColor;width:100%;height:100%;vertical-align:top}.el-empty__description{margin-top:var(--el-empty-description-margin-top)}.el-empty__description p{margin:0;font-size:var(--el-font-size-base);color:var(--el-text-color-secondary)}.el-empty__bottom{margin-top:var(--el-empty-bottom-margin-top)}.page-home[data-v-d2f93fba]{height:100%}.file-box[data-v-d2f93fba]{position:relative;margin-top:20px;padding:30px;flex:1;background-color:#fff}.file-box .title[data-v-d2f93fba]{padding-left:10px;font-size:15px;border-left:4px solid #1989fa}.file-box .empty[data-v-d2f93fba]{position:absolute;top:45%;left:50%;transform:translate(-50%,-50%)}.file-box .empty .upload[data-v-d2f93fba]{color:#1989fa;cursor:pointer} 2 | -------------------------------------------------------------------------------- /docs/assets/Home.d325a6a4.js: -------------------------------------------------------------------------------- 1 | import{u as U,c as v,a as i,i as J,r as I,d as M,b as B,_ as F,o as c,e as d,f as o,g as w,h as S,n as y,j as K,t as Y,k as z,w as W,l as Z,m as q,B as m,p as X,E as Q,q as P,s as ee,v as te,x as R}from"./index.0f0c491a.js";var ne=typeof global=="object"&&global&&global.Object===Object&&global,re=ne,oe=typeof self=="object"&&self&&self.Object===Object&&self,ae=re||oe||Function("return this")(),T=ae,se=T.Symbol,f=se,A=Object.prototype,le=A.hasOwnProperty,ie=A.toString,g=f?f.toStringTag:void 0;function ce(e){var t=le.call(e,g),n=e[g];try{e[g]=void 0;var r=!0}catch{}var a=ie.call(e);return r&&(t?e[g]=n:delete e[g]),a}var de=Object.prototype,pe=de.toString;function ue(e){return pe.call(e)}var fe="[object Null]",he="[object Undefined]",j=f?f.toStringTag:void 0;function G(e){return e==null?e===void 0?he:fe:j&&j in Object(e)?ce(e):ue(e)}function me(e){return e!=null&&typeof e=="object"}var ge="[object Symbol]";function k(e){return typeof e=="symbol"||me(e)&&G(e)==ge}function _e(e,t){for(var n=-1,r=e==null?0:e.length,a=Array(r);++n-1}function lt(e,t){var n=this.__data__,r=b(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}function h(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t(t,n)=>Dt(t,n,i(e)),Dt=(e,t,n)=>Ot(n,e,e).replace(/\{(\w+)\}/g,(r,a)=>{var s;return`${(s=t==null?void 0:t[a])!=null?s:`{${a}}`}`}),Et=e=>{const t=v(()=>i(e).name),n=J(e)?e:I(e);return{lang:t,locale:n,t:jt(e)}},xt=()=>{const e=U("locale");return Et(v(()=>e.value||Pt))};let It=0;const Mt=M({name:"ImgEmpty",setup(){return{ns:B("empty"),id:++It}}}),Bt={viewBox:"0 0 79 86",version:"1.1",xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"},Ft=["id"],zt=["stop-color"],Rt=["stop-color"],At=["id"],Gt=["stop-color"],Vt=["stop-color"],Lt=["id"],Ht={id:"Illustrations",stroke:"none","stroke-width":"1",fill:"none","fill-rule":"evenodd"},Ut={id:"B-type",transform:"translate(-1268.000000, -535.000000)"},Jt={id:"Group-2",transform:"translate(1268.000000, 535.000000)"},Kt=["fill"],Yt=["fill"],Wt={id:"Group-Copy",transform:"translate(34.500000, 31.500000) scale(-1, 1) rotate(-25.000000) translate(-34.500000, -31.500000) translate(7.000000, 10.000000)"},Zt=["fill"],qt=["fill"],Xt=["fill"],Qt=["fill"],en=["fill"],tn={id:"Rectangle-Copy-17",transform:"translate(53.000000, 45.000000)"},nn=["fill","xlink:href"],rn=["fill","mask"],on=["fill"];function an(e,t,n,r,a,s){return c(),d("svg",Bt,[o("defs",null,[o("linearGradient",{id:`linearGradient-1-${e.id}`,x1:"38.8503086%",y1:"0%",x2:"61.1496914%",y2:"100%"},[o("stop",{"stop-color":`var(${e.ns.cssVarBlockName("fill-color-1")})`,offset:"0%"},null,8,zt),o("stop",{"stop-color":`var(${e.ns.cssVarBlockName("fill-color-4")})`,offset:"100%"},null,8,Rt)],8,Ft),o("linearGradient",{id:`linearGradient-2-${e.id}`,x1:"0%",y1:"9.5%",x2:"100%",y2:"90.5%"},[o("stop",{"stop-color":`var(${e.ns.cssVarBlockName("fill-color-1")})`,offset:"0%"},null,8,Gt),o("stop",{"stop-color":`var(${e.ns.cssVarBlockName("fill-color-6")})`,offset:"100%"},null,8,Vt)],8,At),o("rect",{id:`path-3-${e.id}`,x:"0",y:"0",width:"17",height:"36"},null,8,Lt)]),o("g",Ht,[o("g",Ut,[o("g",Jt,[o("path",{id:"Oval-Copy-2",d:"M39.5,86 C61.3152476,86 79,83.9106622 79,81.3333333 C79,78.7560045 57.3152476,78 35.5,78 C13.6847524,78 0,78.7560045 0,81.3333333 C0,83.9106622 17.6847524,86 39.5,86 Z",fill:`var(${e.ns.cssVarBlockName("fill-color-3")})`},null,8,Kt),o("polygon",{id:"Rectangle-Copy-14",fill:`var(${e.ns.cssVarBlockName("fill-color-7")})`,transform:"translate(27.500000, 51.500000) scale(1, -1) translate(-27.500000, -51.500000) ",points:"13 58 53 58 42 45 2 45"},null,8,Yt),o("g",Wt,[o("polygon",{id:"Rectangle-Copy-10",fill:`var(${e.ns.cssVarBlockName("fill-color-7")})`,transform:"translate(11.500000, 5.000000) scale(1, -1) translate(-11.500000, -5.000000) ",points:"2.84078316e-14 3 18 3 23 7 5 7"},null,8,Zt),o("polygon",{id:"Rectangle-Copy-11",fill:`var(${e.ns.cssVarBlockName("fill-color-5")})`,points:"-3.69149156e-15 7 38 7 38 43 -3.69149156e-15 43"},null,8,qt),o("rect",{id:"Rectangle-Copy-12",fill:`url(#linearGradient-1-${e.id})`,transform:"translate(46.500000, 25.000000) scale(-1, 1) translate(-46.500000, -25.000000) ",x:"38",y:"7",width:"17",height:"36"},null,8,Xt),o("polygon",{id:"Rectangle-Copy-13",fill:`var(${e.ns.cssVarBlockName("fill-color-2")})`,transform:"translate(39.500000, 3.500000) scale(-1, 1) translate(-39.500000, -3.500000) ",points:"24 7 41 7 55 -3.63806207e-12 38 -3.63806207e-12"},null,8,Qt)]),o("rect",{id:"Rectangle-Copy-15",fill:`url(#linearGradient-2-${e.id})`,x:"13",y:"45",width:"40",height:"36"},null,8,en),o("g",tn,[o("use",{id:"Mask",fill:`var(${e.ns.cssVarBlockName("fill-color-8")})`,transform:"translate(8.500000, 18.000000) scale(-1, 1) translate(-8.500000, -18.000000) ","xlink:href":`#path-3-${e.id}`},null,8,nn),o("polygon",{id:"Rectangle-Copy",fill:`var(${e.ns.cssVarBlockName("fill-color-9")})`,mask:`url(#mask-4-${e.id})`,transform:"translate(12.000000, 9.000000) scale(-1, 1) translate(-12.000000, -9.000000) ",points:"7 0 24 0 20 18 7 16.5"},null,8,rn)]),o("polygon",{id:"Rectangle-Copy-18",fill:`var(${e.ns.cssVarBlockName("fill-color-2")})`,transform:"translate(66.000000, 51.500000) scale(-1, 1) translate(-66.000000, -51.500000) ",points:"62 45 79 45 70 58 53 58"},null,8,on)])])])])}var sn=F(Mt,[["render",an],["__file","/home/runner/work/element-plus/element-plus/packages/components/empty/src/img-empty.vue"]]);const ln={image:{type:String,default:""},imageSize:Number,description:{type:String,default:""}},cn=["src"],dn={key:1},pn={name:"ElEmpty"},un=M({...pn,props:ln,setup(e){const t=e,{t:n}=xt(),r=B("empty"),a=v(()=>t.description||n("el.table.emptyText")),s=v(()=>({width:t.imageSize?`${t.imageSize}px`:""}));return(l,Sn)=>(c(),d("div",{class:y(i(r).b())},[o("div",{class:y(i(r).e("image")),style:K(i(s))},[l.image?(c(),d("img",{key:0,src:l.image,ondragstart:"return false"},null,8,cn)):w(l.$slots,"image",{key:1},()=>[S(sn)])],6),o("div",{class:y(i(r).e("description"))},[l.$slots.description?w(l.$slots,"description",{key:0}):(c(),d("p",dn,Y(i(a)),1))],2),l.$slots.default?(c(),d("div",{key:0,class:y(i(r).e("bottom"))},[w(l.$slots,"default")],2)):z("v-if",!0)],2))}});var fn=F(un,[["__file","/home/runner/work/element-plus/element-plus/packages/components/empty/src/empty.vue"]]);const hn=W(fn);const mn=e=>(ee("data-v-d2f93fba"),e=e(),te(),e),gn={class:"page page-home"},_n={class:"btn-group"},yn=R("\u4E0A\u4F20"),vn={class:"file-box"},bn=mn(()=>o("p",{class:"title"},"\u6587\u4EF6\u8D44\u6E90\u5E93",-1)),$n={key:0,class:"empty"},wn=R("\u6682\u65E0\u6587\u4EF6\uFF0C\u8BF7\u5148"),Cn={__name:"Home",setup(e){const t=I([]),n=()=>{m.emit("openUploader",{params:{page:"home"},options:{target:"http://localhost:3000/upload"}})};return q(()=>{m.on("fileAdded",()=>{console.log("\u6587\u4EF6\u5DF2\u9009\u62E9")}),m.on("fileSuccess",()=>{console.log("\u6587\u4EF6\u4E0A\u4F20\u6210\u529F")})}),X(()=>{m.off("fileAdded"),m.off("fileSuccess")}),(r,a)=>{const s=Q,l=hn;return c(),d("div",gn,[o("div",_n,[S(s,{type:"primary",onClick:n},{default:P(()=>[yn]),_:1})]),o("div",vn,[bn,t.value.length?z("",!0):(c(),d("div",$n,[S(l,null,{description:P(()=>[o("p",null,[wn,o("a",{class:"upload",onClick:n},"\u4E0A\u4F20")])]),_:1})]))])])}}};var kn=Z(Cn,[["__scopeId","data-v-d2f93fba"]]);export{kn as default}; 2 | -------------------------------------------------------------------------------- /docs/assets/image-icon.63fadd7f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shady-xia/vue-uploader-solutions-next/46cd91d0f1adaffcab76908318846c978ebc19fe/docs/assets/image-icon.63fadd7f.png -------------------------------------------------------------------------------- /docs/assets/index.dd263ccb.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";:root{--el-color-white: #ffffff;--el-color-black: #000000;--el-color-primary-rgb: 64, 158, 255;--el-color-success-rgb: 103, 194, 58;--el-color-warning-rgb: 230, 162, 60;--el-color-danger-rgb: 245, 108, 108;--el-color-error-rgb: 245, 108, 108;--el-color-info-rgb: 144, 147, 153;--el-font-size-extra-large: 20px;--el-font-size-large: 18px;--el-font-size-medium: 16px;--el-font-size-base: 14px;--el-font-size-small: 13px;--el-font-size-extra-small: 12px;--el-font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "\5fae\8f6f\96c5\9ed1", Arial, sans-serif;--el-font-weight-primary: 500;--el-font-line-height-primary: 24px;--el-index-normal: 1;--el-index-top: 1000;--el-index-popper: 2000;--el-border-radius-base: 4px;--el-border-radius-small: 2px;--el-border-radius-round: 20px;--el-border-radius-circle: 100%;--el-transition-duration: .3s;--el-transition-duration-fast: .2s;--el-transition-function-ease-in-out-bezier: cubic-bezier(.645, .045, .355, 1);--el-transition-function-fast-bezier: cubic-bezier(.23, 1, .32, 1);--el-transition-all: all var(--el-transition-duration) var(--el-transition-function-ease-in-out-bezier);--el-transition-fade: opacity var(--el-transition-duration) var(--el-transition-function-fast-bezier);--el-transition-md-fade: transform var(--el-transition-duration) var(--el-transition-function-fast-bezier), opacity var(--el-transition-duration) var(--el-transition-function-fast-bezier);--el-transition-fade-linear: opacity var(--el-transition-duration-fast) linear;--el-transition-border: border-color var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier);--el-transition-box-shadow: box-shadow var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier);--el-transition-color: color var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier);--el-component-size-large: 40px;--el-component-size: 32px;--el-component-size-small: 24px}:root{color-scheme:light;--el-color-white: #ffffff;--el-color-black: #000000;--el-color-primary: #409eff;--el-color-primary-light-3: #79bbff;--el-color-primary-light-5: #a0cfff;--el-color-primary-light-7: #c6e2ff;--el-color-primary-light-8: #d9ecff;--el-color-primary-light-9: #ecf5ff;--el-color-primary-dark-2: #337ecc;--el-color-success: #67c23a;--el-color-success-light-3: #95d475;--el-color-success-light-5: #b3e19d;--el-color-success-light-7: #d1edc4;--el-color-success-light-8: #e1f3d8;--el-color-success-light-9: #f0f9eb;--el-color-success-dark-2: #529b2e;--el-color-warning: #e6a23c;--el-color-warning-light-3: #eebe77;--el-color-warning-light-5: #f3d19e;--el-color-warning-light-7: #f8e3c5;--el-color-warning-light-8: #faecd8;--el-color-warning-light-9: #fdf6ec;--el-color-warning-dark-2: #b88230;--el-color-danger: #f56c6c;--el-color-danger-light-3: #f89898;--el-color-danger-light-5: #fab6b6;--el-color-danger-light-7: #fcd3d3;--el-color-danger-light-8: #fde2e2;--el-color-danger-light-9: #fef0f0;--el-color-danger-dark-2: #c45656;--el-color-error: #f56c6c;--el-color-error-light-3: #f89898;--el-color-error-light-5: #fab6b6;--el-color-error-light-7: #fcd3d3;--el-color-error-light-8: #fde2e2;--el-color-error-light-9: #fef0f0;--el-color-error-dark-2: #c45656;--el-color-info: #909399;--el-color-info-light-3: #b1b3b8;--el-color-info-light-5: #c8c9cc;--el-color-info-light-7: #dedfe0;--el-color-info-light-8: #e9e9eb;--el-color-info-light-9: #f4f4f5;--el-color-info-dark-2: #73767a;--el-bg-color: #ffffff;--el-bg-color-page: #f2f3f5;--el-bg-color-overlay: #ffffff;--el-text-color-primary: #303133;--el-text-color-regular: #606266;--el-text-color-secondary: #909399;--el-text-color-placeholder: #a8abb2;--el-text-color-disabled: #c0c4cc;--el-border-color: #dcdfe6;--el-border-color-light: #e4e7ed;--el-border-color-lighter: #ebeef5;--el-border-color-extra-light: #f2f6fc;--el-border-color-dark: #d4d7de;--el-border-color-darker: #cdd0d6;--el-fill-color: #f0f2f5;--el-fill-color-light: #f5f7fa;--el-fill-color-lighter: #fafafa;--el-fill-color-extra-light: #fafcff;--el-fill-color-dark: #ebedf0;--el-fill-color-darker: #e6e8eb;--el-fill-color-blank: #ffffff;--el-box-shadow: 0px 12px 32px 4px rgba(0, 0, 0, .04), 0px 8px 20px rgba(0, 0, 0, .08);--el-box-shadow-light: 0px 0px 12px rgba(0, 0, 0, .12);--el-box-shadow-lighter: 0px 0px 6px rgba(0, 0, 0, .12);--el-box-shadow-dark: 0px 16px 48px 16px rgba(0, 0, 0, .08), 0px 12px 32px rgba(0, 0, 0, .12), 0px 8px 16px -8px rgba(0, 0, 0, .16);--el-disabled-bg-color: var(--el-fill-color-light);--el-disabled-text-color: var(--el-text-color-placeholder);--el-disabled-border-color: var(--el-border-color-light);--el-overlay-color: rgba(0, 0, 0, .8);--el-overlay-color-light: rgba(0, 0, 0, .7);--el-overlay-color-lighter: rgba(0, 0, 0, .5);--el-mask-color: rgba(255, 255, 255, .9);--el-mask-color-extra-light: rgba(255, 255, 255, .3);--el-border-width: 1px;--el-border-style: solid;--el-border-color-hover: var(--el-text-color-disabled);--el-border: var(--el-border-width) var(--el-border-style) var(--el-border-color);--el-svg-monochrome-grey: var(--el-border-color)}.fade-in-linear-enter-active,.fade-in-linear-leave-active{transition:var(--el-transition-fade-linear)}.fade-in-linear-enter-from,.fade-in-linear-leave-to{opacity:0}.el-fade-in-linear-enter-active,.el-fade-in-linear-leave-active{transition:var(--el-transition-fade-linear)}.el-fade-in-linear-enter-from,.el-fade-in-linear-leave-to{opacity:0}.el-fade-in-enter-active,.el-fade-in-leave-active{transition:all var(--el-transition-duration) cubic-bezier(.55,0,.1,1)}.el-fade-in-enter-from,.el-fade-in-leave-active{opacity:0}.el-zoom-in-center-enter-active,.el-zoom-in-center-leave-active{transition:all var(--el-transition-duration) cubic-bezier(.55,0,.1,1)}.el-zoom-in-center-enter-from,.el-zoom-in-center-leave-active{opacity:0;transform:scaleX(0)}.el-zoom-in-top-enter-active,.el-zoom-in-top-leave-active{opacity:1;transform:scaleY(1);transition:var(--el-transition-md-fade);transform-origin:center top}.el-zoom-in-top-enter-active[data-popper-placement^=top],.el-zoom-in-top-leave-active[data-popper-placement^=top]{transform-origin:center bottom}.el-zoom-in-top-enter-from,.el-zoom-in-top-leave-active{opacity:0;transform:scaleY(0)}.el-zoom-in-bottom-enter-active,.el-zoom-in-bottom-leave-active{opacity:1;transform:scaleY(1);transition:var(--el-transition-md-fade);transform-origin:center bottom}.el-zoom-in-bottom-enter-from,.el-zoom-in-bottom-leave-active{opacity:0;transform:scaleY(0)}.el-zoom-in-left-enter-active,.el-zoom-in-left-leave-active{opacity:1;transform:scale(1);transition:var(--el-transition-md-fade);transform-origin:top left}.el-zoom-in-left-enter-from,.el-zoom-in-left-leave-active{opacity:0;transform:scale(.45)}.collapse-transition{transition:var(--el-transition-duration) height ease-in-out,var(--el-transition-duration) padding-top ease-in-out,var(--el-transition-duration) padding-bottom ease-in-out}.el-collapse-transition-leave-active,.el-collapse-transition-enter-active{transition:var(--el-transition-duration) max-height ease-in-out,var(--el-transition-duration) padding-top ease-in-out,var(--el-transition-duration) padding-bottom ease-in-out}.horizontal-collapse-transition{transition:var(--el-transition-duration) width ease-in-out,var(--el-transition-duration) padding-left ease-in-out,var(--el-transition-duration) padding-right ease-in-out}.el-list-enter-active,.el-list-leave-active{transition:all 1s}.el-list-enter-from,.el-list-leave-to{opacity:0;transform:translateY(-30px)}.el-list-leave-active{position:absolute!important}.el-opacity-transition{transition:opacity var(--el-transition-duration) cubic-bezier(.55,0,.1,1)}.el-icon-loading{animation:rotating 2s linear infinite}.el-icon--right{margin-left:5px}.el-icon--left{margin-right:5px}@keyframes rotating{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.el-icon{--color: inherit;height:1em;width:1em;line-height:1em;display:inline-flex;justify-content:center;align-items:center;position:relative;fill:currentColor;color:var(--color);font-size:inherit}.el-icon.is-loading{animation:rotating 2s linear infinite}.el-icon svg{height:1em;width:1em}.fade-in-linear-enter-active,.fade-in-linear-leave-active{transition:var(--el-transition-fade-linear)}.fade-in-linear-enter-from,.fade-in-linear-leave-to{opacity:0}.el-fade-in-linear-enter-active,.el-fade-in-linear-leave-active{transition:var(--el-transition-fade-linear)}.el-fade-in-linear-enter-from,.el-fade-in-linear-leave-to{opacity:0}.el-fade-in-enter-active,.el-fade-in-leave-active{transition:all var(--el-transition-duration) cubic-bezier(.55,0,.1,1)}.el-fade-in-enter-from,.el-fade-in-leave-active{opacity:0}.el-zoom-in-center-enter-active,.el-zoom-in-center-leave-active{transition:all var(--el-transition-duration) cubic-bezier(.55,0,.1,1)}.el-zoom-in-center-enter-from,.el-zoom-in-center-leave-active{opacity:0;transform:scaleX(0)}.el-zoom-in-top-enter-active,.el-zoom-in-top-leave-active{opacity:1;transform:scaleY(1);transition:var(--el-transition-md-fade);transform-origin:center top}.el-zoom-in-top-enter-active[data-popper-placement^=top],.el-zoom-in-top-leave-active[data-popper-placement^=top]{transform-origin:center bottom}.el-zoom-in-top-enter-from,.el-zoom-in-top-leave-active{opacity:0;transform:scaleY(0)}.el-zoom-in-bottom-enter-active,.el-zoom-in-bottom-leave-active{opacity:1;transform:scaleY(1);transition:var(--el-transition-md-fade);transform-origin:center bottom}.el-zoom-in-bottom-enter-from,.el-zoom-in-bottom-leave-active{opacity:0;transform:scaleY(0)}.el-zoom-in-left-enter-active,.el-zoom-in-left-leave-active{opacity:1;transform:scale(1);transition:var(--el-transition-md-fade);transform-origin:top left}.el-zoom-in-left-enter-from,.el-zoom-in-left-leave-active{opacity:0;transform:scale(.45)}.collapse-transition{transition:var(--el-transition-duration) height ease-in-out,var(--el-transition-duration) padding-top ease-in-out,var(--el-transition-duration) padding-bottom ease-in-out}.el-collapse-transition-leave-active,.el-collapse-transition-enter-active{transition:var(--el-transition-duration) max-height ease-in-out,var(--el-transition-duration) padding-top ease-in-out,var(--el-transition-duration) padding-bottom ease-in-out}.horizontal-collapse-transition{transition:var(--el-transition-duration) width ease-in-out,var(--el-transition-duration) padding-left ease-in-out,var(--el-transition-duration) padding-right ease-in-out}.el-list-enter-active,.el-list-leave-active{transition:all 1s}.el-list-enter-from,.el-list-leave-to{opacity:0;transform:translateY(-30px)}.el-list-leave-active{position:absolute!important}.el-opacity-transition{transition:opacity var(--el-transition-duration) cubic-bezier(.55,0,.1,1)}:root{--el-menu-active-color: var(--el-color-primary);--el-menu-text-color: var(--el-text-color-primary);--el-menu-hover-text-color: var(--el-color-primary);--el-menu-bg-color: var(--el-fill-color-blank);--el-menu-hover-bg-color: var(--el-color-primary-light-9);--el-menu-item-height: 56px;--el-menu-sub-item-height: calc(var(--el-menu-item-height) - 6px);--el-menu-horizontal-sub-item-height: 36px;--el-menu-item-font-size: var(--el-font-size-base);--el-menu-item-hover-fill: var(--el-color-primary-light-9);--el-menu-border-color: var(--el-border-color);--el-menu-base-level-padding: 20px;--el-menu-level-padding: 20px;--el-menu-icon-width: 24px;--el-menu-icon-transform-closed: none;--el-menu-icon-transform-open: rotateZ(180deg)}.el-menu{border-right:solid 1px var(--el-menu-border-color);list-style:none;position:relative;margin:0;padding-left:0;background-color:var(--el-menu-bg-color);box-sizing:border-box}.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-menu-item,.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title,.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-menu-item-group__title{white-space:nowrap;padding-left:calc(var(--el-menu-base-level-padding) + var(--el-menu-level) * var(--el-menu-level-padding))}.el-menu--horizontal{display:flex;flex-wrap:nowrap;border-bottom:solid 1px var(--el-menu-border-color);border-right:none}.el-menu--horizontal>.el-menu-item{display:inline-flex;justify-content:center;align-items:center;height:100%;margin:0;border-bottom:2px solid transparent;color:var(--el-menu-text-color)}.el-menu--horizontal>.el-menu-item a,.el-menu--horizontal>.el-menu-item a:hover{color:inherit}.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus{background-color:#fff}.el-menu--horizontal>.el-sub-menu:focus,.el-menu--horizontal>.el-sub-menu:hover{outline:none}.el-menu--horizontal>.el-sub-menu:hover .el-sub-menu__title{color:var(--el-menu-hover-text-color)}.el-menu--horizontal>.el-sub-menu.is-active .el-sub-menu__title{border-bottom:2px solid var(--el-menu-active-color);color:var(--el-menu-active-color)}.el-menu--horizontal>.el-sub-menu .el-sub-menu__title{height:100%;border-bottom:2px solid transparent;color:var(--el-menu-text-color)}.el-menu--horizontal>.el-sub-menu .el-sub-menu__title:hover{background-color:var(--el-bg-color-overlay)}.el-menu--horizontal>.el-sub-menu .el-sub-menu__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-sub-menu__title{background-color:var(--el-menu-bg-color);display:flex;align-items:center;height:var(--el-menu-horizontal-sub-item-height);padding:0 10px;color:var(--el-menu-text-color)}.el-menu--horizontal .el-menu .el-sub-menu__title{padding-right:40px}.el-menu--horizontal .el-menu .el-menu-item.is-active,.el-menu--horizontal .el-menu .el-sub-menu.is-active>.el-sub-menu__title{color:var(--el-menu-active-color)}.el-menu--horizontal .el-menu-item:not(.is-disabled):hover,.el-menu--horizontal .el-menu-item:not(.is-disabled):focus{outline:none;color:var(--el-menu-hover-text-color);background-color:var(--el-menu-hover-bg-color)}.el-menu--horizontal>.el-menu-item.is-active{border-bottom:2px solid var(--el-menu-active-color);color:var(--el-menu-active-color)!important}.el-menu--collapse{width:calc(var(--el-menu-icon-width) + var(--el-menu-base-level-padding) * 2)}.el-menu--collapse>.el-menu-item [class^=el-icon],.el-menu--collapse>.el-sub-menu>.el-sub-menu__title [class^=el-icon]{margin:0;vertical-align:middle;width:var(--el-menu-icon-width);text-align:center}.el-menu--collapse>.el-menu-item .el-sub-menu__icon-arrow,.el-menu--collapse>.el-sub-menu>.el-sub-menu__title .el-sub-menu__icon-arrow{display:none}.el-menu--collapse>.el-menu-item>span,.el-menu--collapse>.el-sub-menu>.el-sub-menu__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-menu .el-sub-menu{min-width:200px}.el-menu--collapse .el-sub-menu{position:relative}.el-menu--collapse .el-sub-menu .el-menu{position:absolute;margin-left:5px;top:0;left:100%;z-index:10;border:1px solid var(--el-border-color-light);border-radius:var(--el-border-radius-small);box-shadow:var(--el-box-shadow-light)}.el-menu--collapse .el-sub-menu.is-opened>.el-sub-menu__title .el-sub-menu__icon-arrow{transform:var(--el-menu-icon-transform-closed)}.el-menu--collapse .el-sub-menu.is-active .el-sub-menu__title{color:var(--el-menu-active-color)}.el-menu--popup{z-index:100;min-width:200px;border:none;padding:5px 0;border-radius:var(--el-border-radius-small);box-shadow:var(--el-box-shadow-light)}.el-menu .el-icon{flex-shrink:0}.el-menu-item{display:flex;align-items:center;height:var(--el-menu-item-height);line-height:var(--el-menu-item-height);font-size:var(--el-menu-item-font-size);color:var(--el-menu-text-color);padding:0 var(--el-menu-base-level-padding);list-style:none;cursor:pointer;position:relative;transition:border-color var(--el-transition-duration),background-color var(--el-transition-duration),color var(--el-transition-duration);box-sizing:border-box;white-space:nowrap}.el-menu-item *{vertical-align:bottom}.el-menu-item i{color:inherit}.el-menu-item:hover,.el-menu-item:focus{outline:none}.el-menu-item:hover{background-color:var(--el-menu-hover-bg-color)}.el-menu-item.is-disabled{opacity:.25;cursor:not-allowed;background:none!important}.el-menu-item [class^=el-icon]{margin-right:5px;width:var(--el-menu-icon-width);text-align:center;font-size:18px;vertical-align:middle}.el-menu-item.is-active{color:var(--el-menu-active-color)}.el-menu-item.is-active i{color:inherit}.el-menu-item .el-menu-tooltip__trigger{position:absolute;left:0;top:0;height:100%;width:100%;display:inline-flex;align-items:center;box-sizing:border-box;padding:0 var(--el-menu-base-level-padding)}.el-sub-menu{list-style:none;margin:0;padding-left:0}.el-sub-menu__title{display:flex;align-items:center;height:var(--el-menu-item-height);line-height:var(--el-menu-item-height);font-size:var(--el-menu-item-font-size);color:var(--el-menu-text-color);padding:0 var(--el-menu-base-level-padding);list-style:none;cursor:pointer;position:relative;transition:border-color var(--el-transition-duration),background-color var(--el-transition-duration),color var(--el-transition-duration);box-sizing:border-box;white-space:nowrap}.el-sub-menu__title *{vertical-align:bottom}.el-sub-menu__title i{color:inherit}.el-sub-menu__title:hover,.el-sub-menu__title:focus{outline:none}.el-sub-menu__title.is-disabled{opacity:.25;cursor:not-allowed;background:none!important}.el-sub-menu__title:hover{background-color:var(--el-menu-hover-bg-color)}.el-sub-menu .el-menu{border:none}.el-sub-menu .el-menu-item{height:var(--el-menu-sub-item-height);line-height:var(--el-menu-sub-item-height);min-width:200px}.el-sub-menu__hide-arrow .el-sub-menu__icon-arrow{display:none!important}.el-sub-menu.is-active .el-sub-menu__title{border-bottom-color:var(--el-menu-active-color)}.el-sub-menu.is-opened>.el-sub-menu__title .el-sub-menu__icon-arrow{transform:var(--el-menu-icon-transform-open)}.el-sub-menu.is-disabled .el-sub-menu__title,.el-sub-menu.is-disabled .el-menu-item{opacity:.25;cursor:not-allowed;background:none!important}.el-sub-menu .el-icon{vertical-align:middle;margin-right:5px;width:var(--el-menu-icon-width);text-align:center;font-size:18px}.el-sub-menu .el-icon.el-sub-menu__icon-more{margin-right:0!important}.el-sub-menu .el-sub-menu__icon-arrow{position:absolute;top:50%;right:var(--el-menu-base-level-padding);margin-top:-7px;transform:var(--el-menu-icon-transform-closed);transition:transform var(--el-transition-duration);font-size:12px;margin-right:0;width:inherit}.el-menu-item-group>ul{padding:0}.el-menu-item-group__title{padding:7px 0 7px var(--el-menu-base-level-padding);line-height:normal;font-size:12px;color:var(--el-text-color-secondary)}.horizontal-collapse-transition .el-sub-menu__title .el-sub-menu__icon-arrow{transition:var(--el-transition-duration-fast);opacity:0}.el-popper{--el-popper-border-radius: var(--el-popover-border-radius, 4px)}.el-popper{position:absolute;border-radius:var(--el-popper-border-radius);padding:5px 11px;z-index:2000;font-size:12px;line-height:20px;min-width:10px;word-wrap:break-word;visibility:visible}.el-popper.is-dark{color:var(--el-bg-color);background:var(--el-text-color-primary);border:1px solid var(--el-text-color-primary)}.el-popper.is-dark .el-popper__arrow:before{border:1px solid var(--el-text-color-primary);background:var(--el-text-color-primary);right:0}.el-popper.is-light{background:var(--el-bg-color-overlay);border:1px solid var(--el-border-color-light)}.el-popper.is-light .el-popper__arrow:before{border:1px solid var(--el-border-color-light);background:var(--el-bg-color-overlay);right:0}.el-popper.is-pure{padding:0}.el-popper__arrow{position:absolute;width:10px;height:10px;z-index:-1}.el-popper__arrow:before{position:absolute;width:10px;height:10px;z-index:-1;content:" ";transform:rotate(45deg);background:var(--el-text-color-primary);box-sizing:border-box}.el-popper[data-popper-placement^=top]>.el-popper__arrow{bottom:-5px}.el-popper[data-popper-placement^=top]>.el-popper__arrow:before{border-bottom-right-radius:2px}.el-popper[data-popper-placement^=bottom]>.el-popper__arrow{top:-5px}.el-popper[data-popper-placement^=bottom]>.el-popper__arrow:before{border-top-left-radius:2px}.el-popper[data-popper-placement^=left]>.el-popper__arrow{right:-5px}.el-popper[data-popper-placement^=left]>.el-popper__arrow:before{border-top-right-radius:2px}.el-popper[data-popper-placement^=right]>.el-popper__arrow{left:-5px}.el-popper[data-popper-placement^=right]>.el-popper__arrow:before{border-bottom-left-radius:2px}.el-popper[data-popper-placement^=top] .el-popper__arrow:before{border-top-color:transparent!important;border-left-color:transparent!important}.el-popper[data-popper-placement^=bottom] .el-popper__arrow:before{border-bottom-color:transparent!important;border-right-color:transparent!important}.el-popper[data-popper-placement^=left] .el-popper__arrow:before{border-left-color:transparent!important;border-bottom-color:transparent!important}.el-popper[data-popper-placement^=right] .el-popper__arrow:before{border-right-color:transparent!important;border-top-color:transparent!important}.el-button{--el-button-font-weight: var(--el-font-weight-primary);--el-button-border-color: var(--el-border-color);--el-button-bg-color: var(--el-fill-color-blank);--el-button-text-color: var(--el-text-color-regular);--el-button-disabled-text-color: var(--el-disabled-text-color);--el-button-disabled-bg-color: var(--el-fill-color-blank);--el-button-disabled-border-color: var(--el-border-color-light);--el-button-divide-border-color: rgba(255, 255, 255, .5);--el-button-hover-text-color: var(--el-color-primary);--el-button-hover-bg-color: var(--el-color-primary-light-9);--el-button-hover-border-color: var(--el-color-primary-light-7);--el-button-active-text-color: var(--el-button-hover-text-color);--el-button-active-border-color: var(--el-color-primary);--el-button-active-bg-color: var(--el-button-hover-bg-color);--el-button-outline-color: var(--el-color-primary-light-5);--el-button-hover-link-text-color: var(--el-color-info);--el-button-active-color: var(--el-text-color-primary)}.el-button{display:inline-flex;justify-content:center;align-items:center;line-height:1;height:32px;white-space:nowrap;cursor:pointer;color:var(--el-button-text-color);text-align:center;box-sizing:border-box;outline:none;transition:.1s;font-weight:var(--el-button-font-weight);user-select:none;vertical-align:middle;-webkit-appearance:none;background-color:var(--el-button-bg-color);border:var(--el-border);border-color:var(--el-button-border-color);padding:8px 15px;font-size:var(--el-font-size-base);border-radius:var(--el-border-radius-base)}.el-button:hover,.el-button:focus{color:var(--el-button-hover-text-color);border-color:var(--el-button-hover-border-color);background-color:var(--el-button-hover-bg-color);outline:none}.el-button:active{color:var(--el-button-active-text-color);border-color:var(--el-button-active-border-color);background-color:var(--el-button-active-bg-color);outline:none}.el-button:focus-visible{outline:2px solid var(--el-button-outline-color);outline-offset:1px}.el-button>span{display:inline-flex;align-items:center}.el-button+.el-button{margin-left:12px}.el-button.is-round{padding:8px 15px}.el-button::-moz-focus-inner{border:0}.el-button [class*=el-icon]+span{margin-left:6px}.el-button [class*=el-icon] svg{vertical-align:bottom}.el-button.is-plain{--el-button-hover-text-color: var(--el-color-primary);--el-button-hover-bg-color: var(--el-fill-color-blank);--el-button-hover-border-color: var(--el-color-primary)}.el-button.is-active{color:var(--el-button-active-text-color);border-color:var(--el-button-active-border-color);background-color:var(--el-button-active-bg-color);outline:none}.el-button.is-disabled,.el-button.is-disabled:hover,.el-button.is-disabled:focus{color:var(--el-button-disabled-text-color);cursor:not-allowed;background-image:none;background-color:var(--el-button-disabled-bg-color);border-color:var(--el-button-disabled-border-color)}.el-button.is-loading{position:relative;pointer-events:none}.el-button.is-loading:before{z-index:1;pointer-events:none;content:"";position:absolute;left:-1px;top:-1px;right:-1px;bottom:-1px;border-radius:inherit;background-color:var(--el-mask-color-extra-light)}.el-button.is-round{border-radius:var(--el-border-radius-round)}.el-button.is-circle{border-radius:50%;padding:8px}.el-button.is-text{color:var(--el-button-text-color);border:0 solid transparent;background-color:transparent}.el-button.is-text.is-disabled{color:var(--el-button-disabled-text-color);background-color:transparent!important}.el-button.is-text:not(.is-disabled):hover,.el-button.is-text:not(.is-disabled):focus{background-color:var(--el-fill-color-light)}.el-button.is-text:not(.is-disabled):focus-visible{outline:2px solid var(--el-button-outline-color);outline-offset:1px}.el-button.is-text:not(.is-disabled):active{background-color:var(--el-fill-color)}.el-button.is-text:not(.is-disabled).is-has-bg{background-color:var(--el-fill-color-light)}.el-button.is-text:not(.is-disabled).is-has-bg:hover,.el-button.is-text:not(.is-disabled).is-has-bg:focus{background-color:var(--el-fill-color)}.el-button.is-text:not(.is-disabled).is-has-bg:active{background-color:var(--el-fill-color-dark)}.el-button__text--expand{letter-spacing:.3em;margin-right:-.3em}.el-button.is-link{border-color:transparent;color:var(--el-button-text-color);background:transparent;padding:2px;height:auto}.el-button.is-link:hover,.el-button.is-link:focus{color:var(--el-button-hover-link-text-color)}.el-button.is-link.is-disabled{color:var(--el-button-disabled-text-color);background-color:transparent!important;border-color:transparent!important}.el-button.is-link:not(.is-disabled):hover,.el-button.is-link:not(.is-disabled):focus{border-color:transparent;background-color:transparent}.el-button.is-link:not(.is-disabled):active{color:var(--el-button-active-color);border-color:transparent;background-color:transparent}.el-button--text{border-color:transparent;background:transparent;color:var(--el-color-primary);padding-left:0;padding-right:0}.el-button--text.is-disabled{color:var(--el-button-disabled-text-color);background-color:transparent!important;border-color:transparent!important}.el-button--text:not(.is-disabled):hover,.el-button--text:not(.is-disabled):focus{color:var(--el-color-primary-light-3);border-color:transparent;background-color:transparent}.el-button--text:not(.is-disabled):active{color:var(--el-color-primary-dark-2);border-color:transparent;background-color:transparent}.el-button__link--expand{letter-spacing:.3em;margin-right:-.3em}.el-button--primary{--el-button-text-color: var(--el-color-white);--el-button-bg-color: var(--el-color-primary);--el-button-border-color: var(--el-color-primary);--el-button-outline-color: var(--el-color-primary-light-5);--el-button-active-color: var(--el-color-primary-dark-2);--el-button-hover-text-color: var(--el-color-white);--el-button-hover-link-text-color: var(--el-color-primary-light-5);--el-button-hover-bg-color: var(--el-color-primary-light-3);--el-button-hover-border-color: var(--el-color-primary-light-3);--el-button-active-bg-color: var(--el-color-primary-dark-2);--el-button-active-border-color: var(--el-color-primary-dark-2);--el-button-disabled-text-color: var(--el-color-white);--el-button-disabled-bg-color: var(--el-color-primary-light-5);--el-button-disabled-border-color: var(--el-color-primary-light-5)}.el-button--primary.is-plain,.el-button--primary.is-text,.el-button--primary.is-link{--el-button-text-color: var(--el-color-primary);--el-button-bg-color: var(--el-color-primary-light-9);--el-button-border-color: var(--el-color-primary-light-5);--el-button-hover-text-color: var(--el-color-white);--el-button-hover-bg-color: var(--el-color-primary);--el-button-hover-border-color: var(--el-color-primary);--el-button-active-text-color: var(--el-color-white)}.el-button--primary.is-plain.is-disabled,.el-button--primary.is-plain.is-disabled:hover,.el-button--primary.is-plain.is-disabled:focus,.el-button--primary.is-plain.is-disabled:active,.el-button--primary.is-text.is-disabled,.el-button--primary.is-text.is-disabled:hover,.el-button--primary.is-text.is-disabled:focus,.el-button--primary.is-text.is-disabled:active,.el-button--primary.is-link.is-disabled,.el-button--primary.is-link.is-disabled:hover,.el-button--primary.is-link.is-disabled:focus,.el-button--primary.is-link.is-disabled:active{color:var(--el-color-primary-light-5);background-color:var(--el-color-primary-light-9);border-color:var(--el-color-primary-light-8)}.el-button--success{--el-button-text-color: var(--el-color-white);--el-button-bg-color: var(--el-color-success);--el-button-border-color: var(--el-color-success);--el-button-outline-color: var(--el-color-success-light-5);--el-button-active-color: var(--el-color-success-dark-2);--el-button-hover-text-color: var(--el-color-white);--el-button-hover-link-text-color: var(--el-color-success-light-5);--el-button-hover-bg-color: var(--el-color-success-light-3);--el-button-hover-border-color: var(--el-color-success-light-3);--el-button-active-bg-color: var(--el-color-success-dark-2);--el-button-active-border-color: var(--el-color-success-dark-2);--el-button-disabled-text-color: var(--el-color-white);--el-button-disabled-bg-color: var(--el-color-success-light-5);--el-button-disabled-border-color: var(--el-color-success-light-5)}.el-button--success.is-plain,.el-button--success.is-text,.el-button--success.is-link{--el-button-text-color: var(--el-color-success);--el-button-bg-color: var(--el-color-success-light-9);--el-button-border-color: var(--el-color-success-light-5);--el-button-hover-text-color: var(--el-color-white);--el-button-hover-bg-color: var(--el-color-success);--el-button-hover-border-color: var(--el-color-success);--el-button-active-text-color: var(--el-color-white)}.el-button--success.is-plain.is-disabled,.el-button--success.is-plain.is-disabled:hover,.el-button--success.is-plain.is-disabled:focus,.el-button--success.is-plain.is-disabled:active,.el-button--success.is-text.is-disabled,.el-button--success.is-text.is-disabled:hover,.el-button--success.is-text.is-disabled:focus,.el-button--success.is-text.is-disabled:active,.el-button--success.is-link.is-disabled,.el-button--success.is-link.is-disabled:hover,.el-button--success.is-link.is-disabled:focus,.el-button--success.is-link.is-disabled:active{color:var(--el-color-success-light-5);background-color:var(--el-color-success-light-9);border-color:var(--el-color-success-light-8)}.el-button--warning{--el-button-text-color: var(--el-color-white);--el-button-bg-color: var(--el-color-warning);--el-button-border-color: var(--el-color-warning);--el-button-outline-color: var(--el-color-warning-light-5);--el-button-active-color: var(--el-color-warning-dark-2);--el-button-hover-text-color: var(--el-color-white);--el-button-hover-link-text-color: var(--el-color-warning-light-5);--el-button-hover-bg-color: var(--el-color-warning-light-3);--el-button-hover-border-color: var(--el-color-warning-light-3);--el-button-active-bg-color: var(--el-color-warning-dark-2);--el-button-active-border-color: var(--el-color-warning-dark-2);--el-button-disabled-text-color: var(--el-color-white);--el-button-disabled-bg-color: var(--el-color-warning-light-5);--el-button-disabled-border-color: var(--el-color-warning-light-5)}.el-button--warning.is-plain,.el-button--warning.is-text,.el-button--warning.is-link{--el-button-text-color: var(--el-color-warning);--el-button-bg-color: var(--el-color-warning-light-9);--el-button-border-color: var(--el-color-warning-light-5);--el-button-hover-text-color: var(--el-color-white);--el-button-hover-bg-color: var(--el-color-warning);--el-button-hover-border-color: var(--el-color-warning);--el-button-active-text-color: var(--el-color-white)}.el-button--warning.is-plain.is-disabled,.el-button--warning.is-plain.is-disabled:hover,.el-button--warning.is-plain.is-disabled:focus,.el-button--warning.is-plain.is-disabled:active,.el-button--warning.is-text.is-disabled,.el-button--warning.is-text.is-disabled:hover,.el-button--warning.is-text.is-disabled:focus,.el-button--warning.is-text.is-disabled:active,.el-button--warning.is-link.is-disabled,.el-button--warning.is-link.is-disabled:hover,.el-button--warning.is-link.is-disabled:focus,.el-button--warning.is-link.is-disabled:active{color:var(--el-color-warning-light-5);background-color:var(--el-color-warning-light-9);border-color:var(--el-color-warning-light-8)}.el-button--danger{--el-button-text-color: var(--el-color-white);--el-button-bg-color: var(--el-color-danger);--el-button-border-color: var(--el-color-danger);--el-button-outline-color: var(--el-color-danger-light-5);--el-button-active-color: var(--el-color-danger-dark-2);--el-button-hover-text-color: var(--el-color-white);--el-button-hover-link-text-color: var(--el-color-danger-light-5);--el-button-hover-bg-color: var(--el-color-danger-light-3);--el-button-hover-border-color: var(--el-color-danger-light-3);--el-button-active-bg-color: var(--el-color-danger-dark-2);--el-button-active-border-color: var(--el-color-danger-dark-2);--el-button-disabled-text-color: var(--el-color-white);--el-button-disabled-bg-color: var(--el-color-danger-light-5);--el-button-disabled-border-color: var(--el-color-danger-light-5)}.el-button--danger.is-plain,.el-button--danger.is-text,.el-button--danger.is-link{--el-button-text-color: var(--el-color-danger);--el-button-bg-color: var(--el-color-danger-light-9);--el-button-border-color: var(--el-color-danger-light-5);--el-button-hover-text-color: var(--el-color-white);--el-button-hover-bg-color: var(--el-color-danger);--el-button-hover-border-color: var(--el-color-danger);--el-button-active-text-color: var(--el-color-white)}.el-button--danger.is-plain.is-disabled,.el-button--danger.is-plain.is-disabled:hover,.el-button--danger.is-plain.is-disabled:focus,.el-button--danger.is-plain.is-disabled:active,.el-button--danger.is-text.is-disabled,.el-button--danger.is-text.is-disabled:hover,.el-button--danger.is-text.is-disabled:focus,.el-button--danger.is-text.is-disabled:active,.el-button--danger.is-link.is-disabled,.el-button--danger.is-link.is-disabled:hover,.el-button--danger.is-link.is-disabled:focus,.el-button--danger.is-link.is-disabled:active{color:var(--el-color-danger-light-5);background-color:var(--el-color-danger-light-9);border-color:var(--el-color-danger-light-8)}.el-button--info{--el-button-text-color: var(--el-color-white);--el-button-bg-color: var(--el-color-info);--el-button-border-color: var(--el-color-info);--el-button-outline-color: var(--el-color-info-light-5);--el-button-active-color: var(--el-color-info-dark-2);--el-button-hover-text-color: var(--el-color-white);--el-button-hover-link-text-color: var(--el-color-info-light-5);--el-button-hover-bg-color: var(--el-color-info-light-3);--el-button-hover-border-color: var(--el-color-info-light-3);--el-button-active-bg-color: var(--el-color-info-dark-2);--el-button-active-border-color: var(--el-color-info-dark-2);--el-button-disabled-text-color: var(--el-color-white);--el-button-disabled-bg-color: var(--el-color-info-light-5);--el-button-disabled-border-color: var(--el-color-info-light-5)}.el-button--info.is-plain,.el-button--info.is-text,.el-button--info.is-link{--el-button-text-color: var(--el-color-info);--el-button-bg-color: var(--el-color-info-light-9);--el-button-border-color: var(--el-color-info-light-5);--el-button-hover-text-color: var(--el-color-white);--el-button-hover-bg-color: var(--el-color-info);--el-button-hover-border-color: var(--el-color-info);--el-button-active-text-color: var(--el-color-white)}.el-button--info.is-plain.is-disabled,.el-button--info.is-plain.is-disabled:hover,.el-button--info.is-plain.is-disabled:focus,.el-button--info.is-plain.is-disabled:active,.el-button--info.is-text.is-disabled,.el-button--info.is-text.is-disabled:hover,.el-button--info.is-text.is-disabled:focus,.el-button--info.is-text.is-disabled:active,.el-button--info.is-link.is-disabled,.el-button--info.is-link.is-disabled:hover,.el-button--info.is-link.is-disabled:focus,.el-button--info.is-link.is-disabled:active{color:var(--el-color-info-light-5);background-color:var(--el-color-info-light-9);border-color:var(--el-color-info-light-8)}.el-button--large{--el-button-size: 40px;height:var(--el-button-size);padding:12px 19px;font-size:var(--el-font-size-base);border-radius:var(--el-border-radius-base)}.el-button--large [class*=el-icon]+span{margin-left:8px}.el-button--large.is-round{padding:12px 19px}.el-button--large.is-circle{width:var(--el-button-size);padding:12px}.el-button--small{--el-button-size: 24px;height:var(--el-button-size);padding:5px 11px;font-size:12px;border-radius:calc(var(--el-border-radius-base) - 1px)}.el-button--small [class*=el-icon]+span{margin-left:4px}.el-button--small.is-round{padding:5px 11px}.el-button--small.is-circle{width:var(--el-button-size);padding:5px}:root{--el-color-white:#ffffff;--el-color-black:#000000;--el-color-primary-rgb:64,158,255;--el-color-success-rgb:103,194,58;--el-color-warning-rgb:230,162,60;--el-color-danger-rgb:245,108,108;--el-color-error-rgb:245,108,108;--el-color-info-rgb:144,147,153;--el-font-size-extra-large:20px;--el-font-size-large:18px;--el-font-size-medium:16px;--el-font-size-base:14px;--el-font-size-small:13px;--el-font-size-extra-small:12px;--el-font-family:"Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","\5fae\8f6f\96c5\9ed1",Arial,sans-serif;--el-font-weight-primary:500;--el-font-line-height-primary:24px;--el-index-normal:1;--el-index-top:1000;--el-index-popper:2000;--el-border-radius-base:4px;--el-border-radius-small:2px;--el-border-radius-round:20px;--el-border-radius-circle:100%;--el-transition-duration:.3s;--el-transition-duration-fast:.2s;--el-transition-function-ease-in-out-bezier:cubic-bezier(.645, .045, .355, 1);--el-transition-function-fast-bezier:cubic-bezier(.23, 1, .32, 1);--el-transition-all:all var(--el-transition-duration) var(--el-transition-function-ease-in-out-bezier);--el-transition-fade:opacity var(--el-transition-duration) var(--el-transition-function-fast-bezier);--el-transition-md-fade:transform var(--el-transition-duration) var(--el-transition-function-fast-bezier),opacity var(--el-transition-duration) var(--el-transition-function-fast-bezier);--el-transition-fade-linear:opacity var(--el-transition-duration-fast) linear;--el-transition-border:border-color var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier);--el-transition-box-shadow:box-shadow var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier);--el-transition-color:color var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier);--el-component-size-large:40px;--el-component-size:32px;--el-component-size-small:24px}:root{color-scheme:light;--el-color-white:#ffffff;--el-color-black:#000000;--el-color-primary:#409eff;--el-color-primary-light-3:#79bbff;--el-color-primary-light-5:#a0cfff;--el-color-primary-light-7:#c6e2ff;--el-color-primary-light-8:#d9ecff;--el-color-primary-light-9:#ecf5ff;--el-color-primary-dark-2:#337ecc;--el-color-success:#67c23a;--el-color-success-light-3:#95d475;--el-color-success-light-5:#b3e19d;--el-color-success-light-7:#d1edc4;--el-color-success-light-8:#e1f3d8;--el-color-success-light-9:#f0f9eb;--el-color-success-dark-2:#529b2e;--el-color-warning:#e6a23c;--el-color-warning-light-3:#eebe77;--el-color-warning-light-5:#f3d19e;--el-color-warning-light-7:#f8e3c5;--el-color-warning-light-8:#faecd8;--el-color-warning-light-9:#fdf6ec;--el-color-warning-dark-2:#b88230;--el-color-danger:#f56c6c;--el-color-danger-light-3:#f89898;--el-color-danger-light-5:#fab6b6;--el-color-danger-light-7:#fcd3d3;--el-color-danger-light-8:#fde2e2;--el-color-danger-light-9:#fef0f0;--el-color-danger-dark-2:#c45656;--el-color-error:#f56c6c;--el-color-error-light-3:#f89898;--el-color-error-light-5:#fab6b6;--el-color-error-light-7:#fcd3d3;--el-color-error-light-8:#fde2e2;--el-color-error-light-9:#fef0f0;--el-color-error-dark-2:#c45656;--el-color-info:#909399;--el-color-info-light-3:#b1b3b8;--el-color-info-light-5:#c8c9cc;--el-color-info-light-7:#dedfe0;--el-color-info-light-8:#e9e9eb;--el-color-info-light-9:#f4f4f5;--el-color-info-dark-2:#73767a;--el-bg-color:#ffffff;--el-bg-color-page:#f2f3f5;--el-bg-color-overlay:#ffffff;--el-text-color-primary:#303133;--el-text-color-regular:#606266;--el-text-color-secondary:#909399;--el-text-color-placeholder:#a8abb2;--el-text-color-disabled:#c0c4cc;--el-border-color:#dcdfe6;--el-border-color-light:#e4e7ed;--el-border-color-lighter:#ebeef5;--el-border-color-extra-light:#f2f6fc;--el-border-color-dark:#d4d7de;--el-border-color-darker:#cdd0d6;--el-fill-color:#f0f2f5;--el-fill-color-light:#f5f7fa;--el-fill-color-lighter:#fafafa;--el-fill-color-extra-light:#fafcff;--el-fill-color-dark:#ebedf0;--el-fill-color-darker:#e6e8eb;--el-fill-color-blank:#ffffff;--el-box-shadow:0px 12px 32px 4px rgba(0, 0, 0, .04),0px 8px 20px rgba(0, 0, 0, .08);--el-box-shadow-light:0px 0px 12px rgba(0, 0, 0, .12);--el-box-shadow-lighter:0px 0px 6px rgba(0, 0, 0, .12);--el-box-shadow-dark:0px 16px 48px 16px rgba(0, 0, 0, .08),0px 12px 32px rgba(0, 0, 0, .12),0px 8px 16px -8px rgba(0, 0, 0, .16);--el-disabled-bg-color:var(--el-fill-color-light);--el-disabled-text-color:var(--el-text-color-placeholder);--el-disabled-border-color:var(--el-border-color-light);--el-overlay-color:rgba(0, 0, 0, .8);--el-overlay-color-light:rgba(0, 0, 0, .7);--el-overlay-color-lighter:rgba(0, 0, 0, .5);--el-mask-color:rgba(255, 255, 255, .9);--el-mask-color-extra-light:rgba(255, 255, 255, .3);--el-border-width:1px;--el-border-style:solid;--el-border-color-hover:var(--el-text-color-disabled);--el-border:var(--el-border-width) var(--el-border-style) var(--el-border-color);--el-svg-monochrome-grey:var(--el-border-color)}.fade-in-linear-enter-active,.fade-in-linear-leave-active{transition:var(--el-transition-fade-linear)}.fade-in-linear-enter-from,.fade-in-linear-leave-to{opacity:0}.el-fade-in-linear-enter-active,.el-fade-in-linear-leave-active{transition:var(--el-transition-fade-linear)}.el-fade-in-linear-enter-from,.el-fade-in-linear-leave-to{opacity:0}.el-fade-in-enter-active,.el-fade-in-leave-active{transition:all var(--el-transition-duration) cubic-bezier(.55,0,.1,1)}.el-fade-in-enter-from,.el-fade-in-leave-active{opacity:0}.el-zoom-in-center-enter-active,.el-zoom-in-center-leave-active{transition:all var(--el-transition-duration) cubic-bezier(.55,0,.1,1)}.el-zoom-in-center-enter-from,.el-zoom-in-center-leave-active{opacity:0;transform:scaleX(0)}.el-zoom-in-top-enter-active,.el-zoom-in-top-leave-active{opacity:1;transform:scaleY(1);transition:var(--el-transition-md-fade);transform-origin:center top}.el-zoom-in-top-enter-active[data-popper-placement^=top],.el-zoom-in-top-leave-active[data-popper-placement^=top]{transform-origin:center bottom}.el-zoom-in-top-enter-from,.el-zoom-in-top-leave-active{opacity:0;transform:scaleY(0)}.el-zoom-in-bottom-enter-active,.el-zoom-in-bottom-leave-active{opacity:1;transform:scaleY(1);transition:var(--el-transition-md-fade);transform-origin:center bottom}.el-zoom-in-bottom-enter-from,.el-zoom-in-bottom-leave-active{opacity:0;transform:scaleY(0)}.el-zoom-in-left-enter-active,.el-zoom-in-left-leave-active{opacity:1;transform:scale(1);transition:var(--el-transition-md-fade);transform-origin:top left}.el-zoom-in-left-enter-from,.el-zoom-in-left-leave-active{opacity:0;transform:scale(.45)}.collapse-transition{transition:var(--el-transition-duration) height ease-in-out,var(--el-transition-duration) padding-top ease-in-out,var(--el-transition-duration) padding-bottom ease-in-out}.el-collapse-transition-enter-active,.el-collapse-transition-leave-active{transition:var(--el-transition-duration) max-height ease-in-out,var(--el-transition-duration) padding-top ease-in-out,var(--el-transition-duration) padding-bottom ease-in-out}.horizontal-collapse-transition{transition:var(--el-transition-duration) width ease-in-out,var(--el-transition-duration) padding-left ease-in-out,var(--el-transition-duration) padding-right ease-in-out}.el-list-enter-active,.el-list-leave-active{transition:all 1s}.el-list-enter-from,.el-list-leave-to{opacity:0;transform:translateY(-30px)}.el-list-leave-active{position:absolute!important}.el-opacity-transition{transition:opacity var(--el-transition-duration) cubic-bezier(.55,0,.1,1)}.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%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes rotating{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.el-icon{--color:inherit;height:1em;width:1em;line-height:1em;display:inline-flex;justify-content:center;align-items:center;position:relative;fill:currentColor;color:var(--color);font-size:inherit}.el-icon.is-loading{-webkit-animation:rotating 2s linear infinite;animation:rotating 2s linear infinite}.el-icon svg{height:1em;width:1em}.el-notification{--el-notification-width:330px;--el-notification-padding:14px 26px 14px 13px;--el-notification-radius:8px;--el-notification-shadow:var(--el-box-shadow-light);--el-notification-border-color:var(--el-border-color-lighter);--el-notification-icon-size:24px;--el-notification-close-font-size:var(--el-message-close-size, 16px);--el-notification-group-margin-left:13px;--el-notification-group-margin-right:8px;--el-notification-content-font-size:var(--el-font-size-base);--el-notification-content-color:var(--el-text-color-regular);--el-notification-title-font-size:16px;--el-notification-title-color:var(--el-text-color-primary);--el-notification-close-color:var(--el-text-color-secondary);--el-notification-close-hover-color:var(--el-text-color-regular)}.el-notification{display:flex;width:var(--el-notification-width);padding:var(--el-notification-padding);border-radius:var(--el-notification-radius);box-sizing:border-box;border:1px solid var(--el-notification-border-color);position:fixed;background-color:var(--el-bg-color-overlay);box-shadow:var(--el-notification-shadow);transition:opacity var(--el-transition-duration),transform var(--el-transition-duration),left var(--el-transition-duration),right var(--el-transition-duration),top .4s,bottom var(--el-transition-duration);overflow-wrap:anywhere;overflow:hidden;z-index:9999}.el-notification.right{right:16px}.el-notification.left{left:16px}.el-notification__group{margin-left:var(--el-notification-group-margin-left);margin-right:var(--el-notification-group-margin-right)}.el-notification__title{font-weight:700;font-size:var(--el-notification-title-font-size);line-height:var(--el-notification-icon-size);color:var(--el-notification-title-color);margin:0}.el-notification__content{font-size:var(--el-notification-content-font-size);line-height:24px;margin:6px 0 0;color:var(--el-notification-content-color);text-align:justify}.el-notification__content p{margin:0}.el-notification .el-notification__icon{height:var(--el-notification-icon-size);width:var(--el-notification-icon-size);font-size:var(--el-notification-icon-size)}.el-notification .el-notification__closeBtn{position:absolute;top:18px;right:15px;cursor:pointer;color:var(--el-notification-close-color);font-size:var(--el-notification-close-font-size)}.el-notification .el-notification__closeBtn:hover{color:var(--el-notification-close-hover-color)}.el-notification .el-notification--success{--el-notification-icon-color:var(--el-color-success);color:var(--el-notification-icon-color)}.el-notification .el-notification--info{--el-notification-icon-color:var(--el-color-info);color:var(--el-notification-icon-color)}.el-notification .el-notification--warning{--el-notification-icon-color:var(--el-color-warning);color:var(--el-notification-icon-color)}.el-notification .el-notification--error{--el-notification-icon-color:var(--el-color-error);color:var(--el-notification-icon-color)}.el-notification-fade-enter-from.right{right:0;transform:translate(100%)}.el-notification-fade-enter-from.left{left:0;transform:translate(-100%)}.el-notification-fade-leave-to{opacity:0}#global-uploader:not(.global-uploader-single){position:fixed;z-index:20;right:15px;bottom:15px;box-sizing:border-box}#global-uploader .uploader-app{width:520px}#global-uploader .file-panel{background-color:#fff;border:1px solid #e2e2e2;border-radius:7px 7px 0 0;box-shadow:0 0 10px #0003}#global-uploader .file-panel .file-title{display:flex;height:40px;line-height:40px;padding:0 15px;border-bottom:1px solid #ddd}#global-uploader .file-panel .file-title .operate{flex:1;text-align:right}#global-uploader .file-panel .file-title .operate .el-button{--el-button-hover-link-text-color: #108ee9}#global-uploader .file-panel .file-title .operate .el-button+.el-button{margin-left:8px}#global-uploader .file-panel .file-list{position:relative;height:240px;overflow-x:hidden;overflow-y:auto;background-color:#fff;transition:all .3s}#global-uploader .file-panel .file-list .file-item{background-color:#fff}#global-uploader .file-panel.collapse .file-title{background-color:#e7ecf2}#global-uploader .file-panel.collapse .file-list{height:0}#global-uploader .no-file{position:absolute;top:45%;left:50%;transform:translate(-50%,-50%);color:#999}#global-uploader .no-file svg{vertical-align:text-bottom}#global-uploader .uploader-file.md5 .uploader-file-resume{display:none}#global-uploader .uploader-file-icon:before{content:""!important}#global-uploader .uploader-file-icon[icon=image]{background:url(/vue-uploader-solutions-next/assets/image-icon.63fadd7f.png)}#global-uploader .uploader-file-icon[icon=audio]{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACL0lEQVRYR2NkgILPN9XqGRgY0/4zMEjBxCihGRnZL3By+veyyDYvwWcOI9wBt9Su/P/PqE2Jpch6IQ7wM2BgYEhhkW2Zi8tcuAM+3VT/Ty3LQeYgOYCBkZEhi1mmZTo28+niALCDGBjzmWWbJ6E7gm4OADviP0MJs1xLL0pUwTjUjwKW65ycgZqYPv5fySzb2gETp1kIgCxgYZY5wMZmoMnAyCmO4uv/DHXMci3NkKiBAmqHAKEEzad+E2w3RQ5g4XG+wCHRyvD9ecnjv1+P+BKyFFmeag7glJpq8P/PmyNf7tnYDJgDQBb/+bzjwPfnBQ7EOoK6IfDvwwVGJgGD//8+XPhyxwJU+hEEVHfAv99vvjKzq1j//X7i4LfHCfaEXEB1B4B8ziW36hATm6rYlzuGGgPiACYWiZfcSvtZPt/SFB4gB4i94lba/+fzLW2CVTpNooCZ0+Iqq0DI6x/PSwjmBpo4gENywgFQyUZMdqTYAYwMDBeYeZwZwAURCdkPljbIdgCbSMFhdqEUMQYGFrn//78/YWTkVKWbA7jkVh1m5tCzRU/hdHMAr9r15wwMjJLoDvj5ftGhX6/b7AhlPYorI27F3cuZWGUjkQ36++Py1m+PQr1JsRykltw08IBLZtFVJg416X+/P3759WH+uz8fV/iRajklDiDHLqx6yA2BUQeMhgDtQuAzlTun+FzKyPj/Kq/aLR2UZjm1u+e4HMDIwPCMgeH/LF71W40gNQBMREcwqeJwNQAAAABJRU5ErkJggg==);background-size:contain}#global-uploader .uploader-file-icon[icon=video]{background:url(/vue-uploader-solutions-next/assets/video-icon.b22a29fa.png)}#global-uploader .uploader-file-icon[icon=document]{background:url(/vue-uploader-solutions-next/assets/text-icon.83d569a1.png)}#global-uploader .uploader-file-icon[icon=unknown]{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAvCAYAAABkBQNlAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAK8AAACvAAsAdHPAAAAB3RJTUUH4wEJAy0K3tWoHgAABfxJREFUWMPFmEtsJFcVhr9bj66qfla7y+625+HGnoFhMgkDiQISEQIhJRIBCcECdpEQCzassmTNlgWKArNikIKYTZRFlA0SKxZImSBgHprYFsngV7fdbvfb3dXVXYeF7WGc8WuqrMm/rYe++s9/zz231F//9neAaeBnwHeBC4DGMRIRHiwtaLXtOt955RXthatX1Z2PP+b+0hK9TifsdbtyrjQtl8pzaqvVWNpqNd8Mw/DujDdFMAr46Q9eP+71GMA54PfA64DilJI9OAXomoZSBx8VAYViNB6XgT+ahvGLSr32YaPT5tb7HxwLpgE/f1qgfSmlWKlU+Mf9+yyvrtLtdBgOh3sX//9GEflqKPIbwzDKhZzL2laNW+9/cCzUj6MA7WujXmfhk0+o1mr0ez1GQXC4syLfDMPwhqa0smNZx4JpwMWoQAJcmp3lWy+/zBfn5sjl81i2ffT9Iq+GEt7QNK1sJxKUS+e4+e57h0KZUaEQwc1muVAqkXddLNtG1/UTHpFXwzD8g65pX7u9cI83fvTDJxzTRCQylFKKyuYmdxcXWatU6HU6BEeU7zNg3w5DuWEa5vzv/nzriVJqnLD8T9Jatcq/HzxgZX19F2o/6CeBIS+FYfj2YRmLBQQwe/48X79+nbnZWTKuS8KyDlzXlHbkMnqUsT2wn3z/e9x89714UCLC1MQEl8tlpjwPJ5nEMIx9KwBImCbqmMX9WPjn33rnT0wXJjHiQCmlWK5UGAOrlQqddvuJ8qVsB8tMMAj8I+H2wv+OaZpv/Gd9ZTEWFEC1VqPV69HrdNjpdg90dhHBNAyKEwU2G9sMhj6CPHLxM2DfEJHfisgvY0NdnJmhfPEiD1dWWF5bwx8MGPr+gXuSls35ySl6gz5+EBCGIUcE7TVD196KBSUilDyPL8/PM/B9tppNwvH4CSgAQzdwU9ldp47XpdiZWt/cRF9YOFWfOgUQQBi7fKvVKlvt9qGZivqtsftUaXKS5y5fZqZUIplOY5jRd619xc7Uxelprl+7hq5pdHZ26B7SFp5WsZxSSrFZr7P46ads1Grs9HqMRqPP1ymAh2trbDQa9DodemeTqehQSikE8PJ5zs/MsFatUhUhGA4JgiAWXCQopRS2ZYEICcPghStXME2TVrf7qHyObe+Cy6nawAFFypRSinzOxTRNKhsb/Hd1FTebJZ/JoADbsnCz2WfrlIiQy2T5ytXnmCvPMuV5GIZByfNYrVRYWV0n6SQjuRQZCsC2ba586RKpZJL+YECn1yOVTDI3O0shP8Hy8iqj8fjZOuXmMiQdh3a3y+07d2i0WxQLHi89/zyZdIp0Jk2j0YwU+MiZsveCvFmvU2800ZXOxtYWjVYLTdNwbCvyCoy8+jRt93uyqTSzpWl0TSMUIek4gJx4qjlzKABEEBEKeRcJQ7rdHrlclmw6TcR8x4OSx4YQpRRTXoFJr4BSxAaCMzjNAPhBQLvbJQji73uRnXpcO/0+t+/epdFqUfQ8Xrx2DSuR+PycUkqxub3NxtYWo9GItY0NGq1W7E05tlPhOKSYL5C0bHqD/pmUMBqU7M/bQspxyKXSaEphmib2XumibjEQsXwigu8PQcCxLLS9HmXoOknHQUToDwaRwSJDNdttxmFIOp3CK0zg2DZTkx7JpMNoNKLRbkd2KlL5NE2jWquRy2aYKRaZmS4yntqdFESE5UqFRrOFm848O6jd35mKj+7d4wvNJjPFIlYiQb/dZnl9nZVKBS/rouB0J72zgBIgk0zR7e9wf2mJxYcPMQ2DYRAwGo1w0xlSthMJCHYzFelZXdMoTXgUci4SCoPBAAUU8wWm3Il4M3oo4UhXeiTHDF3Hy7m4qQzjcIyu65jRXvVI4/FYtL7vx+p2CoVpGDgJKzYQQG/QR9tutxrDIDj2b9tpFHc4UCj6vk+93aoZO/7gn+v12gUv55K07DM5TD6tQhG6/R3q7SZ+EHxoAG8Phv6L6/XauYRhYsSYGKNqNB7hBwEi8kDBTQP4C/BmGIa/7g/9+TOZ0p5WSomCj4BfAf/6HzQmyAX0AQdiAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE5LTAxLTA5VDAzOjQ1OjEwKzA4OjAwPK9v8AAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOS0wMS0wOVQwMzo0NToxMCswODowME3y10wAAABDdEVYdHNvZnR3YXJlAC91c3IvbG9jYWwvaW1hZ2VtYWdpY2svc2hhcmUvZG9jL0ltYWdlTWFnaWNrLTcvL2luZGV4Lmh0bWy9tXkKAAAAGHRFWHRUaHVtYjo6RG9jdW1lbnQ6OlBhZ2VzADGn/7svAAAAGHRFWHRUaHVtYjo6SW1hZ2U6OkhlaWdodAAyMjRIjLPyAAAAF3RFWHRUaHVtYjo6SW1hZ2U6OldpZHRoADE3Nz1F+AkAAAAZdEVYdFRodW1iOjpNaW1ldHlwZQBpbWFnZS9wbmc/slZOAAAAF3RFWHRUaHVtYjo6TVRpbWUAMTU0Njk3NjcxMHAIjaYAAAARdEVYdFRodW1iOjpTaXplADk1NjJCr9FpAwAAAGJ0RVh0VGh1bWI6OlVSSQBmaWxlOi8vL2hvbWUvd3d3cm9vdC9uZXdzaXRlL3d3dy5lYXN5aWNvbi5uZXQvY2RuLWltZy5lYXN5aWNvbi5jbi9maWxlcy8xMTgvMTE4NTYyNS5wbmfTFu+zAAAAAElFTkSuQmCC) no-repeat center;background-size:contain}#global-uploader .uploader-file-actions>span{margin-right:6px}#global-uploader .custom-status{position:absolute;top:0;left:0;right:0;bottom:0;z-index:1}#global-uploader-btn{position:absolute;clip:rect(0,0,0,0)}.global-uploader-single #global-uploader-btn{position:relative}#app{display:flex;flex-direction:column}#app .app-nav{background-color:#fff}#app .app-nav .app-nav-inner{display:flex;justify-content:space-between;align-items:center;width:1140px;margin:0 auto}#app .app-nav .app-nav-title{color:#1989fa;font-weight:600}#app .app-main{flex:1}#app .app-main>.container{height:100%}.uploader-btn{display:inline-block;position:relative;padding:4px 8px;font-size:100%;line-height:1.4;color:#666;border:1px solid #666;cursor:pointer;border-radius:2px;background:0 0;outline:0}.uploader-btn:hover{background-color:#00000014}.uploader-drop{position:relative;padding:10px;overflow:hidden;border:1px dashed #ccc;background-color:#f5f5f5}.uploader-dragover{border-color:#999;background-color:#f7f7f7}.uploader-unsupport{position:relative;z-index:10;overflow:hidden}.uploader-file{position:relative;height:49px;line-height:49px;overflow:hidden;border-bottom:1px solid #cdcdcd}.uploader-file[status=uploading] .uploader-file-pause,.uploader-file[status=waiting] .uploader-file-pause,.uploader-file[status=paused] .uploader-file-resume,.uploader-file[status=error] .uploader-file-retry{display:block}.uploader-file[status=success] .uploader-file-remove{display:none}.uploader-file[status=error] .uploader-file-progress{background:#ffe0e0}.uploader-file-progress{position:absolute;width:100%;height:100%;background:#e2eeff;-webkit-transform:translateX(-100%);transform:translate(-100%)}.uploader-file-progressing{-webkit-transition:all .4s linear;transition:all .4s linear}.uploader-file-info{position:relative;z-index:1;height:100%;overflow:hidden}.uploader-file-info:hover{background-color:#f0f0f033}.uploader-file-info em,.uploader-file-info i{font-style:normal}.uploader-file-actions,.uploader-file-meta,.uploader-file-name,.uploader-file-size,.uploader-file-status{float:left;position:relative;height:100%}.uploader-file-name{width:45%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-indent:14px}.uploader-file-icon{width:24px;height:24px;display:inline-block;vertical-align:top;margin-top:13px;margin-right:8px}.uploader-file-icon:before{content:"\1f4c3";display:block;height:100%;font-size:24px;line-height:1;text-indent:0}.uploader-file-icon[icon=folder]:before{content:"\1f4c2"}.uploader-file-icon[icon=image]:before{content:"\1f4ca"}.uploader-file-icon[icon=video]:before{content:"\1f4f9"}.uploader-file-icon[icon=audio]:before{content:"\1f3b5"}.uploader-file-icon[icon=document]:before{content:"\1f4cb"}.uploader-file-size{width:13%;text-indent:10px}.uploader-file-meta{width:8%}.uploader-file-status{width:24%;text-indent:20px}.uploader-file-actions{width:10%}.uploader-file-actions>span{display:none;float:left;width:16px;height:16px;margin-top:16px;margin-right:10px;cursor:pointer;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAABkCAYAAAD0ZHJ6AAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAJcEhZcwAACxMAAAsTAQCanBgAAARkSURBVGje7ZnfS1NRHMAH4ptPkvQSuAdBkCxD8FUQJMEULUgzy1KyyPVQ4JMiiP4Bvg6EwUQQfMmwhwRDshwaKUjDVCgoSdDNHkzTJZ6+Z37Purve8+PeTb2TM/ggu+ew89l33x8H9BBCPG7GowXTJej3+wnDvEm0JuLC04+EYWftVAUv+fiCvDUdQR1BHUEdQR3BTIygvixoQS14XgTtthLVdpNWwXRLqvQ724LplFRtyrYF0yVpFLQrKRVMh6RZ0I6kkmCqklaCqpKZH0FX56Crq9jVfdDVk0RfFrSgFsxkQVmLcdKCVrKySCrryhPEyYShhzOcrFtG0EoilfHHk1CRU5rF6ZjNZhlVOW6RnMSVyyilKies4pO41diVy8wIujoHXV3FGdMHXTtJKLFYTLhZtq4vC1rwXApCZTIqgR6g1PBMCO9DL3bMMSqBHqDU8EyISDAHiGKvWwcCQG2KgjlAFCDAOhAAap0K5gKLphk8mqJgLrCIgoxRJ4J5wKpJ7gAoMkn5EBXBPGDVJHcAFJmkfIhQcAql1oBpTvTol9gG9pm4RHAKpdaAaU706JfYBvaZuJVgPQrt4sFlnOh5MC/p3lmJYD0K7eLBZZzoeTAv6d5ZnuAYHjpgEOnk5F0ufhG6v1ggOIaHDhhEOjl5l4tfhO4vthLcwAMrFNvLJO5vEwhu4IEViu1lEve3WQmyoihQFBzG/V0CQVYUBYqCw7i/SxTBcpsRbFeIYLnNCLZbCY5b5KAnxRwct8hBj9McZFVMW0ihRNBuFdMWUigRlFaxuQ9WWYjRMTiIe5z0wSoLMToGB3GPsA9aTZIJoB+nRgBnM1tzOkkmgH6cGgGczWzNpzqLx3n/aULJJgezeNw07oxQySbVywKjBOgFRnDs+VEsx8FlgVEC9AIjOPb8KJYjvSzoG7UW1IJaUAtqQS14toLNM5fN5APdwBJA8G83Pk/aK/rgzVvXzeQD3cASQPBvNz5P2ssTzAaGUIrHEO6zI5gNDKEUjyHcxxWkh4Ylcowwk1QQpIeGJXKMMJO0EgwqyjGCioJBJvDrxRMSuVOTJEXfbz1/bHwWtBL0yoQehK6RucgE+bGzanzulQh6E3IgQV+xpc8kcrfuSO7eTfJ3ZYmQw0Oy9azVKOk1C/bJ5D5F38YPeLfx0rjWJxHsS0SqsSYuxySjj5qO5Oj7xQWy2VBtFOwzCy6ryH3YfE3uh64Y1xckgstJPydEjkkeHv07Iy4Xaao15+KCWTBx6M/db+T9xivSErqaJDdzXI6yLRE8Vgg0coex/SPJvT0SbWu0KpZtbgSpCH3NRt7I5OxHkObc6heU+/M/J5vrpBFM5GBLqCQux14COXs5CNXK5OjPGm1tSMrJSOMNYQ4mVTGV/L6zTL7+DovkbFUxbSW0Wo05l8hJWsU+cRWfSh+Mt5Lb1ck/J1TvVsdDaR/MiEni+llsdZuZp62EViu+96bpNjNPWwmtVnzvFd5m9IVVC54x/wA7gNvqFG9vXQAAAABJRU5ErkJggg==) no-repeat 0 0}.uploader-file-actions>span:hover{background-position-x:-21px}.uploader-file-actions .uploader-file-pause{background-position-y:0}.uploader-file-actions .uploader-file-resume{background-position-y:-17px}.uploader-file-actions .uploader-file-retry{background-position-y:-53px}.uploader-file-actions .uploader-file-remove{display:block;background-position-y:-34px}.uploader-list{position:relative}.uploader-list>ul{list-style:none;margin:0;padding:0}.uploader-files{position:relative}.uploader-files>ul{list-style:none;margin:0;padding:0}.uploader{position:relative}*{margin:0;padding:0;box-sizing:border-box}html,body{height:100%}body{font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,\5fae\8f6f\96c5\9ed1,Arial,sans-serif;background:#f2f3f8;color:#252525;font-size:14px;-webkit-tap-highlight-color:transparent}#app{height:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.container{width:1140px;margin:0 auto}.page{display:flex;flex-direction:column;padding:20px 0} 2 | -------------------------------------------------------------------------------- /docs/assets/text-icon.83d569a1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shady-xia/vue-uploader-solutions-next/46cd91d0f1adaffcab76908318846c978ebc19fe/docs/assets/text-icon.83d569a1.png -------------------------------------------------------------------------------- /docs/assets/video-icon.b22a29fa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shady-xia/vue-uploader-solutions-next/46cd91d0f1adaffcab76908318846c978ebc19fe/docs/assets/video-icon.b22a29fa.png -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shady-xia/vue-uploader-solutions-next/46cd91d0f1adaffcab76908318846c978ebc19fe/docs/favicon.ico -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue Uploader Solutions Next 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue Uploader Solutions Next 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-uploader-solutions-next", 3 | "version": "1.0.1", 4 | "scripts": { 5 | "start": "npm run dev", 6 | "dev": "vite", 7 | "build": "vite build", 8 | "preview": "vite preview", 9 | "lint": "eslint \"src/**/*.{js,vue}\"" 10 | }, 11 | "dependencies": { 12 | "element-plus": "^2.2.12", 13 | "mitt": "^3.0.0", 14 | "spark-md5": "^3.0.2", 15 | "vue": "^3.2.25", 16 | "vue-router": "^4.0.14", 17 | "vue-simple-uploader": "^1.0.0-beta.5" 18 | }, 19 | "devDependencies": { 20 | "@iconify/vue": "^3.2.1", 21 | "@vitejs/plugin-vue": "^2.3.3", 22 | "eslint": "^7.32.0", 23 | "eslint-config-prettier": "^8.3.0", 24 | "eslint-plugin-prettier": "^4.0.0", 25 | "eslint-plugin-vue": "^8.6.0", 26 | "prettier": "^2.3.2", 27 | "sass": "^1.49.9", 28 | "unplugin-auto-import": "^0.6.6", 29 | "unplugin-vue-components": "^0.18.0", 30 | "vite": "^2.9.9", 31 | "vue-eslint-parser": "^7.10.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shady-xia/vue-uploader-solutions-next/46cd91d0f1adaffcab76908318846c978ebc19fe/public/favicon.ico -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | tmp/* 2 | !tmp/ .gitkeep 3 | uploads/* 4 | !uploads/ .gitkeep 5 | -------------------------------------------------------------------------------- /server/app.js: -------------------------------------------------------------------------------- 1 | process.env.TMPDIR = 'tmp' // to avoid the EXDEV rename error, see http://stackoverflow.com/q/21071303/76173 2 | 3 | const express = require('express') 4 | const multipart = require('connect-multiparty') 5 | const multipartMiddleware = multipart() 6 | const uploader = require('./uploader-node.js')('tmp') 7 | const app = express() 8 | const fs = require('fs') 9 | 10 | // Configure access control allow origin header stuff 11 | const ACCESS_CONTROLL_ALLOW_ORIGIN = true 12 | 13 | // Host 14 | // app.use(express.static(__dirname + '/../docs')) 15 | 16 | // Handle uploads through Uploader.js 17 | app.post('/upload', multipartMiddleware, function (req, res) { 18 | uploader.post(req, function (status, filename, original_filename, identifier) { 19 | console.log('POST', status, original_filename, identifier) 20 | if (ACCESS_CONTROLL_ALLOW_ORIGIN) { 21 | res.header('Access-Control-Allow-Origin', '*') 22 | res.header('Access-Control-Allow-Headers', 'content-type') 23 | } 24 | 25 | if (status === 'done') { 26 | const s = fs.createWriteStream('./uploads/' + filename) 27 | s.on('finish', function () { 28 | res.status(200) 29 | }) 30 | 31 | uploader.write(identifier, s, { end: true }) 32 | } else { 33 | res.status(/^(partly_done|done)$/.test(status) ? 200 : 500) 34 | } 35 | 36 | const data = { 37 | result: true, 38 | message: '' 39 | } 40 | res.send(data) 41 | }) 42 | }) 43 | 44 | app.options('/upload', function (req, res) { 45 | console.log('OPTIONS') 46 | if (ACCESS_CONTROLL_ALLOW_ORIGIN) { 47 | res.header('Access-Control-Allow-Origin', '*') 48 | res.header('Access-Control-Allow-Headers', 'content-type') 49 | } 50 | res.status(200).send() 51 | }) 52 | 53 | // Handle status checks on chunks through Uploader.js 54 | app.get('/upload', function (req, res) { 55 | uploader.get(req, function (status, filename, original_filename, identifier) { 56 | console.log('GET', status) 57 | if (ACCESS_CONTROLL_ALLOW_ORIGIN) { 58 | res.header('Access-Control-Allow-Origin', '*') 59 | } 60 | 61 | if (status == 'found') { 62 | status = 200 63 | } else { 64 | status = 204 65 | } 66 | 67 | res.status(status).send() 68 | }) 69 | }) 70 | 71 | app.get('/download/:identifier', function (req, res) { 72 | uploader.write(req.params.identifier, res) 73 | }) 74 | 75 | app.listen(3000, function () { 76 | console.log('Server started...') 77 | }) 78 | -------------------------------------------------------------------------------- /server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.8", 9 | "resolved": "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz", 10 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 11 | "requires": { 12 | "mime-types": "~2.1.34", 13 | "negotiator": "0.6.3" 14 | } 15 | }, 16 | "array-flatten": { 17 | "version": "1.1.1", 18 | "resolved": "https://registry.npmmirror.com/array-flatten/-/array-flatten-1.1.1.tgz", 19 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 20 | }, 21 | "balanced-match": { 22 | "version": "1.0.2", 23 | "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", 24 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 25 | }, 26 | "body-parser": { 27 | "version": "1.20.0", 28 | "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.0.tgz", 29 | "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", 30 | "requires": { 31 | "bytes": "3.1.2", 32 | "content-type": "~1.0.4", 33 | "debug": "2.6.9", 34 | "depd": "2.0.0", 35 | "destroy": "1.2.0", 36 | "http-errors": "2.0.0", 37 | "iconv-lite": "0.4.24", 38 | "on-finished": "2.4.1", 39 | "qs": "6.10.3", 40 | "raw-body": "2.5.1", 41 | "type-is": "~1.6.18", 42 | "unpipe": "1.0.0" 43 | }, 44 | "dependencies": { 45 | "depd": { 46 | "version": "2.0.0", 47 | "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz", 48 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 49 | }, 50 | "http-errors": { 51 | "version": "2.0.0", 52 | "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz", 53 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 54 | "requires": { 55 | "depd": "2.0.0", 56 | "inherits": "2.0.4", 57 | "setprototypeof": "1.2.0", 58 | "statuses": "2.0.1", 59 | "toidentifier": "1.0.1" 60 | } 61 | }, 62 | "on-finished": { 63 | "version": "2.4.1", 64 | "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz", 65 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 66 | "requires": { 67 | "ee-first": "1.1.1" 68 | } 69 | }, 70 | "qs": { 71 | "version": "6.10.3", 72 | "resolved": "https://registry.npmmirror.com/qs/-/qs-6.10.3.tgz", 73 | "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", 74 | "requires": { 75 | "side-channel": "^1.0.4" 76 | } 77 | }, 78 | "setprototypeof": { 79 | "version": "1.2.0", 80 | "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz", 81 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 82 | }, 83 | "statuses": { 84 | "version": "2.0.1", 85 | "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz", 86 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 87 | }, 88 | "toidentifier": { 89 | "version": "1.0.1", 90 | "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", 91 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 92 | } 93 | } 94 | }, 95 | "brace-expansion": { 96 | "version": "1.1.11", 97 | "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz", 98 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 99 | "requires": { 100 | "balanced-match": "^1.0.0", 101 | "concat-map": "0.0.1" 102 | } 103 | }, 104 | "bytes": { 105 | "version": "3.1.2", 106 | "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz", 107 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" 108 | }, 109 | "call-bind": { 110 | "version": "1.0.2", 111 | "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz", 112 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 113 | "requires": { 114 | "function-bind": "^1.1.1", 115 | "get-intrinsic": "^1.0.2" 116 | } 117 | }, 118 | "concat-map": { 119 | "version": "0.0.1", 120 | "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz", 121 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" 122 | }, 123 | "connect-multiparty": { 124 | "version": "2.2.0", 125 | "resolved": "https://registry.npmmirror.com/connect-multiparty/-/connect-multiparty-2.2.0.tgz", 126 | "integrity": "sha512-zKcpA7cuXGEhuw9Pz7JmVCFmp85jzGLGm/iiagXTwyEAJp4ypLPtRS/V4IGuGb9KjjrgHBs6P/gDCpZHnFzksA==", 127 | "requires": { 128 | "http-errors": "~1.7.0", 129 | "multiparty": "~4.2.1", 130 | "on-finished": "~2.3.0", 131 | "qs": "~6.5.2", 132 | "type-is": "~1.6.16" 133 | } 134 | }, 135 | "content-disposition": { 136 | "version": "0.5.4", 137 | "resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz", 138 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 139 | "requires": { 140 | "safe-buffer": "5.2.1" 141 | } 142 | }, 143 | "content-type": { 144 | "version": "1.0.4", 145 | "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.4.tgz", 146 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 147 | }, 148 | "cookie": { 149 | "version": "0.5.0", 150 | "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.5.0.tgz", 151 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" 152 | }, 153 | "cookie-signature": { 154 | "version": "1.0.6", 155 | "resolved": "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.0.6.tgz", 156 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 157 | }, 158 | "debug": { 159 | "version": "2.6.9", 160 | "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", 161 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 162 | "requires": { 163 | "ms": "2.0.0" 164 | } 165 | }, 166 | "depd": { 167 | "version": "1.1.2", 168 | "resolved": "https://registry.npmmirror.com/depd/-/depd-1.1.2.tgz", 169 | "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" 170 | }, 171 | "destroy": { 172 | "version": "1.2.0", 173 | "resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz", 174 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" 175 | }, 176 | "ee-first": { 177 | "version": "1.1.1", 178 | "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz", 179 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 180 | }, 181 | "encodeurl": { 182 | "version": "1.0.2", 183 | "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz", 184 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" 185 | }, 186 | "escape-html": { 187 | "version": "1.0.3", 188 | "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", 189 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 190 | }, 191 | "etag": { 192 | "version": "1.8.1", 193 | "resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz", 194 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" 195 | }, 196 | "express": { 197 | "version": "4.18.1", 198 | "resolved": "https://registry.npmmirror.com/express/-/express-4.18.1.tgz", 199 | "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", 200 | "requires": { 201 | "accepts": "~1.3.8", 202 | "array-flatten": "1.1.1", 203 | "body-parser": "1.20.0", 204 | "content-disposition": "0.5.4", 205 | "content-type": "~1.0.4", 206 | "cookie": "0.5.0", 207 | "cookie-signature": "1.0.6", 208 | "debug": "2.6.9", 209 | "depd": "2.0.0", 210 | "encodeurl": "~1.0.2", 211 | "escape-html": "~1.0.3", 212 | "etag": "~1.8.1", 213 | "finalhandler": "1.2.0", 214 | "fresh": "0.5.2", 215 | "http-errors": "2.0.0", 216 | "merge-descriptors": "1.0.1", 217 | "methods": "~1.1.2", 218 | "on-finished": "2.4.1", 219 | "parseurl": "~1.3.3", 220 | "path-to-regexp": "0.1.7", 221 | "proxy-addr": "~2.0.7", 222 | "qs": "6.10.3", 223 | "range-parser": "~1.2.1", 224 | "safe-buffer": "5.2.1", 225 | "send": "0.18.0", 226 | "serve-static": "1.15.0", 227 | "setprototypeof": "1.2.0", 228 | "statuses": "2.0.1", 229 | "type-is": "~1.6.18", 230 | "utils-merge": "1.0.1", 231 | "vary": "~1.1.2" 232 | }, 233 | "dependencies": { 234 | "depd": { 235 | "version": "2.0.0", 236 | "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz", 237 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 238 | }, 239 | "http-errors": { 240 | "version": "2.0.0", 241 | "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz", 242 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 243 | "requires": { 244 | "depd": "2.0.0", 245 | "inherits": "2.0.4", 246 | "setprototypeof": "1.2.0", 247 | "statuses": "2.0.1", 248 | "toidentifier": "1.0.1" 249 | } 250 | }, 251 | "on-finished": { 252 | "version": "2.4.1", 253 | "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz", 254 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 255 | "requires": { 256 | "ee-first": "1.1.1" 257 | } 258 | }, 259 | "qs": { 260 | "version": "6.10.3", 261 | "resolved": "https://registry.npmmirror.com/qs/-/qs-6.10.3.tgz", 262 | "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", 263 | "requires": { 264 | "side-channel": "^1.0.4" 265 | } 266 | }, 267 | "setprototypeof": { 268 | "version": "1.2.0", 269 | "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz", 270 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 271 | }, 272 | "statuses": { 273 | "version": "2.0.1", 274 | "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz", 275 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 276 | }, 277 | "toidentifier": { 278 | "version": "1.0.1", 279 | "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", 280 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 281 | } 282 | } 283 | }, 284 | "finalhandler": { 285 | "version": "1.2.0", 286 | "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.2.0.tgz", 287 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 288 | "requires": { 289 | "debug": "2.6.9", 290 | "encodeurl": "~1.0.2", 291 | "escape-html": "~1.0.3", 292 | "on-finished": "2.4.1", 293 | "parseurl": "~1.3.3", 294 | "statuses": "2.0.1", 295 | "unpipe": "~1.0.0" 296 | }, 297 | "dependencies": { 298 | "on-finished": { 299 | "version": "2.4.1", 300 | "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz", 301 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 302 | "requires": { 303 | "ee-first": "1.1.1" 304 | } 305 | }, 306 | "statuses": { 307 | "version": "2.0.1", 308 | "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz", 309 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 310 | } 311 | } 312 | }, 313 | "forwarded": { 314 | "version": "0.2.0", 315 | "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz", 316 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 317 | }, 318 | "fresh": { 319 | "version": "0.5.2", 320 | "resolved": "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz", 321 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" 322 | }, 323 | "function-bind": { 324 | "version": "1.1.1", 325 | "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz", 326 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 327 | }, 328 | "get-intrinsic": { 329 | "version": "1.1.2", 330 | "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz", 331 | "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", 332 | "requires": { 333 | "function-bind": "^1.1.1", 334 | "has": "^1.0.3", 335 | "has-symbols": "^1.0.3" 336 | } 337 | }, 338 | "glob": { 339 | "version": "6.0.4", 340 | "resolved": "https://registry.npmmirror.com/glob/-/glob-6.0.4.tgz", 341 | "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", 342 | "requires": { 343 | "inflight": "^1.0.4", 344 | "inherits": "2", 345 | "minimatch": "2 || 3", 346 | "once": "^1.3.0", 347 | "path-is-absolute": "^1.0.0" 348 | } 349 | }, 350 | "has": { 351 | "version": "1.0.3", 352 | "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz", 353 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 354 | "requires": { 355 | "function-bind": "^1.1.1" 356 | } 357 | }, 358 | "has-symbols": { 359 | "version": "1.0.3", 360 | "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz", 361 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" 362 | }, 363 | "http-errors": { 364 | "version": "1.7.3", 365 | "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-1.7.3.tgz", 366 | "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", 367 | "requires": { 368 | "depd": "~1.1.2", 369 | "inherits": "2.0.4", 370 | "setprototypeof": "1.1.1", 371 | "statuses": ">= 1.5.0 < 2", 372 | "toidentifier": "1.0.0" 373 | } 374 | }, 375 | "iconv-lite": { 376 | "version": "0.4.24", 377 | "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz", 378 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 379 | "requires": { 380 | "safer-buffer": ">= 2.1.2 < 3" 381 | } 382 | }, 383 | "inflight": { 384 | "version": "1.0.6", 385 | "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz", 386 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 387 | "requires": { 388 | "once": "^1.3.0", 389 | "wrappy": "1" 390 | } 391 | }, 392 | "inherits": { 393 | "version": "2.0.4", 394 | "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz", 395 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 396 | }, 397 | "ipaddr.js": { 398 | "version": "1.9.1", 399 | "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 400 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 401 | }, 402 | "media-typer": { 403 | "version": "0.3.0", 404 | "resolved": "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz", 405 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" 406 | }, 407 | "merge-descriptors": { 408 | "version": "1.0.1", 409 | "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 410 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 411 | }, 412 | "methods": { 413 | "version": "1.1.2", 414 | "resolved": "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz", 415 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" 416 | }, 417 | "mime": { 418 | "version": "1.6.0", 419 | "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz", 420 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 421 | }, 422 | "mime-db": { 423 | "version": "1.52.0", 424 | "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", 425 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 426 | }, 427 | "mime-types": { 428 | "version": "2.1.35", 429 | "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", 430 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 431 | "requires": { 432 | "mime-db": "1.52.0" 433 | } 434 | }, 435 | "minimatch": { 436 | "version": "3.1.2", 437 | "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz", 438 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 439 | "requires": { 440 | "brace-expansion": "^1.1.7" 441 | } 442 | }, 443 | "minimist": { 444 | "version": "1.2.6", 445 | "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.6.tgz", 446 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" 447 | }, 448 | "mkdirp": { 449 | "version": "0.5.6", 450 | "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz", 451 | "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", 452 | "requires": { 453 | "minimist": "^1.2.6" 454 | } 455 | }, 456 | "ms": { 457 | "version": "2.0.0", 458 | "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", 459 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 460 | }, 461 | "multiparty": { 462 | "version": "4.2.3", 463 | "resolved": "https://registry.npmmirror.com/multiparty/-/multiparty-4.2.3.tgz", 464 | "integrity": "sha512-Ak6EUJZuhGS8hJ3c2fY6UW5MbkGUPMBEGd13djUzoY/BHqV/gTuFWtC6IuVA7A2+v3yjBS6c4or50xhzTQZImQ==", 465 | "requires": { 466 | "http-errors": "~1.8.1", 467 | "safe-buffer": "5.2.1", 468 | "uid-safe": "2.1.5" 469 | }, 470 | "dependencies": { 471 | "http-errors": { 472 | "version": "1.8.1", 473 | "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-1.8.1.tgz", 474 | "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", 475 | "requires": { 476 | "depd": "~1.1.2", 477 | "inherits": "2.0.4", 478 | "setprototypeof": "1.2.0", 479 | "statuses": ">= 1.5.0 < 2", 480 | "toidentifier": "1.0.1" 481 | } 482 | }, 483 | "setprototypeof": { 484 | "version": "1.2.0", 485 | "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz", 486 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 487 | }, 488 | "toidentifier": { 489 | "version": "1.0.1", 490 | "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", 491 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 492 | } 493 | } 494 | }, 495 | "mv": { 496 | "version": "2.1.1", 497 | "resolved": "https://registry.npmmirror.com/mv/-/mv-2.1.1.tgz", 498 | "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", 499 | "requires": { 500 | "mkdirp": "~0.5.1", 501 | "ncp": "~2.0.0", 502 | "rimraf": "~2.4.0" 503 | } 504 | }, 505 | "ncp": { 506 | "version": "2.0.0", 507 | "resolved": "https://registry.npmmirror.com/ncp/-/ncp-2.0.0.tgz", 508 | "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==" 509 | }, 510 | "negotiator": { 511 | "version": "0.6.3", 512 | "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz", 513 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" 514 | }, 515 | "object-inspect": { 516 | "version": "1.12.2", 517 | "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.2.tgz", 518 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" 519 | }, 520 | "on-finished": { 521 | "version": "2.3.0", 522 | "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.3.0.tgz", 523 | "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", 524 | "requires": { 525 | "ee-first": "1.1.1" 526 | } 527 | }, 528 | "once": { 529 | "version": "1.4.0", 530 | "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz", 531 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 532 | "requires": { 533 | "wrappy": "1" 534 | } 535 | }, 536 | "parseurl": { 537 | "version": "1.3.3", 538 | "resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz", 539 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 540 | }, 541 | "path-is-absolute": { 542 | "version": "1.0.1", 543 | "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 544 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" 545 | }, 546 | "path-to-regexp": { 547 | "version": "0.1.7", 548 | "resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 549 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 550 | }, 551 | "proxy-addr": { 552 | "version": "2.0.7", 553 | "resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz", 554 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 555 | "requires": { 556 | "forwarded": "0.2.0", 557 | "ipaddr.js": "1.9.1" 558 | } 559 | }, 560 | "qs": { 561 | "version": "6.5.3", 562 | "resolved": "https://registry.npmmirror.com/qs/-/qs-6.5.3.tgz", 563 | "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" 564 | }, 565 | "random-bytes": { 566 | "version": "1.0.0", 567 | "resolved": "https://registry.npmmirror.com/random-bytes/-/random-bytes-1.0.0.tgz", 568 | "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==" 569 | }, 570 | "range-parser": { 571 | "version": "1.2.1", 572 | "resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz", 573 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 574 | }, 575 | "raw-body": { 576 | "version": "2.5.1", 577 | "resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.1.tgz", 578 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 579 | "requires": { 580 | "bytes": "3.1.2", 581 | "http-errors": "2.0.0", 582 | "iconv-lite": "0.4.24", 583 | "unpipe": "1.0.0" 584 | }, 585 | "dependencies": { 586 | "depd": { 587 | "version": "2.0.0", 588 | "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz", 589 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 590 | }, 591 | "http-errors": { 592 | "version": "2.0.0", 593 | "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz", 594 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 595 | "requires": { 596 | "depd": "2.0.0", 597 | "inherits": "2.0.4", 598 | "setprototypeof": "1.2.0", 599 | "statuses": "2.0.1", 600 | "toidentifier": "1.0.1" 601 | } 602 | }, 603 | "setprototypeof": { 604 | "version": "1.2.0", 605 | "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz", 606 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 607 | }, 608 | "statuses": { 609 | "version": "2.0.1", 610 | "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz", 611 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 612 | }, 613 | "toidentifier": { 614 | "version": "1.0.1", 615 | "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", 616 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 617 | } 618 | } 619 | }, 620 | "rimraf": { 621 | "version": "2.4.5", 622 | "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-2.4.5.tgz", 623 | "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", 624 | "requires": { 625 | "glob": "^6.0.1" 626 | } 627 | }, 628 | "safe-buffer": { 629 | "version": "5.2.1", 630 | "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", 631 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 632 | }, 633 | "safer-buffer": { 634 | "version": "2.1.2", 635 | "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", 636 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 637 | }, 638 | "send": { 639 | "version": "0.18.0", 640 | "resolved": "https://registry.npmmirror.com/send/-/send-0.18.0.tgz", 641 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 642 | "requires": { 643 | "debug": "2.6.9", 644 | "depd": "2.0.0", 645 | "destroy": "1.2.0", 646 | "encodeurl": "~1.0.2", 647 | "escape-html": "~1.0.3", 648 | "etag": "~1.8.1", 649 | "fresh": "0.5.2", 650 | "http-errors": "2.0.0", 651 | "mime": "1.6.0", 652 | "ms": "2.1.3", 653 | "on-finished": "2.4.1", 654 | "range-parser": "~1.2.1", 655 | "statuses": "2.0.1" 656 | }, 657 | "dependencies": { 658 | "depd": { 659 | "version": "2.0.0", 660 | "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz", 661 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 662 | }, 663 | "http-errors": { 664 | "version": "2.0.0", 665 | "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz", 666 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 667 | "requires": { 668 | "depd": "2.0.0", 669 | "inherits": "2.0.4", 670 | "setprototypeof": "1.2.0", 671 | "statuses": "2.0.1", 672 | "toidentifier": "1.0.1" 673 | } 674 | }, 675 | "ms": { 676 | "version": "2.1.3", 677 | "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", 678 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 679 | }, 680 | "on-finished": { 681 | "version": "2.4.1", 682 | "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz", 683 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 684 | "requires": { 685 | "ee-first": "1.1.1" 686 | } 687 | }, 688 | "setprototypeof": { 689 | "version": "1.2.0", 690 | "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz", 691 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 692 | }, 693 | "statuses": { 694 | "version": "2.0.1", 695 | "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz", 696 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 697 | }, 698 | "toidentifier": { 699 | "version": "1.0.1", 700 | "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", 701 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 702 | } 703 | } 704 | }, 705 | "serve-static": { 706 | "version": "1.15.0", 707 | "resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.15.0.tgz", 708 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 709 | "requires": { 710 | "encodeurl": "~1.0.2", 711 | "escape-html": "~1.0.3", 712 | "parseurl": "~1.3.3", 713 | "send": "0.18.0" 714 | } 715 | }, 716 | "setprototypeof": { 717 | "version": "1.1.1", 718 | "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.1.1.tgz", 719 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 720 | }, 721 | "side-channel": { 722 | "version": "1.0.4", 723 | "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz", 724 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 725 | "requires": { 726 | "call-bind": "^1.0.0", 727 | "get-intrinsic": "^1.0.2", 728 | "object-inspect": "^1.9.0" 729 | } 730 | }, 731 | "statuses": { 732 | "version": "1.5.0", 733 | "resolved": "https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz", 734 | "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" 735 | }, 736 | "toidentifier": { 737 | "version": "1.0.0", 738 | "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.0.tgz", 739 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 740 | }, 741 | "type-is": { 742 | "version": "1.6.18", 743 | "resolved": "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz", 744 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 745 | "requires": { 746 | "media-typer": "0.3.0", 747 | "mime-types": "~2.1.24" 748 | } 749 | }, 750 | "uid-safe": { 751 | "version": "2.1.5", 752 | "resolved": "https://registry.npmmirror.com/uid-safe/-/uid-safe-2.1.5.tgz", 753 | "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", 754 | "requires": { 755 | "random-bytes": "~1.0.0" 756 | } 757 | }, 758 | "unpipe": { 759 | "version": "1.0.0", 760 | "resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz", 761 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" 762 | }, 763 | "utils-merge": { 764 | "version": "1.0.1", 765 | "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz", 766 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" 767 | }, 768 | "vary": { 769 | "version": "1.1.2", 770 | "resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz", 771 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" 772 | }, 773 | "wrappy": { 774 | "version": "1.0.2", 775 | "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz", 776 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 777 | } 778 | } 779 | } 780 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "main": "app.js", 5 | "scripts": { 6 | "server": "node app.js" 7 | }, 8 | "dependencies": { 9 | "connect-multiparty": "^2.2.0", 10 | "express": "^4.3.1", 11 | "mv": "^2.1.1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /server/uploader-node.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'), 2 | path = require('path'), 3 | util = require('util'), 4 | mv = require('mv'), 5 | Stream = require('stream').Stream 6 | 7 | module.exports = function (temporaryFolder) { 8 | var $ = this 9 | $.temporaryFolder = temporaryFolder 10 | $.maxFileSize = null 11 | $.fileParameterName = 'file' 12 | 13 | try { 14 | fs.mkdirSync($.temporaryFolder) 15 | } catch (e) {} 16 | 17 | function cleanIdentifier(identifier) { 18 | return identifier.replace(/[^0-9A-Za-z_-]/g, '') 19 | } 20 | 21 | function getChunkFilename(chunkNumber, identifier) { 22 | // Clean up the identifier 23 | identifier = cleanIdentifier(identifier) 24 | // What would the file name be? 25 | return path.resolve($.temporaryFolder, './uploader-' + identifier + '.' + chunkNumber) 26 | } 27 | 28 | function validateRequest(chunkNumber, chunkSize, totalSize, identifier, filename, fileSize) { 29 | // Clean up the identifier 30 | identifier = cleanIdentifier(identifier) 31 | 32 | // Check if the request is sane 33 | if ( 34 | chunkNumber == 0 || 35 | chunkSize == 0 || 36 | totalSize == 0 || 37 | identifier.length == 0 || 38 | filename.length == 0 39 | ) { 40 | return 'non_uploader_request' 41 | } 42 | var numberOfChunks = Math.max(Math.floor(totalSize / (chunkSize * 1.0)), 1) 43 | if (chunkNumber > numberOfChunks) { 44 | return 'invalid_uploader_request1' 45 | } 46 | 47 | // Is the file too big? 48 | if ($.maxFileSize && totalSize > $.maxFileSize) { 49 | return 'invalid_uploader_request2' 50 | } 51 | 52 | if (typeof fileSize != 'undefined') { 53 | if (chunkNumber < numberOfChunks && fileSize != chunkSize) { 54 | // The chunk in the POST request isn't the correct size 55 | return 'invalid_uploader_request3' 56 | } 57 | if ( 58 | numberOfChunks > 1 && 59 | chunkNumber == numberOfChunks && 60 | fileSize != (totalSize % chunkSize) + parseInt(chunkSize) 61 | ) { 62 | // The chunks in the POST is the last one, and the fil is not the correct size 63 | return 'invalid_uploader_request4' 64 | } 65 | if (numberOfChunks == 1 && fileSize != totalSize) { 66 | // The file is only a single chunk, and the data size does not fit 67 | return 'invalid_uploader_request5' 68 | } 69 | } 70 | 71 | return 'valid' 72 | } 73 | 74 | //'found', filename, original_filename, identifier 75 | //'not_found', null, null, null 76 | $.get = function (req, callback) { 77 | var chunkNumber = req.param('chunkNumber', 0) 78 | var chunkSize = req.param('chunkSize', 0) 79 | var totalSize = req.param('totalSize', 0) 80 | var identifier = req.param('identifier', '') 81 | var filename = req.param('filename', '') 82 | 83 | if (validateRequest(chunkNumber, chunkSize, totalSize, identifier, filename) == 'valid') { 84 | var chunkFilename = getChunkFilename(chunkNumber, identifier) 85 | fs.exists(chunkFilename, function (exists) { 86 | if (exists) { 87 | callback('found', chunkFilename, filename, identifier) 88 | } else { 89 | callback('not_found', null, null, null) 90 | } 91 | }) 92 | } else { 93 | callback('not_found', null, null, null) 94 | } 95 | } 96 | 97 | //'partly_done', filename, original_filename, identifier 98 | //'done', filename, original_filename, identifier 99 | //'invalid_uploader_request', null, null, null 100 | //'non_uploader_request', null, null, null 101 | $.post = function (req, callback) { 102 | var fields = req.body 103 | var files = req.files 104 | 105 | var chunkNumber = fields['chunkNumber'] 106 | var chunkSize = fields['chunkSize'] 107 | var totalSize = fields['totalSize'] 108 | var identifier = cleanIdentifier(fields['identifier']) 109 | var filename = fields['filename'] 110 | 111 | if (!files[$.fileParameterName] || !files[$.fileParameterName].size) { 112 | callback('invalid_uploader_request', null, null, null) 113 | return 114 | } 115 | 116 | var original_filename = files[$.fileParameterName]['originalFilename'] 117 | var validation = validateRequest( 118 | chunkNumber, 119 | chunkSize, 120 | totalSize, 121 | identifier, 122 | filename, 123 | files[$.fileParameterName].size 124 | ) 125 | if (validation == 'valid') { 126 | var chunkFilename = getChunkFilename(chunkNumber, identifier) 127 | 128 | // Save the chunk (TODO: OVERWRITE) 129 | mv(files[$.fileParameterName].path, chunkFilename, function (err) { 130 | if (err) { 131 | console.error('err:', err) 132 | } 133 | 134 | // Do we have all the chunks? 135 | var currentTestChunk = 1 136 | var numberOfChunks = Math.max(Math.floor(totalSize / (chunkSize * 1.0)), 1) 137 | var testChunkExists = function () { 138 | fs.exists(getChunkFilename(currentTestChunk, identifier), function (exists) { 139 | if (exists) { 140 | currentTestChunk++ 141 | if (currentTestChunk > numberOfChunks) { 142 | callback('done', filename, original_filename, identifier) 143 | } else { 144 | // Recursion 145 | testChunkExists() 146 | } 147 | } else { 148 | callback('partly_done', filename, original_filename, identifier) 149 | } 150 | }) 151 | } 152 | testChunkExists() 153 | }) 154 | } else { 155 | callback(validation, filename, original_filename, identifier) 156 | } 157 | } 158 | 159 | // Pipe chunks directly in to an existsing WritableStream 160 | // r.write(identifier, response); 161 | // r.write(identifier, response, {end:false}); 162 | // 163 | // var stream = fs.createWriteStream(filename); 164 | // r.write(identifier, stream); 165 | // stream.on('data', function(data){...}); 166 | // stream.on('finish', function(){...}); 167 | $.write = function (identifier, writableStream, options) { 168 | options = options || {} 169 | options.end = typeof options['end'] == 'undefined' ? true : options['end'] 170 | 171 | // Iterate over each chunk 172 | var pipeChunk = function (number) { 173 | var chunkFilename = getChunkFilename(number, identifier) 174 | fs.exists(chunkFilename, function (exists) { 175 | if (exists) { 176 | // If the chunk with the current number exists, 177 | // then create a ReadStream from the file 178 | // and pipe it to the specified writableStream. 179 | var sourceStream = fs.createReadStream(chunkFilename) 180 | sourceStream.pipe(writableStream, { 181 | end: false 182 | }) 183 | sourceStream.on('end', function () { 184 | // When the chunk is fully streamed, 185 | // jump to the next one 186 | pipeChunk(number + 1) 187 | }) 188 | } else { 189 | // When all the chunks have been piped, end the stream 190 | if (options.end) writableStream.end() 191 | if (options.onDone) options.onDone() 192 | } 193 | }) 194 | } 195 | pipeChunk(1) 196 | } 197 | 198 | $.clean = function (identifier, options) { 199 | options = options || {} 200 | 201 | // Iterate over each chunk 202 | var pipeChunkRm = function (number) { 203 | var chunkFilename = getChunkFilename(number, identifier) 204 | 205 | //console.log('removing pipeChunkRm ', number, 'chunkFilename', chunkFilename); 206 | fs.exists(chunkFilename, function (exists) { 207 | if (exists) { 208 | console.log('exist removing ', chunkFilename) 209 | fs.unlink(chunkFilename, function (err) { 210 | if (err && options.onError) options.onError(err) 211 | }) 212 | 213 | pipeChunkRm(number + 1) 214 | } else { 215 | if (options.onDone) options.onDone() 216 | } 217 | }) 218 | } 219 | pipeChunkRm(1) 220 | } 221 | 222 | return $ 223 | } 224 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 46 | 47 | 78 | -------------------------------------------------------------------------------- /src/api/index.js: -------------------------------------------------------------------------------- 1 | export function mergeSimpleUpload() { 2 | return Promise.resolve() 3 | } 4 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shady-xia/vue-uploader-solutions-next/46cd91d0f1adaffcab76908318846c978ebc19fe/src/assets/logo.png -------------------------------------------------------------------------------- /src/auto-imports.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by 'unplugin-auto-import' 2 | // We suggest you to commit this file into source control 3 | declare global { 4 | const computed: typeof import('vue')['computed'] 5 | const createApp: typeof import('vue')['createApp'] 6 | const customRef: typeof import('vue')['customRef'] 7 | const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] 8 | const defineComponent: typeof import('vue')['defineComponent'] 9 | const effectScope: typeof import('vue')['effectScope'] 10 | const EffectScope: typeof import('vue')['EffectScope'] 11 | const getCurrentInstance: typeof import('vue')['getCurrentInstance'] 12 | const getCurrentScope: typeof import('vue')['getCurrentScope'] 13 | const h: typeof import('vue')['h'] 14 | const inject: typeof import('vue')['inject'] 15 | const isReadonly: typeof import('vue')['isReadonly'] 16 | const isRef: typeof import('vue')['isRef'] 17 | const markRaw: typeof import('vue')['markRaw'] 18 | const nextTick: typeof import('vue')['nextTick'] 19 | const onActivated: typeof import('vue')['onActivated'] 20 | const onBeforeMount: typeof import('vue')['onBeforeMount'] 21 | const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] 22 | const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] 23 | const onDeactivated: typeof import('vue')['onDeactivated'] 24 | const onErrorCaptured: typeof import('vue')['onErrorCaptured'] 25 | const onMounted: typeof import('vue')['onMounted'] 26 | const onRenderTracked: typeof import('vue')['onRenderTracked'] 27 | const onRenderTriggered: typeof import('vue')['onRenderTriggered'] 28 | const onScopeDispose: typeof import('vue')['onScopeDispose'] 29 | const onServerPrefetch: typeof import('vue')['onServerPrefetch'] 30 | const onUnmounted: typeof import('vue')['onUnmounted'] 31 | const onUpdated: typeof import('vue')['onUpdated'] 32 | const provide: typeof import('vue')['provide'] 33 | const reactive: typeof import('vue')['reactive'] 34 | const readonly: typeof import('vue')['readonly'] 35 | const ref: typeof import('vue')['ref'] 36 | const resolveComponent: typeof import('vue')['resolveComponent'] 37 | const shallowReactive: typeof import('vue')['shallowReactive'] 38 | const shallowReadonly: typeof import('vue')['shallowReadonly'] 39 | const shallowRef: typeof import('vue')['shallowRef'] 40 | const toRaw: typeof import('vue')['toRaw'] 41 | const toRef: typeof import('vue')['toRef'] 42 | const toRefs: typeof import('vue')['toRefs'] 43 | const triggerRef: typeof import('vue')['triggerRef'] 44 | const unref: typeof import('vue')['unref'] 45 | const useAttrs: typeof import('vue')['useAttrs'] 46 | const useCssModule: typeof import('vue')['useCssModule'] 47 | const useCssVars: typeof import('vue')['useCssVars'] 48 | const useSlots: typeof import('vue')['useSlots'] 49 | const watch: typeof import('vue')['watch'] 50 | const watchEffect: typeof import('vue')['watchEffect'] 51 | } 52 | export {} 53 | -------------------------------------------------------------------------------- /src/components.d.ts: -------------------------------------------------------------------------------- 1 | // generated by unplugin-vue-components 2 | // We suggest you to commit this file into source control 3 | // Read more: https://github.com/vuejs/vue-next/pull/3399 4 | 5 | declare module 'vue' { 6 | export interface GlobalComponents { 7 | GlobalUploader: typeof import('./components/GlobalUploader/GlobalUploader.vue')['default'] 8 | } 9 | } 10 | 11 | export { } 12 | -------------------------------------------------------------------------------- /src/components/GlobalUploader/GlobalUploader.vue: -------------------------------------------------------------------------------- 1 | 57 | 58 | 358 | 359 | 493 | -------------------------------------------------------------------------------- /src/components/GlobalUploader/images/audio-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shady-xia/vue-uploader-solutions-next/46cd91d0f1adaffcab76908318846c978ebc19fe/src/components/GlobalUploader/images/audio-icon.png -------------------------------------------------------------------------------- /src/components/GlobalUploader/images/image-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shady-xia/vue-uploader-solutions-next/46cd91d0f1adaffcab76908318846c978ebc19fe/src/components/GlobalUploader/images/image-icon.png -------------------------------------------------------------------------------- /src/components/GlobalUploader/images/text-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shady-xia/vue-uploader-solutions-next/46cd91d0f1adaffcab76908318846c978ebc19fe/src/components/GlobalUploader/images/text-icon.png -------------------------------------------------------------------------------- /src/components/GlobalUploader/images/video-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shady-xia/vue-uploader-solutions-next/46cd91d0f1adaffcab76908318846c978ebc19fe/src/components/GlobalUploader/images/video-icon.png -------------------------------------------------------------------------------- /src/components/GlobalUploader/images/zip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shady-xia/vue-uploader-solutions-next/46cd91d0f1adaffcab76908318846c978ebc19fe/src/components/GlobalUploader/images/zip.png -------------------------------------------------------------------------------- /src/components/GlobalUploader/utils/bus.js: -------------------------------------------------------------------------------- 1 | import mitt from 'mitt' 2 | 3 | export default mitt() 4 | -------------------------------------------------------------------------------- /src/components/GlobalUploader/utils/md5.js: -------------------------------------------------------------------------------- 1 | import SparkMD5 from 'spark-md5' 2 | 3 | /** 4 | * 分段计算MD5 5 | * @param file {File} 6 | * @param options {Object} - onProgress | onSuccess | onError 7 | */ 8 | export function generateMD5(file, options = {}) { 9 | const fileReader = new FileReader() 10 | const time = new Date().getTime() 11 | const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice 12 | const chunkSize = 10 * 1024 * 1000 13 | const chunks = Math.ceil(file.size / chunkSize) 14 | let currentChunk = 0 15 | const spark = new SparkMD5.ArrayBuffer() 16 | const loadNext = () => { 17 | let start = currentChunk * chunkSize 18 | let end = start + chunkSize >= file.size ? file.size : start + chunkSize 19 | 20 | fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end)) 21 | } 22 | 23 | loadNext() 24 | 25 | fileReader.onload = (e) => { 26 | spark.append(e.target.result) 27 | 28 | if (currentChunk < chunks) { 29 | currentChunk++ 30 | loadNext() 31 | if (options.onProgress && typeof options.onProgress == 'function') { 32 | options.onProgress(currentChunk, chunks) 33 | } 34 | } else { 35 | let md5 = spark.end() 36 | 37 | // md5计算完毕 38 | if (options.onSuccess && typeof options.onSuccess == 'function') { 39 | options.onSuccess(md5) 40 | } 41 | 42 | console.log( 43 | `MD5计算完毕:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${file.size} 用时:${ 44 | new Date().getTime() - time 45 | } ms` 46 | ) 47 | } 48 | } 49 | 50 | fileReader.onerror = function () { 51 | console.log('MD5计算失败') 52 | if (options.onError && typeof options.onError == 'function') { 53 | options.onError() 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import { Icon } from '@iconify/vue' 3 | import App from './App.vue' 4 | import router from './router' 5 | import uploader from 'vue-simple-uploader' 6 | import 'vue-simple-uploader/dist/style.css' 7 | import './styles/index.scss' 8 | 9 | const app = createApp(App) 10 | app.use(router) 11 | app.use(uploader) 12 | app.component('Icon', Icon) 13 | 14 | app.mount('#app') 15 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHashHistory } from 'vue-router' 2 | 3 | const routes = [ 4 | { 5 | path: '/', 6 | redirect: '/home' 7 | }, 8 | { 9 | path: '/home', 10 | name: 'home', 11 | component: () => import('../views/Home.vue') 12 | }, 13 | { 14 | path: '/about', 15 | name: 'about', 16 | component: () => import('../views/About.vue') 17 | }, 18 | { 19 | path: '/:path(.*)*', 20 | redirect: '/' 21 | } 22 | ] 23 | 24 | const router = createRouter({ 25 | history: createWebHashHistory(''), 26 | routes 27 | }) 28 | 29 | export default router 30 | -------------------------------------------------------------------------------- /src/styles/index.scss: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | html, 8 | body { 9 | height: 100%; 10 | } 11 | 12 | body { 13 | font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 14 | '微软雅黑', Arial, sans-serif; 15 | background: #f2f3f8; 16 | color: #252525; 17 | font-size: 14px; 18 | -webkit-tap-highlight-color: transparent; 19 | } 20 | 21 | #app { 22 | height: 100%; 23 | -webkit-font-smoothing: antialiased; 24 | -moz-osx-font-smoothing: grayscale; 25 | } 26 | 27 | .container { 28 | width: 1140px; 29 | margin: 0 auto; 30 | } 31 | 32 | .page { 33 | display: flex; 34 | flex-direction: column; 35 | padding: 20px 0; 36 | } 37 | -------------------------------------------------------------------------------- /src/styles/variable.scss: -------------------------------------------------------------------------------- 1 | // 定义项目全局变量 2 | $blue: #108ee9; 3 | $red: #f04134; 4 | $green: #00a854; 5 | $orange: #f56a00; 6 | $yellow: #ffbf00; 7 | $pink: #f5317f; 8 | $purple: #7265e6; 9 | $cyan: #00a2ae; 10 | $grey: #bfbfbf; 11 | 12 | -------------------------------------------------------------------------------- /src/views/About.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 58 | 59 | 90 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | import path from 'path' 4 | import AutoImport from 'unplugin-auto-import/vite' 5 | import Components from 'unplugin-vue-components/vite' 6 | import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' 7 | 8 | const production = process.env.NODE_ENV === 'production' 9 | const pathSrc = path.resolve(__dirname, 'src') 10 | 11 | // https://vitejs.dev/config/ 12 | export default defineConfig({ 13 | base: production ? '/vue-uploader-solutions-next/' : '/', 14 | build: { 15 | outDir: 'docs' 16 | }, 17 | server: { 18 | port: 8000, 19 | open: true 20 | }, 21 | resolve: { 22 | alias: { 23 | '~/': `${pathSrc}/` 24 | } 25 | }, 26 | css: { 27 | preprocessorOptions: { 28 | scss: { 29 | additionalData: `@use "~/styles/variable.scss" as *;` 30 | } 31 | } 32 | }, 33 | plugins: [ 34 | vue(), 35 | AutoImport({ 36 | imports: ['vue'], 37 | resolvers: [ElementPlusResolver()], 38 | dts: 'src/auto-imports.d.ts' 39 | }), 40 | Components({ 41 | resolvers: [ 42 | ElementPlusResolver({ 43 | importStyle: 'sass' 44 | }) 45 | ], 46 | dts: 'src/components.d.ts' 47 | }) 48 | ] 49 | }) 50 | --------------------------------------------------------------------------------