oro-sdk 5.3.2 → 5.3.5

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.3.2",
2
+ "version": "5.3.5",
3
3
  "main": "dist/index.js",
4
4
  "typings": "dist/index.d.ts",
5
5
  "files": [
@@ -55,7 +55,7 @@
55
55
  "form-data": "^4.0.0",
56
56
  "formdata-node": "^4.3.1",
57
57
  "idb-keyval": "^5.0.6",
58
- "oro-sdk-apis": "3.2.2",
58
+ "oro-sdk-apis": "3.2.4",
59
59
  "oro-toolbox": "0.0.6",
60
60
  "uuid": "^8.3.2"
61
61
  }
package/src/client.ts CHANGED
@@ -46,7 +46,13 @@ import {
46
46
  } from 'oro-sdk-apis'
47
47
  import * as OroToolbox from 'oro-toolbox'
48
48
  import { CryptoRSA } from 'oro-toolbox'
49
- import { decryptConsultLockboxGrants, decryptGrants, registerPatient, sessionStorePrivateKeyName } from './helpers'
49
+ import {
50
+ createRefill,
51
+ decryptConsultLockboxGrants,
52
+ decryptGrants,
53
+ registerPatient,
54
+ sessionStorePrivateKeyName,
55
+ } from './helpers'
50
56
  import {
51
57
  AssociatedLockboxNotFound,
52
58
  IncompleteAuthentication,
@@ -88,7 +94,7 @@ export class OroClient {
88
94
  public workflowClient: WorkflowService,
89
95
  public diagnosisClient: DiagnosisService,
90
96
  private authenticationCallback?: (err: Error) => void
91
- ) {}
97
+ ) { }
92
98
 
93
99
  /**
94
100
  * clears the vaultIndex and cached metadata grants
@@ -312,6 +318,21 @@ export class OroClient {
312
318
  )
313
319
  }
314
320
 
321
+ /**
322
+ * Creates and stores all relevant refill data
323
+ * - New consultation is created
324
+ * - Stores refill workflow data in the lockbox
325
+ * - Updates the consult to new
326
+ *
327
+ * @param consult
328
+ * @param populatedRefillWorkflow
329
+ * @returns
330
+ */
331
+ public async createRefill(consult: ConsultRequest, populatedRefillWorkflow: WorkflowData): Promise<void> {
332
+ if (!this.rsa) throw IncompleteAuthentication
333
+ return createRefill(consult, populatedRefillWorkflow, this)
334
+ }
335
+
315
336
  /**
316
337
  * Fetches all grants, and consultations that exist in each lockbox
317
338
  * Then updates the index for the current user with the lockbox consult relationship
@@ -386,18 +407,18 @@ export class OroClient {
386
407
  }))
387
408
  .map(
388
409
  (e: IndexConsultLockbox) =>
389
- ({
390
- uuid: e.uuid,
391
- timestamp: e.timestamp,
392
- uniqueHash: e.uniqueHash,
393
- encryptedIndexEntry: CryptoRSA.jsonWithPubEncryptToBase64(
394
- {
395
- consultationId: e.consultationId,
396
- grant: e.grant,
397
- },
398
- rsaPub
399
- ),
400
- } as EncryptedIndexEntry)
410
+ ({
411
+ uuid: e.uuid,
412
+ timestamp: e.timestamp,
413
+ uniqueHash: e.uniqueHash,
414
+ encryptedIndexEntry: CryptoRSA.jsonWithPubEncryptToBase64(
415
+ {
416
+ consultationId: e.consultationId,
417
+ grant: e.grant,
418
+ },
419
+ rsaPub
420
+ ),
421
+ } as EncryptedIndexEntry)
401
422
  )
402
423
  break
403
424
  }
@@ -532,7 +553,7 @@ export class OroClient {
532
553
  documentType: DocumentType,
533
554
  lockboxOwnerUuid?: Uuid,
534
555
  previousDataUuid?: Uuid,
535
- withNotification: boolean = false
556
+ options: { withNotification?: boolean } = { withNotification: false }
536
557
  ): Promise<DataCreateResponse> {
537
558
  if (!this.rsa) throw IncompleteAuthentication
538
559
 
@@ -551,7 +572,7 @@ export class OroClient {
551
572
  },
552
573
  lockboxOwnerUuid,
553
574
  previousDataUuid,
554
- withNotification
575
+ options
555
576
  )
556
577
  }
557
578
 
@@ -564,7 +585,7 @@ export class OroClient {
564
585
  * @param privateMeta the metadata that will be secured in the vault
565
586
  * @param lockboxOwnerUuid the lockbox owner (ignored if lockbox is owned by self)
566
587
  * @param previousDataUuid if it's a revision of existing data, specify the previous data uuid
567
- * @param withNotification if the insertion of data requires notification
588
+ * @param options if the insertion of data requires email notification
568
589
  * @returns the data uuid
569
590
  */
570
591
  public async createJsonData<T extends Metadata>(
@@ -574,7 +595,7 @@ export class OroClient {
574
595
  privateMeta?: { [val: string]: any },
575
596
  lockboxOwnerUuid?: Uuid,
576
597
  previousDataUuid?: Uuid,
577
- withNotification: boolean = false
598
+ options: { withNotification?: boolean } = { withNotification: false }
578
599
  ): Promise<DataCreateResponse> {
579
600
  if (!this.rsa) throw IncompleteAuthentication
580
601
 
@@ -587,7 +608,7 @@ export class OroClient {
587
608
  publicMetadata: meta,
588
609
  privateMetadata: encryptedPrivateMeta,
589
610
  }
590
- if (withNotification)
611
+ if (options.withNotification)
591
612
  return this.tellerClient.lockboxDataStore(lockboxUuid, request, lockboxOwnerUuid, previousDataUuid)
592
613
  else return this.vaultClient.lockboxDataStore(lockboxUuid, request, lockboxOwnerUuid, previousDataUuid)
593
614
  }
@@ -599,7 +620,7 @@ export class OroClient {
599
620
  * @param publicMetadata the public Metadata
600
621
  * @param privateMetadata the private Metadata
601
622
  * @param forceReplace set true when the insertion of data requires to replace the data when it exists already
602
- * @param withNotification if the insertion of data requires notification
623
+ * @param options if the insertion of data requires email notification
603
624
  * @returns the data uuid
604
625
  */
605
626
  public async getOrInsertJsonData<M extends Metadata>(
@@ -607,11 +628,10 @@ export class OroClient {
607
628
  data: any,
608
629
  publicMetadata: M,
609
630
  privateMetadata: Metadata,
610
- forceReplace: boolean = false,
611
- withNotification: boolean = false
631
+ options: { withNotification?: boolean, forceReplace?: boolean } = { withNotification: false, forceReplace: false }
612
632
  ): Promise<Uuid> {
613
633
  let manifest = await this.vaultClient.lockboxManifestGet(lockboxUuid, publicMetadata)
614
- if (!forceReplace && manifest.length > 0) {
634
+ if (!options.forceReplace && manifest.length > 0) {
615
635
  console.log(`The data for ${JSON.stringify(publicMetadata)} already exist`)
616
636
  return manifest[0].dataUuid
617
637
  } else
@@ -622,8 +642,9 @@ export class OroClient {
622
642
  publicMetadata,
623
643
  privateMetadata,
624
644
  undefined,
625
- forceReplace && manifest.length > 0 ? manifest[0].dataUuid : undefined, // if forceReplace and data already exist, then replace data. Otherwise insert it
626
- withNotification
645
+ // if forceReplace and data already exist, then replace data. Otherwise insert it
646
+ options.forceReplace && manifest.length > 0 ? manifest[0].dataUuid : undefined,
647
+ { withNotification: options.withNotification }
627
648
  ).catch((err) => {
628
649
  console.error(`Error while upserting data ${JSON.stringify(publicMetadata)} data`, err)
629
650
  throw err
@@ -650,7 +671,7 @@ export class OroClient {
650
671
  privateMeta: { [val: string]: any },
651
672
  lockboxOwnerUuid?: Uuid,
652
673
  previousDataUuid?: Uuid,
653
- withNotification: boolean = false
674
+ options: { withNotification?: boolean } = { withNotification: false }
654
675
  ): Promise<DataCreateResponse> {
655
676
  if (!this.rsa) throw IncompleteAuthentication
656
677
  let symmetricEncryptor = await this.getCachedSecretCryptor(lockboxUuid, lockboxOwnerUuid)
@@ -662,7 +683,7 @@ export class OroClient {
662
683
  publicMetadata: meta,
663
684
  privateMetadata: encryptedPrivateMeta,
664
685
  }
665
- if (withNotification)
686
+ if (options.withNotification)
666
687
  return this.tellerClient.lockboxDataStore(lockboxUuid, request, lockboxOwnerUuid, previousDataUuid)
667
688
  else return this.vaultClient.lockboxDataStore(lockboxUuid, request, lockboxOwnerUuid, previousDataUuid)
668
689
  }
@@ -811,9 +832,9 @@ export class OroClient {
811
832
  public async getPersonalInformationsFromConsultId(
812
833
  consultationId: Uuid,
813
834
  category: MetadataCategory.Personal | MetadataCategory.ChildPersonal | MetadataCategory.OtherPersonal,
814
- forceRefresh = false
835
+ options: { forceRefresh: boolean } = { forceRefresh: false }
815
836
  ): Promise<LocalizedData<PopulatedWorkflowData>[]> {
816
- return this.getMetaCategoryFromConsultId(consultationId, category, forceRefresh)
837
+ return this.getMetaCategoryFromConsultId(consultationId, category, options)
817
838
  }
818
839
 
819
840
  /**
@@ -826,15 +847,15 @@ export class OroClient {
826
847
  */
827
848
  public async getMedicalDataFromConsultId(
828
849
  consultationId: Uuid,
829
- forceRefresh = false
850
+ options: { forceRefresh: boolean } = { forceRefresh: false }
830
851
  ): Promise<LocalizedData<PopulatedWorkflowData>[]> {
831
- return this.getMetaCategoryFromConsultId(consultationId, MetadataCategory.Medical, forceRefresh)
852
+ return this.getMetaCategoryFromConsultId(consultationId, MetadataCategory.Medical, options)
832
853
  }
833
854
 
834
855
  private async getMetaCategoryFromConsultId(
835
856
  consultationId: Uuid,
836
857
  category: MetadataCategory,
837
- forceRefresh = false
858
+ options: { forceRefresh: boolean } = { forceRefresh: false }
838
859
  ): Promise<LocalizedData<PopulatedWorkflowData>[]> {
839
860
  let grants = await this.getGrants({ consultationId })
840
861
  let workflowData: LocalizedData<PopulatedWorkflowData>[] = []
@@ -848,7 +869,7 @@ export class OroClient {
848
869
  },
849
870
  true,
850
871
  grant.lockboxOwnerUuid,
851
- forceRefresh
872
+ options
852
873
  )
853
874
 
854
875
  // TODO: find another solution for backwards compatibility (those without the metadata consultationIds)
@@ -863,7 +884,7 @@ export class OroClient {
863
884
  },
864
885
  true,
865
886
  grant.lockboxOwnerUuid,
866
- forceRefresh
887
+ options
867
888
  )
868
889
  ).filter((entry) => !entry.metadata.consultationIds) // Keep only entries without associated consultationIds
869
890
  }
@@ -966,7 +987,7 @@ export class OroClient {
966
987
  filter: Metadata,
967
988
  expandPrivateMetadata: boolean,
968
989
  lockboxOwnerUuid?: Uuid,
969
- forceRefresh: boolean = false
990
+ options: { forceRefresh: boolean } = { forceRefresh: false }
970
991
  ): Promise<LockboxManifest> {
971
992
  let manifestKey = JSON.stringify({
972
993
  lockboxUuid,
@@ -974,7 +995,7 @@ export class OroClient {
974
995
  expandPrivateMetadata,
975
996
  lockboxOwnerUuid,
976
997
  })
977
- if (!forceRefresh && this.cachedManifest[manifestKey]) return this.cachedManifest[manifestKey]
998
+ if (!options.forceRefresh && this.cachedManifest[manifestKey]) return this.cachedManifest[manifestKey]
978
999
 
979
1000
  return this.vaultClient.lockboxManifestGet(lockboxUuid, filter, lockboxOwnerUuid).then((manifest) => {
980
1001
  return Promise.all(
@@ -1075,11 +1096,10 @@ export class OroClient {
1075
1096
  const identificationDataUuid = (
1076
1097
  await this.getLockboxManifest(
1077
1098
  lockboxUuid,
1078
-
1079
1099
  filter,
1080
1100
  false,
1081
1101
  grant.lockboxOwnerUuid,
1082
- true
1102
+ { forceRefresh: true }
1083
1103
  )
1084
1104
  )[0].dataUuid
1085
1105
 
@@ -1232,7 +1252,7 @@ export class OroClient {
1232
1252
  */
1233
1253
  public async getPatientConsultationData(
1234
1254
  consultationId: Uuid,
1235
- forceRefresh: boolean = false
1255
+ options: { forceRefresh: boolean } = { forceRefresh: false }
1236
1256
  ): Promise<PopulatedWorkflowData[]> {
1237
1257
  //TODO: make use of getPatientDocumentsList instead of doing it manually here
1238
1258
  return Promise.all(
@@ -1247,7 +1267,7 @@ export class OroClient {
1247
1267
  },
1248
1268
  true,
1249
1269
  grant.lockboxOwnerUuid,
1250
- forceRefresh
1270
+ options
1251
1271
  ).then((manifest) =>
1252
1272
  Promise.all(
1253
1273
  manifest.map((e) =>
@@ -1352,7 +1372,7 @@ export class OroClient {
1352
1372
  { ...filters, consultationId },
1353
1373
  expandPrivateMetadata,
1354
1374
  grant.lockboxOwnerUuid,
1355
- true
1375
+ { forceRefresh: true }
1356
1376
  ).then((manifest) =>
1357
1377
  Promise.all(
1358
1378
  manifest.map(async (entry): Promise<Document> => {
@@ -1533,7 +1553,7 @@ export class OroClient {
1533
1553
  contentType: 'application/json',
1534
1554
  },
1535
1555
  {},
1536
- true
1556
+ { forceReplace: true }
1537
1557
  )
1538
1558
 
1539
1559
  return updatedIdentity
@@ -0,0 +1,29 @@
1
+ import { Consult, ConsultRequest } from 'oro-sdk-apis'
2
+ import { OroClient } from '..'
3
+
4
+ /**
5
+ * Creates a consultation if one has not been created and fails to be retrieved by the payment intent
6
+ * @param consult
7
+ * @param oroClient
8
+ * @returns the consult Uuid
9
+ */
10
+ export async function getOrCreatePatientConsultationUuid(
11
+ consult: ConsultRequest,
12
+ oroClient: OroClient
13
+ ): Promise<Consult> {
14
+ let payment = await oroClient.practiceClient.practiceGetPayment(
15
+ consult.uuidPractice,
16
+ consult.idStripeInvoiceOrPaymentIntent
17
+ )
18
+ if (payment && payment.uuidConsult) {
19
+ return oroClient.consultClient.getConsultByUUID(payment.uuidConsult).catch((err) => {
20
+ console.error('Error while retrieving consult', err)
21
+ throw err
22
+ })
23
+ } else {
24
+ return await oroClient.consultClient.consultCreate(consult).catch((err) => {
25
+ console.error('Error while creating consult', err)
26
+ throw err
27
+ })
28
+ }
29
+ }
@@ -2,3 +2,4 @@ export * from './client'
2
2
  export * from './workflow'
3
3
  export * from './patient-registration'
4
4
  export * from './vault-grants'
5
+ export * from './prescription-refill'
@@ -29,6 +29,7 @@ import {
29
29
  RegisterPatientOutput,
30
30
  toActualObject,
31
31
  } from '..'
32
+ import { getOrCreatePatientConsultationUuid } from './consult'
32
33
 
33
34
  const MAX_RETRIES = 15
34
35
 
@@ -167,10 +168,10 @@ export async function registerPatient(
167
168
  oroClient,
168
169
  onProgress
169
170
  ? {
170
- onProgress,
171
- currentStep,
172
- stepsTotalNum,
173
- }
171
+ onProgress,
172
+ currentStep,
173
+ stepsTotalNum,
174
+ }
174
175
  : undefined
175
176
  ).catch((err) => {
176
177
  console.error('[SDK: registration] Some errors happened during image upload', err)
@@ -275,30 +276,6 @@ export async function registerPatient(
275
276
  }
276
277
  }
277
278
 
278
- /**
279
- * Creates a consultation if one has not been created and fails to be retrieved by the payment intent
280
- * @param consult
281
- * @param oroClient
282
- * @returns the consult Uuid
283
- */
284
- async function getOrCreatePatientConsultationUuid(consult: ConsultRequest, oroClient: OroClient): Promise<Consult> {
285
- let payment = await oroClient.practiceClient.practiceGetPayment(
286
- consult.uuidPractice,
287
- consult.idStripeInvoiceOrPaymentIntent
288
- )
289
- if (payment && payment.uuidConsult) {
290
- return oroClient.consultClient.getConsultByUUID(payment.uuidConsult).catch((err) => {
291
- console.error('Error while retrieving consult', err)
292
- throw err
293
- })
294
- } else {
295
- return await oroClient.consultClient.consultCreate(consult).catch((err) => {
296
- console.error('Error while creating consult', err)
297
- throw err
298
- })
299
- }
300
- }
301
-
302
279
  /**
303
280
  * Creates a new lockbox for the patient if they do not have any, otherwise, use the first (and only one)
304
281
  * @param oroClient
@@ -362,8 +339,8 @@ async function storePatientData(
362
339
  consultationId, // TODO: deprecated. Will finally only be in privateMetadata
363
340
  },
364
341
  { consultationId },
365
- false,
366
- true // the only data that needs to include an email notification
342
+ { withNotification: true },
343
+ // the only data that needs to include an email notification
367
344
  )
368
345
  ),
369
346
  getWorkflowDataByCategory(workflow, MetadataCategory.Medical).then((data) =>
@@ -462,11 +439,11 @@ async function storeImageAliases(
462
439
  Math.round(
463
440
  ((progress.currentStep + 1) / progress.stepsTotalNum -
464
441
  progress.currentStep / progress.stepsTotalNum) *
465
- 100
442
+ 100
466
443
  ) / 100
467
444
  progress.onProgress(
468
445
  progress.currentStep / progress.stepsTotalNum +
469
- progressStepValue * (storedImagesNum / totalImagesNum),
446
+ progressStepValue * (storedImagesNum / totalImagesNum),
470
447
  'store_images',
471
448
  {
472
449
  storedImagesNum,
@@ -0,0 +1,177 @@
1
+ import {
2
+ Consult,
3
+ ConsultRequest,
4
+ DocumentType,
5
+ MedicalStatus,
6
+ MetadataCategory,
7
+ PlaceData,
8
+ SelectedAnswersData,
9
+ Uuid,
10
+ WorkflowData,
11
+ } from 'oro-sdk-apis'
12
+ import { OroClient } from '..'
13
+ import { getOrCreatePatientConsultationUuid } from './consult'
14
+
15
+ const MAX_RETRIES = 15
16
+ /**
17
+ * Placeholder while the workflow interpreter for the refill flows is complete
18
+ *
19
+ * Creates a fake workflow in which the workflow data will reside
20
+ *
21
+ * @param isTreatmentWorking the value from the `is treatment working` question
22
+ * @param hasSideEffects the value from the `does the treatment have side effects` question
23
+ * @param deliveryAddress the provided delivery address
24
+ * @param pharmacy
25
+ * @returns a workflow
26
+ */
27
+ export function getRefillAnswersAsWorkflow(
28
+ isTreatmentWorking: string,
29
+ hasSideEffects: string,
30
+ deliveryAddress?: string,
31
+ pharmacy?: PlaceData
32
+ ): WorkflowData {
33
+ let selectedAnswers: SelectedAnswersData = [
34
+ {
35
+ ['isTreatmentWorking']: isTreatmentWorking,
36
+ },
37
+ {
38
+ ['hasSideEffects']: hasSideEffects,
39
+ },
40
+ ]
41
+
42
+ if (deliveryAddress) selectedAnswers.push({ ['deliveryAddress']: deliveryAddress })
43
+ if (pharmacy) selectedAnswers.push({ ['pharmacy']: JSON.stringify(pharmacy) })
44
+
45
+ return {
46
+ id: '32573a20-6f1d-49be-9ad3-b87c58074979',
47
+ createdAt: '2022-10-03T00:00:00.000Z',
48
+ culDeSacs: [],
49
+ hidePlanRules: [],
50
+ pages: [
51
+ {
52
+ title: 'Prescription Refill',
53
+ groups: [
54
+ {
55
+ type: 'field-group',
56
+ fieldsAndGroups: [
57
+ {
58
+ type: 'field',
59
+ id: 'isTreatmentWorking',
60
+ },
61
+ {
62
+ type: 'field',
63
+ id: 'hasSideEffects',
64
+ },
65
+ {
66
+ type: 'field',
67
+ id: 'youPharmacy',
68
+ },
69
+ {
70
+ type: 'field',
71
+ id: 'youAddress',
72
+ },
73
+ ],
74
+ },
75
+ ],
76
+ questions: {
77
+ isTreatmentWorking: {
78
+ label: 'Is the treatment working for you?',
79
+ kind: 'radio',
80
+ inline: true,
81
+ inlineLabel: false,
82
+ metaCategory: MetadataCategory.Refill,
83
+ answers: {
84
+ '73bec6eb-0310-4787-af3c-ac9c291737b2': {
85
+ text: 'Yes',
86
+ },
87
+ 'e193951f-986f-4db3-bede-903045a1804a': {
88
+ text: 'No',
89
+ },
90
+ },
91
+ },
92
+ hasSideEffects: {
93
+ label: 'Are there any side effects',
94
+ kind: 'radio',
95
+ inline: true,
96
+ inlineLabel: false,
97
+ metaCategory: MetadataCategory.Refill,
98
+ answers: {
99
+ '1b87ad22-d316-4fac-9c7f-8f4ccb841aed': {
100
+ text: 'Yes',
101
+ },
102
+ 'ab7f5a41-c351-4f5d-a568-e38f9f200e9a': {
103
+ text: 'No',
104
+ },
105
+ },
106
+ },
107
+ youPharmacy: {
108
+ kind: 'online-pharmacy-picker',
109
+ label: 'Which pharmacy do you want the prescription sent to?',
110
+ metaCategory: MetadataCategory.Refill,
111
+ minorLabel: ' (Optional)',
112
+ summaryLabel: 'Your pharmacy',
113
+ },
114
+ youAddress: {
115
+ kind: 'place-address',
116
+ label: 'Address',
117
+ metaCategory: MetadataCategory.Refill,
118
+ },
119
+ },
120
+ },
121
+ ],
122
+ locale: 'en',
123
+ selectedAnswers,
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Complete refill flow, creates a consult, stores refill data and updates consultation status
129
+ * @param consultRequest
130
+ * @param populatedRefillWorkflow the refill workflow data
131
+ * @param oroClient
132
+ */
133
+ export async function createRefill(
134
+ consultRequest: ConsultRequest,
135
+ populatedRefillWorkflow: WorkflowData,
136
+ oroClient: OroClient
137
+ ) {
138
+ let retry = MAX_RETRIES
139
+ let errorsThrown: Error[] = []
140
+
141
+ let newConsult: Consult | undefined
142
+ let lockboxUuid: Uuid | undefined
143
+
144
+ for (; retry > 0; retry--) {
145
+ try {
146
+ if (!newConsult) newConsult = await getOrCreatePatientConsultationUuid(consultRequest, oroClient)
147
+
148
+ if (!lockboxUuid) lockboxUuid = (await oroClient.getGrants())[0].lockboxUuid
149
+
150
+ await oroClient
151
+ .getOrInsertJsonData(
152
+ lockboxUuid!,
153
+ populatedRefillWorkflow,
154
+ {
155
+ category: MetadataCategory.Refill,
156
+ documentType: DocumentType.PopulatedWorkflowData,
157
+ consultationIds: [newConsult.uuid],
158
+ },
159
+ {},
160
+ { withNotification: true }
161
+ )
162
+ .catch((err) => {
163
+ console.error('[SDK: prescription refill] Some errors happened during refill data upload', err)
164
+ errorsThrown.push(err)
165
+ })
166
+
167
+ if (errorsThrown.length > 0) throw errorsThrown
168
+ await oroClient.consultClient.updateConsultByUUID(newConsult.uuid, {
169
+ statusMedical: MedicalStatus.New,
170
+ })
171
+ } catch (err) {
172
+ console.error(`[SDK] Error occured during refill: ${err}, retrying... Retries remaining: ${retry}`)
173
+ errorsThrown = []
174
+ continue
175
+ }
176
+ }
177
+ }