w-converhp 2.0.36 → 2.0.38

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/sclc.mjs CHANGED
@@ -27,7 +27,7 @@ wo.on('error', (err) => {
27
27
  function uploadLargeFile() {
28
28
  let core = async() => {
29
29
 
30
- let fsz = '1000mb' //0mb 10mb 100mb 1000mb
30
+ let fsz = '10mb' //0mb 10mb 100mb 1000mb
31
31
 
32
32
  //u8a
33
33
  let u8a = fs.readFileSync(`../_data/${fsz}.7z`) //用fs讀有檔案大小上限
@@ -54,6 +54,9 @@ function uploadLargeFile() {
54
54
 
55
55
  }
56
56
  core()
57
+ .catch((err) => {
58
+ console.log(err)
59
+ })
57
60
  }
58
61
 
59
62
  uploadLargeFile()
package/scld.mjs CHANGED
@@ -49,6 +49,9 @@ function downloadLargeFile() {
49
49
 
50
50
  }
51
51
  core()
52
+ .catch((err) => {
53
+ console.log(err)
54
+ })
52
55
  }
53
56
 
54
57
  downloadLargeFile()
@@ -164,12 +164,12 @@ function WConverhpClient(opt) {
164
164
  else if (type === 'slice') {
165
165
  urlUse = `${url}slc`
166
166
  }
167
- else if (type === 'upload-check') {
168
- urlUse = `${url}ulck`
169
- }
170
- else if (type === 'slice-merge') {
171
- urlUse = `${url}slcm`
167
+ else if (type === 'upload-controller') {
168
+ urlUse = `${url}ulctr`
172
169
  }
170
+ // else if (type === 'slice-merge') {
171
+ // urlUse = `${url}slcm`
172
+ // }
173
173
  else if (type === 'download-get-filename') {
174
174
  urlUse = `${url}dwgfn`
175
175
  }
@@ -682,11 +682,11 @@ function WConverhpClient(opt) {
682
682
  let fileTotalHash = await calcHash(bb)
683
683
  // console.log(`calc hash for fileTotalSize[${fileTotalSize}] done`, fileTotalHash)
684
684
 
685
- //send upload-check
685
+ //send check-total-hash
686
686
  // console.log(`send check-total-hash...`)
687
- let resCk = await send('upload-check', { mode: 'check-total-hash', fileHash: fileTotalHash, fileSize: fileTotalSize }, { dataType: 'json' })
688
- // console.log('resCk', resCk)
689
- // resCk {
687
+ let resUpCkt = await send('upload-controller', { mode: 'check-total-hash', fileHash: fileTotalHash, filename: fileTotalName, fileSize: fileTotalSize }, { dataType: 'json' })
688
+ // console.log('resUpCkt', resUpCkt)
689
+ // resUpCkt {
690
690
  // path: 'uploadTemp\\2429b7ef08ce6ba9',
691
691
  // bAllExist: false,
692
692
  // bAllSize: false,
@@ -702,30 +702,30 @@ function WConverhpClient(opt) {
702
702
  // }
703
703
 
704
704
  //check
705
- if (resCk.bAllHash) {
705
+ if (resUpCkt.bAllHash) {
706
706
  // console.log('已有上傳大檔')
707
707
  let resMg = {
708
708
  filename: fileTotalName,
709
- path: resCk.path,
709
+ path: resUpCkt.path,
710
710
  }
711
711
  return resMg
712
712
  }
713
713
 
714
714
  //針對伺服器上已有切片檔案計算hash與比對
715
- if (resCk.slks.length > 0) {
716
- // console.log('receive slks...', resCk.slks[0], size(resCk.slks))
715
+ if (resUpCkt.slks.length > 0) {
716
+ // console.log('receive slks...', resUpCkt.slks[0], size(resUpCkt.slks))
717
717
 
718
718
  //fileSliceHashs
719
719
  let fileSliceHashs = []
720
- // let n = Math.max(resCk.slks.length, 1)
720
+ // let n = Math.max(resUpCkt.slks.length, 1)
721
721
  // let nr = Math.floor(n / 100)
722
- for (let k = 0; k < resCk.slks.length; k++) {
722
+ for (let k = 0; k < resUpCkt.slks.length; k++) {
723
723
  // if (k % nr === 0) {
724
- // console.log(`calc hash for slices`, round(k / resCk.slks.length * 100, 1), '%')
724
+ // console.log(`calc hash for slices`, round(k / resUpCkt.slks.length * 100, 1), '%')
725
725
  // }
726
726
 
727
727
  //i
728
- let i = resCk.slks[k]
728
+ let i = resUpCkt.slks[k]
729
729
 
730
730
  //start
731
731
  let start = i * sizeSlice
@@ -749,11 +749,11 @@ function WConverhpClient(opt) {
749
749
  }
750
750
  // console.log('fileSliceHashs', fileSliceHashs)
751
751
 
752
- //send upload-check
752
+ //send check-slices-hash
753
753
  // console.log(`send check-slices-hash...`)
754
- let resCks = await send('upload-check', { mode: 'check-slices-hash', fileHash: fileTotalHash, fileSliceHashs }, { dataType: 'json' })
755
- // console.log('resCks', resCks)
756
- // resCks {
754
+ let resUpCks = await send('upload-controller', { mode: 'check-slices-hash', fileHash: fileTotalHash, fileSliceHashs }, { dataType: 'json' })
755
+ // console.log('resUpCks', resUpCks)
756
+ // resUpCks {
757
757
  // slks: [
758
758
  // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
759
759
  // 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
@@ -763,8 +763,8 @@ function WConverhpClient(opt) {
763
763
  // ]
764
764
  // }
765
765
 
766
- //update
767
- resCk.slks = resCks.slks
766
+ //update, 伺服器針對各切片計算hash與比對, 回傳resUpCks.slks代表hash一致的切片編號, 非一致hash的切片則須重傳, 尚未傳切片亦須繼續傳
767
+ resUpCkt.slks = resUpCks.slks
768
768
 
769
769
  }
770
770
 
@@ -804,7 +804,7 @@ function WConverhpClient(opt) {
804
804
  for (let i = 0; i < chunkTotal; i++) {
805
805
 
806
806
  //check
807
- if (resCk.slks.indexOf(i) >= 0) {
807
+ if (resUpCkt.slks.indexOf(i) >= 0) {
808
808
  // console.log('已有上傳切片檔')
809
809
  cbProgressSlice({ prog: 100, m: 'upload' }) //直接觸發更新進度
810
810
  continue
@@ -820,7 +820,7 @@ function WConverhpClient(opt) {
820
820
  let chunk = bb.slice(start, end)
821
821
 
822
822
  //send slice
823
- let hd = {
823
+ let hd = { //用header傳key與value時, key不分大小寫, 故使用kebabCase
824
824
  'chunk-index': i,
825
825
  'chunk-total': chunkTotal,
826
826
  'package-id': packageId,
@@ -830,16 +830,64 @@ function WConverhpClient(opt) {
830
830
 
831
831
  }
832
832
 
833
- //send slice-merge
834
- let msg = {
835
- 'filename': fileTotalName,
836
- 'chunk-total': chunkTotal,
837
- 'package-id': packageId,
833
+ //send merge-slices-push
834
+ // console.log(`send merge-slices-push...`)
835
+ let resUpMgp = await send('upload-controller', { mode: 'merge-slices-push', fileHash: fileTotalHash, chunkTotal }, { dataType: 'json' })
836
+ // console.log('resUpMgp', resUpMgp)
837
+
838
+ //checkMerging
839
+ let checkMerging = () => {
840
+ let pm = genPm()
841
+
842
+ //queueId
843
+ let queueId = resUpMgp.queueId
844
+ // console.log('queueId', queueId)
845
+
846
+ let t = setInterval(() => {
847
+
848
+ //send merge-slices-get
849
+ // console.log(`send merge-slices-get...`)
850
+ send('upload-controller', { mode: 'merge-slices-get', fileHash: fileTotalHash, filename: fileTotalName, queueId }, { dataType: 'json' })
851
+ .then((res) => {
852
+ // console.log('res', res)
853
+ // res => {
854
+ // queueId,
855
+ // state,
856
+ // filename,
857
+ // path,
858
+ // msg: ...
859
+ // }
860
+
861
+ //check
862
+ if (res.state === 'done') {
863
+
864
+ //cbProgressMerge
865
+ cbProgressMerge({ prog: 100, m: 'download' })
866
+
867
+ //resolve, 前端偵測state為'done'時提取msg顯示
868
+ pm.resolve(res.msg)
869
+
870
+ }
871
+
872
+ })
873
+ .catch((err) => {
874
+ console.log(err)
875
+ })
876
+ .finally(() => {
877
+ clearInterval(t)
878
+ })
879
+
880
+ }, 2000)
881
+
882
+ return pm
838
883
  }
839
- let resMg = await send('slice-merge', msg, { dataType: 'json', cbProgress: cbProgressMerge })
884
+
885
+ //checkMerging
886
+ let resUpMgr = await checkMerging()
887
+ // console.log('resUpMgr', resUpMgr)
840
888
 
841
889
  // console.log(`upload slice done`)
842
- return resMg
890
+ return resUpMgr
843
891
  }
844
892
 
845
893
  //execute
@@ -23,8 +23,7 @@ import obj2u8arr from 'wsemi/src/obj2u8arr.mjs'
23
23
  import u8arr2obj from 'wsemi/src/u8arr2obj.mjs'
24
24
  import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
25
25
  import fsCreateFolder from 'wsemi/src/fsCreateFolder.mjs'
26
- // import mergeFiles from './mergeFiles.mjs'
27
- import mergeFiles from './mergeFiles.wk.umd.js'
26
+ import managerMergeSlices from './managerMergeSlices.mjs'
28
27
  // import checkTotalHash from './checkTotalHash.mjs'
29
28
  import checkTotalHash from './checkTotalHash.wk.umd.js'
30
29
  // import checkSlicesHash from './checkSlicesHash.mjs'
@@ -36,6 +35,10 @@ import checkSlicesHash from './checkSlicesHash.wk.umd.js'
36
35
  //回傳前端(browser)時, 針對超大檔, 可用POST並用stream回傳但還要處理進度條, 若要交由瀏覽器下載器處理, 只能用GET並用stream回傳, 且前端只能用window.location.href或a.href+a.click()下載
37
36
 
38
37
 
38
+ //mmg
39
+ let mmg = managerMergeSlices()
40
+
41
+
39
42
  /**
40
43
  * 建立Hapi伺服器
41
44
  *
@@ -605,7 +608,7 @@ function WConverhpServer(opt = {}) {
605
608
 
606
609
  //apiUploadCheck
607
610
  let apiUploadCheck = {
608
- path: `/${apiName}ulck`,
611
+ path: `/${apiName}ulctr`,
609
612
  method: 'POST',
610
613
  options: {
611
614
  payload: {
@@ -642,7 +645,7 @@ function WConverhpServer(opt = {}) {
642
645
  if (true) {
643
646
 
644
647
  //verifyConn
645
- let m = verifyConn({ apiType: 'upload-check', authorization, headers, query })
648
+ let m = verifyConn({ apiType: 'upload-controller', authorization, headers, query })
646
649
  if (ispm(m)) {
647
650
  m = await m
648
651
  }
@@ -665,13 +668,14 @@ function WConverhpServer(opt = {}) {
665
668
  let mode = get(req, 'payload.mode', '')
666
669
 
667
670
  //check
668
- if (mode !== 'check-total-hash' && mode !== 'check-slices-hash') {
671
+ if (mode !== 'check-total-hash' && mode !== 'check-slices-hash' && mode !== 'merge-slices-push' && mode !== 'merge-slices-get') {
669
672
  // console.log('invalid mode in payload')
670
673
  return responseU8aStreamWithError(res, `invalid mode[${mode}] in payload`)
671
674
  }
672
675
 
673
676
  //fileHash, 從payload接收
674
677
  let fileHash = get(req, 'payload.fileHash', '')
678
+ // console.log(mode, 'fileHash', fileHash)
675
679
 
676
680
  //check
677
681
  if (!isestr(fileHash)) {
@@ -679,36 +683,143 @@ function WConverhpServer(opt = {}) {
679
683
  return responseU8aStreamWithError(res, 'invalid fileHash in payload')
680
684
  }
681
685
 
682
- //out
683
- let out = null
684
- if (mode === 'check-total-hash') {
686
+ //procCore
687
+ let procCore = async() => {
688
+ let out = null
689
+ if (mode === 'check-total-hash') {
685
690
 
686
- //fileSize, 從payload接收
687
- let fileSize = get(req, 'payload.fileSize', '')
691
+ //filename, 從payload接收
692
+ let filename = get(req, 'payload.filename', '')
693
+ // console.log(mode, 'filename', filename)
688
694
 
689
- //checkTotalHash
690
- out = await checkTotalHash(fileSize, sizeSlice, fileHash, pathUploadTemp)
695
+ //fileSize, 從payload接收
696
+ let fileSize = get(req, 'payload.fileSize', '')
697
+ // console.log(mode, 'fileSize', fileSize)
691
698
 
692
- }
693
- else if (mode === 'check-slices-hash') {
699
+ //checkTotalHash
700
+ out = await checkTotalHash(fileSize, sizeSlice, fileHash, pathUploadTemp)
701
+ // console.log(mode, 'out', out)
702
+
703
+ //check, 因合併大檔後可能非預期中斷而重傳, 每次偵測有合併完成大檔, 就得調用procUpload讓伺服器攔截函數處理
704
+ if (out.bAllHash) {
705
+
706
+ //ri
707
+ let ri = {
708
+ filename,
709
+ path: out.path,
710
+ }
711
+
712
+ //procUpload
713
+ // console.log('procUpload start')
714
+ let ro = await procUpload(ri)
715
+ // console.log('procUpload done', ro)
716
+
717
+ //out merge, 直接添加ro就回傳, 此處不使用msg儲存
718
+ out = {
719
+ ...out,
720
+ ...ro,
721
+ }
722
+
723
+ }
724
+
725
+ }
726
+ else if (mode === 'check-slices-hash') {
727
+
728
+ //fileSliceHashs, 從payload接收
729
+ let fileSliceHashs = get(req, 'payload.fileSliceHashs', [])
730
+ // console.log(mode, 'fileSliceHashs', fileSliceHashs)
731
+
732
+ //checkSlicesHash
733
+ out = await checkSlicesHash(fileSliceHashs, fileHash, pathUploadTemp)
734
+ // console.log(mode, 'out', out)
735
+
736
+ }
737
+ else if (mode === 'merge-slices-push') {
738
+
739
+ //chunkTotal, 從payload接收
740
+ let chunkTotal = get(req, 'payload.chunkTotal', '')
741
+ // console.log(mode, 'chunkTotal', chunkTotal)
742
+
743
+ //mmg.push
744
+ let queueId = mmg.push(fileHash, chunkTotal, pathUploadTemp)
745
+
746
+ //out
747
+ out = {
748
+ queueId,
749
+ }
750
+
751
+ }
752
+ else if (mode === 'merge-slices-get') {
753
+
754
+ //filename, 從payload接收
755
+ let filename = get(req, 'payload.filename', '')
756
+ // console.log(mode, 'filename', filename)
757
+
758
+ //queueId, 從payload接收
759
+ let queueId = get(req, 'payload.queueId', '')
760
+ // console.log(mode, 'queueId', queueId)
761
+
762
+ //mmg.get
763
+ let r = mmg.get(queueId, pathUploadTemp)
764
+
765
+ //out
766
+ out = {
767
+ queueId,
768
+ state: r.state,
769
+ filename,
770
+ path: r.path,
771
+ }
772
+
773
+ //check
774
+ if (r.state === 'done') {
694
775
 
695
- //fileSliceHashs, 從payload接收
696
- let fileSliceHashs = get(req, 'payload.fileSliceHashs', [])
697
- // console.log('fileSliceHashs', fileSliceHashs)
776
+ //ri
777
+ let ri = {
778
+ filename,
779
+ path: r.path,
780
+ }
698
781
 
699
- //checkSlicesHash
700
- out = await checkSlicesHash(fileSliceHashs, fileHash, pathUploadTemp)
782
+ //procUpload, 偵測有合併完成大檔, 得調用procUpload讓伺服器攔截函數處理
783
+ // console.log('procUpload start')
784
+ let ro = await procUpload(ri)
785
+ // console.log('procUpload done', ro)
701
786
 
787
+ //out merge, ro須附加至msg, 才供前端偵測state為'done'時提取msg顯示
788
+ out = {
789
+ ...out,
790
+ msg: ro,
791
+ }
792
+
793
+ }
794
+
795
+ }
796
+ // console.log('out', out)
797
+
798
+ return out
702
799
  }
800
+
801
+ //procCore
802
+ let out = {}
803
+ let returnType = ''
804
+ let returnMsg = ''
805
+ await procCore()
806
+ .then((res) => {
807
+ out.success = res
808
+ returnType = 'success'
809
+ returnMsg = 'need to parse'
810
+ })
811
+ .catch((err) => {
812
+ out.error = err
813
+ returnType = 'error'
814
+ returnMsg = 'need to parse'
815
+ })
703
816
  // console.log('out', out)
704
817
 
705
- if (out.error) {
706
- return responseU8aStreamWithError(res, out.error)
707
- }
708
- else {
709
- let u8aOut = obj2u8arr(out)
710
- return responseU8aStream(res, u8aOut, { returnType: 'success', returnMsg: 'need to parse' })
711
- }
818
+ //u8aOut
819
+ let u8aOut = obj2u8arr(out)
820
+ // console.log('u8aOut', u8aOut)
821
+
822
+ return responseU8aStream(res, u8aOut, { returnType, returnMsg })
712
823
  },
713
824
  }
714
825
 
@@ -777,18 +888,18 @@ function WConverhpServer(opt = {}) {
777
888
 
778
889
  //check
779
890
  if (!isp0int(chunkIndex)) {
780
- console.log('invalid chunkIndex in headers')
781
- return res.response({ error: 'invalid chunkIndex in headers' }).code(400)
891
+ // console.log('invalid chunkIndex in headers')
892
+ return responseU8aStreamWithError(res, 'invalid chunkIndex in headers')
782
893
  }
783
894
  chunkIndex = cint(chunkIndex)
784
895
  if (!isp0int(chunkTotal)) {
785
- console.log('invalid chunkTotal in headers')
786
- return res.response({ error: 'invalid chunkTotal in headers' }).code(400)
896
+ // console.log('invalid chunkTotal in headers')
897
+ return responseU8aStreamWithError(res, 'invalid chunkTotal in headers')
787
898
  }
788
899
  chunkTotal = cint(chunkTotal)
789
900
  if (!isestr(packageId)) {
790
- console.log('invalid packageId in headers')
791
- return res.response({ error: 'invalid packageId in headers' }).code(400)
901
+ // console.log('invalid packageId in headers')
902
+ return responseU8aStreamWithError(res, 'invalid packageId in headers')
792
903
  }
793
904
 
794
905
  //pathFileChunk
@@ -855,126 +966,6 @@ function WConverhpServer(opt = {}) {
855
966
  },
856
967
  }
857
968
 
858
- //apiUploadSliceMerge
859
- let apiUploadSliceMerge = {
860
- path: `/${apiName}slcm`,
861
- method: 'POST',
862
- options: {
863
- payload: {
864
- maxBytes: 1024 * 1024 * 1024 * 1024, //預設為1mb, 調整至1tb, 也就是給予3次方
865
- maxParts: 1000 * 1000 * 1000, //預設為1000, 給予3次方
866
- timeout: false, //避免請求未完成時中斷
867
- // output: 'stream',
868
- parse: true, //前端送obj過來須自動解析
869
- },
870
- timeout: {
871
- server: false, //關閉伺服器超時
872
- socket: false, //關閉socket超時
873
- },
874
- },
875
- handler: async function (req, res) {
876
- // console.log(req, res)
877
- // console.log('payload', req.payload)
878
-
879
- //headers
880
- let headers = get(req, 'headers')
881
- headers = iseobj(headers) ? headers : ''
882
- // console.log('headers', headers)
883
-
884
- //query
885
- let query = get(req, 'query')
886
- query = iseobj(query) ? query : ''
887
- // console.log('query', query)
888
-
889
- //authorization
890
- let authorization = get(headers, 'authorization', '')
891
- authorization = isestr(authorization) ? authorization : ''
892
-
893
- //check
894
- if (true) {
895
-
896
- //verifyConn
897
- let m = verifyConn({ apiType: 'upload-slice-merge', authorization, headers, query })
898
- if (ispm(m)) {
899
- m = await m
900
- }
901
-
902
- //check
903
- if (m !== true) {
904
- return responseU8aStreamWithError(res, 'permission denied')
905
- }
906
-
907
- }
908
-
909
- //eeEmit
910
- eeEmit('handler', {
911
- api: 'apiUploadSliceMerge',
912
- headers,
913
- query,
914
- })
915
-
916
- //filename, chunkTotal, packageId, 從payload接收
917
- let filename = get(req, 'payload.filename', '')
918
- let chunkTotal = get(req, 'payload.chunk-total', '')
919
- let packageId = get(req, 'payload.package-id', '')
920
-
921
- //check
922
- if (!isestr(filename)) {
923
- console.log('invalid filename in payload')
924
- return res.response({ error: 'invalid filename in payload' }).code(400)
925
- }
926
- if (!isp0int(chunkTotal)) {
927
- console.log('invalid chunkTotal in payload')
928
- return res.response({ error: 'invalid chunkTotal in payload' }).code(400)
929
- }
930
- chunkTotal = cint(chunkTotal)
931
- if (!isestr(packageId)) {
932
- console.log('invalid packageId in payload')
933
- return res.response({ error: 'invalid packageId in payload' }).code(400)
934
- }
935
-
936
- //mergeAndPorc
937
- let mergeAndPorc = async() => {
938
-
939
- //merge
940
- // console.log('merge start')
941
- let rMerg = await mergeFiles(pathUploadTemp, packageId, chunkTotal, filename)
942
- // console.log('merge done', rMerg)
943
-
944
- //procUpload
945
- // console.log('procUpload start')
946
- let rProc = await procUpload(rMerg)
947
- // console.log('procUpload done', rProc)
948
-
949
- return rProc
950
- }
951
-
952
- //mergeAndPorc
953
- let out = {}
954
- let returnType = ''
955
- let returnMsg = ''
956
- await mergeAndPorc()
957
- .then((res) => {
958
- out.success = res
959
- returnType = 'success'
960
- returnMsg = 'need to parse'
961
- })
962
- .catch((err) => {
963
- out.error = err
964
- returnType = 'error'
965
- returnMsg = 'need to parse'
966
- eeEmit('error', `${err.message}`)
967
- })
968
- // console.log('out', out)
969
-
970
- //u8aOut
971
- let u8aOut = obj2u8arr(out)
972
- // console.log('u8aOut', u8aOut)
973
-
974
- return responseU8aStream(res, u8aOut, { returnType, returnMsg })
975
- },
976
- }
977
-
978
969
  //apiDownloadGetFilename
979
970
  let apiDownloadGetFilename = {
980
971
  path: `/${apiName}dwgfn`,
@@ -1386,7 +1377,7 @@ function WConverhpServer(opt = {}) {
1386
1377
  apiMain,
1387
1378
  apiUploadCheck,
1388
1379
  apiUploadSlice,
1389
- apiUploadSliceMerge,
1380
+ // apiUploadSliceMerge,
1390
1381
  apiDownloadGetFilename,
1391
1382
  apiDownloadGetFile,
1392
1383
  apiDownload,
@@ -1405,7 +1396,8 @@ function WConverhpServer(opt = {}) {
1405
1396
 
1406
1397
  //start
1407
1398
  if (get(opt, 'serverHapi')) {
1408
- server.route([apiMain, apiUploadCheck, apiUploadSlice, apiUploadSliceMerge, apiDownloadGetFilename, apiDownloadGetFile, apiDownload])
1399
+ // server.route([apiMain, apiUploadCheck, apiUploadSlice, apiUploadSliceMerge, apiDownloadGetFilename, apiDownloadGetFile, apiDownload])
1400
+ server.route([apiMain, apiUploadCheck, apiUploadSlice, apiDownloadGetFilename, apiDownloadGetFile, apiDownload])
1409
1401
  }
1410
1402
  else {
1411
1403
  startServer()
@@ -58,9 +58,7 @@ let checkSlicesHash = async(fileSliceHashs, fileHash, pathUploadTemp) => {
58
58
 
59
59
  //r
60
60
  let r = {
61
- success: {
62
- slks: slksCfm,
63
- },
61
+ slks: slksCfm,
64
62
  }
65
63
 
66
64
  return r