@ganwei-web/ganwei-pc-cli 6.2.9 → 6.3.2

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.
Files changed (71) hide show
  1. package/ganwei-iotcenter-index-6.2.3/configuration/moduleConfiguration.json +2 -0
  2. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/env.d.ts +8 -5
  3. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/index.html +1 -1
  4. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/public/static/css/ElementPlusAdapter.css +437 -68
  5. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/public/static/css/reset-6-1.css +1 -0
  6. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/public/static/css/reset-plus.css +396 -0
  7. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/public/static/http/createAxios.js +38 -13
  8. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/public/static/js/getLanguage.js +19 -12
  9. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/public/static/themes/dark-6-1.css +3 -3
  10. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/public/static/themes/green-6-1.css +12 -11
  11. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/App.vue +11 -6
  12. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/components/indexRightContent/headerRight/equipAlarmDialog/index.vue +6 -0
  13. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/components/indexRightContent/headerRight/expirationReminder/index.vue +7 -3
  14. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/components/indexRightContent/headerRight/index.scss +4 -0
  15. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/components/indexRightContent/headerRight/userInfo/index.js +35 -3
  16. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/components/indexRightContent/headerRight/userInfo/index.scss +7 -1
  17. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/components/indexRightContent/headerRight/userInfo/index.vue +2 -2
  18. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/components/layouts/Navigation/ContractMenu.vue +11 -37
  19. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/components/layouts/Navigation/TopNav.vue +3 -2
  20. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/components/layouts/Sidebar/LeftContent/index.vue +7 -1
  21. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/router.js +120 -18
  22. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/utils/date.ts +80 -0
  23. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/utils/dom.ts +99 -0
  24. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/utils/env.ts +20 -0
  25. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/utils/file.ts +74 -0
  26. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/utils/index.ts +26 -0
  27. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/utils/number.ts +83 -0
  28. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/utils/performance.ts +69 -0
  29. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/utils/storage.ts +80 -0
  30. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/utils/string.ts +116 -0
  31. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/utils/xss-filter.ts +260 -0
  32. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/views/jumpIframe/index.vue +45 -28
  33. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/tsconfig.json +1 -0
  34. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/vite.config.ts +10 -1
  35. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-login/public/static/http/createAxios.js +40 -15
  36. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-login/public/static/js/getLanguage.js +10 -2
  37. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-login/src/views/login.vue +55 -53
  38. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-login/src/views/ssoLogin.vue +10 -9
  39. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/.env.development +0 -3
  40. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/.env.production +1 -4
  41. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/.env.test +0 -3
  42. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/.eslintrc.cjs +2 -2
  43. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/env.d.ts +9 -5
  44. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/index.html +1 -0
  45. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/package.json +3 -2
  46. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/public/static/http/createAxios.js +38 -13
  47. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/public/static/js/getLanguage.js +10 -2
  48. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/App.vue +1 -1
  49. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/request/api.ts +0 -1
  50. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/request/models/response/template.ts +0 -0
  51. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/utils/date.ts +79 -0
  52. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/utils/dom.ts +99 -0
  53. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/utils/env.ts +20 -0
  54. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/utils/file.ts +74 -0
  55. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/utils/index.ts +29 -0
  56. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/utils/number.ts +83 -0
  57. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/utils/performance.ts +69 -0
  58. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/utils/signalr.ts +564 -0
  59. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/utils/storage.ts +80 -0
  60. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/utils/string.ts +116 -0
  61. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/utils/xss-filter.ts +260 -0
  62. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/views/template.vue +0 -1
  63. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/tsconfig.json +7 -0
  64. package/ganwei-iotcenter-index-6.2.3/pnpm-lock.yaml +489 -155
  65. package/package.json +1 -1
  66. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/mixins/judgePermission.js +0 -60
  67. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/src/utils/setStorage.js +0 -5
  68. package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/utils/setStorage.js +0 -5
  69. /package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-index/build/{enteryJson.js → entryJson.js} +0 -0
  70. /package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/{request/models/request/index.ts → enum/template.ts} +0 -0
  71. /package/ganwei-iotcenter-index-6.2.3/packages/ganwei-iotcenter-template/src/request/models/{response/index.ts → request/template.ts} +0 -0
@@ -0,0 +1,116 @@
1
+ /**
2
+ * 首字母大写
3
+ */
4
+ export function capitalize(str: string): string {
5
+ return str.charAt(0).toUpperCase() + str.slice(1)
6
+ }
7
+
8
+ /**
9
+ * 驼峰转连字符
10
+ */
11
+ export function camelToKebab(str: string): string {
12
+ return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
13
+ }
14
+
15
+ /**
16
+ * 连字符转驼峰
17
+ */
18
+ export function kebabToCamel(str: string): string {
19
+ return str.replace(/-([a-z])/g, (_, char) => char.toUpperCase())
20
+ }
21
+
22
+ /**
23
+ * 手机号脱敏
24
+ */
25
+ export function maskPhone(phone: string): string {
26
+ return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
27
+ }
28
+
29
+ /**
30
+ * 身份证号脱敏
31
+ */
32
+ export function maskIdCard(idCard: string): string {
33
+ return idCard.replace(/(\d{6})\d{8}(\d{4})/, '$1********$2')
34
+ }
35
+
36
+ /**
37
+ * 银行卡号脱敏
38
+ */
39
+ export function maskBankCard(cardNo: string): string {
40
+ return cardNo.replace(/(\d{4})\d+(\d{4})/, '$1 **** **** $2')
41
+ }
42
+
43
+ /** 邮箱脱敏:t***e@example.com */
44
+ export function maskEmail(email: string): string {
45
+ if (!email || !email.includes('@')) return email
46
+ const [prefix, suffix] = email.split('@')
47
+ const maskedPrefix = prefix.charAt(0) + '***' + prefix.charAt(prefix.length - 1)
48
+ return `${maskedPrefix}@${suffix}`
49
+ }
50
+
51
+ /** 姓名脱敏:张*(2字)/ 张**(3字+) */
52
+ export function maskName(name: string): string {
53
+ if (!name) return name
54
+ if (name.length === 2) return name.charAt(0) + '*'
55
+ return name.charAt(0) + '*'.repeat(name.length - 1)
56
+ }
57
+
58
+ /** 地址脱敏:北京市朝阳区*** */
59
+ export function maskAddress(address: string): string {
60
+ if (!address || address.length <= 6) return address
61
+ return address.substring(0, 6) + '***'
62
+ }
63
+
64
+ /**
65
+ * 截断字符串
66
+ */
67
+ export function truncate(str: string, length: number, suffix = '...'): string {
68
+ if (str.length <= length) return str
69
+ return str.substring(0, length) + suffix
70
+ }
71
+
72
+ /**
73
+ * 移除 HTML 标签
74
+ */
75
+ export function stripHtml(html: string): string {
76
+ return html.replace(/<[^>]*>/g, '')
77
+ }
78
+
79
+ /**
80
+ * 转义 HTML 特殊字符
81
+ */
82
+ export function escapeHtml(str: string): string {
83
+ const escapeMap: Record<string, string> = {
84
+ '&': '&amp;',
85
+ '<': '&lt;',
86
+ '>': '&gt;',
87
+ '"': '&quot;',
88
+ "'": '&#39;'
89
+ }
90
+
91
+ return str.replace(/[&<>"']/g, char => escapeMap[char])
92
+ }
93
+
94
+ /**
95
+ * 解析 URL 参数
96
+ */
97
+ export function parseQueryString(url: string): Record<string, string> {
98
+ const queryString = url.split('?')[1]
99
+ if (!queryString) return {}
100
+
101
+ return queryString.split('&').reduce((params, param) => {
102
+ const [key, value] = param.split('=')
103
+ params[decodeURIComponent(key)] = decodeURIComponent(value || '')
104
+ return params
105
+ }, {} as Record<string, string>)
106
+ }
107
+
108
+ /**
109
+ * 序列化对象为 URL 参数
110
+ */
111
+ export function stringifyQueryString(obj: Record<string, any>): string {
112
+ return Object.entries(obj)
113
+ .filter(([, value]) => value !== undefined && value !== null)
114
+ .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
115
+ .join('&')
116
+ }
@@ -0,0 +1,260 @@
1
+ /**
2
+ * XSS 过滤工具
3
+ * 用于过滤和清理用户输入,防止 XSS 攻击
4
+ */
5
+
6
+ /**
7
+ * HTML 实体编码映射
8
+ */
9
+ const HTML_ENTITIES: Record<string, string> = {
10
+ '&': '&amp;',
11
+ '<': '&lt;',
12
+ '>': '&gt;',
13
+ '"': '&quot;',
14
+ "'": '&#x27;',
15
+ '/': '&#x2F;',
16
+ '`': '&#x60;',
17
+ '=': '&#x3D;'
18
+ }
19
+
20
+ /**
21
+ * 危险 HTML 标签正则
22
+ */
23
+ const DANGEROUS_TAGS_REGEX =
24
+ /<(script|iframe|object|embed|form|input|button|textarea|select|style|link|meta|base)[^>]*>.*?<\/\1>|<(script|iframe|object|embed|form|input|button|textarea|select|style|link|meta|base)[^>]*\/?>/gi
25
+
26
+ /**
27
+ * 危险属性正则
28
+ */
29
+ const DANGEROUS_ATTRS_REGEX = /\s(on\w+|href|src|action|formaction|data|dynsrc|lowsrc)\s*=\s*(['"]?)[^'">\s]*\2/gi
30
+
31
+ /**
32
+ * javascript: 协议正则
33
+ */
34
+ const JAVASCRIPT_PROTOCOL_REGEX = /javascript\s*:/gi
35
+
36
+ /**
37
+ * 转义 HTML 特殊字符
38
+ * @param str - 要转义的字符串
39
+ * @returns 转义后的字符串
40
+ * @example
41
+ * escapeHtml('<script>alert("xss")</script>')
42
+ * // '&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;'
43
+ */
44
+ export function escapeHtml(str: string): string {
45
+ if (!str) return ''
46
+ return str.replace(/[&<>"'`=/]/g, char => HTML_ENTITIES[char])
47
+ }
48
+
49
+ /**
50
+ * 反转义 HTML 特殊字符
51
+ * @param str - 要反转义的字符串
52
+ * @returns 反转义后的字符串
53
+ */
54
+ export function unescapeHtml(str: string): string {
55
+ if (!str) return ''
56
+ const entities: Record<string, string> = {
57
+ '&amp;': '&',
58
+ '&lt;': '<',
59
+ '&gt;': '>',
60
+ '&quot;': '"',
61
+ '&#x27;': "'",
62
+ '&#x2F;': '/',
63
+ '&#x60;': '`',
64
+ '&#x3D;': '='
65
+ }
66
+ return str.replace(/&(amp|lt|gt|quot|#x27|#x2F|#x60|#x3D);/g, entity => entities[entity] || entity)
67
+ }
68
+
69
+ /**
70
+ * 移除危险 HTML 标签
71
+ * @param html - HTML 字符串
72
+ * @returns 清理后的 HTML
73
+ * @example
74
+ * stripDangerousTags('<script>alert(1)</script><p>安全</p>')
75
+ * // '<p>安全</p>'
76
+ */
77
+ export function stripDangerousTags(html: string): string {
78
+ if (!html) return ''
79
+ return html.replace(DANGEROUS_TAGS_REGEX, '')
80
+ }
81
+
82
+ /**
83
+ * 移除危险属性
84
+ * @param html - HTML 字符串
85
+ * @returns 清理后的 HTML
86
+ * @example
87
+ * stripDangerousAttrs('<div onclick="alert(1)">内容</div>')
88
+ * // '<div>内容</div>'
89
+ */
90
+ export function stripDangerousAttrs(html: string): string {
91
+ if (!html) return ''
92
+ return html.replace(DANGEROUS_ATTRS_REGEX, '')
93
+ }
94
+
95
+ /**
96
+ * 移除 javascript: 协议
97
+ * @param str - 字符串
98
+ * @returns 清理后的字符串
99
+ */
100
+ export function stripJavascriptProtocol(str: string): string {
101
+ if (!str) return ''
102
+ return str.replace(JAVASCRIPT_PROTOCOL_REGEX, '')
103
+ }
104
+
105
+ /**
106
+ * XSS 过滤(完整版)
107
+ * @param input - 用户输入
108
+ * @param options - 过滤选项
109
+ * @returns 过滤后的安全字符串
110
+ */
111
+ export interface XssFilterOptions {
112
+
113
+ /** 是否转义 HTML,默认 true */
114
+ escapeHtml?: boolean
115
+
116
+ /** 是否移除危险标签,默认 true */
117
+ stripDangerousTags?: boolean
118
+
119
+ /** 是否移除危险属性,默认 true */
120
+ stripDangerousAttrs?: boolean
121
+
122
+ /** 是否移除 javascript 协议,默认 true */
123
+ stripJavascriptProtocol?: boolean
124
+ }
125
+
126
+ export function xssFilter(input: string, options: XssFilterOptions = {}): string {
127
+ if (!input) return ''
128
+
129
+ const {
130
+ escapeHtml: shouldEscape = true,
131
+ stripDangerousTags: shouldStripTags = true,
132
+ stripDangerousAttrs: shouldStripAttrs = true,
133
+ stripJavascriptProtocol: shouldStripJsProtocol = true
134
+ } = options
135
+
136
+ let result = input
137
+
138
+ // 移除危险标签
139
+ if (shouldStripTags) {
140
+ result = stripDangerousTags(result)
141
+ }
142
+
143
+ // 移除危险属性
144
+ if (shouldStripAttrs) {
145
+ result = stripDangerousAttrs(result)
146
+ }
147
+
148
+ // 移除 javascript 协议
149
+ if (shouldStripJsProtocol) {
150
+ result = stripJavascriptProtocol(result)
151
+ }
152
+
153
+ // 转义 HTML
154
+ if (shouldEscape) {
155
+ result = escapeHtml(result)
156
+ }
157
+
158
+ return result
159
+ }
160
+
161
+ /**
162
+ * 过滤 URL,只允许安全协议
163
+ * @param url - URL 字符串
164
+ * @param allowedProtocols - 允许的协议列表
165
+ * @returns 安全的 URL 或空字符串
166
+ * @example
167
+ * filterUrl('javascript:alert(1)') // ''
168
+ * filterUrl('https://example.com') // 'https://example.com'
169
+ */
170
+ export function filterUrl(
171
+ url: string,
172
+ allowedProtocols: string[] = ['http', 'https', 'mailto', 'tel', 'ftp']
173
+ ): string {
174
+ if (!url) return ''
175
+
176
+ // 移除空白字符
177
+ const trimmedUrl = url.trim()
178
+
179
+ // 检查是否为相对路径或锚点
180
+ if (trimmedUrl.startsWith('/') || trimmedUrl.startsWith('#') || trimmedUrl.startsWith('?')) {
181
+ return trimmedUrl
182
+ }
183
+
184
+ // 提取协议
185
+ const protocolMatch = trimmedUrl.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):/)
186
+ if (!protocolMatch) {
187
+ return trimmedUrl // 无协议,视为相对路径
188
+ }
189
+
190
+ const protocol = protocolMatch[1].toLowerCase()
191
+
192
+ // 检查协议是否在允许列表中
193
+ if (allowedProtocols.includes(protocol)) {
194
+ return trimmedUrl
195
+ }
196
+
197
+ return ''
198
+ }
199
+
200
+ /**
201
+ * 过滤对象中的 XSS
202
+ * @param obj - 要过滤的对象
203
+ * @param options - 过滤选项
204
+ * @returns 过滤后的对象
205
+ */
206
+ export function filterObject<T extends Record<string, any>>(
207
+ obj: T,
208
+ options: XssFilterOptions = {}
209
+ ): T {
210
+ if (!obj || typeof obj !== 'object') return obj
211
+
212
+ const result: Record<string, any> = {}
213
+
214
+ for (const [key, value] of Object.entries(obj)) {
215
+ if (typeof value === 'string') {
216
+ result[key] = xssFilter(value, options)
217
+ } else if (typeof value === 'object' && value !== null) {
218
+ result[key] = filterObject(value, options)
219
+ } else {
220
+ result[key] = value
221
+ }
222
+ }
223
+
224
+ return result as T
225
+ }
226
+
227
+ /**
228
+ * 白名单标签过滤
229
+ * 只保留允许的 HTML 标签
230
+ * @param html - HTML 字符串
231
+ * @param allowedTags - 允许的标签列表
232
+ * @returns 过滤后的 HTML
233
+ * @example
234
+ * filterHtmlTags('<p><script>alert(1)</script>内容</p>', ['p'])
235
+ * // '<p>内容</p>'
236
+ */
237
+ export function filterHtmlTags(html: string, allowedTags: string[] = []): string {
238
+ if (!html) return ''
239
+ if (allowedTags.length === 0) return escapeHtml(html)
240
+
241
+ // 构建白名单正则
242
+ const allowedTagsPattern = allowedTags.join('|')
243
+ const openTagRegex = new RegExp(`<(${allowedTagsPattern})([^>]*)>`, 'gi')
244
+ const closeTagRegex = new RegExp(`</(${allowedTagsPattern})>`, 'gi')
245
+
246
+ // 先转义所有 HTML
247
+ let result = escapeHtml(html)
248
+
249
+ // 恢复允许的标签
250
+ result = result.replace(
251
+ new RegExp(`&lt;(${allowedTagsPattern})([^&]*)&gt;`, 'gi'),
252
+ (_, tag, attrs) => `<${tag}${unescapeHtml(attrs)}>`
253
+ )
254
+ result = result.replace(
255
+ new RegExp(`&lt;/(${allowedTagsPattern})&gt;`, 'gi'),
256
+ (_, tag) => `</${tag}>`
257
+ )
258
+
259
+ return result
260
+ }
@@ -8,7 +8,6 @@
8
8
  import { ref, reactive } from 'vue'
9
9
  import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
10
10
 
11
-
12
11
  </script>
13
12
 
14
13
  <style scoped lang="scss">
@@ -45,11 +45,18 @@
45
45
  }
46
46
  },
47
47
  "include": [
48
+ "env.d.ts",
48
49
  "src/**/*.ts",
49
50
  "src/**/*.d.ts",
50
51
  "src/**/*.tsx",
51
52
  "src/**/*.vue",
52
53
  "build/**/*.ts",
53
54
  "build/**/*.tsx"
55
+ ],
56
+ /** 编译器默认排除的编译文件 */
57
+ "exclude": [
58
+ "node_modules",
59
+ "dist",
60
+ "public"
54
61
  ]
55
62
  }