@indfnd/utils 0.0.34 → 0.0.36

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indfnd/utils",
3
- "version": "0.0.34",
3
+ "version": "0.0.36",
4
4
  "author": "huxuetong",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -1,8 +1,58 @@
1
- import { axios } from '@/utils'
1
+ import { CONTENT_TYPE, axios } from '@/utils'
2
2
  import { config } from '@/config'
3
+ import { AxiosRequestConfig, ResponseType } from 'axios'
3
4
 
4
5
  const CONTEXT = config.ossServerContext
5
6
 
6
- export function getOssFileApi(fileId: string) {
7
- return axios.get(`${CONTEXT}/oss/file/get/${fileId}`)
7
+ /**
8
+ * 文档中心下载文件的url,主要用于图片等直接写在 href 里
9
+ *
10
+ * @param fileId 文件Id
11
+ * @returns url
12
+ */
13
+ export function getOssFileUrl(fileId = '') {
14
+ return `${CONTEXT}/oss/file/get/${fileId}`
15
+ }
16
+
17
+ /**
18
+ * 文档中心上传文件的url
19
+ *
20
+ * @returns url
21
+ */
22
+ export function putOssFileUrl() {
23
+ return `${CONTEXT}/oss/file/put`
24
+ }
25
+
26
+ /**
27
+ * 获取文档中心文件
28
+ *
29
+ * @param fileId 文件Id
30
+ * @param responseType 数据类型,支持 arraybuffer | blob | document | json | text | stream
31
+ * @returns 文件内容
32
+ */
33
+ export function getOssFileApi(fileId: string, responseType?: ResponseType) {
34
+ const config = {} as AxiosRequestConfig
35
+ if (responseType) {
36
+ config.responseType = responseType
37
+ }
38
+ return axios.get(getOssFileUrl(fileId), config)
39
+ }
40
+
41
+ /**
42
+ * 将文件上传到文档中心
43
+ *
44
+ * @param filename 文件名
45
+ * @param blob 文件的Blob数据
46
+ * @returns 文件Id
47
+ */
48
+ export function putOssFileApi(filename: string, blob: Blob) {
49
+ let formData = new FormData()
50
+ formData.append('file', blob, filename)
51
+
52
+ return axios({
53
+ method: 'post',
54
+ url: putOssFileUrl(),
55
+ headers: { 'Content-Type': CONTENT_TYPE.multiForm },
56
+ data: formData,
57
+ })
8
58
  }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 将base64转换为Blob
3
+ *
4
+ * @param base64Data base64数据
5
+ * @param contentType 数据的MIME Type,如 png 为 image/png
6
+ * @returns Blob数据
7
+ */
8
+ export function base64ToBlob(base64Data: string, contentType: string): Blob {
9
+ contentType = contentType || ''
10
+ const sliceSize = 1024
11
+ const byteCharacters = atob(base64Data)
12
+ const bytesLength = byteCharacters.length
13
+ const slicesCount = Math.ceil(bytesLength / sliceSize)
14
+ const byteArrays = new Array(slicesCount)
15
+
16
+ for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
17
+ const begin = sliceIndex * sliceSize
18
+ const end = Math.min(begin + sliceSize, bytesLength)
19
+
20
+ const bytes = new Array(end - begin)
21
+ for (let offset = begin, i = 0; offset < end; ++i, ++offset) {
22
+ bytes[i] = byteCharacters[offset].charCodeAt(0)
23
+ }
24
+ byteArrays[sliceIndex] = new Uint8Array(bytes)
25
+ }
26
+ return new Blob(byteArrays, { type: contentType })
27
+ }
@@ -35,7 +35,7 @@ function offFn() {
35
35
  }
36
36
 
37
37
  /**
38
- * @description 绑定事件 on(element, event, handler)
38
+ * 绑定事件 on(element, event, handler)
39
39
  */
40
40
  export function on(element, event, handler) {
41
41
  const fn = onFn()
@@ -44,10 +44,29 @@ export function on(element, event, handler) {
44
44
  }
45
45
 
46
46
  /**
47
- * @description 解绑事件 off(element, event, handler)
47
+ * 解绑事件 off(element, event, handler)
48
48
  */
49
49
  export function off(element, event, handler) {
50
50
  const fn = offFn()
51
51
  fn(element, event, handler)
52
52
  return fn
53
53
  }
54
+
55
+ export const stopPropagation = (event: Event) => event.stopPropagation()
56
+
57
+ /**
58
+ * 事件 preventDefault
59
+ *
60
+ * @param event 事件
61
+ * @param isStopPropagation 是否阻止冒泡
62
+ */
63
+ export function preventDefault(event: Event, isStopPropagation?: Boolean) {
64
+ /* istanbul ignore else */
65
+ if (typeof event.cancelable !== 'boolean' || event.cancelable) {
66
+ event.preventDefault()
67
+ }
68
+
69
+ if (isStopPropagation) {
70
+ stopPropagation(event)
71
+ }
72
+ }
@@ -2,6 +2,7 @@ export * from './cache'
2
2
  export * from './request'
3
3
  export * from './sm3'
4
4
 
5
+ export * from './blob'
5
6
  export * from './date'
6
7
  export * from './enum'
7
8
  export * from './excel'
@@ -10,7 +10,7 @@ export function setContentType(headers: any, type: string) {
10
10
 
11
11
  export const CONTENT_TYPE = {
12
12
  form: 'application/x-www-form-urlencoded',
13
- 'multi-form': 'multipart/form-data',
13
+ multiForm: 'multipart/form-data',
14
14
  body: 'application/json',
15
15
  os: 'application/octet-stream',
16
16
  }
@@ -98,8 +98,7 @@ export function inspectorError(error) {
98
98
  if (error?.code === 'ECONNABORTED') {
99
99
  // 超时
100
100
  window.apiErrorHandler && window.apiErrorHandler('请求超时,请稍后再试')
101
- }
102
- if (error.response.status !== 200) {
101
+ } else if (error?.response?.status !== 200) {
103
102
  window.apiErrorHandler && window.apiErrorHandler('请求出错了')
104
103
  }
105
104
  return Promise.reject(error)
@@ -2,10 +2,11 @@
2
2
  * @Author: huxuetong
3
3
  * @Date: 2023-10-27 15:05:25
4
4
  * @Last Modified by: huxuetong
5
- * @Last Modified time: 2024-02-21 17:34:35
5
+ * @Last Modified time: 2024-03-01 16:43:10
6
6
  */
7
7
 
8
8
  import _ from 'lodash'
9
+ import { isNil } from './is-type'
9
10
 
10
11
  const GROUP_SEP = '__'
11
12
  const VALUE_SEP = '--'
@@ -19,6 +20,12 @@ interface ColumnGroup {
19
20
  keyProp?: string
20
21
  titleProp?: string
21
22
  titleFormatter?: (title: string) => string
23
+ // 动态列的列顺序key
24
+ sortProp?: string
25
+ // 动态列的列顺序 asc | desc,默认asc
26
+ sortOrder?: boolean | 'asc' | 'desc'
27
+ // 当动态列为最后一层只有一个指标,又不想再展示一行指标时,指标对应的属性key
28
+ keyLastSuffix?: string
22
29
 
23
30
  // 每层分组表头下继续分组
24
31
  children?: ColumnGroup[]
@@ -32,8 +39,6 @@ interface row2columnOption {
32
39
  titlePropName?: string
33
40
  // 组织列定义 key 的前缀
34
41
  keyPrefix?: string
35
- // 组织列定义 key 的后缀
36
- keyLastSuffix?: string
37
42
  }
38
43
 
39
44
  interface Column {
@@ -54,18 +59,28 @@ function renderColumnTree(
54
59
  columnGroup: ColumnGroup,
55
60
  option: row2columnOption = {},
56
61
  ): Column | Column[] {
57
- const { key, keyProp, title, titleProp, titleFormatter, children, ...args } = columnGroup
58
62
  const {
59
- keyPropName = 'key',
60
- titlePropName = 'title',
61
- keyPrefix = '',
62
- keyLastSuffix = '',
63
- } = option
63
+ key,
64
+ keyProp,
65
+ title,
66
+ titleProp,
67
+ titleFormatter,
68
+ sortProp = keyProp,
69
+ sortOrder = 'asc',
70
+ keyLastSuffix,
71
+ children,
72
+ ...args
73
+ } = columnGroup
74
+ const { keyPropName = 'key', titlePropName = 'title', keyPrefix = '' } = option
64
75
 
65
76
  // 动态列
66
77
  if (keyProp) {
67
- const columnGroupData = _.uniqBy(data, columnGroup.keyProp)
68
- return columnGroupData.map((item) => {
78
+ let columnGroupData = _.uniqBy(data, columnGroup.keyProp) || []
79
+ const unSortData = columnGroupData.filter((item) => isNil(item[sortProp]))
80
+ const sortData = columnGroupData.filter((item) => !isNil(item[sortProp]))
81
+ const sortedData = _.orderBy(sortData, [sortProp], [sortOrder]).concat(unSortData)
82
+
83
+ return sortedData.map((item) => {
69
84
  const columnTitle = titleFormatter ? titleFormatter(item[titleProp]) : item[titleProp]
70
85
 
71
86
  // 不是最后一层,继续组织tree
@@ -1,2 +1,37 @@
1
- export declare function getOssFileApi(fileId: string): Promise<import('axios').AxiosResponse<any>>
1
+ import { ResponseType } from 'axios'
2
+ /**
3
+ * 文档中心下载文件的url,主要用于图片等直接写在 href 里
4
+ *
5
+ * @param fileId 文件Id
6
+ * @returns url
7
+ */
8
+ export declare function getOssFileUrl(fileId?: string): string
9
+ /**
10
+ * 文档中心上传文件的url
11
+ *
12
+ * @returns url
13
+ */
14
+ export declare function putOssFileUrl(): string
15
+ /**
16
+ * 获取文档中心文件
17
+ *
18
+ * @param fileId 文件Id
19
+ * @param responseType 数据类型,支持 arraybuffer | blob | document | json | text | stream
20
+ * @returns 文件内容
21
+ */
22
+ export declare function getOssFileApi(
23
+ fileId: string,
24
+ responseType?: ResponseType,
25
+ ): Promise<import('axios').AxiosResponse<any>>
26
+ /**
27
+ * 将文件上传到文档中心
28
+ *
29
+ * @param filename 文件名
30
+ * @param blob 文件的Blob数据
31
+ * @returns 文件Id
32
+ */
33
+ export declare function putOssFileApi(
34
+ filename: string,
35
+ blob: Blob,
36
+ ): import('axios').AxiosPromise<any>
2
37
  //# sourceMappingURL=oss.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oss.d.ts","sourceRoot":"","sources":["../../../src/api/platform/oss.ts"],"names":[],"mappings":"AAKA,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,+CAE3C"}
1
+ {"version":3,"file":"oss.d.ts","sourceRoot":"","sources":["../../../src/api/platform/oss.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsB,YAAY,EAAE,MAAM,OAAO,CAAA;AAIxD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,SAAK,UAExC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,WAE5B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY,+CAMxE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,qCAUzD"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 将base64转换为Blob
3
+ *
4
+ * @param base64Data base64数据
5
+ * @param contentType 数据的MIME Type,如 png 为 image/png
6
+ * @returns Blob数据
7
+ */
8
+ export declare function base64ToBlob(base64Data: string, contentType: string): Blob
9
+ //# sourceMappingURL=blob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blob.d.ts","sourceRoot":"","sources":["../../src/utils/blob.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAmB1E"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @description 绑定事件 on(element, event, handler)
2
+ * 绑定事件 on(element, event, handler)
3
3
  */
4
4
  export declare function on(
5
5
  element: any,
@@ -7,11 +7,19 @@ export declare function on(
7
7
  handler: any,
8
8
  ): (element: any, event: any, handler: any) => void
9
9
  /**
10
- * @description 解绑事件 off(element, event, handler)
10
+ * 解绑事件 off(element, event, handler)
11
11
  */
12
12
  export declare function off(
13
13
  element: any,
14
14
  event: any,
15
15
  handler: any,
16
16
  ): (element: HTMLElement, event: string, handler: EventListenerOrEventListenerObject) => void
17
+ export declare const stopPropagation: (event: Event) => void
18
+ /**
19
+ * 事件 preventDefault
20
+ *
21
+ * @param event 事件
22
+ * @param isStopPropagation 是否阻止冒泡
23
+ */
24
+ export declare function preventDefault(event: Event, isStopPropagation?: Boolean): void
17
25
  //# sourceMappingURL=event.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../src/utils/event.ts"],"names":[],"mappings":"AAoCA;;GAEG;AACH,wBAAgB,EAAE,CAAC,OAAO,KAAA,EAAE,KAAK,KAAA,EAAE,OAAO,KAAA,oDAIzC;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,OAAO,KAAA,EAAE,KAAK,KAAA,EAAE,OAAO,KAAA,8FAI1C"}
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../src/utils/event.ts"],"names":[],"mappings":"AAoCA;;GAEG;AACH,wBAAgB,EAAE,CAAC,OAAO,KAAA,EAAE,KAAK,KAAA,EAAE,OAAO,KAAA,oDAIzC;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,OAAO,KAAA,EAAE,KAAK,KAAA,EAAE,OAAO,KAAA,8FAI1C;AAED,eAAO,MAAM,eAAe,UAAW,KAAK,SAA4B,CAAA;AAExE;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,iBAAiB,CAAC,EAAE,OAAO,QASvE"}
@@ -1,6 +1,7 @@
1
1
  export * from './cache'
2
2
  export * from './request'
3
3
  export * from './sm3'
4
+ export * from './blob'
4
5
  export * from './date'
5
6
  export * from './enum'
6
7
  export * from './excel'
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,OAAO,CAAA;AAErB,cAAc,QAAQ,CAAA;AACtB,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,OAAO,CAAA;AAErB,cAAc,QAAQ,CAAA;AACtB,cAAc,QAAQ,CAAA;AACtB,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA"}
@@ -2,7 +2,7 @@ export declare function getContentType(config: any): any
2
2
  export declare function setContentType(headers: any, type: string): void
3
3
  export declare const CONTENT_TYPE: {
4
4
  form: string
5
- 'multi-form': string
5
+ multiForm: string
6
6
  body: string
7
7
  os: string
8
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"interceptors.d.ts","sourceRoot":"","sources":["../../../src/utils/request/interceptors.ts"],"names":[],"mappings":"AAuBA,wBAAgB,mBAAmB,CAAC,MAAM,KAAA,OAwCzC;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,KAAA,OA6B5C;AAED,wBAAgB,cAAc,CAAC,KAAK,KAAA,kBASnC"}
1
+ {"version":3,"file":"interceptors.d.ts","sourceRoot":"","sources":["../../../src/utils/request/interceptors.ts"],"names":[],"mappings":"AAuBA,wBAAgB,mBAAmB,CAAC,MAAM,KAAA,OAwCzC;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,KAAA,OA6B5C;AAED,wBAAgB,cAAc,CAAC,KAAK,KAAA,kBAQnC"}
@@ -4,6 +4,9 @@ interface ColumnGroup {
4
4
  keyProp?: string
5
5
  titleProp?: string
6
6
  titleFormatter?: (title: string) => string
7
+ sortProp?: string
8
+ sortOrder?: boolean | 'asc' | 'desc'
9
+ keyLastSuffix?: string
7
10
  children?: ColumnGroup[]
8
11
  [propName: string]: any
9
12
  }
@@ -11,7 +14,6 @@ interface row2columnOption {
11
14
  keyPropName?: string
12
15
  titlePropName?: string
13
16
  keyPrefix?: string
14
- keyLastSuffix?: string
15
17
  }
16
18
  interface Column {
17
19
  key?: string
@@ -1 +1 @@
1
- {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/utils/table.ts"],"names":[],"mappings":"AAYA,UAAU,WAAW;IAEnB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IAGd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAG1C,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAA;IACxB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAA;CACxB;AAED,UAAU,gBAAgB;IAExB,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,UAAU,MAAM;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAA;CACxB;AAED,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;CACjB;AA8FD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,KAAK,CAAC,GAAG,CAAM,EACrB,YAAY,EAAE,WAAW,EAAO,EAChC,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,gBAAqB,GAC5B,gBAAgB,CA0BlB;AAkDD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,GAAE,KAAK,CAAC,GAAG,CAAM,EACrB,OAAO,GAAE,MAAM,EAAO,EACtB,MAAM,GAAE,gBAAqB,GAC5B,KAAK,CAAC,GAAG,CAAC,CAMZ"}
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/utils/table.ts"],"names":[],"mappings":"AAaA,UAAU,WAAW;IAEnB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IAGd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAE1C,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB,SAAS,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,CAAA;IAEpC,aAAa,CAAC,EAAE,MAAM,CAAA;IAGtB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAA;IACxB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAA;CACxB;AAED,UAAU,gBAAgB;IAExB,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,UAAU,MAAM;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAA;CACxB;AAED,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;CACjB;AAwGD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,KAAK,CAAC,GAAG,CAAM,EACrB,YAAY,EAAE,WAAW,EAAO,EAChC,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,gBAAqB,GAC5B,gBAAgB,CA0BlB;AAkDD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,GAAE,KAAK,CAAC,GAAG,CAAM,EACrB,OAAO,GAAE,MAAM,EAAO,EACtB,MAAM,GAAE,gBAAqB,GAC5B,KAAK,CAAC,GAAG,CAAC,CAMZ"}