vue2server7 5.0.8 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,146 @@
1
+ <!-- ImportTableDialog.vue -->
2
+ <template>
3
+ <el-dialog
4
+ v-model="dialogVisible"
5
+ :title="title"
6
+ width="520px"
7
+ destroy-on-close
8
+ @closed="handleClosed"
9
+ >
10
+ <el-upload
11
+ ref="uploadRef"
12
+ v-model:file-list="fileList"
13
+ drag
14
+ action="#"
15
+ :auto-upload="false"
16
+ :limit="1"
17
+ :accept="accept"
18
+ :on-change="handleChange"
19
+ :on-exceed="handleExceed"
20
+ :on-remove="handleRemove"
21
+ >
22
+ <el-icon class="el-icon--upload">
23
+ <UploadFilled />
24
+ </el-icon>
25
+
26
+ <div class="el-upload__text">
27
+ 将表格文件拖到这里,或 <em>点击选择</em>
28
+ </div>
29
+
30
+ <template #tip>
31
+ <div class="el-upload__tip">
32
+ 仅支持 xls / xlsx / csv,每次只允许上传 1 个文件
33
+ </div>
34
+ </template>
35
+ </el-upload>
36
+
37
+ <template #footer>
38
+ <el-button :disabled="loading" @click="dialogVisible = false">
39
+ 取消
40
+ </el-button>
41
+ <el-button type="primary" :loading="loading" @click="handleConfirm">
42
+ 导入
43
+ </el-button>
44
+ </template>
45
+ </el-dialog>
46
+ </template>
47
+
48
+ <script setup>
49
+ import { computed, ref } from 'vue'
50
+ import { ElMessage, genFileId } from 'element-plus'
51
+ import { UploadFilled } from '@element-plus/icons-vue'
52
+
53
+ const props = defineProps({
54
+ modelValue: {
55
+ type: Boolean,
56
+ default: false,
57
+ },
58
+ title: {
59
+ type: String,
60
+ default: '导入表格',
61
+ },
62
+ loading: {
63
+ type: Boolean,
64
+ default: false,
65
+ },
66
+ })
67
+
68
+ const emit = defineEmits(['update:modelValue', 'confirm'])
69
+
70
+ const dialogVisible = computed({
71
+ get: () => props.modelValue,
72
+ set: (value) => emit('update:modelValue', value),
73
+ })
74
+
75
+ const uploadRef = ref()
76
+ const fileList = ref([])
77
+ const selectedFile = ref(null)
78
+
79
+ const accept = '.xls,.xlsx,.csv'
80
+ const allowExt = ['xls', 'xlsx', 'csv']
81
+
82
+ const isTableFile = (file) => {
83
+ const ext = file.name?.split('.').pop()?.toLowerCase()
84
+ return allowExt.includes(ext)
85
+ }
86
+
87
+ const reset = () => {
88
+ selectedFile.value = null
89
+ fileList.value = []
90
+ uploadRef.value?.clearFiles()
91
+ }
92
+
93
+ const handleChange = (uploadFile, uploadFiles) => {
94
+ const rawFile = uploadFile.raw
95
+ if (!rawFile) return
96
+
97
+ if (!isTableFile(rawFile)) {
98
+ ElMessage.error('只能上传表格文件(xls、xlsx、csv)')
99
+ reset()
100
+ return
101
+ }
102
+
103
+ // 只保留最后一个文件
104
+ fileList.value = uploadFiles.slice(-1)
105
+ selectedFile.value = rawFile
106
+ }
107
+
108
+ const handleExceed = (files) => {
109
+ const file = files[0]
110
+
111
+ if (!isTableFile(file)) {
112
+ ElMessage.error('只能上传表格文件(xls、xlsx、csv)')
113
+ return
114
+ }
115
+
116
+ // 超出 1 个时,用新文件覆盖旧文件
117
+ uploadRef.value?.clearFiles()
118
+ file.uid = genFileId()
119
+ uploadRef.value?.handleStart(file)
120
+ }
121
+
122
+ const handleRemove = () => {
123
+ selectedFile.value = null
124
+ }
125
+
126
+ const handleConfirm = () => {
127
+ if (!selectedFile.value) {
128
+ ElMessage.warning('请先选择一个表格文件')
129
+ return
130
+ }
131
+
132
+ // 把原始 File 对象交给父组件
133
+ emit('confirm', selectedFile.value)
134
+ }
135
+
136
+ const handleClosed = () => {
137
+ reset()
138
+ }
139
+ </script>
140
+
141
+ <style scoped>
142
+ :deep(.el-upload),
143
+ :deep(.el-upload-dragger) {
144
+ width: 100%;
145
+ }
146
+ </style>
@@ -0,0 +1,164 @@
1
+ <template>
2
+ <section class="page import-page">
3
+ <h1 class="title">导入表格</h1>
4
+
5
+ <el-card class="upload-card">
6
+ <template #header>
7
+ <div class="card-header">
8
+ <span>数据导入</span>
9
+ </div>
10
+ </template>
11
+
12
+ <div class="upload-content">
13
+ <el-button type="primary" @click="showImportDialog">
14
+ 导入表格文件
15
+ </el-button>
16
+
17
+ <div v-if="uploadedFile" class="file-info">
18
+ <el-alert
19
+ title="已选择文件"
20
+ type="success"
21
+ :closable="false"
22
+ show-icon
23
+ >
24
+ <div class="file-details">
25
+ <p><strong>文件名:</strong>{{ uploadedFile.name }}</p>
26
+ <p><strong>文件大小:</strong>{{ formatFileSize(uploadedFile.size) }}</p>
27
+ <p><strong>文件类型:</strong>{{ uploadedFile.type || '未知' }}</p>
28
+ </div>
29
+ </el-alert>
30
+
31
+ <el-button type="danger" size="small" @click="clearFile" style="margin-top: 12px">
32
+ 清除文件
33
+ </el-button>
34
+ </div>
35
+
36
+ <div v-else class="upload-tips">
37
+ <el-alert
38
+ title="上传说明"
39
+ type="info"
40
+ :closable="false"
41
+ show-icon
42
+ >
43
+ <template #default>
44
+ <ul>
45
+ <li>支持的文件格式:xls、xlsx、csv</li>
46
+ <li>每次只能上传一个文件</li>
47
+ <li>上传后可以在这里查看文件信息</li>
48
+ </ul>
49
+ </template>
50
+ </el-alert>
51
+ </div>
52
+ </div>
53
+ </el-card>
54
+
55
+ <!-- 导入对话框 -->
56
+ <ImportTableDialog
57
+ v-model="dialogVisible"
58
+ :loading="loading"
59
+ @confirm="handleImportConfirm"
60
+ />
61
+ </section>
62
+ </template>
63
+
64
+ <script setup>
65
+ import { ref } from 'vue'
66
+ import { ElMessage } from 'element-plus'
67
+ import ImportTableDialog from '../components/ImportTableDialog.vue'
68
+
69
+ const dialogVisible = ref(false)
70
+ const loading = ref(false)
71
+ const uploadedFile = ref(null)
72
+
73
+ const showImportDialog = () => {
74
+ dialogVisible.value = true
75
+ }
76
+
77
+ const handleImportConfirm = (file) => {
78
+ loading.value = true
79
+
80
+ // 模拟上传处理
81
+ setTimeout(() => {
82
+ loading.value = false
83
+ dialogVisible.value = false
84
+ uploadedFile.value = file
85
+
86
+ ElMessage.success(`文件 "${file.name}" 上传成功!`)
87
+
88
+ // 这里可以添加实际的文件上传逻辑
89
+ console.log('准备上传的文件:', file)
90
+ // 例如:调用 API 上传文件
91
+ // uploadFileApi(file).then(res => { ... })
92
+ }, 1000)
93
+ }
94
+
95
+ const clearFile = () => {
96
+ uploadedFile.value = null
97
+ ElMessage.info('已清除文件')
98
+ }
99
+
100
+ const formatFileSize = (bytes) => {
101
+ if (!bytes) return '0 B'
102
+ const sizes = ['B', 'KB', 'MB', 'GB']
103
+ const i = Math.floor(Math.log(bytes) / Math.log(1024))
104
+ return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${sizes[i]}`
105
+ }
106
+ </script>
107
+
108
+ <style scoped>
109
+ .page.import-page {
110
+ padding: 16px;
111
+ }
112
+
113
+ .title {
114
+ font-size: 18px;
115
+ margin-bottom: 12px;
116
+ }
117
+
118
+ .upload-card {
119
+ max-width: 800px;
120
+ }
121
+
122
+ .card-header {
123
+ display: flex;
124
+ justify-content: space-between;
125
+ align-items: center;
126
+ }
127
+
128
+ .upload-content {
129
+ min-height: 200px;
130
+ display: flex;
131
+ flex-direction: column;
132
+ align-items: center;
133
+ justify-content: center;
134
+ }
135
+
136
+ .file-info {
137
+ margin-top: 16px;
138
+ text-align: center;
139
+ }
140
+
141
+ .file-details {
142
+ text-align: left;
143
+ }
144
+
145
+ .file-details p {
146
+ margin: 8px 0;
147
+ font-size: 14px;
148
+ }
149
+
150
+ .upload-tips {
151
+ margin-top: 16px;
152
+ width: 100%;
153
+ }
154
+
155
+ .upload-tips ul {
156
+ margin: 8px 0;
157
+ padding-left: 20px;
158
+ }
159
+
160
+ .upload-tips li {
161
+ margin: 4px 0;
162
+ font-size: 14px;
163
+ }
164
+ </style>
@@ -1,6 +1,7 @@
1
1
  import TablePage from '../pages/TablePage.vue'
2
2
  import CascaderPage from '../pages/CascaderPage.vue'
3
3
  import ExportExcelPage from '../pages/ExportExcelPage.vue'
4
+ import ImportTablePage from '../pages/ImportTablePage.vue'
4
5
 
5
6
  export const routes = [
6
7
  {
@@ -30,7 +31,16 @@ export const routes = [
30
31
  name: 'ExportExcel',
31
32
  component: ExportExcelPage,
32
33
  meta: {
33
- title: '导出Excel',
34
+ title: '导出 Excel',
35
+ showInMenu: true
36
+ }
37
+ },
38
+ {
39
+ path: '/import-table',
40
+ name: 'ImportTable',
41
+ component: ImportTablePage,
42
+ meta: {
43
+ title: '导入表格',
34
44
  showInMenu: true
35
45
  }
36
46
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue2server7",
3
- "version": "5.0.8",
3
+ "version": "6.0.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "dev": "nodemon --watch src --ext ts --exec \"ts-node src/app.ts\"",
@@ -30,19 +30,18 @@
30
30
  "author": "",
31
31
  "license": "ISC",
32
32
  "dependencies": {
33
- "@element-plus/icons-vue": "^2.3.1",
34
- "axios": "^1.13.2",
35
33
  "cors": "^2.8.5",
36
34
  "dotenv": "^16.6.1",
37
- "echarts": "^5.5.1",
38
- "element-plus": "^2.8.4",
39
35
  "express": "^5.2.1",
40
36
  "helmet": "^8.1.0",
41
37
  "morgan": "^1.10.1",
38
+ "@element-plus/icons-vue": "^2.3.1",
39
+ "axios": "^1.13.2",
40
+ "echarts": "^5.5.1",
41
+ "element-plus": "^2.8.4",
42
42
  "sortablejs": "^1.15.6",
43
43
  "vue": "^3.5.13",
44
- "vue-router": "^4.4.5",
45
- "vue2webstrom": "^0.0.1"
44
+ "vue-router": "^4.4.5"
46
45
  },
47
46
  "devDependencies": {
48
47
  "@types/cors": "^2.8.19",
@@ -51,12 +50,12 @@
51
50
  "@types/node": "^22.10.5",
52
51
  "@typescript-eslint/parser": "^8.19.0",
53
52
  "@vitejs/plugin-vue": "^6.0.0",
54
- "concurrently": "^9.1.0",
55
53
  "eslint": "^9.18.0",
56
- "nodemon": "^3.0.1",
57
- "supertest": "^7.1.4",
58
54
  "ts-node": "^10.9.2",
55
+ "supertest": "^7.1.4",
59
56
  "typescript": "^5.7.3",
57
+ "nodemon": "^3.0.1",
58
+ "concurrently": "^9.1.0",
60
59
  "vite": "^6.0.0",
61
60
  "vite-plugin-vue-devtools": "^8.0.6"
62
61
  },
Binary file
Binary file
@@ -1 +0,0 @@
1
- VHQBB5TES2-eyJsaWNlbnNlSWQiOiJWSFFCQjVURVMyIiwibGljZW5zZWVOYW1lIjoieW9uZyB6aGFuZyIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb24iOiIiLCJjaGVja0NvbmN1cnJlbnRVc2UiOmZhbHNlLCJwcm9kdWN0cyI6W3siY29kZSI6IkdPIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9LHsiY29kZSI6IlJTMCIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAifSx7ImNvZGUiOiJETSIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAifSx7ImNvZGUiOiJDTCIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAifSx7ImNvZGUiOiJSU1UiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIn0seyJjb2RlIjoiUlNDIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9LHsiY29kZSI6IlBDIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9LHsiY29kZSI6IkRTIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9LHsiY29kZSI6IlJEIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9LHsiY29kZSI6IlJDIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9LHsiY29kZSI6IlJTRiIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAifSx7ImNvZGUiOiJEQlIiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIn0seyJjb2RlIjoiUk0iLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIn0seyJjb2RlIjoiSUkiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIn0seyJjb2RlIjoiRFBOIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9LHsiY29kZSI6IkRCIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9LHsiY29kZSI6IkRDIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9LHsiY29kZSI6IlBTIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9LHsiY29kZSI6IlJSIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9LHsiY29kZSI6IlJTViIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAifSx7ImNvZGUiOiJBSVAiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAifSx7ImNvZGUiOiJXUyIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAifSx7ImNvZGUiOiJQU0kiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIn0seyJjb2RlIjoiUENXTVAiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAifSx7ImNvZGUiOiJBSUwiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAifSx7ImNvZGUiOiJBSUYiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAifSx7ImNvZGUiOiJSUyIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAifSx7ImNvZGUiOiJQUlIiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIn0seyJjb2RlIjoiRFAiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIn0seyJjb2RlIjoiUERCIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9LHsiY29kZSI6IkdaTCIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCJ9XSwiaGFzaCI6IjcxODE5NTMyLzA6LTEyMDcxMjE3NjMiLCJncmFjZVBlcmlvZERheXMiOjcsImF1dG9Qcm9sb25nYXRlZCI6ZmFsc2UsImlzQXV0b1Byb2xvbmdhdGVkIjpmYWxzZX0=-qGdpNRWCSO+fI5MSoLjoZwHomF3UJM54dwfNBG1CoFhcrcf3mGcnBOcztY80v0VtUuU015ThEKRUzpDGX44hXJKOO9fP+257gXXGvwkWq7Q/IKD2tHDeMc6LdmSMmrlFl2mQ8vDaK3ZV9BXCTeJrR0mn5OmRZvL241twFvAEvqwMSM58v1lCjUD2J3IGbz7rkWkW/+OVplSbYG5F6EzOTi/O9WmsvE6w32kWtwgVKbkAM20rL2W6tgRKw4bvFgEZch2OvHqhuntbGk/gRjsW/b+9mfwuMaSNHOoTE6wPtPHBnhm6ibx7vJ1+mrgAIVe7aEKPXUiXpApCOvjxGQeHwA==-MIIETDCCAjSgAwIBAgIBETANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTI0MDkyMDEyMTEyN1oXDTI2MDkyMjEyMTEyN1owHzEdMBsGA1UEAwwUcHJvZDJ5LWZyb20tMjAyNDA5MjAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7SH/XcUoMwkDi8JJPzXWWHWFdOZdrP2Dqkz2W8iUi650cwz2vdPEd0tMzosLAj7ifkFEHUyiuEcL//q9d9Op7ZsV23lpPXX8tFMLFwugoQ9D8jDLT/XP9pp/YukWkKF5jpNbaCvsVQkDdYkArBkYvhH3aN4v9BkEsXahfgLLOPe4IG2FDJNf9R4to9V1vt+m2UVJB0zV4a/sVMKUZLgqKmKKKOKoLrE3OjBlZlb+Q0z2N5dsW0hDEVRFGmBUAbHN/mp44MMMvEIFKfoLIGpgic92P2O6uFh75PI7mcultL6yuR48ajErx8CjjQEGOSnoq/8hD+yVE+6GW2gJa2CPvAgMBAAGjgZkwgZYwCQYDVR0TBAIwADAdBgNVHQ4EFgQUb5NERj05GyNerQ/Mjm9XH8HXtLIwSAYDVR0jBEEwP4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0GCCQDSbLGDsoN54TATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQELBQADggIBALq6VfVUjmPI3N/w0RYoPGFYUieCfRO0zVvD1VYHDWsN3F9buVsdudhxEsUb8t7qZPkDKTOB6DB+apgt2ZdKwok8S0pwifwLfjHAhO3b+LUQaz/VmKQW8gTOS5kTVcpM0BY7UPF8cRBqxMsdUfm5ejYk93lBRPBAqntznDY+DNc9aXOldFiACyutB1/AIh7ikUYPbpEIPZirPdAahroVvfp2tr4BHgCrk9z0dVi0tk8AHE5t7Vk4OOaQRJzy3lST4Vv6Mc0+0z8lNa+Sc3SVL8CrRtnTAs7YpD4fpI5AFDtchNrgFalX+BZ9GLu4FDsshVI4neqV5Jd5zwWPnwRuKLxsCO/PB6wiBKzdapQBG+P9z74dQ0junol+tqxd7vUV/MFsR3VwVMTndyapIS+fMoe+ZR5g+y44R8C7fXyVE/geg+JXQKvRwS0C5UpnS5FcGk+61b0e4U7pwO20RlwhEFHLSaP61p2TaVGo/TQtT/fWmrtV+HegAv9P3X3Se+xIVtJzQsk8QrB/w52IB3FKiAKl/KRn1egbMIs4uoNAkqNZ9Ih2P1NpiQnONFmkiAgeynJ+0FPykKdJQbV3Mx44jkaHIif4aFReTsYX1WUBNu/QerZRjn4FVSHRaZPSR5Oi82Wz0Nj7IY9ocTpLnXFrqkb/Kt3S6B9s2Kol3Lr1ElYA
@@ -1 +0,0 @@
1
- VHQBB5TES2-eyJsaWNlbnNlSWQiOiJWSFFCQjVURVMyIiwibGljZW5zZWVOYW1lIjoieW9uZyB6aGFuZyIsImxpY2Vuc2VlVHlwZSI6IlBFUlNPTkFMIiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdGlvbiI6IiIsImNoZWNrQ29uY3VycmVudFVzZSI6ZmFsc2UsInByb2R1Y3RzIjpbeyJjb2RlIjoiR08iLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSUzAiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJETSIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkNMIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUlNVIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUlNDIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQQyIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRTIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUkQiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSQyIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlJTRiIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiREJSIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUk0iLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJJSSIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRQTiIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRCIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiREMiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJQUyIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlJSIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUlNWIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJBSVAiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IldTIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUFNJIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wNy0wMSIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQQ1dNUCIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJBSUwiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkFJRiIsInBhaWRVcFRvIjoiMjAyNi0wNi0zMCIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUlMiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBSUiIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiRFAiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA3LTAxIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBEQiIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDctMDEiLCJwYWlkVXBUbyI6IjIwMjYtMDYtMzAiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiR1pMIiwicGFpZFVwVG8iOiIyMDI2LTA2LTMwIiwiZXh0ZW5kZWQiOnRydWV9XSwibWV0YWRhdGEiOiIwNDIwMjUwOTIzUFBBQTAwNjAwOEEwMDAwMDBYWCIsImhhc2giOiI3MTgxOTUzMi8wOi0xMjA3MTIxNzYzIiwiZ3JhY2VQZXJpb2REYXlzIjo3LCJhdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlLCJpc0F1dG9Qcm9sb25nYXRlZCI6ZmFsc2UsInRyaWFsIjpmYWxzZSwiYWlBbGxvd2VkIjp0cnVlfQ==-ltum38hvV6+MO1jre8LGbwBQEH85U+6FyL7MJU/nAEWTARdwnAIw9mQMOUQrM1WFD2MFag+JBtKsaGz8v8QDS5MYd4pRwk2b8X09I4l0xAczHkkI8Gs2DfVPR0ZUoTdfwWjmY9mvP7sxuuPQaG3RJ4YaKYpj3i37YYh0IQpFqNpgMMJLEM9nfbZL+zP8dzeZjeK4fWG/l92uYRFk766ZIrkxrq2woOo4urlIH6p7YwSTrcda3h+MzF781Diq86AV82zQd1ACBjxmSRh7nzM/xuqw7YfzceCd8yij2FmgsvqVoQMfUpqjy0CivBKEjmRJ/QdhJM7qLwsmbNT51UN0XA==-MIIETDCCAjSgAwIBAgIBETANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTI0MDkyMDEyMTEyN1oXDTI2MDkyMjEyMTEyN1owHzEdMBsGA1UEAwwUcHJvZDJ5LWZyb20tMjAyNDA5MjAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7SH/XcUoMwkDi8JJPzXWWHWFdOZdrP2Dqkz2W8iUi650cwz2vdPEd0tMzosLAj7ifkFEHUyiuEcL//q9d9Op7ZsV23lpPXX8tFMLFwugoQ9D8jDLT/XP9pp/YukWkKF5jpNbaCvsVQkDdYkArBkYvhH3aN4v9BkEsXahfgLLOPe4IG2FDJNf9R4to9V1vt+m2UVJB0zV4a/sVMKUZLgqKmKKKOKoLrE3OjBlZlb+Q0z2N5dsW0hDEVRFGmBUAbHN/mp44MMMvEIFKfoLIGpgic92P2O6uFh75PI7mcultL6yuR48ajErx8CjjQEGOSnoq/8hD+yVE+6GW2gJa2CPvAgMBAAGjgZkwgZYwCQYDVR0TBAIwADAdBgNVHQ4EFgQUb5NERj05GyNerQ/Mjm9XH8HXtLIwSAYDVR0jBEEwP4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0GCCQDSbLGDsoN54TATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQELBQADggIBALq6VfVUjmPI3N/w0RYoPGFYUieCfRO0zVvD1VYHDWsN3F9buVsdudhxEsUb8t7qZPkDKTOB6DB+apgt2ZdKwok8S0pwifwLfjHAhO3b+LUQaz/VmKQW8gTOS5kTVcpM0BY7UPF8cRBqxMsdUfm5ejYk93lBRPBAqntznDY+DNc9aXOldFiACyutB1/AIh7ikUYPbpEIPZirPdAahroVvfp2tr4BHgCrk9z0dVi0tk8AHE5t7Vk4OOaQRJzy3lST4Vv6Mc0+0z8lNa+Sc3SVL8CrRtnTAs7YpD4fpI5AFDtchNrgFalX+BZ9GLu4FDsshVI4neqV5Jd5zwWPnwRuKLxsCO/PB6wiBKzdapQBG+P9z74dQ0junol+tqxd7vUV/MFsR3VwVMTndyapIS+fMoe+ZR5g+y44R8C7fXyVE/geg+JXQKvRwS0C5UpnS5FcGk+61b0e4U7pwO20RlwhEFHLSaP61p2TaVGo/TQtT/fWmrtV+HegAv9P3X3Se+xIVtJzQsk8QrB/w52IB3FKiAKl/KRn1egbMIs4uoNAkqNZ9Ih2P1NpiQnONFmkiAgeynJ+0FPykKdJQbV3Mx44jkaHIif4aFReTsYX1WUBNu/QerZRjn4FVSHRaZPSR5Oi82Wz0Nj7IY9ocTpLnXFrqkb/Kt3S6B9s2Kol3Lr1ElYA