From ebe67c26df7ba4a7a4162816b881ac003f140526 Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Wed, 27 Sep 2023 10:49:54 +0200 Subject: [PATCH 01/12] chore: [TECH-1644] flaky custom program stage working list tests (#3420) --- .../TeiWorkingListsUser.feature | 2 +- .../TeiWorkingListsUser/index.js | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser.feature b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser.feature index fe69bbc858..d3f07adfe2 100644 --- a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser.feature +++ b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser.feature @@ -233,7 +233,7 @@ And the Custom Program stage list is deleted @v>=40 Scenario: The user can save a program stage working list, based on a TEI working list configuration -Given you open the main page with Ngelehun and Malaria focus investigation context +Given you open a clean main page with Ngelehun and Malaria focus investigation context Then you see the custom TEI working lists And you can load the view with the name Ongoing foci responses And you open the program stage filters from the more filters dropdown menu diff --git a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js index dedb6cd458..974685a855 100644 --- a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js +++ b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js @@ -2,6 +2,19 @@ import { v4 as uuid } from 'uuid'; import '../../sharedSteps'; import '../../../sharedSteps'; +const cleanUpIfApplicable = () => { + cy.buildApiUrl('programStageWorkingLists?filter=program.id:eq:qDkgAbB5Jlk&fields=id,displayName') + .then(url => cy.request(url)) + .then(({ body }) => { + const workingList = body.programStageWorkingLists?.find(e => e.displayName === 'Custom Program stage list'); + if (!workingList) { + return null; + } + return cy + .buildApiUrl('programStageWorkingLists', workingList.id) + .then(workingListUrl => cy.request('DELETE', workingListUrl)); + }); +}; Given('you open the main page with Ngelehun and child programme context', () => { cy.visit('#/?programId=IpHINAT79UW&orgUnitId=DiszpKrYNg8'); }); @@ -42,6 +55,7 @@ Given('you open the main page with Ngelehun and Malaria case diagnosis context', }); Given('you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context', () => { + cleanUpIfApplicable(); cy.visit('#/?programId=qDkgAbB5Jlk&orgUnitId=DiszpKrYNg8'); cy.get('[data-test="tei-working-lists"]') @@ -60,6 +74,11 @@ Given('you open the main page with Ngelehun and Malaria case diagnosis and House .click(); }); +Given('you open a clean main page with Ngelehun and Malaria focus investigation context', () => { + cleanUpIfApplicable(); + cy.visit('#/?programId=M3xtLkYBlKI&orgUnitId=DiszpKrYNg8'); +}); + Then('the default working list should be displayed', () => { const names = [ 'Filona', @@ -740,3 +759,4 @@ Then('the program stage custom working list filters are loaded', () => { .find('[data-test="more-filters"]') .should('have.length', 2); }); + From b58bc66db4136ad558c02f38ac54a2319b3af3f1 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Sat, 30 Sep 2023 03:31:27 +0200 Subject: [PATCH 02/12] fix(translations): sync translations from transifex (master) Automatically merged. --- i18n/zh.po | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/i18n/zh.po b/i18n/zh.po index 77abc5059a..3776db9b73 100644 --- a/i18n/zh.po +++ b/i18n/zh.po @@ -320,7 +320,7 @@ msgid "" msgstr "一个具有 {{attributeName}} 的 {{trackedEntityTypeName}} 实体已经登记" msgid "Show registered {{trackedEntityTypeName}}" -msgstr "显示登记的 {{attributeName}} " +msgstr "显示已注册的{{trackedEntityTypeName}}" msgid "Registered person" msgstr "登记的人" @@ -1069,7 +1069,7 @@ msgid "To work with the selected program," msgstr "基于选择的项目工作" msgid "open the Tracker Capture app" -msgstr "打开跟踪随访采集APP" +msgstr "打开跟踪记录APP" msgid "This program is protected" msgstr "该项目受保护" @@ -1257,7 +1257,7 @@ msgid "Save changes" msgstr "保存修改" msgid "Profile" -msgstr "简历" +msgstr "基本信息" msgid "There is a problem with this form" msgstr "这个表单有问题" @@ -1278,7 +1278,7 @@ msgid "Profile widget could not be loaded. Please try again later" msgstr "无法加载个人资料窗口小部件。请稍后再试" msgid "{{TETName}} profile" -msgstr "{{TETName}} 基本资料" +msgstr "{{TETName}} 基本信息" msgid "Edit" msgstr "编辑" @@ -1314,7 +1314,7 @@ msgid "{{ overdueEvents }} overdue" msgstr "{{ overdueEvents }} 逾期" msgid "{{ scheduledEvents }} scheduled" -msgstr "{{scheduledEvents}} 已调度" +msgstr "{{ ScheduledEvents }} 已安排" msgid "Stages and Events" msgstr "阶段与活动" @@ -1416,7 +1416,7 @@ msgid "Scheduled" msgstr "已经调度" msgid "Overdue{{ escape }} due {{ time }}" -msgstr "逾期{{逃脱}}到期{{时间}}" +msgstr "逾期{{ escape }}到期{{ time }}" msgid "Overdue" msgstr "逾期" From 12060edc2ec032cf6cf4dbf8ed75226902f5b138 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Sat, 30 Sep 2023 01:39:09 +0000 Subject: [PATCH 03/12] chore(release): cut 100.40.1 [skip release] ## [100.40.1](https://github.com/dhis2/capture-app/compare/v100.40.0...v100.40.1) (2023-09-30) ### Bug Fixes * **translations:** sync translations from transifex (master) ([b58bc66](https://github.com/dhis2/capture-app/commit/b58bc66db4136ad558c02f38ac54a2319b3af3f1)) --- CHANGELOG.md | 7 +++++++ package.json | 4 ++-- packages/rules-engine/package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5540c833b..110d6a07aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [100.40.1](https://github.com/dhis2/capture-app/compare/v100.40.0...v100.40.1) (2023-09-30) + + +### Bug Fixes + +* **translations:** sync translations from transifex (master) ([b58bc66](https://github.com/dhis2/capture-app/commit/b58bc66db4136ad558c02f38ac54a2319b3af3f1)) + # [100.40.0](https://github.com/dhis2/capture-app/compare/v100.39.4...v100.40.0) (2023-09-20) diff --git a/package.json b/package.json index 9acdd9c1cb..a0589b228f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "100.40.0", + "version": "100.40.1", "cacheVersion": "5", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "100.40.0", + "@dhis2/rules-engine-javascript": "100.40.1", "@dhis2/app-runtime": "^3.9.3", "@dhis2/d2-i18n": "^1.1.0", "@dhis2/d2-icons": "^1.0.1", diff --git a/packages/rules-engine/package.json b/packages/rules-engine/package.json index c3b109cd88..0b391e85fa 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "100.40.0", + "version": "100.40.1", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From 6e5f6fea7b6ab043800e806c7459210f10ef608a Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Tue, 3 Oct 2023 08:49:19 +0200 Subject: [PATCH 04/12] feat: [DHIS2-9661][DHIS2-14830] first stage on registration page (#3267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: jasminenguyennn Co-authored-by: Joakim Storløkken Melseth --- .../EnrollmentPage/BreakingTheGlass/index.js | 4 + cypress/integration/NewPage.feature | 7 +- cypress/integration/NewPage/index.js | 23 +- .../TeiWorkingListsUser/index.js | 8 +- i18n/en.pot | 22 +- package.json | 2 +- .../components/D2Form/D2Form.component.js | 12 +- .../components/D2Form/D2Form.types.js | 3 +- .../EnrollmentDataEntry.component.js | 79 +++--- .../EnrollmentDataEntry.container.js | 19 +- ...llmentWithFirstStageDataEntry.component.js | 231 ++++++++++++++++++ ...llmentWithFirstStageDataEntry.constants.js | 7 + ...llmentWithFirstStageDataEntry.container.js | 28 +++ ...EnrollmentWithFirstStageDataEntry.types.js | 9 + .../fieldLabels.module.css | 45 ++++ .../eventDate.validatorContainersGetter.js | 26 ++ .../fieldValidators/index.js | 3 + .../getDataEntryPropsToInclude.js | 39 +++ .../hooks/index.js | 3 + .../hooks/useDataEntrySections.js | 34 +++ .../index.js | 4 + .../withCleanUp.js | 21 ++ .../actions/enrollment.actionBatchs.js | 41 +++- .../Enrollment/actions/enrollment.actions.js | 5 +- .../Enrollment/actions/open.actionBatchs.js | 38 ++- .../Enrollment/epics/enrollment.epics.js | 64 +++-- .../EnrollmentRegistrationEntry.actions.js | 23 +- .../EnrollmentRegistrationEntry.container.js | 14 +- .../EnrollmentRegistrationEntry.epics.js | 13 +- .../EnrollmentRegistrationEntry.types.js | 3 +- .../hooks/useBuildFirstStageRegistration.js | 32 +++ .../hooks/useLifecycle.js | 40 ++- .../useMergeFormFoundationsIfApplicable.js | 72 ++++++ .../types/duplicateCheckOnSave.types.js | 6 +- .../DataEntries/converters/converters.js | 9 +- .../DataEntry/DataEntry.component.js | 41 +++- ...ection.component.js => Field.component.js} | 4 +- .../DataEntry/actions/dataEntryLoad.utils.js | 9 +- .../convertDataEntryValuesToClientValues.js | 3 +- .../DataEntry/constants/placements.const.js | 1 + .../EnrollmentEditEventPage.container.js | 26 +- .../EnrollmentEditEventPage.types.js | 3 +- .../RegistrationDataEntry.actions.js | 13 +- .../RegistrationDataEntry.component.js | 4 +- .../RegistrationDataEntry.container.js | 4 +- .../RegistrationDataEntry.epics.js | 166 +++++-------- .../helpers/deriveAutoGenerateEvents.js | 79 ++++++ ...deriveFirstStageDuringRegistrationEvent.js | 55 +++++ .../getStageWithOpenAfterEnrollment.js | 45 ++++ .../RegistrationDataEntry/helpers/index.js | 5 + .../helpers/standardGeoJson.js | 19 ++ .../EditEventDataEntry.component.js | 2 +- .../EditEventDataEntry.container.js | 2 +- .../WidgetEventEdit/widgetEventEdit.types.js | 2 +- .../hooks/useEnrollmentEditEventPageMode.js | 17 +- .../metaData/DataElement/DataElement.js | 9 + .../capture-core/metaData/Program/Program.js | 9 + .../metaData/Program/ProgramStage.js | 9 + .../RenderFoundation/RenderFoundation.js | 18 +- .../metaData/RenderFoundation/Section.js | 13 + .../factory/enrollment/DataElementFactory.js | 13 +- .../factory/enrollment/EnrollmentFactory.js | 23 +- .../factory/program/ProgramFactory.js | 1 + .../programStage/DataElementFactory.js | 7 +- .../programStage/ProgramStageFactory.js | 5 +- .../quickStoreOperations/storePrograms.js | 2 +- .../types/apiPrograms.types.js | 1 + .../rules/getApplicableRuleEffects.js | 4 +- .../capture-core/rules/rules.types.js | 1 + .../storageControllers/cache.types.js | 2 + 70 files changed, 1334 insertions(+), 272 deletions(-) create mode 100644 src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.component.js create mode 100644 src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.constants.js create mode 100644 src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.container.js create mode 100644 src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.types.js create mode 100644 src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldLabels.module.css create mode 100644 src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/eventDate.validatorContainersGetter.js create mode 100644 src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/index.js create mode 100644 src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/getDataEntryPropsToInclude.js create mode 100644 src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/index.js create mode 100644 src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/useDataEntrySections.js create mode 100644 src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/index.js create mode 100644 src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/withCleanUp.js create mode 100644 src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useBuildFirstStageRegistration.js create mode 100644 src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useMergeFormFoundationsIfApplicable.js rename src/core_modules/capture-core/components/DataEntry/{FieldSection.component.js => Field.component.js} (91%) create mode 100644 src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveAutoGenerateEvents.js create mode 100644 src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveFirstStageDuringRegistrationEvent.js create mode 100644 src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/getStageWithOpenAfterEnrollment.js create mode 100644 src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/index.js create mode 100644 src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/standardGeoJson.js diff --git a/cypress/integration/EnrollmentPage/BreakingTheGlass/index.js b/cypress/integration/EnrollmentPage/BreakingTheGlass/index.js index 45ad92f517..70a2fdad96 100644 --- a/cypress/integration/EnrollmentPage/BreakingTheGlass/index.js +++ b/cypress/integration/EnrollmentPage/BreakingTheGlass/index.js @@ -31,6 +31,10 @@ And('you create a new tei in Child programme from Ngelehun CHC', () => { .eq(1) .type('TheGlass') .blur(); + cy.get('[data-test="capture-ui-input"]') + .eq(7) + .type('2023-09-01') + .blur(); clickSave(); }); diff --git a/cypress/integration/NewPage.feature b/cypress/integration/NewPage.feature index 21b3d996d8..85aaa709d3 100644 --- a/cypress/integration/NewPage.feature +++ b/cypress/integration/NewPage.feature @@ -178,6 +178,7 @@ Feature: User creates a new entries from the registration page Scenario: New person in Tracker Program > Submitting the form shows a list with duplicates Given you are in Child programme registration page When you fill the Child programme registration form with a first name with value that has duplicates + And you fill in the birth report date And you click the save person submit button And you see the possible duplicates modal When you click the next page button @@ -197,7 +198,7 @@ Feature: User creates a new entries from the registration page When you are in the Malaria case diagnosis, treatment and investigation program registration page And you fill the Malaria case diagnosis registration form with values And you click the save malaria entity submit button - Then you see the enrollment event New page + Then you see the enrollment event Edit page When you open the main page with Ngelehun and Malaria case diagnosis, treatment and investigation context And you opt out to use the new enrollment Dashboard for Malaria case diagnosis, treatment and investigation Then you see the opt in component for Malaria case diagnosis, treatment and investigation @@ -208,3 +209,7 @@ Feature: User creates a new entries from the registration page Given you are in Child programme reenrollment page Then you see the form prefield with existing TEI attributes values And the scope selector has the TEI context + + Scenario: First stage appears on registration page + Given you are in Child programme registration page + Then the first stage appears on registration page diff --git a/cypress/integration/NewPage/index.js b/cypress/integration/NewPage/index.js index 09046c7c65..4cc6af0afb 100644 --- a/cypress/integration/NewPage/index.js +++ b/cypress/integration/NewPage/index.js @@ -502,6 +502,13 @@ And('you fill the Child programme registration form with a first name with value .blur(); }); +And('you fill in the birth report date', () => { + cy.get('[data-test="capture-ui-input"]') + .eq(7) + .type('2023-01-01') + .blur(); +}); + And('you are in the WNCH PNC program registration page', () => { cy.visit('/#/new?programId=uy2gU8kT1jF&orgUnitId=DiszpKrYNg8'); }); @@ -561,12 +568,10 @@ And('you fill the Malaria case diagnosis registration form with values', () => { .blur(); }); -Then('you see the enrollment event New page', () => { - cy.url().should('include', '/#/enrollmentEventNew?'); - cy.url().should('include', 'stageId=hYyB7FUS5eR'); +Then('you see the enrollment event Edit page', () => { + cy.url().should('include', '/#/enrollmentEventEdit?'); }); - And('you fill in multiple Allergies options', () => { cy.get('[data-test="registration-page-content"]').within(() => { cy.contains('Allergies').should('exist'); @@ -585,3 +590,13 @@ Then('you can see the multiple selections in the form', () => { cy.contains('Other').should('exist'); }); }); + +Then('the first stage appears on registration page', () => { + cy.get('[data-test="registration-page-content"]').within(() => { + cy.contains('Birth - Basic info').should('exist'); + cy.contains('Birth - Details').should('exist'); + cy.contains('Birth - Status').should('exist'); + cy.contains('Report date').should('exist'); + cy.contains('Apgar Score').should('exist'); + }); +}); diff --git a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js index 974685a855..7e5825c8a1 100644 --- a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js +++ b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js @@ -2,8 +2,8 @@ import { v4 as uuid } from 'uuid'; import '../../sharedSteps'; import '../../../sharedSteps'; -const cleanUpIfApplicable = () => { - cy.buildApiUrl('programStageWorkingLists?filter=program.id:eq:qDkgAbB5Jlk&fields=id,displayName') +const cleanUpIfApplicable = (programId) => { + cy.buildApiUrl(`programStageWorkingLists?filter=program.id:eq:${programId}&fields=id,displayName`) .then(url => cy.request(url)) .then(({ body }) => { const workingList = body.programStageWorkingLists?.find(e => e.displayName === 'Custom Program stage list'); @@ -55,7 +55,7 @@ Given('you open the main page with Ngelehun and Malaria case diagnosis context', }); Given('you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context', () => { - cleanUpIfApplicable(); + cleanUpIfApplicable('qDkgAbB5Jlk'); cy.visit('#/?programId=qDkgAbB5Jlk&orgUnitId=DiszpKrYNg8'); cy.get('[data-test="tei-working-lists"]') @@ -75,7 +75,7 @@ Given('you open the main page with Ngelehun and Malaria case diagnosis and House }); Given('you open a clean main page with Ngelehun and Malaria focus investigation context', () => { - cleanUpIfApplicable(); + cleanUpIfApplicable('M3xtLkYBlKI'); cy.visit('#/?programId=M3xtLkYBlKI&orgUnitId=DiszpKrYNg8'); }); diff --git a/i18n/en.pot b/i18n/en.pot index e179d736a4..06e8de8d33 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -5,8 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2023-09-04T07:07:59.195Z\n" -"PO-Revision-Date: 2023-09-04T07:07:59.195Z\n" +"POT-Creation-Date: 2023-09-29T14:14:34.330Z\n" +"PO-Revision-Date: 2023-09-29T14:14:34.330Z\n" msgid "Choose one or more dates..." msgstr "Choose one or more dates..." @@ -149,6 +149,15 @@ msgstr "Coordinate" msgid "Enrollment" msgstr "Enrollment" +msgid "Complete event" +msgstr "Complete event" + +msgid "{{ stageName }} - Basic info" +msgstr "{{ stageName }} - Basic info" + +msgid "{{ stageName }} - Status" +msgstr "{{ stageName }} - Status" + msgid "Please select {{categoryName}}" msgstr "Please select {{categoryName}}" @@ -167,15 +176,18 @@ msgstr "Cancel" msgid "Metadata error. see log for details" msgstr "Metadata error. see log for details" +msgid "{{ stageName }} - Details" +msgstr "{{ stageName }} - Details" + +msgid "{{ stageName }} - {{ sectionName }}" +msgstr "{{ stageName }} - {{ sectionName }}" + msgid "Assigned user" msgstr "Assigned user" msgid "Search for user" msgstr "Search for user" -msgid "Complete event" -msgstr "Complete event" - msgid "Basic info" msgstr "Basic info" diff --git a/package.json b/package.json index a0589b228f..6d42913001 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "capture-app", "homepage": ".", "version": "100.40.1", - "cacheVersion": "5", + "cacheVersion": "6", "serverVersion": "38", "license": "BSD-3-Clause", "private": true, diff --git a/src/core_modules/capture-core/components/D2Form/D2Form.component.js b/src/core_modules/capture-core/components/D2Form/D2Form.component.js index 5d24c11bba..4f17677b07 100644 --- a/src/core_modules/capture-core/components/D2Form/D2Form.component.js +++ b/src/core_modules/capture-core/components/D2Form/D2Form.component.js @@ -116,11 +116,21 @@ class D2Form extends React.PureComponent { id, classes, isFormInReduxStore, + getCustomContent, ...passOnProps } = this.props; const metaDataSectionsAsArray = Array.from(formFoundation.sections.entries()).map(entry => entry[1]); - const sections = metaDataSectionsAsArray.map(section => (passOnProps.formHorizontal ? this.renderHorizontal(section, passOnProps) : this.renderVertical(section, passOnProps))); + const sections = metaDataSectionsAsArray.map(section => ( + passOnProps.formHorizontal + ? this.renderHorizontal(section, passOnProps) + : ( + <> + {getCustomContent && getCustomContent(section.id) } + {this.renderVertical(section, passOnProps)} + + ) + )); return ( <> diff --git a/src/core_modules/capture-core/components/D2Form/D2Form.types.js b/src/core_modules/capture-core/components/D2Form/D2Form.types.js index 59f5065222..9671d8309f 100644 --- a/src/core_modules/capture-core/components/D2Form/D2Form.types.js +++ b/src/core_modules/capture-core/components/D2Form/D2Form.types.js @@ -1,5 +1,5 @@ // @flow - +import * as React from 'react'; import type { RenderFoundation } from '../../metaData'; export type FormRef = $ReadOnly<{| @@ -10,6 +10,7 @@ export type OwnProps = $ReadOnly<{| formFoundation: RenderFoundation, id: string, formHorizontal?: boolean, + getCustomContent?: (beforeSectionId: string) => React.Node, ...FormRef |}> diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentDataEntry.component.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentDataEntry.component.js index aa756a6f5a..afb0561e04 100644 --- a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentDataEntry.component.js +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentDataEntry.component.js @@ -33,7 +33,8 @@ import { getIncidentDateValidatorContainer, } from './fieldValidators'; import { sectionKeysForEnrollmentDataEntry } from './constants/sectionKeys.const'; -import { type Enrollment, getProgramThrowIfNotFound } from '../../../metaData'; +import { type Enrollment, ProgramStage, RenderFoundation, getProgramThrowIfNotFound } from '../../../metaData'; +import { EnrollmentWithFirstStageDataEntry } from './EnrollmentWithFirstStageDataEntry'; import { getCategoryOptionsValidatorContainers, attributeOptionsKey, @@ -41,7 +42,6 @@ import { withAOCFieldBuilder, withDataEntryFields, } from '../../DataEntryDhis2Helpers'; -import { shouldUseNewDashboard } from '../../../utils/routing'; const overrideMessagePropNames = { errorMessage: 'validationError', @@ -290,40 +290,35 @@ const getCategoryOptionsSettingsFn = () => { getPropName: (props: Object, fieldId?: string) => (fieldId ? `${attributeOptionsKey}-${fieldId}` : attributeOptionsKey), getFieldIds: (props: Object) => props.categories?.map(category => category.id), getValidatorContainers: (props: Object, fieldId?: string) => getCategoryOptionsValidatorContainers(props, fieldId), - getMeta: (props: Object) => ({ - section: AOCsectionKey, - placement: placements.BOTTOM, - sectionName: props.programCategory?.displayName, - }), + getMeta: (props: Object) => { + const { firstStageMetaData, programCategory } = props; + + return { + section: AOCsectionKey, + placement: placements.BOTTOM, + sectionName: firstStageMetaData + ? `${firstStageMetaData.stage.name} - ${programCategory?.displayName}` + : programCategory?.displayName, + }; + }, }; return categoryOptionsSettings; }; const getAOCSettingsFn = () => ({ - hideAOC: ({ programId, newDashboardConfig }) => { - const { stages: stagesMap } = getProgramThrowIfNotFound(programId); + hideAOC: ({ programId }) => { + const { stages: stagesMap, useFirstStageDuringRegistration } = getProgramThrowIfNotFound(programId); /* Show AOC selection if: - - There are any program stages in the program with “Auto-generate" event and NOT “Open data entry form after enrollment”. - - There are multiple program stages with "Auto-generate" event and "Open data entry form after enrollment" - (in this scenario we are currently generating events for the program stages that are not the first one) - - Using the old dashboard and we have a stage with auto generate event. + - There are any program stages in the program with “Auto-generate" + - The "Show first stage on registration page" is selected for the program */ const stages = [...stagesMap.values()]; - const usingNewDashboardForProgram = shouldUseNewDashboard( - newDashboardConfig.userDataStore, - newDashboardConfig.dataStore, - newDashboardConfig.temp, - programId, - ); - - const shouldShowAOC = (!usingNewDashboardForProgram && stages.some(stage => stage.autoGenerateEvent)) || - stages.some(stage => stage.autoGenerateEvent && !stage.openAfterEnrollment) || - stages.filter(stage => stage.autoGenerateEvent && stage.openAfterEnrollment).length > 1; + const shouldShowAOC = stages.some(stage => stage.autoGenerateEvent) || useFirstStageDuringRegistration; return !shouldShowAOC; }, @@ -336,7 +331,9 @@ type FinalTeiDataEntryProps = { orgUnitId: string, onUpdateDataEntryField: Function, onUpdateFormFieldAsync: Function, - onUpdateFormField: Function + onUpdateFormField: Function, + firstStageMetaData?: ?{ stage: ProgramStage }, + formFoundation: RenderFoundation, }; // final step before the generic dataEntry is inserted class FinalEnrollmentDataEntry extends React.Component { @@ -355,14 +352,21 @@ class FinalEnrollmentDataEntry extends React.Component { }; render() { - const { enrollmentMetadata, ...passOnProps } = this.props; + const { enrollmentMetadata, firstStageMetaData, ...passOnProps } = this.props; + return ( // $FlowFixMe[cannot-spread-inexact] automated comment - + firstStageMetaData ? ( + + ) : ( + + ) ); } } @@ -385,6 +389,8 @@ type PreEnrollmentDataEntryProps = { onStartAsyncUpdateField: Function, onGetUnsavedAttributeValues?: ?Function, teiId?: ?string, + firstStageMetaData?: ?{ stage: ProgramStage }, + formFoundation: RenderFoundation, }; class PreEnrollmentDataEntryPure extends React.PureComponent { @@ -409,18 +415,18 @@ export class EnrollmentDataEntryComponent extends React.Component) => { - const { programId, orgUnit } = this.props; - this.props.onUpdateField(...args, programId, orgUnit); + const { programId, orgUnit, firstStageMetaData, formFoundation } = this.props; + this.props.onUpdateField(...args, programId, orgUnit, firstStageMetaData?.stage, formFoundation); } handleUpdateDataEntryField = (...args: Array) => { - const { programId, orgUnit } = this.props; - this.props.onUpdateDataEntryField(...args, programId, orgUnit); + const { programId, orgUnit, firstStageMetaData, formFoundation } = this.props; + this.props.onUpdateDataEntryField(...args, programId, orgUnit, firstStageMetaData?.stage, formFoundation); } handleStartAsyncUpdateField = (...args: Array) => { - const { programId, orgUnit } = this.props; - this.props.onStartAsyncUpdateField(...args, programId, orgUnit); + const { programId, orgUnit, firstStageMetaData, formFoundation } = this.props; + this.props.onStartAsyncUpdateField(...args, programId, orgUnit, firstStageMetaData?.stage, formFoundation); } render() { @@ -432,6 +438,7 @@ export class EnrollmentDataEntryComponent extends React.Component ({ - newDashboardConfig: useNewDashboard, -}); - const mapDispatchToProps = (dispatch: ReduxDispatch) => ({ onUpdateDataEntryField: ( innerAction: ReduxAction, data: any, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => { - dispatch(updateDataEntryFieldBatch(innerAction, programId, orgUnit)); + dispatch(updateDataEntryFieldBatch(innerAction, programId, orgUnit, stage, formFoundation)); }, onUpdateField: ( innerAction: ReduxAction, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => { - dispatch(updateFieldBatch(innerAction, programId, orgUnit)); + dispatch(updateFieldBatch(innerAction, programId, orgUnit, stage, formFoundation)); }, onStartAsyncUpdateField: ( innerAction: ReduxAction, @@ -31,9 +32,11 @@ const mapDispatchToProps = (dispatch: ReduxDispatch) => ({ itemId: string, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => { const onAsyncUpdateSuccess = (successInnerAction: ReduxAction) => - asyncUpdateSuccessBatch(successInnerAction, dataEntryId, itemId, programId, orgUnit); + asyncUpdateSuccessBatch(successInnerAction, dataEntryId, itemId, programId, orgUnit, stage, formFoundation); const onAsyncUpdateError = (errorInnerAction: ReduxAction) => errorInnerAction; dispatch(startAsyncUpdateFieldForNewEnrollment(innerAction, onAsyncUpdateSuccess, onAsyncUpdateError)); @@ -41,5 +44,5 @@ const mapDispatchToProps = (dispatch: ReduxDispatch) => ({ }); // $FlowFixMe -export const EnrollmentDataEntry = connect(mapStateToProps, mapDispatchToProps)(EnrollmentDataEntryComponent); +export const EnrollmentDataEntry = connect(() => ({}), mapDispatchToProps)(EnrollmentDataEntryComponent); diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.component.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.component.js new file mode 100644 index 0000000000..c1b0b328b0 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.component.js @@ -0,0 +1,231 @@ +// @flow +import i18n from '@dhis2/d2-i18n'; +import { DataEntry } from '../../../DataEntry'; +import { + withInternalChangeHandler, + withLabel, + withFocusSaver, + DateField, + PolygonField, + CoordinateField, + withCalculateMessages, + withDisplayMessages, + withFilterProps, + withDefaultFieldContainer, + withDefaultShouldUpdateInterface, + TrueOnlyField, + orientations, +} from '../../../FormFields/New'; +import { placements } from '../../../DataEntry/constants/placements.const'; +import { withDataEntryFieldIfApplicable } from '../../../DataEntry/dataEntryField/withDataEntryFieldIfApplicable'; +import { sectionKeysForFirstStageDataEntry } from './EnrollmentWithFirstStageDataEntry.constants'; +import labelTypeClasses from './fieldLabels.module.css'; +import { withCleanUp } from './withCleanUp'; +import { getEventDateValidatorContainers } from './fieldValidators/eventDate.validatorContainersGetter'; +import { stageMainDataIds } from './getDataEntryPropsToInclude'; + +const overrideMessagePropNames = { + errorMessage: 'validationError', +}; + +const getCalendarAnchorPosition = (formHorizontal: ?boolean) => (formHorizontal ? 'center' : 'left'); + +const baseComponentStyles = { + labelContainerStyle: { + flexBasis: 200, + }, + inputContainerStyle: { + flexBasis: 150, + }, +}; +const baseComponentStylesVertical = { + labelContainerStyle: { + width: 150, + }, + inputContainerStyle: { + width: 150, + }, +}; + +function defaultFilterProps(props: Object) { + const { formHorizontal, fieldOptions, validationError, modified, ...passOnProps } = props; + return passOnProps; +} + +const getBaseComponentProps = (props: Object) => ({ + fieldOptions: props.fieldOptions, + formHorizontal: props.formHorizontal, + styles: props.formHorizontal ? baseComponentStylesVertical : baseComponentStyles, +}); + +const createComponentProps = (props: Object, componentProps: Object) => ({ + ...getBaseComponentProps(props), + ...componentProps, +}); + +const getOrientation = (formHorizontal: ?boolean) => (formHorizontal ? orientations.VERTICAL : orientations.HORIZONTAL); + +const pointComponent = withCalculateMessages(overrideMessagePropNames)( + withFocusSaver()( + withDefaultFieldContainer()( + withDefaultShouldUpdateInterface()( + withLabel({ + onGetUseVerticalOrientation: (props: Object) => props.formHorizontal, + onGetCustomFieldLabeClass: (props: Object) => + `${props.fieldOptions && props.fieldOptions.fieldLabelMediaBasedClass} ${labelTypeClasses.coordinateLabel}`, + })( + withDisplayMessages()( + withInternalChangeHandler()( + withFilterProps(defaultFilterProps)(CoordinateField), + ), + ), + ), + ), + ), + ), +); + +const polygonComponent = withCalculateMessages(overrideMessagePropNames)( + withFocusSaver()( + withDefaultFieldContainer()( + withDefaultShouldUpdateInterface()( + withLabel({ + onGetUseVerticalOrientation: (props: Object) => props.formHorizontal, + onGetCustomFieldLabeClass: (props: Object) => + `${props.fieldOptions && props.fieldOptions.fieldLabelMediaBasedClass} ${labelTypeClasses.coordinateLabel}`, + })( + withDisplayMessages()( + withInternalChangeHandler()( + withFilterProps(defaultFilterProps)(PolygonField), + ), + ), + ), + ), + ), + ), +); + +const getStageGeometrySettings = () => ({ + isApplicable: (props: Object) => { + const featureType = props.firstStageMetaData?.stage?.stageForm?.featureType; + return ['Polygon', 'Point'].includes(featureType); + }, + getComponent: (props: Object) => { + const featureType = props.firstStageMetaData?.stage?.stageForm?.featureType; + if (featureType === 'Polygon') { + return polygonComponent; + } + return pointComponent; + }, + getComponentProps: (props: Object) => { + const featureType = props.firstStageMetaData?.stage?.stageForm?.featureType; + if (featureType === 'Polygon') { + return createComponentProps(props, { + width: props && props.formHorizontal ? 150 : 350, + label: i18n.t('Area'), + dialogLabel: i18n.t('Area'), + required: false, + orientation: getOrientation(props.formHorizontal), + }); + } + + return createComponentProps(props, { + width: props && props.formHorizontal ? 150 : 350, + label: i18n.t('Coordinate'), + dialogLabel: i18n.t('Coordinate'), + required: false, + orientation: getOrientation(props.formHorizontal), + shrinkDisabled: props.formHorizontal, + }); + }, + getPropName: () => stageMainDataIds.GEOMETRY, + getValidatorContainers: () => [], + getMeta: () => ({ + section: sectionKeysForFirstStageDataEntry.STAGE_BASIC_INFO, + }), +}); + +const getCompleteFieldSettingsFn = () => { + const completeComponent = + withCalculateMessages(overrideMessagePropNames)( + withFocusSaver()( + withDefaultFieldContainer()( + withDefaultShouldUpdateInterface()( + withLabel({ + onGetUseVerticalOrientation: (props: Object) => props.formHorizontal, + onGetCustomFieldLabeClass: (props: Object) => + `${props.fieldOptions && props.fieldOptions.fieldLabelMediaBasedClass} ${labelTypeClasses.trueOnlyLabel}`, + })( + withDisplayMessages()( + withInternalChangeHandler()( + withFilterProps(defaultFilterProps)(TrueOnlyField), + ), + ), + ), + ), + ), + ), + ); + const completeSettings = { + isApplicable: (props: Object) => props.firstStageMetaData && props.firstStageMetaData.stage?.stageForm, + getComponent: () => completeComponent, + getComponentProps: (props: Object) => createComponentProps(props, { + label: i18n.t('Complete event'), + id: 'complete', + }), + getPropName: () => stageMainDataIds.COMPLETE, + getValidatorContainers: () => [], + getMeta: () => ({ + placement: placements.BOTTOM, + section: sectionKeysForFirstStageDataEntry.STATUS, + }), + getPassOnFieldData: () => true, + }; + + return completeSettings; +}; + +const getReportDateSettingsFn = () => { + const reportDateComponent = + withCalculateMessages(overrideMessagePropNames)( + withFocusSaver()( + withDefaultFieldContainer()( + withDefaultShouldUpdateInterface()( + withLabel({ + onGetUseVerticalOrientation: (props: Object) => props.formHorizontal, + onGetCustomFieldLabeClass: (props: Object) => + `${props.fieldOptions && props.fieldOptions.fieldLabelMediaBasedClass} ${labelTypeClasses.dateLabel}`, + })( + withDisplayMessages()( + withInternalChangeHandler()( + withFilterProps(defaultFilterProps)(DateField), + ), + ), + ), + ), + ), + ), + ); + const reportDateSettings = { + isApplicable: (props: Object) => props.firstStageMetaData?.stage?.stageForm, + getComponent: () => reportDateComponent, + getComponentProps: (props: Object) => createComponentProps(props, { + width: props && props.formHorizontal ? 150 : '100%', + label: props.firstStageMetaData?.stage?.stageForm?.getLabel('occurredAt'), + required: true, + calendarWidth: props.formHorizontal ? 250 : 350, + popupAnchorPosition: getCalendarAnchorPosition(props.formHorizontal), + }), + getPropName: () => stageMainDataIds.OCCURRED_AT, + getValidatorContainers: () => getEventDateValidatorContainers(), + getMeta: () => ({ + section: sectionKeysForFirstStageDataEntry.STAGE_BASIC_INFO, + }), + }; + + return reportDateSettings; +}; + +const StageLocationHOC = withDataEntryFieldIfApplicable(getStageGeometrySettings())(withCleanUp()(DataEntry)); +const CompleteHOC = withDataEntryFieldIfApplicable(getCompleteFieldSettingsFn())(StageLocationHOC); +export const FirstStageDataEntry = withDataEntryFieldIfApplicable(getReportDateSettingsFn())(CompleteHOC); diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.constants.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.constants.js new file mode 100644 index 0000000000..1abc295aa9 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.constants.js @@ -0,0 +1,7 @@ +// @flow + +export const sectionKeysForFirstStageDataEntry = { + ENROLLMENT: 'enrollment', + STATUS: 'status', + STAGE_BASIC_INFO: 'stageBasicInfo', +}; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.container.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.container.js new file mode 100644 index 0000000000..b831b9f197 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.container.js @@ -0,0 +1,28 @@ +// @flow +import React from 'react'; +import type { Props } from './EnrollmentWithFirstStageDataEntry.types'; +import { FirstStageDataEntry } from './EnrollmentWithFirstStageDataEntry.component'; +import { useDataEntrySections } from './hooks'; +import { Section } from '../../../../metaData'; + +const getSectionId = sectionId => + (sectionId === Section.MAIN_SECTION_ID ? `${Section.MAIN_SECTION_ID}-stage` : sectionId); + +export const EnrollmentWithFirstStageDataEntry = (props: Props) => { + const { firstStageMetaData, ...passOnProps } = props; + const { + stage: { stageForm: firstStageFormFoundation, name: stageName }, + } = firstStageMetaData; + // $FlowFixMe[incompatible-type] + const [[firstSectionId]] = firstStageFormFoundation.sections; + const beforeSectionId = getSectionId(firstSectionId); + const dataEntrySections = useDataEntrySections(stageName, beforeSectionId); + + return ( + + ); +}; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.types.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.types.js new file mode 100644 index 0000000000..6c2a054867 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/EnrollmentWithFirstStageDataEntry.types.js @@ -0,0 +1,9 @@ +// @flow +import type { ProgramStage, RenderFoundation } from '../../../../metaData'; + +export type Props = { + firstStageMetaData: { + stage: ProgramStage, + }, + formFoundation: RenderFoundation, +}; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldLabels.module.css b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldLabels.module.css new file mode 100644 index 0000000000..faa712abaf --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldLabels.module.css @@ -0,0 +1,45 @@ +.booleanLabel { + padding-top: 13px; +} + +.trueOnlyLabel { + padding-top: 13px; +} +.noteLabel { + padding-top: 13px; +} + +.textLabel { + padding-top: 13px; +} + +.ageLabel { + padding-top: 13px; +} + +.coordinateLabel { + padding-top: 13px; +} +.polygonLabel { + padding-top: 4px; +} + +.dateLabel { + padding-top: 13px; +} + +.dateTimeLabel { + padding-top: 13px; +} + +.imageLabel { + padding-top: 9px; +} + +.fileLabel { + padding-top: 9px; +} + +.orgUnitLabel { + padding-top: 3px; +} \ No newline at end of file diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/eventDate.validatorContainersGetter.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/eventDate.validatorContainersGetter.js new file mode 100644 index 0000000000..3cb0a56c19 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/eventDate.validatorContainersGetter.js @@ -0,0 +1,26 @@ +// @flow +import { hasValue } from 'capture-core-utils/validators/form'; +import i18n from '@dhis2/d2-i18n'; +import { isValidDate } from '../../../../../utils/validators/form'; + +const preValidateDate = (value?: ?string) => { + if (!value) { + return true; + } + + return isValidDate(value); +}; + +export const getEventDateValidatorContainers = () => { + const validatorContainers = [ + { + validator: hasValue, + message: i18n.t('A value is required'), + }, + { + validator: preValidateDate, + message: i18n.t('Please provide a valid date'), + }, + ]; + return validatorContainers; +}; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/index.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/index.js new file mode 100644 index 0000000000..5399d49334 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/fieldValidators/index.js @@ -0,0 +1,3 @@ +// @flow + +export { getEventDateValidatorContainers } from './eventDate.validatorContainersGetter'; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/getDataEntryPropsToInclude.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/getDataEntryPropsToInclude.js new file mode 100644 index 0000000000..aef6ec85cf --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/getDataEntryPropsToInclude.js @@ -0,0 +1,39 @@ +// @flow +import type { RenderFoundation } from '../../../../metaData'; +import { getEventDateValidatorContainers } from './fieldValidators'; +import { getConvertGeometryIn, convertGeometryOut, convertStatusIn, convertStatusOut } from '../../converters'; + +export const stageMainDataIds = { + OCCURRED_AT: 'stageOccurredAt', + COMPLETE: 'stageComplete', + GEOMETRY: 'stageGeometry', +}; + +const stageMainDataRulesEngineIds = { + OCCURRED_AT: 'occurredAt', + COMPLETE: 'complete', + GEOMETRY: 'geometry', +}; + +export const convertToRulesEngineIds = (id: string) => stageMainDataRulesEngineIds[id]; + +export const getDataEntryPropsToInclude = (formFoundation: RenderFoundation) => [ + { + id: stageMainDataIds.OCCURRED_AT, + type: 'DATE', + validatorContainers: getEventDateValidatorContainers(), + }, + { + clientId: stageMainDataIds.COMPLETE, + dataEntryId: stageMainDataIds.COMPLETE, + onConvertIn: convertStatusIn, + onConvertOut: convertStatusOut, + }, + { + clientId: stageMainDataIds.GEOMETRY, + dataEntryId: stageMainDataIds.GEOMETRY, + onConvertIn: getConvertGeometryIn(formFoundation), + onConvertOut: convertGeometryOut, + featureType: formFoundation.featureType, + }, +]; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/index.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/index.js new file mode 100644 index 0000000000..83d6e81265 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/index.js @@ -0,0 +1,3 @@ +// @flow + +export { useDataEntrySections } from './useDataEntrySections'; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/useDataEntrySections.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/useDataEntrySections.js new file mode 100644 index 0000000000..3aab5bd6d2 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/hooks/useDataEntrySections.js @@ -0,0 +1,34 @@ +// @flow +import { useMemo } from 'react'; +import i18n from '@dhis2/d2-i18n'; +import { placements } from '../../../../DataEntry/constants/placements.const'; +import { sectionKeysForFirstStageDataEntry } from '../EnrollmentWithFirstStageDataEntry.constants'; +import { AOCsectionKey } from '../../../../DataEntryDhis2Helpers'; + +export const useDataEntrySections = (stageName: string, beforeSectionId: string) => + useMemo( + () => ({ + [sectionKeysForFirstStageDataEntry.ENROLLMENT]: { + placement: placements.TOP, + name: i18n.t('Enrollment'), + }, + [sectionKeysForFirstStageDataEntry.STAGE_BASIC_INFO]: { + beforeSectionId, + placement: placements.BEFORE_METADATA_BASED_SECTION, + name: i18n.t('{{ stageName }} - Basic info', { + stageName, + }), + }, + [AOCsectionKey]: { + beforeSectionId, + placement: placements.BEFORE_METADATA_BASED_SECTION, + }, + [sectionKeysForFirstStageDataEntry.STATUS]: { + placement: placements.BOTTOM, + name: i18n.t('{{ stageName }} - Status', { + stageName, + }), + }, + }), + [stageName, beforeSectionId], + ); diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/index.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/index.js new file mode 100644 index 0000000000..9570ba1aba --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/index.js @@ -0,0 +1,4 @@ +// @flow + +export { EnrollmentWithFirstStageDataEntry } from './EnrollmentWithFirstStageDataEntry.container'; +export { getDataEntryPropsToInclude, stageMainDataIds, convertToRulesEngineIds } from './getDataEntryPropsToInclude'; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/withCleanUp.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/withCleanUp.js new file mode 100644 index 0000000000..5b2cc24c0e --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/EnrollmentWithFirstStageDataEntry/withCleanUp.js @@ -0,0 +1,21 @@ +// @flow +import * as React from 'react'; + +const getCleanUpHOC = (InnerComponent: React.ComponentType) => + (props: Object) => { + const { + dataEntryFieldRef, + firstStageMetaData, + ...passOnProps + } = props; + + return ( + + ); + }; + +export const withCleanUp = () => + (InnerComponent: React.ComponentType) => + getCleanUpHOC(InnerComponent); diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actionBatchs.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actionBatchs.js index c59fa959ee..f84452c7fe 100644 --- a/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actionBatchs.js +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actionBatchs.js @@ -8,7 +8,7 @@ import type { } from '@dhis2/rules-engine-javascript'; import { getApplicableRuleEffectsForTrackerProgram, updateRulesEffects } from '../../../../rules'; import { rulesExecutedPostUpdateField } from '../../../DataEntry/actions/dataEntry.actions'; -import type { TrackerProgram, RenderFoundation } from '../../../../metaData'; +import { TrackerProgram, RenderFoundation, ProgramStage } from '../../../../metaData'; import { startRunRulesPostUpdateField } from '../../../DataEntry'; import { startRunRulesOnUpdateForNewEnrollment } from './enrollment.actions'; @@ -18,25 +18,42 @@ export const batchActionTypes = { UPDATE_DATA_ENTRY_FIELD_NEW_ENROLLMENT_ACTION_BATCH: 'UpdateDataEntryFieldNewEnrollmentActionBatch', }; -export const runRulesOnUpdateFieldBatch = ( +export const runRulesOnUpdateFieldBatch = ({ + program, + formId, + dataEntryId, + itemId, + orgUnit, + enrollmentData, + attributeValues, + extraActions = [], + uid, + stage, + formFoundation, + currentEvent, +}: { program: TrackerProgram, - foundation: RenderFoundation, formId: string, dataEntryId: string, itemId: string, orgUnit: OrgUnit, enrollmentData?: Enrollment, attributeValues?: TEIValues, - extraActions: Array> = [], + extraActions: Array>, uid: string, -) => { + stage?: ProgramStage, + formFoundation?: RenderFoundation, + currentEvent?: {[id: string]: any}, +}) => { const effects = getApplicableRuleEffectsForTrackerProgram({ program, + stage, orgUnit, + currentEvent, enrollmentData, attributeValues, + formFoundation, }); - return batchActions([ updateRulesEffects(effects, formId), rulesExecutedPostUpdateField(dataEntryId, itemId, uid), @@ -48,6 +65,8 @@ export const updateDataEntryFieldBatch = ( innerAction: ReduxAction, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => { const { dataEntryId, itemId } = innerAction.payload; const uid = uuid(); @@ -55,7 +74,7 @@ export const updateDataEntryFieldBatch = ( return batchActions([ innerAction, startRunRulesPostUpdateField(dataEntryId, itemId, uid), - startRunRulesOnUpdateForNewEnrollment(innerAction.payload, uid, programId, orgUnit), + startRunRulesOnUpdateForNewEnrollment(innerAction.payload, uid, programId, orgUnit, stage, formFoundation), ], batchActionTypes.UPDATE_DATA_ENTRY_FIELD_NEW_ENROLLMENT_ACTION_BATCH); }; @@ -63,6 +82,8 @@ export const updateFieldBatch = ( innerAction: ReduxAction, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => { const { dataEntryId, itemId } = innerAction.payload; const uid = uuid(); @@ -70,7 +91,7 @@ export const updateFieldBatch = ( return batchActions([ innerAction, startRunRulesPostUpdateField(dataEntryId, itemId, uid), - startRunRulesOnUpdateForNewEnrollment(innerAction.payload, uid, programId, orgUnit), + startRunRulesOnUpdateForNewEnrollment(innerAction.payload, uid, programId, orgUnit, stage, formFoundation), ], batchActionTypes.UPDATE_FIELD_NEW_ENROLLMENT_ACTION_BATCH); }; @@ -80,12 +101,14 @@ export const asyncUpdateSuccessBatch = ( itemId: string, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => { const uid = uuid(); return batchActions([ innerAction, startRunRulesPostUpdateField(dataEntryId, itemId, uid), - startRunRulesOnUpdateForNewEnrollment({ ...innerAction.payload, dataEntryId, itemId }, uid, programId, orgUnit), + startRunRulesOnUpdateForNewEnrollment({ ...innerAction.payload, dataEntryId, itemId }, uid, programId, orgUnit, stage, formFoundation), ], batchActionTypes.UPDATE_FIELD_NEW_ENROLLMENT_ACTION_BATCH); }; diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actions.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actions.js index b259a5821c..68d8a8cb7e 100644 --- a/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actions.js +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/enrollment.actions.js @@ -1,6 +1,7 @@ // @flow import type { OrgUnit } from '@dhis2/rules-engine-javascript'; import { actionCreator, actionPayloadAppender } from '../../../../actions/actions.utils'; +import { ProgramStage, RenderFoundation } from '../../../../metaData'; export const actionTypes = { START_RUN_RULES_ON_UPDATE: 'StartRunRulesOnUpdateForNewEnrollment', @@ -11,9 +12,11 @@ export const startRunRulesOnUpdateForNewEnrollment = ( uid: string, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, ) => actionCreator(actionTypes.START_RUN_RULES_ON_UPDATE)( - { innerPayload: payload, uid, programId, orgUnit }); + { innerPayload: payload, uid, programId, orgUnit, stage, formFoundation }); export const startAsyncUpdateFieldForNewEnrollment = ( innerAction: ReduxAction, diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/open.actionBatchs.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/open.actionBatchs.js index f83897ebfa..2507d1c474 100644 --- a/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/open.actionBatchs.js +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/actions/open.actionBatchs.js @@ -2,21 +2,26 @@ import { batchActions } from 'redux-batched-actions'; import type { OrgUnit } from '@dhis2/rules-engine-javascript'; import { getApplicableRuleEffectsForTrackerProgram, updateRulesEffects } from '../../../../rules'; -import type { TrackerProgram } from '../../../../metaData'; +import type { ProgramStage, TrackerProgram, RenderFoundation } from '../../../../metaData'; import { getDataEntryKey } from '../../../DataEntry/common/getDataEntryKey'; import { loadNewDataEntry } from '../../../DataEntry/actions/dataEntryLoadNew.actions'; import { openDataEntryForNewEnrollment } from './open.actions'; -import { getEnrollmentDateValidatorContainer, getIncidentDateValidatorContainer, getCategoryOptionsValidatorContainers } from '../fieldValidators'; +import { + getEnrollmentDateValidatorContainer, + getIncidentDateValidatorContainer, + getCategoryOptionsValidatorContainers, +} from '../fieldValidators'; import { convertGeometryOut } from '../../converters'; import { convertDateObjectToDateFormatString } from '../../../../utils/converters/date'; import { addFormData } from '../../../D2Form/actions/form.actions'; import type { ProgramCategory } from '../../../WidgetEventSchedule/CategoryOptions/CategoryOptions.types'; +import { getDataEntryPropsToInclude } from '../EnrollmentWithFirstStageDataEntry'; const itemId = 'newEnrollment'; type DataEntryPropsToInclude = Array; -const dataEntryPropsToInclude: DataEntryPropsToInclude = [ +const enrollmentDataEntryPropsToInclude: DataEntryPropsToInclude = [ { id: 'enrolledAt', type: 'DATE', @@ -48,7 +53,9 @@ export const openDataEntryForNewEnrollmentBatchAsync = async ({ extraDataEntryProps = [], formValues, clientValues, + firstStage, programCategory, + formFoundation, }: { program: TrackerProgram, orgUnit: OrgUnit, @@ -57,30 +64,39 @@ export const openDataEntryForNewEnrollmentBatchAsync = async ({ extraDataEntryProps?: Array, formValues: { [key: string]: any }, clientValues: { [key: string]: any }, + firstStage?: ProgramStage, programCategory?: ProgramCategory, + formFoundation: RenderFoundation, }) => { const formId = getDataEntryKey(dataEntryId, itemId); - - if (programCategory && programCategory.categories) { - dataEntryPropsToInclude.push(...programCategory.categories.map(category => ({ + const addFormDataActions = addFormData(`${dataEntryId}-${itemId}`, formValues); + const firstStageDataEntryPropsToInclude = firstStage && getDataEntryPropsToInclude(firstStage.stageForm); + const dataEntryPropsToInclude = [ + ...enrollmentDataEntryPropsToInclude, + ...extraDataEntryProps, + ...(firstStageDataEntryPropsToInclude || []), + ...(programCategory && programCategory.categories ? programCategory.categories.map(category => ({ id: `attributeCategoryOptions-${category.id}`, type: 'TEXT', - validatorContainers: getCategoryOptionsValidatorContainers({ categories: programCategory.categories }, category.id), - }))); - } + validatorContainers: + getCategoryOptionsValidatorContainers({ categories: programCategory.categories }, category.id), + })) : []), + ]; + const dataEntryActions = loadNewDataEntry( dataEntryId, itemId, - [...dataEntryPropsToInclude, ...extraDataEntryProps], + dataEntryPropsToInclude, { enrolledAt: convertDateObjectToDateFormatString(new Date()) }, ); - const addFormDataActions = addFormData(`${dataEntryId}-${itemId}`, formValues); const effects = getApplicableRuleEffectsForTrackerProgram({ program, orgUnit, + stage: firstStage, attributeValues: clientValues, + formFoundation, }); return batchActions([ diff --git a/src/core_modules/capture-core/components/DataEntries/Enrollment/epics/enrollment.epics.js b/src/core_modules/capture-core/components/DataEntries/Enrollment/epics/enrollment.epics.js index f5b11285e8..9bc4da634a 100644 --- a/src/core_modules/capture-core/components/DataEntries/Enrollment/epics/enrollment.epics.js +++ b/src/core_modules/capture-core/components/DataEntries/Enrollment/epics/enrollment.epics.js @@ -4,9 +4,11 @@ import { ofType } from 'redux-observable'; import { map } from 'rxjs/operators'; import { batchActionTypes, runRulesOnUpdateFieldBatch } from '../actions/enrollment.actionBatchs'; import { actionTypes } from '../actions/enrollment.actions'; -import { getTrackerProgramThrowIfNotFound } from '../../../../metaData'; -import { getCurrentClientValues, getCurrentClientMainData, type FieldData } from '../../../../rules'; +import { getTrackerProgramThrowIfNotFound, ProgramStage, RenderFoundation, Section } from '../../../../metaData'; +import { getCurrentClientMainData, type FieldData } from '../../../../rules'; import { getDataEntryKey } from '../../../DataEntry/common/getDataEntryKey'; +import { convertFormToClient } from '../../../../converters'; +import { stageMainDataIds, convertToRulesEngineIds } from '../EnrollmentWithFirstStageDataEntry'; type Context = { dataEntryId: string, @@ -14,31 +16,59 @@ type Context = { uid: string, programId: string, orgUnit: OrgUnit, + stage?: ProgramStage, + formFoundation: RenderFoundation, } +const splitCurrentClientMainData = (stage, currentClientMainData) => { + if (!stage) { + return { currentEnrollmentValues: currentClientMainData, currentEventMainData: {} }; + } + return Object.keys(currentClientMainData).reduce((acc, id) => { + const stageMainDataId = Object.keys(stageMainDataIds).find(key => stageMainDataIds[key] === id); + if (stageMainDataId) { + acc.currentEventMainData = { + ...acc.currentEventMainData, + [convertToRulesEngineIds(stageMainDataId)]: currentClientMainData[id], + }; + } else { + acc.currentEnrollmentValues = { ...acc.currentEnrollmentValues, [id]: currentClientMainData[id] }; + } + return acc; + }, { currentEnrollmentValues: {}, currentEventMainData: {} }); +}; + const runRulesOnEnrollmentUpdate = (store: ReduxStore, context: Context, fieldData?: ?FieldData, searchActions?: any = []) => { const state = store.value; - const { programId, dataEntryId, itemId, orgUnit, uid } = context; + const { programId, dataEntryId, itemId, orgUnit, uid, stage, formFoundation } = context; const formId = getDataEntryKey(dataEntryId, itemId); const program = getTrackerProgramThrowIfNotFound(programId); - const foundation = program.enrollment.enrollmentForm; - const currentTEIValues = getCurrentClientValues(state, foundation, formId, fieldData); - const currentEnrollmentValues = - getCurrentClientMainData(state, itemId, dataEntryId, foundation); + const currentFormData = state.formsValues[formId] || {}; + const convertedValues = formFoundation.convertAndGroupBySection(currentFormData, convertFormToClient); + const attributeValues = convertedValues[Section.groups.ENROLLMENT]; + const currentEventValues = convertedValues[Section.groups.EVENT] || {}; + const currentClientMainData = + getCurrentClientMainData(state, itemId, dataEntryId, formFoundation) || {}; + const { currentEnrollmentValues, currentEventMainData } + = splitCurrentClientMainData(state, currentClientMainData); + const currentEvent = stage + ? { ...currentEventValues, ...currentEventMainData, programStageId: stage.id } : undefined; - return runRulesOnUpdateFieldBatch( + return runRulesOnUpdateFieldBatch({ program, - foundation, formId, dataEntryId, itemId, orgUnit, - currentEnrollmentValues, - currentTEIValues ?? undefined, - searchActions, + enrollmentData: currentEnrollmentValues, + attributeValues, + currentEvent, + extraActions: searchActions, uid, - ); + stage, + formFoundation: stage ? formFoundation : undefined, + }); }; @@ -53,6 +83,8 @@ export const runRulesOnEnrollmentDataEntryFieldUpdateEpic = (action$: InputObser programId, orgUnit, innerPayload, + stage, + formFoundation, } = action.payload; const { @@ -66,6 +98,8 @@ export const runRulesOnEnrollmentDataEntryFieldUpdateEpic = (action$: InputObser uid, programId, orgUnit, + stage, + formFoundation, }); })); @@ -75,7 +109,7 @@ export const runRulesOnEnrollmentFieldUpdateEpic = (action$: InputObservable, st map(actionBatch => actionBatch.payload.find(action => action.type === actionTypes.START_RUN_RULES_ON_UPDATE)), map((action) => { - const { innerPayload: payload, searchActions, uid, programId, orgUnit } = action.payload; + const { innerPayload: payload, searchActions, uid, programId, orgUnit, stage, formFoundation } = action.payload; const { dataEntryId, itemId, elementId, value, uiState } = payload; const fieldData: FieldData = { @@ -90,6 +124,8 @@ export const runRulesOnEnrollmentFieldUpdateEpic = (action$: InputObservable, st dataEntryId, itemId, uid, + stage, + formFoundation, }, fieldData, searchActions); }), ); diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.actions.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.actions.js index 4e74581537..2a54784b45 100644 --- a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.actions.js +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.actions.js @@ -5,6 +5,23 @@ export const enrollmentRegistrationEntryActionTypes = { TRACKER_PROGRAM_REGISTRATION_ENTRY_INITIALISATION_START: 'StartInitForEnrollmentRegistrationForm', }; -export const startNewEnrollmentDataEntryInitialisation = ({ selectedOrgUnit, selectedScopeId, dataEntryId, formValues, clientValues, programCategory }: Object) => - actionCreator(enrollmentRegistrationEntryActionTypes.TRACKER_PROGRAM_REGISTRATION_ENTRY_INITIALISATION_START)({ selectedOrgUnit, selectedScopeId, dataEntryId, formValues, clientValues, programCategory }); - +export const startNewEnrollmentDataEntryInitialisation = ({ + selectedOrgUnit, + selectedScopeId, + dataEntryId, + formValues, + clientValues, + programCategory, + firstStage, + formFoundation, +}: Object) => + actionCreator(enrollmentRegistrationEntryActionTypes.TRACKER_PROGRAM_REGISTRATION_ENTRY_INITIALISATION_START)({ + selectedOrgUnit, + selectedScopeId, + dataEntryId, + formValues, + clientValues, + programCategory, + firstStage, + formFoundation, + }); diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.container.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.container.js index 6d624541be..623a16abce 100644 --- a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.container.js +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.container.js @@ -8,23 +8,26 @@ import { useLifecycle } from './hooks'; import { useCurrentOrgUnitInfo } from '../../../hooks/useCurrentOrgUnitInfo'; import { useRulesEngineOrgUnit } from '../../../hooks'; import { dataEntryHasChanges } from '../../DataEntry/common/dataEntryHasChanges'; -import { useMetadataForRegistrationForm } from '../common/TEIAndEnrollment/useMetadataForRegistrationForm'; export const EnrollmentRegistrationEntry: ComponentType = ({ selectedScopeId, id, saveButtonText, trackedEntityInstanceAttributes, + onSave, ...passOnProps }) => { const orgUnitId = useCurrentOrgUnitInfo().id; const { orgUnit, error } = useRulesEngineOrgUnit(orgUnitId); - const { teiId, ready, skipDuplicateCheck } = useLifecycle(selectedScopeId, id, trackedEntityInstanceAttributes, orgUnit); const { + teiId, + ready, + skipDuplicateCheck, + firstStageMetaData, formId, - registrationMetaData: enrollmentMetadata, + enrollmentMetadata, formFoundation, - } = useMetadataForRegistrationForm({ selectedScopeId }); + } = useLifecycle(selectedScopeId, id, trackedEntityInstanceAttributes, orgUnit); const isUserInteractionInProgress: boolean = useSelector( state => @@ -35,7 +38,6 @@ export const EnrollmentRegistrationEntry: ComponentType = ({ ); const trackedEntityTypeNameLC = enrollmentMetadata?.trackedEntityType?.name.toLocaleLowerCase() ?? ''; - const isSavingInProgress = useSelector(({ possibleDuplicates, newPage }) => possibleDuplicates.isLoading || possibleDuplicates.isUpdating || !!newPage.uid); @@ -46,6 +48,7 @@ export const EnrollmentRegistrationEntry: ComponentType = ({ return ( = ({ orgUnit={orgUnit} isUserInteractionInProgress={isUserInteractionInProgress} isSavingInProgress={isSavingInProgress} + onSave={() => onSave(formFoundation, firstStageMetaData)} /> ); }; diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.epics.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.epics.js index 5737a4988b..44e25f9bc4 100644 --- a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.epics.js +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.epics.js @@ -15,7 +15,16 @@ export const startNewEnrollmentDataEntrySelfInitialisationEpic = (action$: Input action$.pipe( ofType(enrollmentRegistrationEntryActionTypes.TRACKER_PROGRAM_REGISTRATION_ENTRY_INITIALISATION_START), pluck('payload'), - switchMap(({ selectedOrgUnit, selectedScopeId: programId, dataEntryId, formValues, clientValues, programCategory }) => { + switchMap(({ + selectedOrgUnit, + selectedScopeId: programId, + dataEntryId, + formValues, + clientValues, + programCategory, + firstStage, + formFoundation, + }) => { if (selectedOrgUnit) { let trackerProgram: ?TrackerProgram; try { @@ -33,7 +42,9 @@ export const startNewEnrollmentDataEntrySelfInitialisationEpic = (action$: Input dataEntryId, formValues, clientValues, + firstStage, programCategory, + formFoundation, }); return from(openEnrollmentPromise); diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.types.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.types.js index 463fbecc06..f1924c00b3 100644 --- a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.types.js +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/EnrollmentRegistrationEntry.types.js @@ -6,7 +6,7 @@ import type { RenderCustomCardActions } from '../../CardList'; import type { SaveForDuplicateCheck } from '../common/TEIAndEnrollment/DuplicateCheckOnSave'; import type { ExistingUniqueValueDialogActionsComponent } from '../withErrorMessagePostProcessor'; import type { InputAttribute } from './hooks/useFormValues'; -import { RenderFoundation } from '../../../metaData'; +import { RenderFoundation, ProgramStage } from '../../../metaData'; export type OwnProps = $ReadOnly<{| id: string, @@ -21,6 +21,7 @@ export type OwnProps = $ReadOnly<{| skipDuplicateCheck?: ?boolean, trackedEntityInstanceAttributes?: Array, saveButtonText: (trackedEntityName: string) => string, + firstStageMetaData?: ?{ stage: ?ProgramStage }, |}>; type ContainerProps = {| diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useBuildFirstStageRegistration.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useBuildFirstStageRegistration.js new file mode 100644 index 0000000000..4bd04e8f62 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useBuildFirstStageRegistration.js @@ -0,0 +1,32 @@ +// @flow +import { useMemo } from 'react'; +import { getProgramAndStageForProgram } from '../../../../metaData'; +import { useProgramFromIndexedDB } from '../../../../utils/cachedDataHooks/useProgramFromIndexedDB'; + +export const useBuildFirstStageRegistration = (programId: string, skip: boolean = false) => { + const { program, isLoading } = useProgramFromIndexedDB(programId, { enabled: !skip }); + + const firstStage = useMemo(() => { + if (!isLoading && program?.useFirstStageDuringRegistration) { + const { programStages } = program; + const programStagesWithAccess = programStages + .filter((stage) => { + const access = { + read: stage.access.data.read, + write: stage.access.data.write, + }; + return access.write; + }) + .sort((a, b) => a.sortOrder - b.sortOrder); + return programStagesWithAccess[0]?.id; + } + return null; + }, [program, isLoading]); + + const firstStageMetaData = useMemo( + () => (firstStage && programId ? getProgramAndStageForProgram(programId, firstStage) : null), + [firstStage, programId], + ); + + return { loading: isLoading, firstStageMetaData }; +}; diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useLifecycle.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useLifecycle.js index a7b645c87c..0c4a280bf6 100644 --- a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useLifecycle.js +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useLifecycle.js @@ -8,8 +8,10 @@ import { useLocationQuery } from '../../../../utils/routing'; import { useScopeInfo } from '../../../../hooks/useScopeInfo'; import { useFormValues } from './index'; import type { InputAttribute } from './useFormValues'; +import { useBuildFirstStageRegistration } from './useBuildFirstStageRegistration'; import { useMetadataForRegistrationForm } from '../../common/TEIAndEnrollment/useMetadataForRegistrationForm'; import { useCategoryCombinations } from '../../../DataEntryDhis2Helpers/AOC/useCategoryCombinations'; +import { useMergeFormFoundationsIfApplicable } from './useMergeFormFoundationsIfApplicable'; export const useLifecycle = ( selectedScopeId: string, @@ -24,7 +26,14 @@ export const useLifecycle = ( const ready = useSelector(({ dataEntries }) => !!dataEntries[dataEntryId]) && !!orgUnit; const searchTerms = useSelector(({ searchDomain }) => searchDomain.currentSearchInfo.currentSearchTerms); const { scopeType } = useScopeInfo(selectedScopeId); - const { formFoundation } = useMetadataForRegistrationForm({ selectedScopeId }); + const { firstStageMetaData } = useBuildFirstStageRegistration(programId, scopeType !== scopeTypes.TRACKER_PROGRAM); + const { + formId, + registrationMetaData: enrollmentMetadata, + formFoundation: enrollmentFormFoundation, + } = useMetadataForRegistrationForm({ selectedScopeId }); + + const { formFoundation } = useMergeFormFoundationsIfApplicable(enrollmentFormFoundation, firstStageMetaData); const { programCategory } = useCategoryCombinations(programId, scopeType !== scopeTypes.TRACKER_PROGRAM); const { formValues, clientValues, formValuesReadyRef } = useFormValues({ program, @@ -43,7 +52,8 @@ export const useLifecycle = ( dataEntryReadyRef.current === false && formValuesReadyRef.current === true && orgUnit && - scopeType === scopeTypes.TRACKER_PROGRAM + scopeType === scopeTypes.TRACKER_PROGRAM && + formFoundation ) { dataEntryReadyRef.current = true; dispatch( @@ -54,10 +64,32 @@ export const useLifecycle = ( formValues, clientValues, programCategory, + firstStage: firstStageMetaData?.stage, + formFoundation, }), ); } - }, [scopeType, dataEntryId, selectedScopeId, orgUnit, formValuesReadyRef, formValues, clientValues, programCategory, dispatch]); + }, [ + formFoundation, + scopeType, + dataEntryId, + selectedScopeId, + orgUnit, + formValuesReadyRef, + formValues, + clientValues, + programCategory, + firstStageMetaData, + dispatch, + ]); - return { teiId, ready, skipDuplicateCheck: !!teiId }; + return { + teiId, + ready, + skipDuplicateCheck: !!teiId, + firstStageMetaData, + formId, + enrollmentMetadata, + formFoundation, + }; }; diff --git a/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useMergeFormFoundationsIfApplicable.js b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useMergeFormFoundationsIfApplicable.js new file mode 100644 index 0000000000..77235be403 --- /dev/null +++ b/src/core_modules/capture-core/components/DataEntries/EnrollmentRegistrationEntry/hooks/useMergeFormFoundationsIfApplicable.js @@ -0,0 +1,72 @@ +// @flow +import { useMemo } from 'react'; +import i18n from '@dhis2/d2-i18n'; +import { RenderFoundation, Section, ProgramStage } from '../../../../metaData'; + +const addElements = (section, newSection) => + Array.from(section.elements.entries()) + .map(entry => entry[1]) + .forEach((element) => { + // $FlowFixMe[prop-missing] section is missing in FormFieldPluginConfig + element.section = newSection; + newSection.addElement(element); + }); + +const getSectionId = sectionId => + (sectionId === Section.MAIN_SECTION_ID ? `${Section.MAIN_SECTION_ID}-stage` : sectionId); + +export const useMergeFormFoundationsIfApplicable = ( + enrollmentFormFoundation?: ?RenderFoundation, + firstStageMetaData?: ?{ stage: ?ProgramStage }, +) => { + const enrollmentSectionsSize = enrollmentFormFoundation?.sections.size; + + return useMemo(() => { + const firstStageFormFoundation = firstStageMetaData?.stage?.stageForm; + if (!enrollmentFormFoundation) { + return { formFoundation: null }; + } + + if (!firstStageFormFoundation || enrollmentSectionsSize === 0) { + return { formFoundation: enrollmentFormFoundation }; + } + + const stageName = firstStageMetaData?.stage?.name; + const { id, name, access, description, featureType, validationStrategy } = enrollmentFormFoundation; + const renderFoundation = new RenderFoundation((o) => { + o.id = id; + o.name = name; + o.access = access; + o.description = description; + o.featureType = featureType; + o.validationStrategy = validationStrategy; + }); + + enrollmentFormFoundation.sections.forEach(section => renderFoundation.addSection(section)); + + firstStageFormFoundation.sections.forEach((section) => { + const isMainSection = section.id === Section.MAIN_SECTION_ID; + const newSection = new Section((o) => { + o.id = getSectionId(section.id); + o.name = isMainSection + ? i18n.t('{{ stageName }} - Details', { + stageName, + }) + : i18n.t('{{ stageName }} - {{ sectionName }}', { + stageName, + sectionName: section.name, + }); + o.group = Section.groups.EVENT; + o.customForm = section.customForm; + o.showContainer = section.showContainer; + o.open = section.open; + o.visible = section.visible; + o.displayDescription = section.displayDescription; + }); + addElements(section, newSection); + renderFoundation.addSection(newSection); + }); + + return { formFoundation: renderFoundation }; + }, [enrollmentFormFoundation, firstStageMetaData, enrollmentSectionsSize]); +}; diff --git a/src/core_modules/capture-core/components/DataEntries/common/TEIAndEnrollment/DuplicateCheckOnSave/types/duplicateCheckOnSave.types.js b/src/core_modules/capture-core/components/DataEntries/common/TEIAndEnrollment/DuplicateCheckOnSave/types/duplicateCheckOnSave.types.js index 83ab589551..a727db9ec2 100644 --- a/src/core_modules/capture-core/components/DataEntries/common/TEIAndEnrollment/DuplicateCheckOnSave/types/duplicateCheckOnSave.types.js +++ b/src/core_modules/capture-core/components/DataEntries/common/TEIAndEnrollment/DuplicateCheckOnSave/types/duplicateCheckOnSave.types.js @@ -1,3 +1,7 @@ // @flow +import { ProgramStage, RenderFoundation } from '../../../../../../metaData'; -export type SaveForDuplicateCheck = () => void; +export type SaveForDuplicateCheck = ( + formFoundation?: RenderFoundation, + firstStageMetaData?: { stage: ProgramStage }, +) => void; diff --git a/src/core_modules/capture-core/components/DataEntries/converters/converters.js b/src/core_modules/capture-core/components/DataEntries/converters/converters.js index 64b17bc514..a0efa43b3a 100644 --- a/src/core_modules/capture-core/components/DataEntries/converters/converters.js +++ b/src/core_modules/capture-core/components/DataEntries/converters/converters.js @@ -1,14 +1,15 @@ // @flow import type { RenderFoundation } from '../../../metaData'; -export function convertGeometryOut(dataEntryValue: any, foundation: RenderFoundation) { - if (!dataEntryValue || !['Polygon', 'Point'].includes(foundation.featureType)) return null; +export function convertGeometryOut(dataEntryValue: any, foundation: RenderFoundation, customFeatureType: string) { + const featureType = customFeatureType || foundation.featureType; + if (!dataEntryValue || !['Polygon', 'Point'].includes(featureType)) return null; let coordinates = dataEntryValue; - if (foundation.featureType === 'Point') { + if (featureType === 'Point') { coordinates = [dataEntryValue.longitude, dataEntryValue.latitude]; } return { - type: foundation.featureType, + type: featureType, coordinates, }; } diff --git a/src/core_modules/capture-core/components/DataEntry/DataEntry.component.js b/src/core_modules/capture-core/components/DataEntry/DataEntry.component.js index b554fb3b2b..c0c818c491 100644 --- a/src/core_modules/capture-core/components/DataEntry/DataEntry.component.js +++ b/src/core_modules/capture-core/components/DataEntry/DataEntry.component.js @@ -10,7 +10,7 @@ import { getDataEntryKey } from './common/getDataEntryKey'; import { StickyOnScroll } from '../Sticky/StickyOnScroll.component'; import { Section } from '../Section/Section.component'; import { SectionHeaderSimple } from '../Section/SectionHeaderSimple.component'; -import { FieldSection } from './FieldSection.component'; +import { Field } from './Field.component'; const styles = theme => ({ loadingContainer: { @@ -69,11 +69,17 @@ const styles = theme => ({ verticalOutputsContainer: { marginBottom: theme.typography.pxToRem(10), }, - dataEntryFieldSectionContainer: { + dataEntrySectionContainer: { marginBottom: spacers.dp16, }, }); +type DataEntrySection = { + placement: $Values, + name: string, + beforeSectionId?: string +}; + type FieldContainer = { field: React.Element, placement: $Values, @@ -120,7 +126,7 @@ type Props = { dataEntryId: string, itemId: string, ) => void, - dataEntrySections?: { [string]: {name: string, placement: $Values}}, + dataEntrySections?: { [string]: DataEntrySection }, dataEntryFieldRef: any, onAddNote?: ?Function, onOpenAddRelationship?: ?Function, @@ -159,22 +165,34 @@ class DataEntryPlain extends React.Component { }; } + hasPlacement = ( + dataEntrySection: DataEntrySection, + placement: $Values, + beforeSectionId?: string, + ) => + dataEntrySection.placement === placement && + (dataEntrySection.placement !== placements.BEFORE_METADATA_BASED_SECTION || + (dataEntrySection.placement === placements.BEFORE_METADATA_BASED_SECTION && + dataEntrySection.beforeSectionId === beforeSectionId + ) + ); + handleUpdateFieldAsync = (...args) => { this.props.onUpdateFormFieldAsync(...args, this.props.id, this.props.itemId); } - getFieldSectionsWithPlacement(placement: $Values) { + getSectionsWithPlacement(placement: $Values, beforeSectionId?: string) { const fields = this.props.fields || []; const sections = this.props.dataEntrySections || {}; return this.props.dataEntrySections ? Object.keys(this.props.dataEntrySections).reduce((accSections, sectionKey) => { const section = sections[sectionKey]; - if (section.placement === placement) { + if (this.hasPlacement(section, placement, beforeSectionId)) { const sectionFields = fields .filter(fieldContainer => fieldContainer.section === sectionKey); const sectionFieldsContainer = sectionFields.map((fieldContainer, index, array) => ( - { accSections.push(
{ : []; } - renderDataEntryFieldsByPlacement = (placement: $Values) => { + renderDataEntryFieldsByPlacement = (placement: $Values, beforeSectionId?: string) => { const fields = this.props.fields || []; const fieldFilter = this.props.formHorizontal ? fieldHorizontalFilter(placement) : fieldVerticalFilter(placement); const fieldsByPlacement = fields ? fields .filter(fieldFilter) - .map((fieldContainer, index, array) => ( ( { : []; if (!this.props.formHorizontal) { - return [...fieldsByPlacement, ...this.getFieldSectionsWithPlacement(placement)]; + return [...fieldsByPlacement, ...this.getSectionsWithPlacement(placement, beforeSectionId)]; } return fieldsByPlacement; } @@ -258,6 +276,9 @@ class DataEntryPlain extends React.Component { validationAttempted={completionAttempted || saveAttempted} onUpdateField={this.handleUpdateField} onUpdateFieldAsync={this.handleUpdateFieldAsync} + getCustomContent={beforeSectionId => ( + this.renderDataEntryFieldsByPlacement(placements.BEFORE_METADATA_BASED_SECTION, beforeSectionId) + )} {...passOnProps} /> ); diff --git a/src/core_modules/capture-core/components/DataEntry/FieldSection.component.js b/src/core_modules/capture-core/components/DataEntry/Field.component.js similarity index 91% rename from src/core_modules/capture-core/components/DataEntry/FieldSection.component.js rename to src/core_modules/capture-core/components/DataEntry/Field.component.js index a67eb08b33..d53831c878 100644 --- a/src/core_modules/capture-core/components/DataEntry/FieldSection.component.js +++ b/src/core_modules/capture-core/components/DataEntry/Field.component.js @@ -24,7 +24,7 @@ type Props = { ...CssClasses } -const FieldSectionPlain = (props: Props) => { +const FieldPlain = (props: Props) => { const { formHorizontal, index, fieldContainer, total, classes } = props; const className = !formHorizontal ? index % 2 !== 0 && classes.evenNumbers : null; @@ -44,4 +44,4 @@ const FieldSectionPlain = (props: Props) => { ); }; -export const FieldSection = withStyles(styles)(FieldSectionPlain); +export const Field = withStyles(styles)(FieldPlain); diff --git a/src/core_modules/capture-core/components/DataEntry/actions/dataEntryLoad.utils.js b/src/core_modules/capture-core/components/DataEntry/actions/dataEntryLoad.utils.js index 5fb8fccaec..88e7bb9208 100644 --- a/src/core_modules/capture-core/components/DataEntry/actions/dataEntryLoad.utils.js +++ b/src/core_modules/capture-core/components/DataEntry/actions/dataEntryLoad.utils.js @@ -17,7 +17,8 @@ type DataEntryPropToIncludeSpecial = {| clientId: string, dataEntryId: string, onConvertIn: (value: any) => any, - onConvertOut: (dataEntryValue: any, prevValue: any, foundation: RenderFoundation) => any, + onConvertOut: (dataEntryValue: any, foundation: RenderFoundation, customFeatureType: string) => any, + featureType?: string, validatorContainers?: ?Array, |}; @@ -30,7 +31,11 @@ export function getDataEntryMeta(dataEntryPropsToInclude: Array { const error = useSelector(({ activePage }) => activePage.viewEventLoadError?.error); const { loading, event } = useEvent(eventId); const { program: programId, programStage: stageId, trackedEntity: teiId, enrollment: enrollmentId } = event; - const { orgUnitId, eventId: urlEventId } = useLocationQuery(); + const { orgUnitId, eventId: urlEventId, initMode } = useLocationQuery(); useEffect(() => { if (!urlEventId) { @@ -73,11 +73,20 @@ export const EnrollmentEditEventPage = () => { orgUnitId={orgUnitId} eventId={eventId} error={error} + initMode={initMode} /> ) : ; }; -const EnrollmentEditEventPageWithContextPlain = ({ programId, stageId, teiId, enrollmentId, orgUnitId, eventId }: Props) => { +const EnrollmentEditEventPageWithContextPlain = ({ + programId, + stageId, + teiId, + enrollmentId, + orgUnitId, + eventId, + initMode, +}: Props) => { const history = useHistory(); const dispatch = useDispatch(); @@ -98,9 +107,14 @@ const EnrollmentEditEventPageWithContextPlain = ({ programId, stageId, teiId, en const onAddNew = () => { history.push(`/new?${buildUrlQueryString({ programId, orgUnitId, teiId })}`); }; - const onCancelEditEvent = () => { - history.push(`/enrollment?${buildUrlQueryString({ enrollmentId })}`); - }; + const onCancelEditEvent = useCallback((isScheduled: boolean) => { + if (isScheduled) { + history.push(`/enrollment?${buildUrlQueryString({ enrollmentId })}`); + } + if (initMode) { + history.push(`/enrollmentEventEdit?${buildUrlQueryString({ eventId, orgUnitId })}`); + } + }, [initMode, enrollmentId, eventId, orgUnitId, history]); const onGoBack = () => history.push(`/enrollment?${buildUrlQueryString({ enrollmentId })}`); diff --git a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.types.js b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.types.js index 59ff58c190..8e16b09325 100644 --- a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.types.js +++ b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.types.js @@ -21,7 +21,7 @@ export type PlainProps = {| onGoBack: () => void, onEnrollmentError: (message: string) => void, onEnrollmentSuccess: () => void, - onCancelEditEvent: () => void, + onCancelEditEvent: (isScheduled: boolean) => void, onHandleScheduleSave: (eventData: Object) => void, pageStatus: string, eventStatus?: string, @@ -35,4 +35,5 @@ export type Props = {| enrollmentId: string, orgUnitId: string, eventId: string, + initMode?: string, |}; diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.actions.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.actions.js index 74753cb8b0..e716f71741 100644 --- a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.actions.js +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.actions.js @@ -1,5 +1,5 @@ // @flow -import type { RenderFoundation } from '../../../../metaData'; +import type { ProgramStage, RenderFoundation } from '../../../../metaData'; import { actionCreator } from '../../../../actions/actions.utils'; import { effectMethods } from '../../../../trackerOffline'; @@ -41,23 +41,26 @@ export const saveNewTrackedEntityInstance = (candidateForRegistration: any) => ); // with enrollment -export const startSavingNewTrackedEntityInstanceWithEnrollment = (formFoundation: RenderFoundation, teiId: string, uid: string) => +export const startSavingNewTrackedEntityInstanceWithEnrollment = (formFoundation: RenderFoundation, teiId: string, uid: string, firstStage?: ProgramStage) => actionCreator(registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_START)({ formFoundation, teiId, + firstStage, uid, }); export const saveNewTrackedEntityInstanceWithEnrollment = ({ candidateForRegistration, - redirectToEnrollmentEventNew, + redirectTo, uid, stageId, + eventIndex, }: { candidateForRegistration: any, - redirectToEnrollmentEventNew: boolean, + redirectTo: string, uid: string, stageId?: string, + eventIndex: number, }) => actionCreator(registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE)( { ...candidateForRegistration }, @@ -70,7 +73,7 @@ export const saveNewTrackedEntityInstanceWithEnrollment = ({ }, commit: { type: registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_COMPLETED, - meta: { redirectToEnrollmentEventNew, stageId, uid }, + meta: { redirectTo, stageId, uid, eventIndex }, }, rollback: { type: registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_FAILED, diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.component.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.component.js index 7a8cf76cc6..cf14636450 100644 --- a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.component.js +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.component.js @@ -179,7 +179,9 @@ const RegistrationDataEntryPlain = ({ onSaveWithEnrollment(formFoundation)} + onSave={(customFormFoundation, firstStageMetaData) => + onSaveWithEnrollment(customFormFoundation, firstStageMetaData?.stage) + } saveButtonText={(trackedEntityTypeNameLC: string) => i18n.t('Save {{trackedEntityTypeName}}', { trackedEntityTypeName: trackedEntityTypeNameLC, interpolation: { escapeValue: false }, diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.container.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.container.js index bdebbcb962..41f5a864d5 100644 --- a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.container.js +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.container.js @@ -30,9 +30,9 @@ export const RegistrationDataEntry: ComponentType = ({ [dispatch]); const dispatchOnSaveWithEnrollment = useCallback( - (formFoundation) => { + (formFoundation, firstStage) => { const uid = uuid(); - dispatch(startSavingNewTrackedEntityInstanceWithEnrollment(formFoundation, teiId, uid)); + dispatch(startSavingNewTrackedEntityInstanceWithEnrollment(formFoundation, teiId, uid, firstStage)); }, [dispatch, teiId]); diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.epics.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.epics.js index 7fab7c500f..004adb75f7 100644 --- a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.epics.js +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/RegistrationDataEntry.epics.js @@ -3,46 +3,30 @@ import { ofType } from 'redux-observable'; import { pipe } from 'capture-core-utils'; import { flatMap, map } from 'rxjs/operators'; import { of, EMPTY } from 'rxjs'; -import moment from 'moment'; +import { FEATURETYPE, dataEntryKeys } from 'capture-core/constants'; import { registrationFormActionTypes, saveNewTrackedEntityInstance, saveNewTrackedEntityInstanceWithEnrollment, } from './RegistrationDataEntry.actions'; -import { getTrackerProgramThrowIfNotFound, dataElementTypes } from '../../../../metaData'; +import { getTrackerProgramThrowIfNotFound, dataElementTypes, Section } from '../../../../metaData'; import { navigateToEnrollmentOverview, } from '../../../../actions/navigateToEnrollmentOverview/navigateToEnrollmentOverview.actions'; import { convertFormToClient, convertClientToServer } from '../../../../converters'; -import { FEATURETYPE } from '../../../../constants'; import { buildUrlQueryString, shouldUseNewDashboard } from '../../../../utils/routing'; -import { convertCategoryOptionsToServer } from '../../../../converters/clientToServer'; +import { + deriveAutoGenerateEvents, + deriveFirstStageDuringRegistrationEvent, + getStageWithOpenAfterEnrollment, + standardGeoJson, + PAGES, +} from './helpers'; const convertFn = pipe(convertFormToClient, convertClientToServer); const geometryType = formValuesKey => Object.values(FEATURETYPE).find(geometryKey => geometryKey === formValuesKey); -const standardGeoJson = (geometry) => { - if (!geometry) { - return undefined; - } - if (Array.isArray(geometry)) { - return { - type: 'Polygon', - coordinates: geometry, - }; - } else if (geometry.longitude && geometry.latitude) { - return { - type: 'Point', - coordinates: [geometry.longitude, geometry.latitude], - }; - } - return undefined; -}; - -const getStageWithOpenAfterEnrollment = stages => - [...stages.values()].find(({ openAfterEnrollment }) => openAfterEnrollment); - const deriveAttributesFromFormValues = (formValues = {}) => Object.keys(formValues) .filter(key => !geometryType(key)) @@ -53,64 +37,6 @@ const deriveGeometryFromFormValues = (formValues = {}) => .filter(key => geometryType(key)) .reduce((acc, currentKey) => (standardGeoJson(formValues[currentKey])), undefined); - -const deriveEvents = ({ - stages, - enrolledAt, - occurredAt, - programId, - orgUnitId, - redirectToEnrollmentEventNew, - redirectToStageId, - attributeCategoryOptions, -}) => { - // in case we have a program that does not have an incident date (occurredAt), such as Malaria case diagnosis, - // we want the incident to default to enrollmentDate (enrolledAt) - const sanitizedOccurredAt = occurredAt || enrolledAt; - return [...stages.values()] - .filter(({ id }) => (redirectToEnrollmentEventNew && id !== redirectToStageId) || !redirectToEnrollmentEventNew) - .filter(({ autoGenerateEvent }) => autoGenerateEvent) - .map(({ - id: programStage, - reportDateToUse: reportDateToUseInActiveStatus, - generatedByEnrollmentDate: generateScheduleDateByEnrollmentDate, - openAfterEnrollment, - minDaysFromStart, - }) => { - const dateToUseInActiveStatus = - reportDateToUseInActiveStatus === 'enrolledAt' ? enrolledAt : sanitizedOccurredAt; - const dateToUseInScheduleStatus = generateScheduleDateByEnrollmentDate ? enrolledAt : sanitizedOccurredAt; - const eventAttributeCategoryOptions = {}; - if (attributeCategoryOptions) { - eventAttributeCategoryOptions.attributeCategoryOptions = convertCategoryOptionsToServer(attributeCategoryOptions); - } - const eventInfo = - openAfterEnrollment - ? - { - status: 'ACTIVE', - occurredAt: convertFn(dateToUseInActiveStatus, dataElementTypes.DATE), - scheduledAt: convertFn(dateToUseInActiveStatus, dataElementTypes.DATE), - } - : - { - status: 'SCHEDULE', - // for schedule type of events we want to add the standard interval days to the date - scheduledAt: moment(convertFn(dateToUseInScheduleStatus, dataElementTypes.DATE)) - .add(minDaysFromStart, 'days') - .format('YYYY-MM-DD'), - }; - - return { - ...eventInfo, - ...eventAttributeCategoryOptions, - programStage, - program: programId, - orgUnit: orgUnitId, - }; - }); -}; - export const startSavingNewTrackedEntityInstanceEpic: Epic = (action$: InputObservable, store: ReduxStore) => action$.pipe( ofType(registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_SAVE_START), @@ -154,9 +80,11 @@ export const startSavingNewTrackedEntityInstanceWithEnrollmentEpic: Epic = ( action$.pipe( ofType(registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_START), map((action) => { + const formId = 'newPageDataEntryId-newEnrollment'; const { currentSelections: { orgUnitId, programId }, formsValues, dataEntriesFieldsValue } = store.value; const { dataStore, userDataStore, temp } = store.value.useNewDashboard; - const fieldsValue = dataEntriesFieldsValue['newPageDataEntryId-newEnrollment'] || {}; + const { formFoundation, teiId: trackedEntity, firstStage: firstStageMetadata, uid } = action.payload; + const fieldsValue = dataEntriesFieldsValue[formId] || {}; const { occurredAt, enrolledAt, geometry } = fieldsValue; const attributeCategoryOptionsId = 'attributeCategoryOptions'; const attributeCategoryOptions = Object.keys(fieldsValue) @@ -167,29 +95,47 @@ export const startSavingNewTrackedEntityInstanceWithEnrollmentEpic: Epic = ( return acc; }, {}); const { trackedEntityType, stages } = getTrackerProgramThrowIfNotFound(programId); - const values = formsValues['newPageDataEntryId-newEnrollment'] || {}; - const stageWithOpenAfterEnrollment = getStageWithOpenAfterEnrollment(stages); - const redirectToEnrollmentEventNew = - shouldUseNewDashboard(userDataStore, dataStore, temp, programId) && stageWithOpenAfterEnrollment !== undefined; - const events = deriveEvents({ + const currentFormData = formsValues[formId] || {}; + const shouldRedirect = shouldUseNewDashboard(userDataStore, dataStore, temp, programId); + const { stageWithOpenAfterEnrollment, redirectTo } = getStageWithOpenAfterEnrollment( + stages, + firstStageMetadata, + shouldRedirect, + ); + const convertedValues = formFoundation.convertAndGroupBySection(currentFormData, convertFn); + const formServerValues = convertedValues[Section.groups.ENROLLMENT]; + const currentEventValues = convertedValues[Section.groups.EVENT]; + + const firstStageDuringRegistrationEvent = deriveFirstStageDuringRegistrationEvent({ + firstStageMetadata, + programId, + orgUnitId, + currentEventValues, + fieldsValue, + attributeCategoryOptions, + }); + const autoGenerateEvents = deriveAutoGenerateEvents({ stages, enrolledAt, occurredAt, programId, orgUnitId, - redirectToEnrollmentEventNew, - redirectToStageId: stageWithOpenAfterEnrollment?.id, + firstStageMetadata, attributeCategoryOptions, }); - const { formFoundation, teiId: trackedEntity, uid } = action.payload; - const formServerValues = formFoundation?.convertValues(values, convertFn); + const allEventsToBeCreated = firstStageDuringRegistrationEvent + ? [firstStageDuringRegistrationEvent, ...autoGenerateEvents] + : autoGenerateEvents; + const eventIndex = allEventsToBeCreated.findIndex( + eventsToBeCreated => eventsToBeCreated.programStage === stageWithOpenAfterEnrollment?.id, + ); return saveNewTrackedEntityInstanceWithEnrollment({ candidateForRegistration: { trackedEntities: [ { - geometry: deriveGeometryFromFormValues(values), + geometry: deriveGeometryFromFormValues(currentFormData), enrollments: [ { geometry: standardGeoJson(geometry), @@ -199,7 +145,7 @@ export const startSavingNewTrackedEntityInstanceWithEnrollmentEpic: Epic = ( orgUnit: orgUnitId, attributes: deriveAttributesFromFormValues(formServerValues), status: 'ACTIVE', - events, + events: allEventsToBeCreated, }, ], orgUnit: orgUnitId, @@ -208,7 +154,8 @@ export const startSavingNewTrackedEntityInstanceWithEnrollmentEpic: Epic = ( }, ], }, - redirectToEnrollmentEventNew, + redirectTo, + eventIndex, stageId: stageWithOpenAfterEnrollment?.id, uid, }); @@ -223,7 +170,12 @@ export const completeSavingNewTrackedEntityInstanceWithEnrollmentEpic = ( action$.pipe( ofType(registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_COMPLETED), flatMap((action) => { - const { payload: { bundleReport: { typeReportMap } }, meta } = action; + const { + payload: { + bundleReport: { typeReportMap }, + }, + meta: { uid, redirectTo, stageId, eventIndex }, + } = action; const { currentSelections: { orgUnitId, programId }, newPage, @@ -231,19 +183,31 @@ export const completeSavingNewTrackedEntityInstanceWithEnrollmentEpic = ( const { uid: stateUid } = newPage || {}; const teiId = typeReportMap.TRACKED_ENTITY.objectReports[0].uid; const enrollmentId = typeReportMap.ENROLLMENT.objectReports[0].uid; + const eventId = typeReportMap.EVENT.objectReports?.[eventIndex]?.uid; - if (stateUid !== meta.uid) { + if (stateUid !== uid) { return EMPTY; } - if (meta?.redirectToEnrollmentEventNew) { + if (redirectTo === PAGES.enrollmentEventNew) { history.push( - `/enrollmentEventNew?${buildUrlQueryString({ + `/${redirectTo}?${buildUrlQueryString({ programId, orgUnitId, teiId, enrollmentId, - stageId: meta?.stageId, + stageId, + })}`, + ); + return EMPTY; + } + + if (redirectTo === PAGES.enrollmentEventEdit) { + history.push( + `/${redirectTo}?${buildUrlQueryString({ + eventId, + orgUnitId, + initMode: dataEntryKeys.EDIT, })}`, ); return EMPTY; diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveAutoGenerateEvents.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveAutoGenerateEvents.js new file mode 100644 index 0000000000..a38c30e4e5 --- /dev/null +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveAutoGenerateEvents.js @@ -0,0 +1,79 @@ +// @flow +import { pipe } from 'capture-core-utils'; +import moment from 'moment'; +import { dataElementTypes, ProgramStage } from '../../../../../metaData'; +import { convertFormToClient, convertClientToServer } from '../../../../../converters'; +import { convertCategoryOptionsToServer } from '../../../../../converters/clientToServer'; + +const convertFn = pipe(convertFormToClient, convertClientToServer); + +const ignoreAutoGenerateIfApplicable = (stage, firstStageDuringRegistrationEvent) => + !firstStageDuringRegistrationEvent || firstStageDuringRegistrationEvent.id !== stage.id; + +export const deriveAutoGenerateEvents = ({ + stages, + enrolledAt, + occurredAt, + programId, + orgUnitId, + firstStageMetadata, + attributeCategoryOptions, +}: { + stages: Map, + enrolledAt: string, + occurredAt: string, + programId: string, + orgUnitId: string, + firstStageMetadata: ProgramStage, + attributeCategoryOptions: { [categoryId: string]: string } | string, +}) => { + // in case we have a program that does not have an incident date (occurredAt), such as Malaria case diagnosis, + // we want the incident to default to enrollmentDate (enrolledAt) + const sanitizedOccurredAt = occurredAt || enrolledAt; + + // $FlowFixMe[missing-annot] + return [...stages.values()] + .filter(({ autoGenerateEvent }) => autoGenerateEvent) + .filter(stage => ignoreAutoGenerateIfApplicable(stage, firstStageMetadata)) + .map( + ({ + id: programStage, + reportDateToUse: reportDateToUseInActiveStatus, + generatedByEnrollmentDate: generateScheduleDateByEnrollmentDate, + openAfterEnrollment, + minDaysFromStart, + }) => { + const dateToUseInActiveStatus = + reportDateToUseInActiveStatus === 'enrolledAt' ? enrolledAt : sanitizedOccurredAt; + const dateToUseInScheduleStatus = generateScheduleDateByEnrollmentDate + ? enrolledAt + : sanitizedOccurredAt; + const eventAttributeCategoryOptions = {}; + if (attributeCategoryOptions) { + eventAttributeCategoryOptions.attributeCategoryOptions = + convertCategoryOptionsToServer(attributeCategoryOptions); + } + const eventInfo = openAfterEnrollment + ? { + status: 'ACTIVE', + occurredAt: convertFn(dateToUseInActiveStatus, dataElementTypes.DATE), + scheduledAt: convertFn(dateToUseInActiveStatus, dataElementTypes.DATE), + } + : { + status: 'SCHEDULE', + // for schedule type of events we want to add the standard interval days to the date + scheduledAt: moment(convertFn(dateToUseInScheduleStatus, dataElementTypes.DATE)) + .add(minDaysFromStart, 'days') + .format('YYYY-MM-DD'), + }; + + return { + ...eventInfo, + ...eventAttributeCategoryOptions, + programStage, + program: programId, + orgUnit: orgUnitId, + }; + }, + ); +}; diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveFirstStageDuringRegistrationEvent.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveFirstStageDuringRegistrationEvent.js new file mode 100644 index 0000000000..bf40f45135 --- /dev/null +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/deriveFirstStageDuringRegistrationEvent.js @@ -0,0 +1,55 @@ +// @flow +import { pipe } from 'capture-core-utils'; +import { dataElementTypes, ProgramStage } from '../../../../../metaData'; +import { convertFormToClient, convertClientToServer } from '../../../../../converters'; +import { convertCategoryOptionsToServer } from '../../../../../converters/clientToServer'; +import { convertStatusOut } from '../../../../DataEntries'; +import { standardGeoJson } from './standardGeoJson'; + +const convertFn = pipe(convertFormToClient, convertClientToServer); + +export const deriveFirstStageDuringRegistrationEvent = ({ + firstStageMetadata, + programId, + orgUnitId, + currentEventValues, + fieldsValue, + attributeCategoryOptions, +}: { + firstStageMetadata: ProgramStage, + programId: string, + orgUnitId: string, + currentEventValues?: { [id: string]: any }, + fieldsValue: { [id: string]: any }, + attributeCategoryOptions: { [categoryId: string]: string } | string, +}) => { + if (!firstStageMetadata) { + return null; + } + const { enrolledAt, stageComplete, stageOccurredAt, stageGeometry } = fieldsValue; + + const eventAttributeCategoryOptions = attributeCategoryOptions + ? { attributeCategoryOptions: convertCategoryOptionsToServer(attributeCategoryOptions) } + : {}; + + const event = { + status: convertStatusOut(stageComplete), + geometry: standardGeoJson(stageGeometry), + occurredAt: convertFn(stageOccurredAt, dataElementTypes.DATE), + scheduledAt: convertFn(enrolledAt, dataElementTypes.DATE), + programStage: firstStageMetadata.id, + program: programId, + orgUnit: orgUnitId, + ...eventAttributeCategoryOptions, + }; + + const dataValues = currentEventValues ? Object.keys(currentEventValues).reduce((acc, dataElement) => { + acc.push({ dataElement, value: currentEventValues[dataElement] }); + return acc; + }, []) : undefined; + + if (dataValues) { + return { ...event, dataValues }; + } + return event; +}; diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/getStageWithOpenAfterEnrollment.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/getStageWithOpenAfterEnrollment.js new file mode 100644 index 0000000000..26bd03daad --- /dev/null +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/getStageWithOpenAfterEnrollment.js @@ -0,0 +1,45 @@ +// @flow +import { ProgramStage } from '../../../../../metaData'; + +export const PAGES = { + enrollmentEventNew: 'enrollmentEventNew', + enrollmentEventEdit: 'enrollmentEventEdit', + enrollmentDashboard: 'enrollmentDashboard', +}; + +// an event can be created either during first stage registration or autogenerated +// when the event will be created redirect to enrollmentEventEdit +// when the event will not be created redirect to enrollmentEventNew +export const getStageWithOpenAfterEnrollment = ( + stages: Map, + firstStageMetadata: ProgramStage, + shouldRedirect: boolean, +) => { + const stagesArray = [...stages.values()]; + const [firstStageWithOpenAfterEnrollment] = stagesArray.filter(({ openAfterEnrollment }) => openAfterEnrollment); + + const redirectTo = (() => { + if (shouldRedirect && firstStageWithOpenAfterEnrollment) { + // event will be created during first stage registration + if ( + firstStageMetadata && + firstStageMetadata.id === firstStageWithOpenAfterEnrollment.id + ) { + return PAGES.enrollmentEventEdit; + } + // event will be autogenerated + if ( + stagesArray.find(stage => stage.autoGenerateEvent && stage.id === firstStageWithOpenAfterEnrollment.id) + ) { + return PAGES.enrollmentEventEdit; + } + return PAGES.enrollmentEventNew; + } + return PAGES.enrollmentDashboard; + })(); + + return { + stageWithOpenAfterEnrollment: firstStageWithOpenAfterEnrollment, + redirectTo, + }; +}; diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/index.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/index.js new file mode 100644 index 0000000000..fe7c884a9e --- /dev/null +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/index.js @@ -0,0 +1,5 @@ +// @flow +export { deriveFirstStageDuringRegistrationEvent } from './deriveFirstStageDuringRegistrationEvent'; +export { deriveAutoGenerateEvents } from './deriveAutoGenerateEvents'; +export { getStageWithOpenAfterEnrollment, PAGES } from './getStageWithOpenAfterEnrollment'; +export { standardGeoJson } from './standardGeoJson'; diff --git a/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/standardGeoJson.js b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/standardGeoJson.js new file mode 100644 index 0000000000..4342ab42c8 --- /dev/null +++ b/src/core_modules/capture-core/components/Pages/New/RegistrationDataEntry/helpers/standardGeoJson.js @@ -0,0 +1,19 @@ +// @flow + +export const standardGeoJson = (geometry: Array | { longitude: number, latitude: number }) => { + if (!geometry) { + return undefined; + } + if (Array.isArray(geometry)) { + return { + type: 'Polygon', + coordinates: geometry, + }; + } else if (geometry.longitude && geometry.latitude) { + return { + type: 'Point', + coordinates: [geometry.longitude, geometry.latitude], + }; + } + return undefined; +}; diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.component.js b/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.component.js index 6561b81018..5542c3e8d4 100644 --- a/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.component.js +++ b/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.component.js @@ -394,7 +394,7 @@ type Props = { }, theme: Theme, dataEntryId: string, - onCancelEditEvent?: () => void, + onCancelEditEvent?: (isScheduled: boolean) => void, eventStatus?: string, enrollmentId?: string, isCompleted?: boolean, diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.container.js b/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.container.js index eb4e6b0829..0a701bf622 100644 --- a/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.container.js +++ b/src/core_modules/capture-core/components/WidgetEventEdit/EditEventDataEntry/EditEventDataEntry.container.js @@ -103,7 +103,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props): any => ({ cancelEditEventDataEntry(), ...(isScheduled ? [] : [setCurrentDataEntry(props.dataEntryId, dataEntryKeys.VIEW)]), ])); - isScheduled && onCancelEditEvent && onCancelEditEvent(); + onCancelEditEvent && onCancelEditEvent(isScheduled); }, onDelete: () => { const { enrollmentId } = props; diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/widgetEventEdit.types.js b/src/core_modules/capture-core/components/WidgetEventEdit/widgetEventEdit.types.js index 16536ce27c..8dbc06e0c6 100644 --- a/src/core_modules/capture-core/components/WidgetEventEdit/widgetEventEdit.types.js +++ b/src/core_modules/capture-core/components/WidgetEventEdit/widgetEventEdit.types.js @@ -6,7 +6,7 @@ export type Props = {| programStage: ProgramStage, eventStatus?: string, onGoBack: () => void, - onCancelEditEvent: () => void, + onCancelEditEvent: (isScheduled: boolean) => void, onHandleScheduleSave: (eventData: Object) =>void, orgUnitId: string, programId: string, diff --git a/src/core_modules/capture-core/hooks/useEnrollmentEditEventPageMode.js b/src/core_modules/capture-core/hooks/useEnrollmentEditEventPageMode.js index 80b36d6210..c3a62fbb53 100644 --- a/src/core_modules/capture-core/hooks/useEnrollmentEditEventPageMode.js +++ b/src/core_modules/capture-core/hooks/useEnrollmentEditEventPageMode.js @@ -1,13 +1,22 @@ // @flow import { useSelector } from 'react-redux'; +import { useMemo } from 'react'; import { dataEntryKeys } from 'capture-core/constants'; import { statusTypes } from '../events/statusTypes'; +import { useLocationQuery } from '../utils/routing'; export const useEnrollmentEditEventPageMode = (eventStatus?: string) => { const showEditEvent = useSelector(({ viewEventPage }) => viewEventPage?.eventDetailsSection?.showEditEvent); + const { initMode } = useLocationQuery(); - if (eventStatus === statusTypes.SCHEDULE || eventStatus === statusTypes.OVERDUE) { - return { currentPageMode: dataEntryKeys.EDIT }; - } - return { currentPageMode: showEditEvent ? dataEntryKeys.EDIT : dataEntryKeys.VIEW }; + return useMemo(() => { + if (initMode) { + return { currentPageMode: initMode }; + } + + if (eventStatus === statusTypes.SCHEDULE || eventStatus === statusTypes.OVERDUE) { + return { currentPageMode: dataEntryKeys.EDIT }; + } + return { currentPageMode: showEditEvent ? dataEntryKeys.EDIT : dataEntryKeys.VIEW }; + }, [initMode, showEditEvent, eventStatus]); }; diff --git a/src/core_modules/capture-core/metaData/DataElement/DataElement.js b/src/core_modules/capture-core/metaData/DataElement/DataElement.js index c336e0f4f5..5555d4842e 100644 --- a/src/core_modules/capture-core/metaData/DataElement/DataElement.js +++ b/src/core_modules/capture-core/metaData/DataElement/DataElement.js @@ -11,6 +11,7 @@ import { OptionSet } from '../OptionSet/OptionSet'; import type { Unique } from './Unique'; import { dataElementTypes } from './dataElementTypes'; import type { CachedAttributeValue } from '../../storageControllers'; +import type { Section } from '../RenderFoundation'; // eslint-disable-next-line no-use-before-define export type ConvertFn = (value: any, type: $Keys, element: DataElement) => any; @@ -37,6 +38,7 @@ export class DataElement { _searchable: ?boolean; _url: ?string; _attributeValues: Array + _section: ?Section; constructor(initFn: ?(_this: DataElement) => void) { this._displayInReports = true; @@ -60,6 +62,13 @@ export class DataElement { return this._name; } + set section(section: ?Section) { + this._section = section; + } + get section(): ?Section { + return this._section; + } + set code(code: string) { this._code = code; } diff --git a/src/core_modules/capture-core/metaData/Program/Program.js b/src/core_modules/capture-core/metaData/Program/Program.js index e3d9645332..88ff443877 100644 --- a/src/core_modules/capture-core/metaData/Program/Program.js +++ b/src/core_modules/capture-core/metaData/Program/Program.js @@ -25,6 +25,7 @@ export class Program { _programRuleVariables: Array; _icon: Icon | void; _displayFrontPageList: boolean; + _useFirstStageDuringRegistration: boolean; _onlyEnrollOnce: boolean; constructor(initFn: ?(_this: Program) => void) { @@ -115,6 +116,14 @@ export class Program { return this._displayFrontPageList; } + set useFirstStageDuringRegistration(useFirstStageDuringRegistration: boolean) { + this._useFirstStageDuringRegistration = useFirstStageDuringRegistration; + } + + get useFirstStageDuringRegistration() { + return this._useFirstStageDuringRegistration; + } + set onlyEnrollOnce(onlyEnrollOnce: boolean) { this._onlyEnrollOnce = onlyEnrollOnce; } diff --git a/src/core_modules/capture-core/metaData/Program/ProgramStage.js b/src/core_modules/capture-core/metaData/Program/ProgramStage.js index 1c501643ca..403a2df333 100644 --- a/src/core_modules/capture-core/metaData/Program/ProgramStage.js +++ b/src/core_modules/capture-core/metaData/Program/ProgramStage.js @@ -20,6 +20,7 @@ export class ProgramStage { _openAfterEnrollment: boolean; _allowGenerateNextVisit: boolean; _generatedByEnrollmentDate: boolean; + _repeatable: boolean; _hideDueDate: boolean; _reportDateToUse: string; _minDaysFromStart: number; @@ -156,4 +157,12 @@ export class ProgramStage { get programRules(): Array { return this._programRules; } + + set repeatable(repeatable: boolean) { + this._repeatable = repeatable; + } + + get repeatable(): boolean { + return this._repeatable; + } } diff --git a/src/core_modules/capture-core/metaData/RenderFoundation/RenderFoundation.js b/src/core_modules/capture-core/metaData/RenderFoundation/RenderFoundation.js index 8c11e94144..9fdf44a12f 100644 --- a/src/core_modules/capture-core/metaData/RenderFoundation/RenderFoundation.js +++ b/src/core_modules/capture-core/metaData/RenderFoundation/RenderFoundation.js @@ -4,7 +4,7 @@ import log from 'loglevel'; import { errorCreator } from 'capture-core-utils'; import isFunction from 'd2-utilizr/lib/isFunction'; import { validationStrategies, validationStrategiesAsArray } from './renderFoundation.const'; -import type { Section } from './Section'; +import { Section } from './Section'; import type { ConvertFn } from '../DataElement/DataElement'; import type { Access } from '../Access'; import { convertDataElementsValues } from '../helpers'; @@ -163,4 +163,20 @@ export class RenderFoundation { const dataElements = this.getElements(); return convertDataElementsValues(values, dataElements, onConvert); } + + convertAndGroupBySection(currentFormData: {[id: string]: any}, onConvert: ConvertFn) { + const metaElements = [...this.getElements().values()]; + + return Object.keys(currentFormData).reduce((acc, id) => { + const metaElement = metaElements.find(o => o.id === id); + const rawValue = currentFormData[id]; + const convertedValue = metaElement ? metaElement.convertValue(rawValue, onConvert) : rawValue; + const group = metaElement?.section?.group; + if (group) { + acc[group] = { ...acc[group], [id]: convertedValue }; + return acc; + } + return { ...acc, [id]: convertedValue }; + }, {}); + } } diff --git a/src/core_modules/capture-core/metaData/RenderFoundation/Section.js b/src/core_modules/capture-core/metaData/RenderFoundation/Section.js index d312f59842..411067757b 100644 --- a/src/core_modules/capture-core/metaData/RenderFoundation/Section.js +++ b/src/core_modules/capture-core/metaData/RenderFoundation/Section.js @@ -15,6 +15,11 @@ export class Section { DATA_ELEMENT_NOT_FOUND: 'Data element was not found', }; + static groups = { + ENROLLMENT: 'ENROLLMENT', + EVENT: 'EVENT', + } + _id: string; _name: string; _displayDescription: string; @@ -24,6 +29,7 @@ export class Section { _elements: Map; _showContainer: boolean; _customForm: ?CustomForm; + _group: string; constructor(initFn: (_this: Section) => void) { this._visible = true; @@ -90,6 +96,13 @@ export class Section { return this._elements; } + set group(group: string) { + this._group = group; + } + get group(): string { + return this._group; + } + addElement(element: DataElement | FormFieldPluginConfig) { if (!this.elements.has(element.id)) { this.elements.set(element.id, element); diff --git a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/DataElementFactory.js b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/DataElementFactory.js index 3fa73e1130..18e56e1869 100644 --- a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/DataElementFactory.js +++ b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/DataElementFactory.js @@ -15,6 +15,7 @@ import { DataElementUnique, dataElementUniqueScope, dataElementTypes, + Section, } from '../../../../metaData'; import { OptionSetFactory } from '../../../common/factory'; import { convertFormToClient, convertClientToServer } from '../../../../converters'; @@ -37,8 +38,9 @@ export class DataElementFactory { 'could not create the metadata because a MULIT_TEXT without associated option sets was found', }; - static buildtetFeatureType(featureType: 'POINT' | 'POLYGON') { + static buildtetFeatureType(featureType: 'POINT' | 'POLYGON', section: Section) { const dataElement = new DataElement((o) => { + o.section = section; o.id = `FEATURETYPE_${featureType}`; o.name = featureType === 'POINT' ? i18n.t('Coordinate') : i18n.t('Area'); o.formName = o.name; @@ -206,8 +208,10 @@ export class DataElementFactory { async _buildBaseDataElement( cachedProgramTrackedEntityAttribute: CachedProgramTrackedEntityAttribute, cachedTrackedEntityAttribute: CachedTrackedEntityAttribute, + section?: Section, ) { const dataElement = new DataElement(); + dataElement.section = section; dataElement.type = cachedTrackedEntityAttribute.valueType; await this._setBaseProperties( dataElement, @@ -224,10 +228,12 @@ export class DataElementFactory { async _buildDateDataElement( cachedProgramTrackedEntityAttribute: CachedProgramTrackedEntityAttribute, cachedTrackedEntityAttribute: CachedTrackedEntityAttribute, + section?: Section, ) { const dateDataElement = new DateDataElement(); dateDataElement.type = dataElementTypes.DATE; dateDataElement.allowFutureDate = cachedProgramTrackedEntityAttribute.allowFutureDate; + dateDataElement.section = section; await this._setBaseProperties( dateDataElement, cachedProgramTrackedEntityAttribute, @@ -238,6 +244,7 @@ export class DataElementFactory { build( cachedProgramTrackedEntityAttribute: CachedProgramTrackedEntityAttribute, + section?: Section, ) { const cachedTrackedEntityAttribute = cachedProgramTrackedEntityAttribute.trackedEntityAttributeId && this.cachedTrackedEntityAttributes.get( @@ -253,7 +260,7 @@ export class DataElementFactory { } return cachedTrackedEntityAttribute.valueType === dataElementTypes.DATE ? - this._buildDateDataElement(cachedProgramTrackedEntityAttribute, cachedTrackedEntityAttribute) : - this._buildBaseDataElement(cachedProgramTrackedEntityAttribute, cachedTrackedEntityAttribute); + this._buildDateDataElement(cachedProgramTrackedEntityAttribute, cachedTrackedEntityAttribute, section) : + this._buildBaseDataElement(cachedProgramTrackedEntityAttribute, cachedTrackedEntityAttribute, section); } } diff --git a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/EnrollmentFactory.js b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/EnrollmentFactory.js index 19230eace9..3358d5f648 100644 --- a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/EnrollmentFactory.js +++ b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/enrollment/EnrollmentFactory.js @@ -78,7 +78,7 @@ export class EnrollmentFactory { }); } - _buildTetFeatureTypeField(trackedEntityTypeId: ?string) { + _buildTetFeatureTypeField(trackedEntityTypeId: ?string, section: Section) { const teType = trackedEntityTypeId && this.cachedTrackedEntityTypes.get(trackedEntityTypeId); if (!teType) { return null; @@ -90,23 +90,24 @@ export class EnrollmentFactory { } // $FlowFixMe - return DataElementFactory.buildtetFeatureType(featureType); + return DataElementFactory.buildtetFeatureType(featureType, section); } async _buildTetFeatureTypeSection( cachedProgramTrackedEntityTypeId: string, ) { - const featureTypeField = this._buildTetFeatureTypeField(cachedProgramTrackedEntityTypeId); const trackedEntityType = this.cachedTrackedEntityTypes.get(cachedProgramTrackedEntityTypeId); - if (!featureTypeField) { - return null; - } - const section = new Section((o) => { o.id = cachedProgramTrackedEntityTypeId; o.name = trackedEntityType?.displayName || ''; + o.group = Section.groups.ENROLLMENT; }); + const featureTypeField = this._buildTetFeatureTypeField(cachedProgramTrackedEntityTypeId, section); + + if (!featureTypeField) { + return null; + } featureTypeField && section.addElement(featureTypeField); return section; @@ -119,12 +120,13 @@ export class EnrollmentFactory { const section = new Section((o) => { o.id = Section.MAIN_SECTION_ID; o.name = i18n.t('Profile'); + o.group = Section.groups.ENROLLMENT; }); if (!cachedProgramTrackedEntityAttributes?.length) { return null; } if (cachedProgramTrackedEntityTypeId) { - const featureTypeField = this._buildTetFeatureTypeField(cachedProgramTrackedEntityTypeId); + const featureTypeField = this._buildTetFeatureTypeField(cachedProgramTrackedEntityTypeId, section); featureTypeField && section.addElement(featureTypeField); } @@ -166,7 +168,7 @@ export class EnrollmentFactory { element && section.addElement(element); } else { - const element = await this.dataElementFactory.build(trackedEntityAttribute); + const element = await this.dataElementFactory.build(trackedEntityAttribute, section); element && section.addElement(element); } }); @@ -185,6 +187,7 @@ export class EnrollmentFactory { const section = new Section((o) => { o.id = cachedSectionCustomId; o.name = cachedSectionCustomLabel; + o.group = Section.groups.ENROLLMENT; }); await this._buildElementsForSection(cachedProgramTrackedEntityAttributes, section); @@ -200,6 +203,7 @@ export class EnrollmentFactory { let section = new Section((o) => { o.id = Section.MAIN_SECTION_ID; + o.group = Section.groups.ENROLLMENT; }); section.showContainer = false; @@ -353,6 +357,7 @@ export class EnrollmentFactory { const foundation = new RenderFoundation(); const section = new Section((oSection) => { oSection.id = Section.MAIN_SECTION_ID; + oSection.group = Section.groups.ENROLLMENT; }); Array.from( searchGroupFoundation diff --git a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/program/ProgramFactory.js b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/program/ProgramFactory.js index b76d755531..28ff91fe67 100644 --- a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/program/ProgramFactory.js +++ b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/program/ProgramFactory.js @@ -175,6 +175,7 @@ export class ProgramFactory { program.icon = buildIcon(cachedProgram.style); program.displayFrontPageList = cachedProgram.displayFrontPageList; program.onlyEnrollOnce = cachedProgram.onlyEnrollOnce; + program.useFirstStageDuringRegistration = cachedProgram.useFirstStageDuringRegistration; return program; } diff --git a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/DataElementFactory.js b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/DataElementFactory.js index 389b6dcc4c..6bd83c7f08 100644 --- a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/DataElementFactory.js +++ b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/DataElementFactory.js @@ -9,7 +9,7 @@ import type { CachedProgramStageDataElement, CachedOptionSet, } from '../../../../storageControllers/cache.types'; -import { DataElement, DateDataElement, dataElementTypes } from '../../../../metaData'; +import { DataElement, DateDataElement, dataElementTypes, Section } from '../../../../metaData'; import { buildIcon } from '../../../common/helpers'; import { OptionSetFactory } from '../../../common/factory'; import { isNotValidOptionSet } from '../../../../utils/isNotValidOptionSet'; @@ -99,8 +99,10 @@ export class DataElementFactory { cachedProgramStageDataElement: CachedProgramStageDataElement, cachedDataElement: CachedDataElement, dataElementType: $Keys, + section: ?Section, ) { const dataElement = new DataElement(); + dataElement.section = section; dataElement.type = dataElementType; await this._setBaseProperties(dataElement, cachedProgramStageDataElement, cachedDataElement); if (isNotValidOptionSet(dataElement.type, dataElement.optionSet)) { @@ -123,6 +125,7 @@ export class DataElementFactory { async build( cachedProgramStageDataElement: CachedProgramStageDataElement, + section: ?Section, ): Promise { const cachedDataElement = await getUserStorageController().get(userStores.DATA_ELEMENTS, cachedProgramStageDataElement.dataElementId); @@ -139,6 +142,6 @@ export class DataElementFactory { return dataElementType === dataElementTypes.DATE ? this._buildDateDataElement(cachedProgramStageDataElement, cachedDataElement) : - this._buildBaseDataElement(cachedProgramStageDataElement, cachedDataElement, dataElementType); + this._buildBaseDataElement(cachedProgramStageDataElement, cachedDataElement, dataElementType, section); } } diff --git a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/ProgramStageFactory.js b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/ProgramStageFactory.js index adc65c2f5a..83bc11b8ff 100644 --- a/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/ProgramStageFactory.js +++ b/src/core_modules/capture-core/metaDataMemoryStoreBuilders/programs/factory/programStage/ProgramStageFactory.js @@ -65,7 +65,7 @@ export class ProgramStageFactory { { sectionDataElement })); return; } - const element = await this.dataElementFactory.build(cachedProgramStageDataElement); + const element = await this.dataElementFactory.build(cachedProgramStageDataElement, section); element && section.addElement(element); }); } @@ -81,7 +81,7 @@ export class ProgramStageFactory { if (cachedProgramStageDataElements) { // $FlowFixMe await cachedProgramStageDataElements.asyncForEach((async (cachedProgramStageDataElement) => { - const element = await this.dataElementFactory.build(cachedProgramStageDataElement); + const element = await this.dataElementFactory.build(cachedProgramStageDataElement, section); element && section.addElement(element); })); } @@ -128,6 +128,7 @@ export class ProgramStageFactory { _stage.generatedByEnrollmentDate = !!cachedProgramStage.generatedByEnrollmentDate; _stage.reportDateToUse = cachedProgramStage.reportDateToUse; _stage.minDaysFromStart = cachedProgramStage.minDaysFromStart; + _stage.repeatable = cachedProgramStage.repeatable; _stage.stageForm = new RenderFoundation((_form) => { _form.id = cachedProgramStage.id; _form.name = cachedProgramStage.displayName; diff --git a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storePrograms.js b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storePrograms.js index 1e04d03ec7..adebf39a14 100644 --- a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storePrograms.js +++ b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/storePrograms.js @@ -80,7 +80,7 @@ const convert = (() => { }; })(); -const fieldsParam = 'id,displayName,displayShortName,description,programType,style,displayFrontPageList,onlyEnrollOnce,' + +const fieldsParam = 'id,displayName,displayShortName,description,programType,style,displayFrontPageList,useFirstStageDuringRegistration,onlyEnrollOnce,' + 'minAttributesRequiredToSearch,enrollmentDateLabel,incidentDateLabel,' + 'featureType,selectEnrollmentDatesInFuture,selectIncidentDatesInFuture,displayIncidentDate,' + 'dataEntryForm[id,htmlCode],' + diff --git a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/apiPrograms.types.js b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/apiPrograms.types.js index 32c02464d8..70ac391972 100644 --- a/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/apiPrograms.types.js +++ b/src/core_modules/capture-core/metaDataStoreLoaders/programs/quickStoreOperations/types/apiPrograms.types.js @@ -140,6 +140,7 @@ type apiProgram = { featureType?: ?string, selectEnrollmentDatesInFuture: boolean, displayFrontPageList: boolean, + useFirstStageDuringRegistration: boolean, selectIncidentDatesInFuture: boolean, displayIncidentDate: boolean, dataEntryForm?: ?apiDataEntryForm, diff --git a/src/core_modules/capture-core/rules/getApplicableRuleEffects.js b/src/core_modules/capture-core/rules/getApplicableRuleEffects.js index 57ffddac38..2d261aef78 100644 --- a/src/core_modules/capture-core/rules/getApplicableRuleEffects.js +++ b/src/core_modules/capture-core/rules/getApplicableRuleEffects.js @@ -74,6 +74,7 @@ export const getApplicableRuleEffectsForTrackerProgram = ({ otherEvents, attributeValues, enrollmentData, + formFoundation, }: GetApplicableRuleEffectsForTrackerProgramInput, flattenedResult: boolean = false, ) => { @@ -82,6 +83,7 @@ flattenedResult: boolean = false, program.programRules, stage?.programRules, ); + const foundationForPostProcessing = formFoundation || (stage ? stage.stageForm : program.enrollment.enrollmentForm); if (!programRules.length) { return []; } @@ -103,7 +105,7 @@ flattenedResult: boolean = false, programRules, programRuleVariables, trackedEntityAttributes: getTrackedEntityAttributesForRulesExecution(program.attributes), - foundationForPostProcessing: stage ? stage.stageForm : program.enrollment.enrollmentForm, + foundationForPostProcessing, }); return flattenedResult ? effects : buildEffectsHierarchy(effects); diff --git a/src/core_modules/capture-core/rules/rules.types.js b/src/core_modules/capture-core/rules/rules.types.js index 606ae8336f..0249ee664c 100644 --- a/src/core_modules/capture-core/rules/rules.types.js +++ b/src/core_modules/capture-core/rules/rules.types.js @@ -19,6 +19,7 @@ export type GetApplicableRuleEffectsForTrackerProgramInput = {| otherEvents?: EventsData, attributeValues?: TEIValues, enrollmentData?: Enrollment, + formFoundation?: RenderFoundation, |}; export type GetApplicableRuleEffectsForEventProgramInput = {| diff --git a/src/core_modules/capture-core/storageControllers/cache.types.js b/src/core_modules/capture-core/storageControllers/cache.types.js index cfcaa75c92..df2cffbb41 100644 --- a/src/core_modules/capture-core/storageControllers/cache.types.js +++ b/src/core_modules/capture-core/storageControllers/cache.types.js @@ -119,6 +119,7 @@ export type CachedProgramStage = { generatedByEnrollmentDate?: ?boolean, hideDueDate?: ?boolean, reportDateToUse: string, + repeatable: boolean, minDaysFromStart: number, style?: ?CachedStyle, }; @@ -204,6 +205,7 @@ export type CachedProgram = { selectIncidentDatesInFuture: boolean, displayIncidentDate: boolean, onlyEnrollOnce: boolean, + useFirstStageDuringRegistration: boolean, }; export type CachedProgramStageDataElementsAsObject = { From 302eb2a6041ae16321c0e306ea9d0546d6c4b33e Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Tue, 3 Oct 2023 06:59:50 +0000 Subject: [PATCH 05/12] chore(release): cut 100.41.0 [skip release] # [100.41.0](https://github.com/dhis2/capture-app/compare/v100.40.1...v100.41.0) (2023-10-03) ### Features * [DHIS2-9661][DHIS2-14830] first stage on registration page ([#3267](https://github.com/dhis2/capture-app/issues/3267)) ([6e5f6fe](https://github.com/dhis2/capture-app/commit/6e5f6fea7b6ab043800e806c7459210f10ef608a)) --- CHANGELOG.md | 7 +++++++ package.json | 4 ++-- packages/rules-engine/package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 110d6a07aa..a9b8e29d4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [100.41.0](https://github.com/dhis2/capture-app/compare/v100.40.1...v100.41.0) (2023-10-03) + + +### Features + +* [DHIS2-9661][DHIS2-14830] first stage on registration page ([#3267](https://github.com/dhis2/capture-app/issues/3267)) ([6e5f6fe](https://github.com/dhis2/capture-app/commit/6e5f6fea7b6ab043800e806c7459210f10ef608a)) + ## [100.40.1](https://github.com/dhis2/capture-app/compare/v100.40.0...v100.40.1) (2023-09-30) diff --git a/package.json b/package.json index 6d42913001..fbf2ef4982 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "100.40.1", + "version": "100.41.0", "cacheVersion": "6", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "100.40.1", + "@dhis2/rules-engine-javascript": "100.41.0", "@dhis2/app-runtime": "^3.9.3", "@dhis2/d2-i18n": "^1.1.0", "@dhis2/d2-icons": "^1.0.1", diff --git a/packages/rules-engine/package.json b/packages/rules-engine/package.json index 0b391e85fa..411dcf5450 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "100.40.1", + "version": "100.41.0", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From 7ae8326fb571f31225495aaaafa25138644387a6 Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Wed, 4 Oct 2023 09:47:11 +0200 Subject: [PATCH 06/12] docs: [DHIS2-9661] first stage appears on registration page (#3424) --- .../images/first-stage-during-registration.png | Bin 0 -> 222975 bytes docs/user/using-the-capture-app.md | 8 ++++++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 docs/user/resources/images/first-stage-during-registration.png diff --git a/docs/user/resources/images/first-stage-during-registration.png b/docs/user/resources/images/first-stage-during-registration.png new file mode 100644 index 0000000000000000000000000000000000000000..1baba4bc34120c7a54d3921ddb63c70308f7734b GIT binary patch literal 222975 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%0AASN z+L`ezI9TJNj{B9C@^5-e_gO*@7hlKRMU~JmbDOOUh)ZG{4PFWObN6tX%x8GvBhzhN z&0A$X;k#<8YBG5jBq0DmxFZ2Uy5j@qaq&Yk9#H$D%nEJ7_y_N@Kay!)Bql9)jR#2v z(ES`dF8dk4nTsuMgd3+kQ;CE<^8r+eg}Y@XRHlo46(QdbXV2a0W=7 z#r-I#d5)S9UlipNJo4~yj!Cp#85Jb@oOg_X9h%48GnRGFOwZRJ$+~z&X~GroiTqJ1 zG1oIhm!8>^J?7uLrebQj+xV?{yDzpY71rPa(jK6v0^aTB6|Gw4J|D{>y&;PwpU4f3nXjg!H&AtiG1r(GIzks)pA^wMtV<$3A%yyDjmo3 z^5LXu?e1WE>+_X@+DWDZ&5~>SJt+^@ijflW$oz_#;68tu5Lnc@WnQV;oK;9VP&bez zt@NH?G^Q;$Vw?b<|Je#>i{BK%?esZTSD5rLW@?P2Y*`y8mpkYh@2;g21VxQG`7gHQ zdpma30#lcTFGKw#w68q0>Jmyt;z^adGv{HeqjMW;#%D@3jZYepF2gSaoOTD)W405G z8I$^e4x8~bf_Y8~1_+yp&<pZt3P_Y!ZkHZcjfCZ+l`NzB~=_7N^| zXl6psRdB4Y*;!soriQV)4}CBCumlj3mgimqoo%K}uaQyH=*CN;9IN#w$8#D6I`-ad z>`tvkBU#OSsv|R~bM{?)7MrQJfAb`|0;(*0+3BJBOb4aF0MG-RscpuD5wsQ)RnF~= z9~31pMs*^uzfoMZG!IGM2Fex~Cp!=h0bI^YgdkRW%%PpL4==0kfYnXIZ+P>Js^)_# zo#9JYqR@Cc8tEC@?dbO|Rhp-eAFaKX8+&EC21wLD3se-v`D+1XFb6p-dFkdA_WTOQ zL|~(=Y)yDE9_kr3h3@_&l@s0EQDWY=g}ch0a#+4+>x{iN?)n!NHmB zIgkzfp}t#+1RmlUp6R zZUXt$YgJnx0hQ7f0i3H16U)oXo)i{MZ#ewrB{bvu33H}DI>q9-$!|GJf1u?4bsCu% zhL-D=x$j|n#fYd&@@F#`$#qI-ZEJY>)zX}n`m+{S%TZiaYPITbKZeM*P#j~|T z#z4NSZLzH_A!;m|E>4)j&|+cy7>Gyn50(uC0sD30jb%gbgM1yA)OX{6;2>hQ@^p{| z^fU(x#Gwxodin!4DIb<9(Mj4|A&z&yb>p!6if_(cWE;YP@OL+ZorUp81fRz2F^RWU zQ*iYU8q~qgSCj-Q|xzyYVG>RM1=!`ER8 z1e-aYS;s}-`CRB_#YY1e#-kg{0;6WBhq@w0b;q^j5S>g^OE{gjkCJ>>LCsd%T*V9q zJIipQ(WS1S<2LO-x02x46)P}q*XU4J*9sQ@`r+vxk*q3hOEYs*CdEPcphh-Do#EUg zO-%_vh)mky=4`8C`8dIEX*;^opzh~w{?2)pgm-N0wgLhr_>jE2f?1!LNPQe83pw~o zri_!E1gP^v9d6Y&gB$27tlye<#{}y(!>&TZQz=i^?+$8n7nten;M&ydJ}~NB=VarS zp#^|R%X@cVdvWlH<>7n0XXFTkkq?2>Qk^S=Bn?Pcj>7f8k3Y8scPjUeLXh7$SikzVVG#wlu!LtYy9F!6ijlX}<;iXk9nI9F50q1iRMB*B+!J|Ln{_6W+=9vKFC z?%Ew?-uQZOwk#T-ozo!yG@v;#^HHf;n60rMB*{2MysklE5`LCa5Mnn#mivGxuC^ws zlQQGQS<>cti;YQrQk%Dq*!tur3na_`Qcd@`B+{E?{iSX5WVTO|KOQ;;<2y71-|P;4zkz!Bb; zm5~&O=mbucgip}bcxurS2HUn z2DIb~ydAwqml$525MOyb#iONzsFbtFUCvyM;T9D+5;CMcA*W&E~A$>LK#!EG}XFTyRaAeJe@VIaf4{RR8^X~dS}>QI4x@Nty2 znglHpa^eMBIOw=>&*;f0h)NF2^}sDzvv<_X!rcVe;HZSfK`|eEV(So))r1)tf*u%9 zLeoJ?hqd4x{Xivy`_K1B{4c-x9f@)$^+YI$WC=I+1pE$dYp}Wl%I^$g978zEzDwyV zNmpdKtQ5A+pGK!tSrCo|FSe~R8hHWkbpM*xBoKac2)gZ84y|+Y%Cbo$TLrAm9Xohs zg2~lY(`+*D?WzN*_@1ARdjj#DBp|!8W*a{K;s6rQi$FTbUHPCW1Dz+PEx&!Fv+^^L zDf~OTrOchh%wXKl2*vpV1Mf`q>)1JjAWxs(o$TB2@b>}|l=Dk$8zvqNOA6%!k^T$@R{F6?0B__ogsaq#{tC{6f4 zbR)G70JZ4+s-^5ApM+LrInJm6Kf`HI-V=ZFBza4ZT@?8_s13aZEU=S3Rb9k$mc8vz&`?NABK|4;}{oZRZ#47^@!!n`vW0G>M6aeEoek@Utfz!;pZ zm-l6luBBIGEUEwG7IoPQI%vOO?>*zl2phh_`Fd$H8#Pn#z%TyylB?__PPLay5~tW? zqQ;3m`3DYn79;S&Pt84ZRrWAD^Bx0{>?nHYekFXp(X(wN#HTQOsrFvSji|^}Ml&4M zg9%~|>b$(K6Cj_!Exz5s#~MyYnI2NsKtTFA(~E}E&9LedIMHz&D1nFBg@_bsGbbQl zJp=3MsYl}o%5=EYN)N;d2Jy)$`sd*mnNge_hM^RXLfFQ4$MB^J>Z_rrcJa)sRHWq^ zR6W&WMFP8`QktLBQ8G6w*qRAYsTd4Yd~B0@sv2@@txwi&2Y<(xB^2KEfm^iXnd5T< zhd_Mgn{cE->W`n`y`>#rN0FaPsLhq|;|gBL?gKb$8_k!Ui?_E6)&L!Jsnd^fU{WGO5c8FGYa8jPu6Psh_D7^540^CZJfkVNArT)$S#mx z;KfV-P~40jJR7^&7)I`CF7lDp~4B)eyYA6b}QFRC>sa8@F{)SM(6x~?` z*zoCQ@P?!D&8j=tk4h*I?wS6EoxZ=jWe&hb9*H&5Yz*Mz+u|T>VldJ-JsyABqggHB z%SUJq)d^EsZ^B8Y>}?<4SqIeMmh>=&;p9LDD!BuyJuEh4&UDgf?*th>@}I7#pCKaN zeUsHWf$UhqtLcjmNArZ$u00-@%p9hLbOlP9ift#R$tQ^klaaM<)84{H!xRQ)+*`!= z0b!e)-Z`+!K04hQ+9C=-=nCo%W?xe^C!C?=(HuH|e5QKKpIYxb-Au88O9fH&)~?gq z|6T6))uQ~bYVoCwbXs-fVzfp#>)8}p6T(yxm5{by4?eta^OKoRvR6uGV1IsOsl@km(@S_-?f36zIQF)P(GaJC=T=1P<`ocrq9 z;S&kgv^h6W3D)e`M;earrKx`CN41N#JNco8Gz`PK?v0y-@xeMM3g*i+aaK)aZZiR# zqxENJwjErmiFCDp3+7on8?tJ%KMOYp41Z!JxnR0v{UnKoMgoBsYwjYcx>yi+_V%hb)gm|eJ8v(>e5-zw`t zSYBDe@0`*9`~Ub-k<@G)V$EZ}p3$m+wmPp*+6TB8{g$=-i-(jv1N^{P&*RE3pY?y= z?SGWKb^C%Y1iHZW?ti(|@1!LDbGu)x^M4leS61{NQ~8gn{AM)!kE#6HRK!I$hKq5Z zWWs46V+b&};4cp-zlMjn`P2W@9X_TJ=s!yU-%7q^ez+47WWLmIUc57W=^u=vLxMou z(@D`AoxrpkZ@YFMeWTU{aV5SJ`RJ5~Kz)OP?H=WZ&yytYf;>K^U)@mB^vd(A>BYLd zvv>aX<3#-zD+kEFKr+bFGuX~}swIf+(nzWd8p3M&kB>VAHbiEr^i?Rbd@i3n;o+>A z@-jbmpI>@sFJ#sZio&($(**y=`Si;h6OjPONDSfTHT&8x6V-C5=JF-^zokq}$b1iO zLF+Mx>6M2&3brP<7KATBCSGTi4(r%eS3|Nc1LNd%j= zAqUHsH*GKG?cuu%Pp;GaPW5<$51|Ckz#z_bO+xISh-sCJ#}*~ASiFL|uC+=^EID+{ zfA8UMIEe2F@v}q`&SpgR(0^Tuv%A<7e*X@({H+=m9OR`wVWIE-@~r>WTAl(|C6=tF z{O1*a6~KRi2Nv#wyCu#m)7<@y{rcAjBIsWG!%q;3gn{b&j7rsWvj3JA`{f(`^ZKt& zm3aQyCrctUHy*5#Kx3`(RooG?-9XrlFz;($|5tvcsq{vIX%;%fhWqfE|#yqtm)MU1A&qSN=USl1K^ zTDCuUHZTNYj}o-d>m%bv#sHOznuMVfy~NlrY2VsiM?nCyVPEv0=1%KLeVlPi>Rg8N zpdLF&^3^~MVc101KJbZHZf%!Xq|__0yl|6=dG1F_!w|8Yr0B}!DXA|*n|o`n>l zVb7%O5iXlck`YDO`?6(cT{cDb-s3W}_ulLKygK)}&+ooJ=iH~y{m<{8&p(bFZ`XUg zUeECu&-Xm=%n=GIW=ish-9t7U`+(O;#tQE-FyDUljGPZqn^V40pQusNH`!&k(L32* ztu5T-1M?lY(pUud8?v#Wxby%-+LTn_4UyX~pEgGx3JpSo-@eLP9IWB69Df^7-vs;* z8O!mV$yI7j6KQ#aGO_~Oa>z4YXH>2-3nKJNn@t7^drOnZ$0f_gGB#&vn0NFaD3 zI967nb+^9q`Qk6#+28khBe5RJ-+<#xTzx9(*6hG$oY#SkKC-3a4DT($_2$I(2p^EzO7TuJ*Y`3QA0HSrd49xc%<>VaUe8(0<#&393+c)X&Wpnttxur>aatjf~WqR@?F)&KOivmIi^hk8NNFe|e## zTeeL>)q$HxM0l%3xXtW(csSOAGFZE@o#73Iy`Yp6xaje%K-k&^JC`JsdbB{;Q_{jT2^Si*`b$zu@v(Rhp)VOa{nMTd8RV+ z8*|=1{SZreS7M~YT@}4(=k2|4<(CsKXSQtZAYQhECIAJJwRyzm(1LWBqhY&)qv|2a zogeaw%Dh9;6c){>J%$1E*?HTK{A3Hc)jsXrrG>~+BsK;M*WosE>wKI1yhPzVML=>b zLCEnyopQ(RvT5yZr4tg}tYN#wo1h3`tWS4Qu+7J6h+n6@vs+{68BSqt!nVx*-*XGW z#(4MMU;Gpa+N9e$4Z&-mL`lQ~i|g|k?p>*l{gv)7S`}@8(dve+TGHaF(A~0K8M|4; zaRsZMKJ=P<9L#ob(lKYNe*TlFXPFVT)3)FNpMyQAno*;Yu_!hNM2Nyowopst`e6Ra z^+Ke{E?juhX%X-W22XcYzX2It$#i+MsV-?O$WBn3n!59x^-C7xXVAR{UII9j_2A30 zDLNLlyAhGHa!VihuSO<0BB$wbhi!wD1AYp1gvzUL2jC#vClaa=ZJ~a7D5~9h$LqzR zwzg5}%^l|44&NJ$B8q6zKuwkmE6UDHi4Wuvhp|it&hot~hAIU_?SB(XL|%(bp7)@c z1l}x|1@K0!orv>Ls#iLq7Asb=0&^3v`26v}1}7$^cbyGRg934_{d@+#5O)_XK4k{} z11I20ym}A&jlISA48w0!;OBJB z+I;TCq9UUxbNUi{emHY^?f4t3$f?0t`-1AvYiecdbG@TwUI*C+u(56il^hnf^9w)Nt8!Ywv7vc;mx!zzM%7nEd>;|52D>6K_4J_^MS5O-t6Tc;hY(x%VE@ zBprtO@5iL-X=e*d$Ns&sS6%g|IR}_ACBBs!I@R;YbUCj_Q*g5I+Jl}r?gelrkTVSJ5bfx9<#hMRppOe+ald(rv@!$Iz!OzUx7&qAXCwMR+=&y>2w7u z5hwZi4e(vx2iM!v0;5W;Y!)1KD#URTFCs8-s(o=9oL%o8x}SGA-ZYKIE|s0ekjb$! ziZGLxOk``Io9&-zZx&)ol>TQ`{FmS4-XL~vN<;S>mk5~YZ+n@sV<9Hn`-6Y+*8XJC!OL6{H?2&gOYgjE9iUuSW3s5rM+$1 zO^y7?)De&T9Q(4^-xLcE=r$ud*shNi@lIWkh%4Fb7fdT&@w{=jg01uuoy7Po*Y3nM z{eqW4`t>6^b?6ei^@k@YmsSx|BNCIl!pmctiQx01b6jVdjW-!6iU$rv?6--ZTLhT;mPRVt zVJbne3CP!!&GPpyc56C0f->LfFkn&i4DVITMWNYQ1`T-9`VGNs`aqvFy0ipbcdELi z8wcYP7%9PDsSlh&n%c|4D!iB{c5=Fr^32|()pJ9KL&u19JIyG6CLIGQi2CSs3BOp| z)yBNG?F(uhFHjJJtrCt$jSm0JskMm*0Vc)Mf#*q4&0F)m?H}|ba=RtnsjXhkbfsYs zvpQXGz;W zaI+^uv|^yN-+Q1B9?plGd+TV0#df#94f0eU0Jm`> zsM=rYP$l$lf}k*v7LRg1%H_<=M;ruiupPLc(uyEuXSNeb;~}7axfRSl!Jn! z?~D+)nBdDg|FsRwVjQT$_z5X^qM}*mvy4{8ZcIm54>fM)_Qbe60lHbWWXN@ApZnp! zOhnILVI(;&B728odqZiMBW*0dJm@hdr4`SQX3ZsHbG z7f4zg4kXvynFpk)qP#_>8cZ-IMaIfU`09yX+WKg4?0#&Y7f!8uf64FpP1w7}ojbLD z*Avgu-HXE)?S6s*PO9zL1+|YvN%T%>#eq%HB~|C-gR!n=vPG8kS*)M#=j;rK{2W6E zEA_0Vow?rj3@bw9&=2=LeWr7$8Y@`c7rE=Xs-d&gP%n#~RMOUrU`^^9#NFuDaTao% zs7YbSvz4ICclnG{((y#9Y3-~Sk3$lDQ1EoM8P4AVPf_Ezj~{P!RYWFY{l}HNJ6QG58Q!svIUvQ#v%&Q0yWqd*R@t((S~2#qc!z_qz;poa2VHIG z2^0!SpFIiO#sPE^lI{4Bsf4$wbdSPt7fUuZewtRX;=({pOd-J`g%2wp_s%2rkwU?HK(Dtm37=%dr;vE+59a>KKMj-VJ?>GZmpb)OsrKicZ;MZKCou)Zy!O-t7!!CFiY6|^ya zO~QwJdmL9wsi6c(JU>K8?i_gX_5tg=z=a1+f4g>mR`g24a7o7PQ*^`>BVAxDFO}Xc zfVIPa8;4S>&(v{Nb(>f06)&SDNNa>2j#m3*@MUB;j5AHcP>Nc3<;D~Fdan?7Dmw<_ z>_)C6_S+P*v{PhP7OVQO`X88;5aF} zz7Vb1mjDQl7E>5=?b_#SR$Zp(tk%E_*tc!ii70ZL%mKD+Tc>iL_cTvsDp+y ztxsbA!}FUk4O6~>JM-IB%oTgWvtkm8KFkiJQ8G*qaMHQ2eXlq+Da{imS(zt@y4 zGPq|ymw;uauQ(44u1}n^A_t(2>k|mv==p|~h(a@r0T>6r?H&&|<0T3ErEe!z>mmp# zC*fX5T{g~nd zm@`9Wzv{AS95cFy7UU_m?Z!v|k0#}Vy_PKGlmZgD-s_hN`kV?~F`7pM`Y&bBO~co+l=y`3no&x%Uap-R#_s8O8GppEJc79NMM1 zr9txc@MNqzHIfGkCslnvX|7s#>|m65C=5#sY|bu$RnI9jCe#e3UOd4I5QZ^H=Sibs zcG0K+-sLM33FT$-{Hfg8;NedIERvV#rUd;szL!M6#O`95aK?9vZ)1AkWzm#>IgzPd zJ)t#;k0%i@1)5U>_^0pZC4_e#+jcA>H;c9lr?3j(pn7c~jr9~| zYM7!_@D$MxV{%q;%<(el5Q6YPvI-G$J0RW4uHWxO*BpyQucN}3o7QNSsE-`c%ftNzq*o;9!bJ|9hhe8<>K2b* zHhNSV!)T_8EmFDz8!^ThfLwXS>3`U;_F;#5DRQ$+%%12vfI%ayFhz=1lX7H$(yAwV zD%5UcE~NCQewCP#G)T2?0R(Rd@PAE&Q6gII=pXKHX7q{Ug=r5xHnYJ_bOLz^Q?~?9 z{%1D_uu_bXM$`xNexFInh;&cTR>pIWRneEiU~L^S>=rrrQkpQm0IM?{H`xK>I?Oie zOpc|5UdfiBaPAS?Sx34l%FdV|xC7@$=4fwSyt76tf;AV$fg`TC-yFv0Our?Oxj&mx zhAh3=&{rfK!IukTP-gZ!+muus&v9M7b@|kHU3~{K1vgae&Ox+0mCE|SIlN_;a{*Dh zqhZkzvM{MQ;?BJHzXyds!3#l01M`WJrCl^k3dWz{NqZ^2b-=V4(BoiJT_V0U;C?mC z<@p&U8!DYMv{*XsgW&3rH#pBo1RvTI?GaSuaL>=2fxEp~)|Cacp0zr5^wNU7y$y7^p zQW7Hua)7<(v$^-_^`LP4q-e*&D0)HL$K^a}pep;pXLd@gI&B&|&?q*{1UuT}ZUfdp z1x;2E`5b_Lg-Caphr=ySzX0Qwe$G8e!g?Kh9H78{*^NJ5Ed_Z%L<0XdDUt;#LL!X+ zju^3LbCq#Qg6VDxTL}yrs|>prbq917X-}lnoquunDOs=M| zczEfmkpZ=_@`cjeHUs^exzC?d;PI(M@j{4xFOIK5KXv!Jy~Qzu$*|7_bX~tRh+BmJ z)Xl6K+WF#Y^n7}juPJ8ZwqYI%jDs5 z{!W4oAhOs7VOId8msk-ekU&|I=K8r7u&b<$! z=tm}h6uU;9B3NWT3pCcdz|z0zNS6-h1_;8X$EmBAQQzK2T&iN3jDsui)LDjy*m!8e{W zFyKk*;4Qgs<|yNK`Vy_mC41=D+4Wjzl2me&3r^S>2QVoHUgFTn=Xdl+Z}05fo8Fod z;9+T`=gaWQB=+#ZtWQPWZ2_62-@Yl?D{BhO zxpbT(Q*Z4T3(WC|MR1P%{TJt5+}>>6AaHcu>l1ZRZSD0WV$YqBxddyb^)*va#^Mi+<5g!{Mk@i8YwX0tDJCPc6L z(o0Du%0#?a{!y7_J}%i>S3`bx4n{M|xf59wqfnZ`#zcmqYN7QN?8C+Q-${?8y>Z&z zFy2LEy{w;*-|FT2dh(7TseQ^ofkpL!t-kRn=@C+oL8q1S^S^LOKYzv9hVfB~LfZXi zwWBJnosvN;%)I7f9_b^`9mC6APlZ{qD1G@##bd?&t|pk2QLg56{E<=hBCCSST}HD# znXzDKy4ROyYPy(>+_%dPXHn|8o)l&6kfN$8JB`fw4gXYbmBJQQt&SqH@=k zpdJWaTCDWC@DieQTcRxLR>k_lfGUexKC#ZO3m0~Al*7rDV*;i78bi|Lo$<}G~9jo>8vQw4M zqx5MEW{Xvp_PzQJ=)x*9MgJg}!EKN(#q?0PApy;IfgBhAJEb$De6q)ZSp2ju0GNWh z$QbrB)k1x^a<7p&i>!+7u*Lu8?qH(;&2aozXs=k0966$~VYLv*@R)Xz@UfC1$k@+& zBe&eU($!USJaf?y1Uwa(x?W`}I1GN#a&g#Ou5L?FWX%?iaeC1lsXpj*=xEUc$&A6Y zc-f7D->N~VAx7M53>3zkBf4p8dtfW+*~D5DHpclZXKEmSGJ)>GKTS2S4oXq6O@8lj zmZ&sR>9h@)3=p=e*V1QjaBwgYYU$XSEU(jGj6v4|fji%=8GZLyZ-GT30qY^mK#i#u z%Tc~!OZdj{{;R#MsVu$BE*7ga3k`QkZL)4j|onm^z7)kEi#aArfrcLd0iE4#GDW;+Ffe54^VH0o@G1yX{qg%aY~|fy8@%$EOyHo zITE9;WtAK~t#t7ep~+^{kX%-&?P@}A!acUu+YS`HGxg*zG)o-{_9eRM`qujKqUe(E zIYCq%Zaqtbvp>}@m5%p|5sAhV3;sloHAV23$5IF*`{g*h>Z*2P1H9?_Zoh^{x#&Sf zc76B4jVEHT#0+sO71l>!{^bKOn~uXQJyfc4_Pv$y`U^<~iT6L<1;YAyGSvl!M_=E* zlSK(J2eE2$MH?FK-E}?bddUfFOYEFKUr-bFa#rpM- z8jTPEynRccYLyN=tzjL>@=RUI*xX9~71`D zda@A)EzPdmbQ7|`lEG9<%OhT!rKoTL+b6eE=ap{sg&kQ7hxBxTkl*klzjWwrDx!AD z20mfSmRBWi0opP8l`|01LcV6ZMOvCyfG8Mo>5?1|NWUn{g&AFOW{94q5P3@Bmz1Yz>^YOY&b6W`I{;*xD>k4=XaM`Xz$)`Cw zI%+@HOJrN8V3WUtnHEd^8BD+1LhLX*AY;4p_qE2)i+AoJTUuWJ1VsmSD{8NGxSk~S zbv<=K5~ikVuL+#?7I}E`s!X^NyG{dxN(660sCU|Ai$&{ii-QKIk>h8O{*^DUFCTGo za#AitB;7XY?`a(TY?}Ne-V?izvUHoN*1ugm;_QAi>f2aD2!~X%TvCkVHNFII=`G$q z{Y%7fsvdc`cu}MCY1%)2H7c?(56{jrJxzG{2~5~`Az_d(CrSn03_;BIb-qoBHEhre zx#&VeOo%((o*4A?tH^`U+xq?z?QDpflzwhMpZV)poFjS?gn?&&sdj^td_}heKxjPx z_2Xd8`hd8I^;KQla+vF3n;t4F3(NjO;4C3Z13CEI`SULZnUF~2*-{3W45m4CfyJNSdg1N7gOgN@*gNbp zS^;qEKH$pq^2u^kyIDt_C8R}A*82sPvw?tj!ScO3HqjV%j-1@UX=rO}>pp}n@su>f zC1s{K35oS7iALYqJJ>UPMMi@&KlcrC{IBG1SQ;ZI^+d8^&cnnc$j`FOM(^=D9Tel8 zI8hHJj<`!3r1ptKo8=$A9J)=fs!T=X(5Ke#vBjgUK>^Nq_Oa{mY*h12r20-iGp@V&q?@i06;t z;G54a7=JMe{mTvU2!*EU^S0UT|K_y6$H2i#-zVgLb#eZGe~*~+2yV;c)lt3w>a@k- z;7pIkq`$l?|KWeo7(jH3od7cSf3q(C@yoK5t1!xxcg^ojlTfb+*L zpdmYkFH%j*m3a4$pZ)T8&YuaczUv$L=h|MtYlK_TD|ADIQ%aQ zljikTQPTSplT3FmwM%_+;JsSn6za}*LB{*ve(UEyMZ~aIC+1c9+pV&>@?~3e$`vk)~|HYO8Z~@Ag*2d?_e|nC8b`Ssf+5dg=?~CUbgUtWk?LUb! z|8qtE-wONxdp}p;_m|i!%0vp>P)t`N$o3(G=pdqY_7+M$QKr5#rJGhDzCI|UW_$Gl ztwT7K1q%;Pd9`{m;(-i`_wvYSIsY(J?&dQcAxnk%0~g5cB$~nnC#^JJa1WL`s(Moj zU&%8W@LVFcBZR;HVabf*pLOvcPyWxp6S+%v-}fVHq@l#u$HRNut8E#Y!dU!5tqeIZ z2lMtk{h1V-GBI=od%#E5fjB818gp!`waa;iNNMDI;$z=Zwd{xVofdBXRI+=<YSV zQy2VwiV*(K#ZTG_sQD;=u}Ml*&ijVv%@IfR(fp;PRK`LCy`#wM>QRCDe2Yo%hanr; z4u=(Tyof1}{xgK6)YR0Yt;vwP6S_Eld`w|%~& zuD`0l@gVYMNKwU~mpFgEM>nC`y8c=s8lX9}Bx*7u{q}F2ttEZDp*VdOzA7+Xh+~7#=s)fhedj20HNw$II)~+m~V9I*38DK3$z+Hy2wW# zBTKUF-TSw;1Rp$!58Xm9?lEXGc9Tiq?O^U^4}CcN)^Ja>sM3=x@EK;Z=(vG|PuSJf z1Erf~P2pGd+vCha&0a0p>JJvW7!9B+-kNhd%t8CjZ$1BM$mqy8Vc0>yV%gIcD0$ZZIjN2b#sYg%ansJCCI5Ju8yR6Jod6FilVlYzVo^Aa#ud zPt*9+Ic|rv_|x0PJ_3hEows7&hw+FD?K^n%rr#M2N4IP=4cNa}*b~n(TUEHk@!aD) zW3X_8StOU<`gFHSj^Fxat`L^q>|?zXzRG7Pg=kL@Q3m?hBdI=p zaW$HA#F+4{@PQIRt7pHxk@G@^g!d<5vi%#`i83Ew)b5p2)F1!#yp?}__~`doR$>Z@ zo9V(ZAtE5xu)7Y>z<7l;m9|1lLsgtv^PK15JZ5)~pT77Ec^6P8%eg74hbcm;BacA$nA~G%IM(> zA?#ZImsUqvC>tJ~3cAS=kW5+K$!oRqIfy`5kwH`8K!vAT&1KMsy6VHNE2{(c8@0n3 zrDg)}U;g@IeFXsZJnjlZhShwZywyU#KC&xK^*ZRWK4J-&M?JuTfwsEPe7Y@OkB-N3 z#vg;-N^w)F+6Leo(ZToo4y!G8dfr7Es(gAE-?qaF^B$#q~E5}_~ z7%}#FZm?*m)YQk=c67q2aYxZ*C$z4ntEn8#SZ}P#$(?dtCepW26|G!EwZ*qwt)Czp z8#EjIHQVy_@fi2hQ*_g937^_^n?gOix`Z4%XIma^%u17A#wx+*KMib_qZX{EK%bi}In_xLU;lVoIG^qYu zs&1%#X`MthM6IA?jHsY>U7bLEn!@g3%?maAHT?eEV~f@cgNDcL(S7YECzv%i2(tHA z#+hO|!_v^mifg=1BQaNH10N;}Kke-^a$;79`#4q?B6?SJu||{WaF_kHrBGT=YMHQ_ z>T-;$bmjAbQq#jDy9-Yfn>`hf=}(f1nHeG)O9xbJ_A-5AMzoFXH}|c>bB6{}knePQ z_g|Z*g*LlR$E?~P^d{@6$Gx|7$KZf zzue!;;DEv1THbAvJ-|6}uXaXYsXu_+gOR|ee^e_l4|!>Nu(UxA z9J{vBn>TOblro=B>|N$EBDRzYVu|o)l$VqYym@KDzst;yvQHP(1X)(|Di3r{ahAe_ zY?*z!=fjAoAST1E)K5T~kt;f$flaT2lnLk2N>4&exBXaLG^LhShcSMvKs=F^EU>?< zyFXZLJHI=?Y%^=S(9a8cdZ&if_~?Vn+$I;p8pF7~+^8YQGXRvEsaRiPH6IF8PRZrq*7h1~~=?d!{JTEf(bYF>B=odKy$?Sn&upGWT+t^z(4IX_vu_x#m>t zOv@Fpr|~ZMMhe>30qJ^iLX#?#%h=#eFA}+M)LzD=UvqnN$SEEKB-d)@@`aPqo|p!) zsK<$WkzK>roxdz#^FZ-`N|uVB)F)k+M!&sN!rs2)$Kqhl9dWFIy1nn>{k+LCzELy*>ac^)MO-=n5Xb z+66738Q&ApUZC*V?--{s9sqU03rx1ad|$2~%)jR`&QqZMk<@Gy#$_y)5-Jgp&&t}_Fk<$m3wvBkCfhQ*|n=shDTU_YCp#5lLS(LzfXz z3VPr_NR4|Cp~5I6-}IC_ab87UMfJyb^egMa!}0;|h`s#^4VQ!J8^${?Jz5^AA2e6a zec6xJ(l(axvAyuR>wu{60@LDP9!c^s1-d>Mw@j z9IYk*V9D$Um%!cwJ{8g8B&fP4x!uG!8D1(48Xd*&HG8Jg3ZasVLNRbwv z+8w*Q-j}f@b`7!?yVhv9@ByX2=*y}pl%!EoxDBkh#Uy#&ji(9sD?LdY zIrAg!$Lj*J5Ytac+B%<^0$p7q_2Ts035n--nAZpOKdPoEgFU-XfJDVrndw~+!{c(f zjV{K9T!T*b0R73vFx|UV&{lFb_xs86DSCcLO;m{Mvek<>Bm4*yto%eX%Csq-G{&+Y zyb@t`9pwF83Ezy;4AM7MT=x1L94n4rZS>xCx+)na1i3KoSr;jB+Mba77Ys+N75Oz+JY zIaoJ96{C||YK=8(@=bOh_7xpQ`78h0 zos5Lx>mtR?rnY!h>g^~)S>9(Uh3cjKB(OH*L-@4O4VquR%e^z{{9&0ms`RG-_CJH4 z2jHW^L&dfnItyd!lrKuy#pePtmYZvFZ;Qi zAPOxo@WA9wbIU-IH0q}m&Y?3L=0l2gtzW2yGZjDD1j>$dQvY=-JsMjeyA#USL3nLQ zt-y5Kut$i8r$^4n>a>VN<5|&-9Z*pdWjZEz2O_CN#q|UD&+Sa{Rk2Belxk&&6;PI*hA*Xz7N}? z<@A*c#;A7AWCen!1>0Twj5Y7BeyVPt33`^}YPa2OL%2V|zpXn;R_n{_htS&%tTwZ( ze%jpOpMq}IOWDRS^2m~N-}OAt_{`XDI7Pm;H#D*6XzJ`K!u`bz+V-zzt+cK$_T8k} zN8FQEDkn=K&Xl}b_Fbdq=`fOtn9;!RPZGsbl!@S@Qx__=_TJ<#W_G^R=6>l;ip1=O zj%jX?v*?1OS^? zst0~PYwX2OXQy^+@bQiv3o&f{l07QiZzy631EXW)Ez*{ECbs0?LxQv>=7EW&6qW>0KX+}eTxyt+ifs;lj{%$mY^8Zs)LYTq_0?`MSG^3W4ls$av3J{S<73hBrh^jS zG1tBXaztC;{Mf>H{kgV9lFa>qlaI;6T+VuY7Riu3QJc&;OK*|zenolFhtAIC?d~C; zsk4Ki`TOngP7yPkfOyNL=i;XxEI)Upe_CbVIn%6}&oFxJVW1Rx^L^(=Z!(9Ikd0C> zYFc#e=10PEzHU5U{6Y=bl~wBN?rpu!jpxY* zCrwy1Pg7o6n9k@G(jK&%Jj$z`5~E)5+*bcUg)VP@y|C=^q06?R5{MRW#7mI|IiMvw z$-4$~by0gdtN-9w{t6NV=A3La^PsDxho4FJA2gry)cKa7aRuj+DT<)XA7~uXsL_pm zTfJA3qY4Fmyf&aZ}3;U4H3)D@@U#<&eW+ET%S}GQzPM6MjoMOhWp)Du4 zPNCx5pQ{{MsNNjJrhTuQ<*aI%<~BQEBXJzC4P zkxb9E+b%obKY9AlDs_*?G9m7Zi+7yS##=P)P{HN$?=09n`e{GTfL6Xsg9$PzH zZ~6US2dAbM5h=ljdu8P5UoS%iGsr;yQ3xd19Ezcg@{G&t>z0Kx5Rq%3gMJB)RCr;+ zS%NcXtoo>113+gNhLcOR3CfgwK{ciggZ5Ry&)~jlML?GqR-LXO|GXp+UM>&am9oIb zx{d@w)5TK8Ua6I=&HFw)^2iBY`IC7X>bnIPs`f~}6Q<>U=@x|9ksXS@gxd-W6oNP3 zJsBXf#+2d@W5!7yyf~$C?PSCG31Ti9ViMeToda4?H%G&RZ}VZ%N8|2CIJTx;ewmu%LI7Hk- zx2&>-@Yoh2^fm+2BoSJdc#R$fo8fZwhZS*Vq$p-Q(3_%s%G{f~+G!Y>5v@K;=F6me zX4|6oq;jcwE`d;x?H-#xr1228Sw#-HM-%po>Vy(SVO|P)R^4kB;}r{zFMC(y(Tx4h z?8vo8mO{%d4SvY;JL!^8K-*F23!ul-PN*)^7_=4u_s0%RQu|#0_4JfhnQ_M5J`CFiL9}+T22uGubAtc^oflh;>l8 zcU%S(+9kg}CKQp_<;Or4;YyX>2B+c4{pPl1ow=9Q}MpdEuCS^D)$B&*WN&g^p&G$R-MA6jB8p=GphAYiRtyJw2$?HM1cH*UbE=|qyPJN>v;b?j5?k~&Rr!Mp>6hfPz(YYr= z)ct66dnQIW-5BGouH#3_)fHu7V__zUYzZ0)_Ut;CZmWCCHgvy>rdcyxxfoHvyEiRK z8eZPq73_L)B8Z|ltL}=b_#Edf7x8QKGaK=LmRx^z)Bmw^zKX-JxKsDUj^u5%{Om8dE!93K|5^0Oty(|&Q|*T>BlZCs94}8_etiagEHSL4Qv;}^>#QY@ zD&$zsaJ;T?yOfRe)12JDa%^QXz(k#oZ*JSPwR>|=w=~ab{ytzv($AF2lJcyFj^rJg z5_R_uCCM*xJ8YUO&e0krQ(oRAe?U!4!`f|MYnyn%aP<2A)gkW?nj5~?gEEJZ^xLZw zXEs06p_9A&d@*;2BUQ4-HWy@T8p9$Bzfk@vl;@1cI()EbA-i;wfauvmf5A@{WCS{+ z%%lClhAE`0>34DB&yyq3*6)Y!0?N{OmhS-ICOR8L&jP?lY?rO)3l(cQjEFu_@>>Nr zVj-Y0^cNL5RfMLf+~n%5(=mLy)uW@KiKG3{IHcpxVVoX8N^Zpq;m5&10iH6u8R}&$%tn*^Hd9~Zl9%EfmTgV*0=y`R zR@S9y>lM=jL$Z;alZbv@X45|N#ZBpvH^)+?M@p}O3KQGUu7z+|BZEtKie3!9snoGw zPnIvAv(CH2bkAw6RyRgIUbSSq5c4d*Xf)NhY`^pomhRZbZO+pq@_j<@sazybYT&AC zJZt>T&|11;;=~y$uA-Aei?iv}n19ni{PjQYPl1MkWQXKg(E-p&lJLUK_hQiBRc7KM zUcLJA_U+qX$Ax4jL%kgkNSlySGTFPix$&*H(pVnsZN7O1xCNqbGXJ@27G++6DiYqp z&@ch$w(V&-A8O&jHLQiF=n8Eyb797na*|iP!&(>fA6}76A*y&P8qlYPYGzQ!KS4(< zikm2dVhadnRV%*Qs9|`Ovae*kGbHDSh2On(>7nKmMA;{dEGsIZW0qKKZY)ifXM6xK zrH=Ap%cgjdH+5a0Q(nC`ns~iN>u5=G*I|d>OM3Ob+cB$qpQ{ti=leK!gH^uSj!i9& z52f*cZ*Er9ut`sL9C9I3DPB&V2A)Yxd6;;t3&&!y`FK6BvR7%oYHB#7hgL_M^y7b` zEZP7Efg@|DhJ*6P9EO!#5}Eeks84l1Cexsi58KE+@Mi$&(ib1W@cHzNQS=2=hKWMZ zO?4LGgWDBvGt&0$Sos|LRZaRBg=ZZZ)RXgby%hg9T*LhzSxpAGXY)-`W(uqqHL#-F z)6_z0KrqmUu)p+$sy9?5sPZEeLRgqP95}&yK2*%0MfV3iZs@cAWcidh=(s18<`>C7 zc1hOXcoKJOB=5szZcoyd+$z{CdByN%MXbl_68j5}OZ6w?45kW!tYX)$Iz8Q)5(I|n z%UxO~noM$^X|T;1Ai6)%T!2|WQSh1vmy-XO?afZas=%SDiqtFJPEtq>SmHM6d;X>l8lHOlc~#8rZ28uMr!OF% z>Rj?*bgkl9sNbaU#}^dw_pxYTx{CJI>+XSpkbEwQr9JNa$^6uGr?Er61LvnIMi zq9J-f*gymp@Nef2t^M7`yWoi7Kez2c1BiNu+%LUG#pHpvpX6CXyUKD2qU4Y@nO zlJ%;Vy_FcvryH`9JxN-s{6We>-r5jnliN#D|s%{UY!M3jcP3QGKA{7SWNp@CH()O z_Fre?9MRMDk+8$sKv%Ga7Q>F@Mg{zb-2MRR%(cJ%VmRBEn}S&AR|cGk7R%s+6QK@l z-(z(FOfmBIK$ROOi!5UDnx`KTy2+<1Jtn)UL<43Svb5sV>O9k-!8QAp+UxOPi-{qP z;(VK?HTk2`3zKXU$vxS|7+k24qQIPJCYYvIvkkZvR{w1aUdF~uK4HSVNM4Jox3%!n zE2iG8m#eqM-sVBYAZCNhazfzr(V!b*`kZJ%PXCNWFDweKAl&Rr@Adv7+g-3T5y#IC zKf`-|cNl1t4J{&SUL8%VykRA0%}qlF+X?^Wwi0V6<>#klGcQV&x%*uGm#yW6PeL;fEZ+nuNRMYx60><(}gzr14R!)~GW{{@Yq&8MpOGut)r6orq zV-Vkymkpn7&tBP&TbkNisqnv)Wn9g&>c^AmbN=Q>Sv$+wo8xu<=mg>k`TeZpFS(qx z=QFg%+I#}=+ZXR#zK!EJUMF~YU-0FzLP5$PLDi4#>9RrxB6R|fB}*^zJ=vhoAeX!w+2En{{wLbDs5?hn zhm#U#@>t9Evh-f+q@8hG8GF#1YZydeAP5FjtjYsK@jeYG;UPJHt7Ar;$pJ<^U+y$T z3NnFNHK^EjmCtgzBgs!-z2oT$%&H0A#Z=Hu^Co&aVzs&*!V0?aO7% z!FW?~k!8v2MJ^3=PY7C0Ej@n9#;e#w;d?U#L7;8+7PYGw5%|qS9!sBr!vQQFrubP46rr zuiE|ccKdki*ty>13xgk6gGwiBF5U30F7SP>7P*@=T#!@Zv`P+#Ec~(vwN~2Q| zRhwvYA9fL`8YSM0?o5Ikc5b6lI6hqn2X zDBS=zq|7#w0;gdpt!Kh1eSDZ@(}>fXt-4Z`W5;_fijN19M1FmXx*+MNA}jSoRa{e6 z^X3B^Mm4rS5s8VYk+mEiIMpjqJg>`;idWtz{}ehCyKyK+>-zQ1@9?1^E@qS32fbIb zKHIHrJQ$AukHz_1fd&exR`WMgd%7R=LLS{DjOmULwtsdrf_Ww}8W+()NYa2$K2{G~ zcl%w9xZ!XCz}iFtkY{CcXe|-BH4U7}limx49y1P9Zg=D+=WHB|Y>yv5?s@Qg*ZHe8 zHqFAR{6qW2(SzcUD}Qp8f57yA@!eGsXlMzR5-e)}GZOZv|M$Bh9K5{V#Af>Ix%;0z z!?`G+p73ni3ts#e2meTcgSYG^gSr2Uizavk;(grWX*Kr$;^1X@ng zCD^gdfgY_5;Ye(V6jVKTU53IZgHb0@$ZAfhH{UE49Cc5Q6Sh9T_4_P<(-(=euWKXV zp3=O5DwYoap7k%^-+qGkRDvoj8pV26db>fF!fi z$6pzHw>XV>ImcpUQcTi6qqP1Xd;b|0RrY*=!ir)55mbVLfQq65f+#tgKt+Ng zIp+)_IdlUu7>J@Gl95c4Brdv~3@9eowHzcLA$)4S3^&+TKCs?6)RHK0Tg@^uJAQ5ZZ7^^JBO zj4x+&T{})FPyu^bA^p+_ARKQ1!TlugXAd4ccmi5`=I*28VbdnEYHefz8jcG8k$r!7 z$Dbdp{#g9(&O{I>&xGjIygWAxKm~`MNWU35F%MUjy((Qmc?Z2MCI${YaO;_la|T&u zw`0U-LFdPDvSvS;2%6e+3IZA4j78LW`Xd7j=QkeV7uZVU3-M4K)Pvib($od#hCHCE zb2CGyvi2-cHFe%K+!ki6K5a&Dc&qEy3qN#en?lKLM2&1u1#C?&Mn6>KHEZv09aT^g z094|@#Kc4^r;V5JcCs1$4^Q8&fgT@I)9J;zx#xi53m$~!a29e#_JRsVMv3!NU6@I0 zp(=Ajo`cOyGy2RT<#ST*b=g|H+1;=nZBV5-Vg9Yu=)Qaq+2;nA_SNGe0gpf`UYHA3_S~ks6HGs69QO?v0fLK=2orw4qtbI|(07F0^=w-li6c{vUzUS(h`)t&fht zUwTwI8aDq$rSUG-&?fsK8Qmw4HP!P*AIulW40Q zbkmq@SX~F*xsR`}JUR(*kUOZmXAjx6yva3fj>?n&sDjlWt_@Z%`T!^ONva0mKaMR* zZUaI%C%TY8e-RpN7#kX6G_^P#lOE~eq)`%t)8DP~o)}b}Xsn<5 z`}>cMgcU8;UPNDqeDgJ^+^@|%Du%-3bRnd+(}5A>TzU2MFT4HXL)U>dYV_0*w3y=G z4MDQb;<8tSUj)=B_ud&_r#`3hYEWpQb&B?W3(GquaUTjY89^R0F_{pqk2??3=c(4v z?rSYi-DSz0J=)IY(4HiBdJHrzswoy^MDZt~sPzIeB76)c?>r!i3WC4gy+2$#mW>Xj zB1_5zsRx)o-8A&fVX_ydo|A5F+p6mphhBv|$M0+`j=EHX#N$4aaujPlXpKZH27}s3 zJ(9YFqfj&SAs+~QU0D^W_Dp=m?{_FbpX>nmH}z5|)SpL3Jd_6onq%iwb8Tqv>{wYC zZ#_f?=#I|2(3VUv0biJD(#n!_JLX}Bi1qL--N8;{DB8_}-qPdJGOoKvH3VIj-`q{Q zQ<>x~lI7R6i0#8tR{4#t-n=pn-H|V#OCPpofpCb8h$-O!m}%5_V(t_%8H-@3-$L&g%>l0Ysdk$*0-l9kz3|n&vO$rT6*O;9sitv;Wc)>@PNMUq7iry)4Xf=v zGiF!HZOpJ+}Y^cJyR!=$L&v zBqOAaDxK~v>H1A5Co|r(*`$Pa8^8#Q_llYhwX5Wqd?W~EpwdhZ%k6kX+ir*9nn!In zXI)Fto`7?A=$q_^G~D?pUE>Ds6H=^IJSHvIvz-$CVm{{wX*k`;E=!*#bE^Qkv??q7w6nRuGoBm?n}1hytFPG}lpQ6FAlzWbN|J zxscWxJ;*RlLwyvAuI;_WKs^^2GQe_6W)Lm&vs3wu{^G>(Q~$b+H`{v^&`#wK--&9M(gh z2m5vh$dq&dLd^1s0y9~KIk}L;PV{x$c2d~q*wT zBKN;s&oaZme(PYaa$Eu0eGVUXYU6BupJAMcoM=lmc+UND5Q!OrMBoR2Q`Gt|h}d+; zuV#PBXgx7k%A%J41~0r0nlGwX_)FFoyDS&a=kKbZSGDQB!umdC4zrX}Dl?DxBGr7e zSD{iP6^9&eIZH@zj;<=RUIzT8Cg|k!Tb&`(@CO9-B!^tQl<4o!=9{VE+x&t*h7 zTQl;^yO`m~fqZ3^t&)%QGs+o;c&)8gJ#t6tvyywCFMkZ;h~yV9dyxV9CkcbxLaFkV zGC<9Npqm>VSFeus@Jo`P&KVo=LRRtf;O{?vn3e-(_sM0y$$8C4bNsF5hU{F&x#3_m zW7a!HjlD|Sjad69$Bs>uBrKs9N~XsS=Q8z6L-9wDD)%pX#eXD5b4$Ys)s4o9mSU*`ksJ zzhrGa`eyYa#A+_ydp|^VoSMJgOT{H?{?>p#V@}JgQS6Y>EKB>cEnc&@0ex~p86%c0 zBB3y3h!?^^tQ79o`U!*UHj=j_yGX;P)KIFK9%I>88h@d{qJ@K&4|(LhKzfA4D#Voa z$P|Sf%!pcbtHDB!z1DHH?f5%hJa`=mhdLa@Zqb_Uua5(Hm8c;gaFFl!phRfzSH&oY zXWD{4a4}+PRQ+Yfm92sm#eYP*$0A6S+}X)anIy^)Wb-Q2>LA#<6{p+Nn0TA%1|)Cu zwco&D>d7wh90bTB4Yw}%Lw^4z0SaTl`Za}>b`}ndAuC4&Y!WB54SG1El0ILqj^D1B zY#e87FO>}Zp;hc6>diDR-y(}8!z4$SOsCLP#at;=qe%A{C-ZRZTdNYoG*K0Ny9xMh zvMkNy2Jv`fDvb$&`3RFeYM}}gAZ_K|bv#CA*iMXt$0WbQB!b1ow7dXZN_^<9;YHBoG~@sLsVn__NR0$6e62{Imz%^y42R8I9|D!3-!$u6nDdjbS4 z^i--30yc+L)yj2bv-2?S8u?W0ToX&9Q!kJ@I{bCtI&UWnYNmKh29ufbx|aXj{2cTV zyCAArU?=>3y{>tu^=Gv+Kbq8Hs)mg*=PB{Wqpn@ifBA%~{%%xmZCc4xE`VS!R4cUk zIJUEJ3d(8*q4MVhib)z2hSbPN1r@aHXj^il1EX@l`+q2Q!d=->3FYAcIAH{P6@~Iz z=Gy0=gjMOd_880Gr03N6%>^V@7jIT7Fp?!GKpeNG)b-BUb{`ki&pUJ#OJJEahv5A% zl!vUFTt(U(3)UgcSS=!&sxn@viD7EaewRii*7_6+yL0V%JZ|BT{qf7f{!~Q%KFWH- ziPcKmzkr(44L}77?Vp=(mI>XKWY?gTtPAp+Bef{Mq0ywkhdEFck_0U!-IuB629=AC zU|!iMT+x2qS*D`DZRCxu8}j2Nw0frA4bww_e52S+yq>JexchYV zi{Dq;V@o2?9Hu}cy2@DE7h$G(n|80BB_*bTg>fT&wzj6I}7 zpZ<3|byuQ>!n>0S8ILO{6cdEo4rOOOs4qmLNK&;0SyN~rT{iY7>t+#k`gIkn zx3LsJ3L-vR*JSF+4YICNTWnJZlPk(gcG3lho7pm^Kk5@96UfjT(lKs3=^C?zUGFDggB%Fix{v>Jf6?1xgt zQz5tVppcV@4aahaC< zZo8goV?2;=rHlL+gjrNxV@N1W76ANBDhYWT0^@}_jL&gaFG2UHVuZuMUgd)OaY^fI zfZ~U=sG%MpMusI=sZEvSJz6`_q125NjhyP~XA4KZV6kv`x7m9UpI)}!$>4^ZtK;=m zeI*^x9d%rWOnd*~^W{Dbr3hz#rfZLatKU|1Xv=rok|B!(-=iqgJ{wfWx7sWO3p&om zt^qrRc^e+Yc7xef%z5D?Z=jrvgFLBHHc7UKoXU*K2L4(_h61;CwN*^v(c5wuLs`~i z6T)|6K!x~PXSOjD?%G2*x`ZYHeWKmi>ws`1!=#gR!gi(%$N-x8HI=*Sg~)R%V;4M# zQrhOCBF!QC&DUte`4NZg%M$$m;;Ik;tV%a~5L z74oL1RdboP-MabWjJ8P4aD6x{&~13p!6K#v*(7KVQ{nQ`ajw|edi}R1i4ra|Bn>j8Pb_?I*KmjDa?GNjIkISx#AM|LT3M@H(XB`vM``-bTxGA|1T?nB#nKifUdOh>nxbLU13tExTUx zN(5jwhY=%uk&kT2=|`TPQ{`z~wOO20{TRm zQU)S zsUMO)4?z_@1eFU1@{2UR5Rb|sI_NwJ)pb95!CRhnkU(^>eq7?OVA5M?3v%gv_oDVj zciM~VT&hR`6a}v+oZ`8*zk?=2q32&Kn58PF_wJBr{nSkRxMe(rHpO?8yCCA2!0;CV z12t8Di;I@&9IoqY%#WQQfpd?XAoaDk&Ezy$Mm z$nXpREnI}#_~m=nE7z|kMm zSTb%#^#d-jiBhb0}FAZW+{v854bUU0+E^s+zQ5BU?1Rre#jMZfh=|tPn_O z%P3+B2_TYwZ4KkD%mkUSUU>lX?dZVssgU{DNG0va|c5<>|6@C_)*^I)Q|QV4(5 zz|>GKV;x&7C&b~U1}h@mkyt5KG1KyVD8c&`P1Vre1AwXHn@*6}g(d|e84BSV3m30c z!;xKU0}Mb91iuZ69{MiSQ2I%UUgY*kp?YPzU*$GP3j;3)v(uDYD|x#y*-hszQ28_v zvBq|;E1XOfNPTOIS*#btet@FhEj~5TAV{T9o>OVDDJ5vuewlJWr{0FW%w*$&G-SWWWLoZTLIoxbvarR6`D)Q=~Qu;=#YxKY`ZLhWsSvZMKE!s{!nE@O3KwDXd|7vjcH zRQEw$pqqgQAWCrd@il5ko2VdKO=u(R%xRUHpXRn+zH%k?+T8fyAd~fQZGdIzO4V;# z;dZ^6d-v_*l2lnB2=`4F{s!kwgmcyuK$q=;&WD@PfjqYy;h@x<1}WI)8w33}@7A7h z=7;JWPirAKn(`tbDbS|NpHqy?1NPN#{NcO0Yl1i|b7jK#8jA@c^V&G&YRFRuMQh8G z-4u8jTXB@alMEcBazd+NBS|xefurv_W4x-SiK3ipEAk(;sV&H-cc7|L=338Zm^L@e zKp>#b8){qfh!)qzqw{`GqinKi^J+X+70-4%5|(jCkx}I+aJzb3;%`9;y0pjY?F=a; zoZ=SMRWeqf9nOUbf;<4EZ#tIv*+&h{=Z5R*f>=|g2p})(R&*vI8mO)7G%PU@>qB*# zm#C~dkZFpQ?bOAmHBuCa>_{WD$6#(r(=;(^jP{(cXglzjAVamss`1F5<(2=a&$~Y+ zHL7eSAxs?8^9*;}`T zv}Rwt?w{pcJO(9Mz91AtQb=Sq|9ktV_db(vx=I6b1#wXpMZre-Y zbcW<$h)oAuY4TTg7FO!3Vh)OzXfCO}ardkyCVn9=R!DSQ`9L6Ttk?11DE3_6V;p+0|aQ3d_$kdO@|b_NNPXT(S4JbUMn zw_3v?1`0_l#m#pM(`hI^#-Ce3$S&wbkO zf8-+b9i_aC+;eSjrups!PIWIu61s(~;_>fDIrRD@dmRRSuODxPhjAx2s4tZkb|pQq zhN5QXr>RFr?_XD#;Z?-1LKUEv2%RKgW6}q0wV2eOo1Wbh*~^g>M=tL&Wvb~-Xr|IJ z*Swqe&d?C_oIFSRDc%&oh2f=NRGm2D`D0%`XdPSCs23)lfw=4K|N#!IH5{WL1+-Uok*YkYtuv)$xFr?+P#-^p}ueU zxu?gj>s$mxpu5!jpkaa)bYe5Cc3v2#g8j~$G9|U^&eM5ld{e(aF6zEht9jC$3HU%p z-tK!>*6*QALf+MZOlK`)5patKL;KbYkfP?X&d?Gr%&B^OI@T-g?7c9e$7fSYv==ax zCiw0V5gPtH%AM07)(Xfh(LO0CEDi#{*cbGeMO@j4_Yry!8LmSAKufy2mEpisrq&?{ zVb3kavP45ZxmGbl`fVYhw+o@`#TvJ9Oo1*6bK}4yRR8+?fzruEcY`F>57yfA7?U(* zk_YkJH_yo*ka;_+*40vABSrEUIicF;m7G?{qS?VM&o6yxn9}0bIeDDaYfRPUx(?!; zve^E4C?SPT#osK4^Jr~2YKa>!a=nc4jx%)RJmI+<+I**c9nNCjQo^Q^NX=GyIh8!% za&Zd2Ad0fRQf8Yj*;S`rLHLdU(#L&vUFIuOWUCud`0U=ZU&7v16}&_-j)+7BwAn$Q ziy4p=*Oy1oCC`SHCWJ#H=M^_A5|;$>y)F2Nr==sY+vXpdgW$b#>q;S7=Jm=v{xnUj z^iu3S8+I4XJpXy^$9F&Td!|~SE6J1NUQr`nee1Ei8V(VRf>YUY)6XXHAtJW|P~Iad zxb@&FjU^ApG3S0ruQ3H1Nzq)#CR5&&!EUHYPCOGi|9rLK3hv^C68k0`Wg+)M1ux@# z_vLlThpxY_>@Dddr;a-||M2rj zyiihnJabwpZag1a^yokpUzv}Cc$eHVKQX!7;}t@?D+;7EBH>dQq4|dgD%AKEFuNV8 zDQk)4aw9>xUIsiSLa`AEc4rA<4a)= z;viK`c=~0(;N(+zCF!{vb2sHRZOUp1yiBAQTcNn(-URa-DVX^TxR zLJ->Eq)Ya>f+kMjM#NJjM}n3silALCD%Z&xUcV+P$<6S!@ zk(R!LT#7+|BK&uKj%dAR(n)*O~&W) zT5VNz+PXOtmNZlnC_|*QF_ac;L2ccAimDej%rhR^R<8o3T#r!z`j=kK5(x_sp$I5V z0M;EZX=yx`RSJ)MQ5C>anlRpR)~y7(rHGR>Sx8HwrO*UF7X$cCsZwrY>*l3~y9InD z{>_irv)}DyQ^`I9ps1lqbO@ZhY0?IL=VOWH#kE2l@>^KMNX2-qv_q|f85g-F>V$vR zT0|^~;B@b(at;z&G;Sw~gAT;%ofC%h-)_({-MdH3GT1DMI4X28ApP7$E8d@s?y+xo z|KKSkC*TJu#KXVuK0|oW4=(+_7jeTuBBF+KuP2ZE$94aFEag>bGJ4EM;P)-$mv4?b zwR2~b>gA4$-@n5@fBOfYaON>!_bwf_z5ENG^xe;iNfLUG{g!F?gP;8ANW!bhQf%Ko z`r!OH$YlK20DkwhZSF5A5{;icx;uOECA+G|$7Wvpt=zqxh?q)tdtp?Vz%MnU`|H74 zrX*lJQtF5;bzq0Dlywhzuo$1Ui>O91)%;%VmcA7(4mk~7w1x7Rds-7DMwrz{PHgRK zcZM*__GH(n0bOiMPj)xwIJT{13RAvki$-J=4Mue6wc78^g@5_x@?07Ux86llt)0JY z=D&Xt*KJrMPh{DDWjfDrxR0AO2G6S8&idB2`zF;_L#LtC;<8Hl-jGm$IR59e#Ztu} zrsey?()Ew^qvtOuy{`*sG?SWC3iJKya#?UsY znXqtKO-t%t{>l&ei9z;hVzT3pPNO%a$|Hy3a&5arMjQL*<%1!J5+(t7qaG20%cPpc^K)f?*!nyrdR?v6;JnAvr=Ivm$ z&-bq{{*?#2<6tvf5T5*{c6NU~Pxd|BcCDE2;T9c>7y@<~9K+&P1_Va$j1Js(LgVO_ zt&U15xIYBB^Oh!H=N`%oxa|Ok-|MZ8iY9o!(nrEuoA8}pN^sj_n(Brvj!GhI3hI3o z48JnZ-(7Q!O;+x`F6+wcI`#bQFC$t%e_QwXJ@aFY1!sc_9&Wa(a%wPeOU~E(Z_1aG z>qy!T`Gju1i0~ILDY4tHbW{%vZVH@UX(+sZ*3(%zyQ*IlcxyJ8x=G^65|9~u49hwofhj8Yxh-PmKKBrX*2WA(*WvE6ps#ZV`Q{Un#8G(*BriJVFsZ6EmSw^mg?7n!%Bw|o z`aFWo|7|E<*N({>9(|*}q;tg2>Q6JujsizOsuMI9gS76VpZUt#CIku zqWQF1)~yzmBfWu+JCv}|>ujo1dp5Fm5el`3?0c*v*TcwuzPi3!l7HGm=s}3PUPvDZ zE3%x-&tDuVGqO3Es)~8bIb{*|w9eKqp9$>Y7yqWQDcR%pZ$uS4zH z3aQT8h7iR_q`h5*H7T`THOMb@^@r{F^T&VbA3V$uX>tai;4g(%c}m3&GvX2#Eqm9N zyWZd6wCmn@U%EO;zcI6rE)E$h9w)?W8KLEBQ4FalIbETg4{eU-)T^Kt1&;{oWQBA; zP@JR0W#G2tv=e1vaUWD!26$W5_LxPqzr$1r_sp~!4T}KLh z53bThtma4T2oG}^*Qt8JjpUi>q8gn~FM3R{=v|rF z`E>rdjPN1r;d)>Ha0i$9=^j?m=XX>2$N8p;pz*d!b-Y<{}NUEsS{ zX6+PoJfoYVVXLM0!fdRI*G61C?X);~#P}9rg=j37yrA47Y}a>A^toa}$;-a=O5ZZC zga{;0*T!%qO{G6_t-15wT$7nAR#;+qM+1~@eACy;NC$m+<43S{<}P0v$T12LBBF)% z*q4HoG@7$hAl0c4c~v#14yumz*EtwhtXIvzO6Pb(fo?T&KJhx*(xeDqUo_Ym*+T*6 z0+fA?+jjh5SCGchibvQx*nIk}tVQ=v6p3j*#xFP6`qURKkk0^K@zD~~lfUML9jQQf z%%D({KzhW!cN}r$W<;i?rTIa*bJ!B`rLlT&9vyZBTRexnClC$*N{M+?>b%;5zeulW zo3LP8oOQxlNnOWsg@>zGq#8m>WUV_!Vrk79YKByis{=v0kpAOMFkSj36Z&67_9EYn zq~TPlTft|4x(zXlix0_q&X%d$>%!bwHMqyAr?+@zhOw`hP2<(PPHkk_v9$HEoEb*V4HLT_^}N0?gz)h4b0*?M zxgtDonU{2UF58;WjOUFRP=uKRz60iAN>Md=slB7m;Zjpz@SR3lPtaRoEU{0xP21k1 zk;p4*EBGZ=X+!cQ(jU3LpLr*-Ymm?gYPgWDRC=O!O+uER%(-KBXy%I?`n|5d)Z?=p zGIa*eP`r^g16IEEq=f%+s z!qFfo1a7`bDci^j)|jLXEae9OM#e2YY%l5Eps(#@CEJL0)AO;QlKWigx~=>08G0WD z7n~5bou)G_&1k)90lP^GkKJS`_N5Jit5ZexZ9~8@7)-#ZVWL(6!%*q(I;+WPSl_*C z_*^&ukIb^Idn7?}Zrm&)x*voB$lJGN46T}BzX(z20i?_xTA z)b`6~tLAj%0Y-u4a-+Ud_4V7~0=7Q4SFv=8_Q$vwyY&|M=xuR3K{+9n|;b_nhLdzUqsY5cC?S1~vY~E`IVmiAE4m zdTAh^pZ;^4$Cvf*{!a_w&p-alKmOk`iHS+09eL$nR_8~%iDYK>Y;7_Fk4F*N=%-{U zZ*6$bkizh0Dv3Y;@nZeSq#Tny0_!3$qu$`g*470ZA*G^oMC!qhP3yaZ#P{zbrVo*z zVwFJXsh_>i4`<&!lLDd&Z+))4TOCSR7e^+{UT$q&e7X$lg6(DF$)9}1Pd@qXLs%F8 zH*w$3;QvkB_oMN<&Hvwu+q|s)Z^do$hu|t(?pATtJ^SWuvQx^}u3_K5FmBdu>mt=1 zLbaY-y(ja7v|PhZcRTa0s~b~JRgYhLL>n%#OXXLb`hoxRx&ls)ukGy_!fZtO?9@Q$ z8VCtnnfP?uK5EwuqK~;!#B)GiUZ3lV+~&N|8Atbp3EdShc~0H>;$?gcx@x=g6z!GW zOB^f4!JFOV-`#%pQ!y0ae9(^=iw&WN95*UC*)$9N4t?%DmUHuqh8}N-i)VglZ^l^S zWaBF;%E?)1KNfp%-e9@l#il1|brB#bg3dC`uqu!^myYD^s^7Yoj zvP2sQ%Wk^vekJ;^L-)_uc0UMZ1oqdJ7w&Ft3If?-3dXS8=Kcz@zcY=W4wUR=!f`oU z>EV_R*aXSbjxj+mk^#i2T=lt|* z6t7~~!($ZvEgIvcCU7(zKX8ga9Rf2Zm>u(-*o>WCH~L#K3Dp(;qVzIC_&f*a^>@3j z&=n3w@fmHD=*%CFiI%}ekkt$R^rtpE3ksvN@ar$1vA-RGY&m{T_ z0eS8KJ*!Sk7fz(L1Ew(4rp)`MgjP2r!xK}aqbg57rHRN;Y>e)Q{;3#1+Ppn^=P550(`ECC``+r}U1McB{>VDcD?Qdb^;*z zJ~FPj=Fp@1kh05~+p&AU4>Ux(n7k7KP-=_Wh|A%{pC8ic0FgQaEwT!*5t5t$WP}55 zg$-&0&Y0!iQ#4mMN=xVpOa>o`I4wVlwntCTOtHFB_u)U1%{<4t2=AKjvKZv$`@#0` zQ?Ga?O3ZfqYLk2bX)H@AuoXJKKwgDK)ElwX!wYEPH;HMBJRf6TELWxQTUG~dEc6BR zlJ?;`JLt$nH$K1KYt=!X=KJJ%0*}BTV)5t!L)XO?rHuRXYPgcfs_~^>(|Lj2TUno; z)PMtQh}LiFbIx&Zd&J;$CbaI-ZhA^ceAnlKDgy;tcu6hxCR9`W{doIaE;8SGMFDJ= z8kD5{SkozvH!dr)4$Ge(4Psq4oKw_`cAMq{sd&EE*YsD05D@UOBK>Z>Vhl3FK zuD*3@5R3DNd{Wi+-AA96{Eq zKS%;rdUKS%64n7STL4PK9(eC>nIfIWlazpJJ_%^}Mi87cn>1bnjT}E{LL!{3(F07c zH3XEmo-6HL=GU99dYHF2YvPlz#Oz69-zmCiS$GAVK`lt{9}GXDS%i z&)18rPAY-!j$IFQtYR$KHV**n!OR+VZ%Wy;t|o-$+5pXmO-46u|W`OQ>aXNp{k8iH_;vi@jr`s!|^bkF^m}@;+_opAwS>zut z-N0i~?);cQVdSP%|Pf&|$MzC64Bd8QB~)fc^?nlAvwAJwI=2Iev$ zvnE0d-J}`K`*#e!ViGC-=qw{(XVZOgTE?nn)PvWt$547T;nmmqIjafF>gvWAQA+h9 zu6@3inLAEz#neN=F_Z*rvAb$&K@CcInSW{uh6FPGUDrr>6Bgeel6eo*l1O=k$k*~6 zStPYd(Q`nJ%4+y3uc#g<{{nbx%~?_RNDd_|mS7Paq$gb01{wXs?R)v1mZrn$EkAK2 znSfw(2VMM~kC z6F}Z)MnpIG?|dlaH(&GcH^@WGM*6RocgcuMKfaz$Zqfr;??FGIlhX{VT0*$@Syls_ zj}Q&#>bC;+&4nnz$$Ob)X_(ST`uGrKeVsg_-Z+-z1CT)L9yE>tNy)3}?9s5x#iFYn z=o7?Ia*Shvoq>uP!NgJiLbD(E#uH=i=W&mjqAm*?HALm(7rW*zO=i^#uqLyIvs@uy z=NE_?2&5msxO!Logl09Yi07{Ljw9hTXT!qM3ZTIilRTpLO%4d2hdPt+CD;K~K~H<) zxwOF9JBI~5gXKg=!mOp&+wO+r+;;5$fRoZi(YZzNn5)Fj#5=~4v@_yICFYjG!MP~& zIfKMY2gt}+cY5bgMadD5BgFlT>Zj;RM%)k*2HQtJ$|dX-v%LFp3n{KBS%}&^pRu_k z@4U&iI94$IR8IagFgnVnUz2yQub^FfkFAASgn;ypoh52tiMFJC;OhL?b9#+}`}$eQ zM=aYdJ3%~bV(#-u_X_1nY3;$g88~1s)w9SaSdVoms##sj22>32P{JjTf4&RP ze=9t=3SRjAqzJZAEHOxPXo#Eli2gVbaO zD3I_0*L(uF8Qegb_5lh5yG6m!OEY}PAvcW@T!~V?(T&N%xu-^;LEj_6TPQphr#Rr* ziP2`HrP_fr#{iMqqr!AG1#0wp26c7xvs;Pz-?YL(A&=I4#K|tH(cKp}XKa#Q_00ju4v!rl^q~v{i?kh~e9-$QZU&Bl zw30nMRs-+Nc!^`_OixER=uo>MCsOk=$2-s7D&aSu5yYZnBrxn!h2{fa6bIUhsw>|d z_Ygh5Exaw)G)OupFr6;Xq-lrx)t`m~o1?!!u;ZUTXQsOhv09BM!CoH-@te3m??^vk zZ+OLJd`D>I%X2F*?5iLiJMi?%{wKPA{LF;#!AQEjkbm&{QcJiZ37=&j zt0G8xitPPEEeg*PLfBms^bJl~^lThu*j$D};ts}U;AhOl?Enap32f6v>I^n44)A$M`GPP$80Mm5BsIY_lJ z%dzpSgbY$86r0^AWs^Y9SYK9;O6GGYL!>4d~!NM zDLnzWgawsE4QJ0sT*f5f=FjDIAKXoEBU_R|sgvN0saNLp4q`iZ)qVkYohpUqoa1S` zqe4-=R)Sl3*VN;(CENn7hC?K=6j%_R&s3BqG|92*wyM^DJ7QhWe_GH5xL%bYiew#> zy^Nv!paH0L=$?(bv|JFkTTWe_p0F=1wnH~cv%u)k;&#+Q)z}p`1UGjz@^c zQp`8d@21Jt4BrZNm-Y~ao5iil3vx+3IeZ!J(UIjrf3zQL&(53(+`Q9> zTSd0h1^ca)qfUcM{#^+i-nkQ78dXiw?^)-8zedWjcBfcOJ-$I&;~51lN{ z*h=d|nkLyBg}akcxLBCUwM%MxNCf@HBPyE!x%73o;l+`u8Da(h1#VL{#c#Ka7UDf+@t zGHFslN8$pj#%nZ{pn{M&clKB~QKM=R1QU*p5VpPo=N|@a%nV?MuQACTTYIT$@dQ}T z{P(G{=T7tL4vsc5dI8XC5d00V69!81x=oVldg%po)OwiWnc>C|LU5L4a9XGa310>f#y|+oyg$TwufIHhIK*@oPkmpP5QR)= zZV24jh9ex%ur4ElgcwYJb&MaRPrV3-43N!ZNK&!cSjUsDEbl_ZeYK{oAh3SPh393D z!U=;D8lV{gKX`Z<1QPVNkA3OvZY#6I@(ncX7$hebJ}}7W!sRD8-r%HO!tHFK=Fs6k zPQTh}zGSc}pL6Opwk+qfirUhIpl;S8`!|yb47ig8zCyl*X z4`ynqcK_q402Dt+)}AH5;IjOcZ>igQa5Tohp0UO}%%@6UBhLj@)hXu5;Q>z z2}OH&yOCEU~trOM+b{R0o8DuoYA*XL_% zimAlZ_UR;bEwGbA<<%X5&q$PzOnYkMnER|_B<06F|F^iYM#;^Y%CL^ONx{%b$a>L zTBCZ`ujgg{Vpw|J((*qbSnZ1M7aj0o)L_h8w{uabTj}4i=*J{_Uu*K>{i`LYoMgo^ znnMvzBI{opeslO7rdik`kR#l?T^LM8F~g$ zmK)A%GXbXugYvrR{Y7TX7U6)w?6fq=pk8F-2kqmkA9P~CATl*_v3;lOMdq^Gb(i1x z&X1q}^)D9FnjjDo)ip~FoiTBTAc=4MjmN+n@+n4F#OFANwU1?0eSKj^NNLXbfpff? zm!_^W`t%Z~&d71AuZbnP@7V=gllQB)Jio~I>uxcM4f3Zo_m!o*%7^#HqR_i11ur<8 z_lBnt$``-->e(q`wlyO4&6}d6f7;zYez3s>vXjGI1(l>ujsN=6b3ifcdDqXdHOhyZ*c=RPsO5>P!dkJL{)376tCk(*NvNY8?jHQr8~#{iMg)%8 z+*J40ATVxXq%h}s=ku$#5~mVI<^Pup&qz%RXc_*3KPdD>DG{&TN>);=%HKSGv;gb1 z*jah}+iC)O5Y(98&r&7pl(?QZVSl~4`34oGV|X^xl~3{k$lSOe4A2>3u*5q`r*sK( z?EdV)Xqh_t6{n#FoTH`p6zVC|iET3NK-Q=4&|`+m7Y*vX*AY$%?7szXPA9#1AtrUh zw@vHY-C_Zx`xphzFgVP2jJC#@{!wfuR4_hBm^*AX%D^*ENk!4B`6rpB@y^k3q0^P_?_KbOjJ^6|Kzsw^g&mojt-%Gez@JTXtW`1v1~up1NPo)7cczN z2Z@~`X;DCGltYEGBH7a5Zr_i}SVz$N|gU691>-iAgMD`9*h23F_o+3NH zv(53i;}AY?B3K?tjZE|5=9S#^Dg}gUam~$;-2@Lr z87PL@iTJSYOxgNs-wzmrKXi&i$7I#_KR>_wpFjP>i~kx;76Jg_LR$yhriuRRn$32# z=Y=OMR%N!B8(XP=?V(8A2lnws^1`TvhkoC%9=NSDP+(533J zBVW?nnpNvF19&s|T;kZKQTu@@|8>n7Ljcw1&5kclc3QEDURwI;gt(itzR~)aX)d@; zW^;u<@eKS5t4V>>W>@fU;iQ-`>|;TTxFf<_vpO$;D5ND0@hER?i2g1j^KUQqH|u4& z3GO2LWtZL--9;|A3*+?2#?4#BU&FuobP7WWU}Y7H=f4Zz{B%D4F=Dcv;4b1ykm6f} zvP2Wy#s5v*_lEQ$S4_&7yl?c|bc(AjetjyvlKFDO>^LjBy*Tx9L z43Z){#VsCho_Z>#H%J7VW(JEvZ7>bF$U3Io^-Fz5bJRN3MZ}@a_HxD?OsPpjG={KX z-A^349vCUNyzE}PG5|*pgN=dY4but@#+78-oV78 z{{I2=R=#0~73ohogT}jy&ey*?ajb;(`hmOe8OjezwY-0JSk59kKC$4&w6BH~*M?Er zSq-_C_lFP3O?r6=M`v6;5YR3ga_8F9UO`DbdS6GN`paCl8iqx|m7|NbP&6D8{4%=R zb>u%;L3eGz+)?X-o2mcaI{RuVYjVr-gf`G z>Yt~3iepc&fRXdhzhT=-!BWgkOr9W+GhVi1GV*Vm;ARi;_rHkk2mI?uLq+BmVT1DO zQ3mq6-vHiIgjy-bNs3J)lMCeh4mmpdMk_Zn-!8IC^%r#5N(!dE8a{k=dHbt~@=|Jm z;ffav%`O~Xr~)yF&jaQ!o8xqg_)xBWhaJo|j2eqOcre`mwjKX-h*|DHFmNKL?poBr zy*@`oIj0$MHn(2!ol=#r*tHO&iDhV9b6fjh+I^myU4wRRn8WLAvxrYpbEMBI1Cqs0 z6!(>HV^T(9Lg5@sqcqzusDk`&ViRw|SIPGqN8&!p>3nR8o9V$Kc?rshithAX1NA#2 zkQTtc_dBkf$JOGpICfehVZV6{l=Zs03$-h%4lnh7$sc)rT6g&a?_gcy;DAJs=0V{i z`=0ppU7NPDe?%7ldjlAW@?OZm^>)1r)LMfk@mFywMF!@llF~rN zvCg+alh$0&_$;scYne5sY1&zbSgOe8W7hs20@!<#P?o*g*V~hYvEDd(ByW9TeR+lh zNu!8g;vM{2Ds1nN?)}}O`LC&QpQTRJ=-olCudA<*6lrYAjK7B$JMs z-BTMOC~C1*5q=x`aIwAbM(NMpp;_vdWEwOqD?L}`6R9-5fJ8XGKSdMHXo{hJzp*~s zrj&<7B;mQXlG9pzC{|a(naH`s=9MbdAhUprOMfO;Fi~G>$ zW+wf1j1IIsY>c|(F$#?ak3!=^!kk2}R{7G=K)04Bdt?Uz7Zode` z?C3=GBD?u9$9ps08zOWrYi@^mweJ+4ceyLXKN)FNADr-_Q|24?{J+fR4-=0nCS<`? zZA57;fg3&(j$Jdnb^UVbDgQ$<0%zB;8y1fV16K56m#gbSjb;_SeeZz@Oe(8gs(f;r zRb39Is{gG=)}r9_^8dr$dxkZcZSTW^1r@Oa3IaAjsUp%#a2!BDnj*a@jPxSC1QJmZ zrA0*qr3C4{_ZF2VHS}JD0HKFo()jN1SMq+>M^j z!0_$HHdA%;^EL)Kp@4k%JTrC;vc+y&wkXnHl!t3M^W=d0r4+49)?s2zH|Urj<`uRx zG&IylhDExKKCAAdrJ$y)FcnaoKNylgFMJOIM&|h2cXnzq(jpjVvS>LmL*b_~QBuO< zuGWl+2gF@`T_YCjycajJ7%_3)^0=&FE%cUkfF~*P#8OXI98TaxchSf}Lg}xt6I?h1 zeBzSYz@ggfsoco*O?0gveFNt6qtaRmm<&vR48%sk`JNnNW966J@+3~mYt`Dp38luR zsPWgs)pLbg7cJR4AE`>Mc8E@dnV8^x+f91fD~+2YdUc}l-ZW4CppQdKE(_X!IwNJG za+4R|eEw1->lTUBkP~f3nJ%+zusNRp;vDA9UG(qWwg$QP7xB(B7(jpDJi&Z<%v*G= z$Rs#FLi37-&bp@P`|4r5X`TX41u-PE%A1Du1RAogUl#m0((F8a4u8qQL+x@8Wldg* zK`=7$k#XH9`(n$rLp1;rJW8Wwcm$1F_-$-l=;A3p!e)QCT@Vyk%*iBddEAJE$dpTL zjy!9CHE@%<-9X1JT99dA6`P7t^nY zx{vh`B>>J9wAOA67va|}uzq8plnP1o9$W!;w6vp34O^U0BzdVEN74e_*OwUhb&tDp zgdpLoGs9K;I3u2yw<*^7P)+i~Hyc_(tdILbByd4zYSWK9GvLD6DJBsGvOpF{VjiF?c;sNatffhQhxk8BxkZ9PjU5R zB3v9m>KOpK&~dRC?Ugav2LOSr7Wd24V`~<*ZyqTHIxpJ|o)xjH6~YKG&Nl*BB!p>$ z7!3vjMKHt2qX57W04(fmje!KtW9)8u?v54cvBdo{xCo^~KkwY4Pwgs*(`~qW`r51! z_0Ax1t_&1;Yt$D~mU4lpUsRdr;K-Dqi~t6XQMeYMYmEVqNU!^F1<9|kT?AZs`&(rc z3)6Ce*<|rO`BG9-1I3Q|gka=x<^$6a} zH~vTSim1c;2gZOhWbQMd3Fk6T#3jNPuHs`S-9D2Ex$B`YLVxu~w1o)@Mmjra$mzl9OYKclsO zm#=Y3AF%s{d0&&`Pkal9bb&<&uxO5bWtt5sSNOpVfAZ1tm?WjjCv>q|XhQ)otfy$I zhB^4XUHIe>3FB93ab1*lKjWafwB14TAxX=Qr0k|U<%E^GJ_bHr?O9!&wSv_h&X(Q1 z_$$z1u$AWh3Cf-;t@5%TW?n|(PkETTc#V8Sbm!V*YO1XCyPN@Bn%%ChSrvi_*qCb) zsSP;fPgATkr>}^~8P|(a4=$^T*B>mfXnd?7F!mxb)(X&nmE88Xk+AN3sksLYLb2C; zM#Z;N3xCPM1FqKcb!$i17#LSl6N`{OdJRzIn{s>@V)tjnIf3!Kz39_S-E)m_whM5 zi3?fwoStYVh<23ExK97dwNVd+J#kPZ^{8uHXC!33*fBVzl1(nXFW=<-1F9FAVzvWG z_HiFZ0pWJ(g`!fSPiK5j9R)xzH_469&)vYtcN5Q>gBww$xMstqw=9Rd4O|T(oR;eJ zhHsAG8cGVwvs*0Mr7tkKtVQ(7;tJh^!}#?IJi{jpEX;fEC@r{;*LRk-NfiY8<2DND z>x$@@I{NK7wSFam8mF{)sXQn2Ujn>ket@o9(}rAWQz&a_7;LO}3je9)=FS$2L?V$G zw||Ab*NPGb)h~=JUcaf}vC?l>8$Voe1-9sKR0U}D^{mVMBzuF)L)OK?xZpSVmHdUj zxB%#M&Ly)-na&m^0T=DAdPI4N$;^b$pdx0VRwdPnU-@A#OMl_T^=!Id@{Y>U9u|Rp zDFyGr=$O$?EqT+up$0CS!XwzZDN4ft1CRD|4K72?j(9Ms&whxp;_$U6k|!uO=$to?CJ%RzpW=J5#U%|@Ou3fVEdlB*yvX0O$nM*J_#Hbmlro>dN|*g z>{T3Ob?N7=--GvSpe|L&dCR9ilt<^(Oc(th)XTv#j&&x)jm2z->VnS4NEm)fbS*5_ zWFh)$cFe08B)%gt=Uu{$sGHWG^6>T}*%r4p_c+nk@)C8r%ISxUh9K?reFmk@4NuDF z3Lw_58y%jiLFW$PA|=~b1w0xbM;^RolPD!Uzc4)$n;Y!p`Q;kuX9Kshl(OY-Vzm?I zLuImKB37@{@#w-~RuF>M4<+9AGxBo&U4J1zvj#BFf%V*Z^f)!*{2f12x8r7}$p zY^@JMG(RVte?|0#43rG63YoWDGGvvOEQO8JYt;ZK`Vlax_}SH+kRt$zdB5?k6t`x& z{z-Rt_tq@+*tGpCAc63&v3mVDA+vbxZP7e@O9a4In~S!*2`2Af$k(Kt-z(+P7}k?@ z_gY7)7JtTd>T*3cUEE=I~4OXT*B~&1!m7DWJ`3ai5;kD5i znyO{~at3tSf?|Zn=wh{Pgb)-4Snb07@&~2Hp3Rm4PrBG6Rd~Ggbrf+t>Rq;r%~elQ z16Ho-Et}TjP(tjlq_Q$%0CN+1&h#EzO7tC@xXd{gW)T~%5~r?SGx=2}p;0YV*%>hG zlM&eW8^2`;fz}b}BVUZZ8H8jZNthKBaGrh@18oxl-72AgU5U>g6Nq}Y4v@b`&dFI9 zM?E$N;Pg|&gv>24;K<{6DW}vX=$SYYJIu-grmzGQ4tWTQyH1rUBbO{M%na3Ak=trE z$?N?7u?TT-7+@}FDxWS2XVGprGlI{}^MdKW299W%kbRu?(e&(;c@8FcxsLt69m5G5tddy%X z)-%vYBd440u7#kOC@?=X#$$CFbVr7RRB-;FodK9MaYKnqG0`#4rkf8aV}2zW>S3?C zR*>k3ne@z%XARk*L^=Qm?s6glX;g7Vb$;p8YL-awIKglI-OQ4Jdsg$$AaB zA)ja4c^2k17^03E3PR4Eyi~rhvBcNWTNf&)NT9wNWQShb?r7God9R=w zx;f$g7?NtmaU*==vwM9bG51nq?!jU&56*CGvz^{v{Fm(cPJ!$Yb zC1tQ}!4PENIo6K->XnfP1)%f9qV;!)##Kp$G1p4F7GoRu z7+^!mZx8-_3?t)CxmzntTHLGQ;B6>XQf-%s63;+wuANw#%u0K^+$z5o_@S1Ko`hey zpqcG5Sh6ax6xg~*gc$i}GYjUN7a(BGf6^8F%R{!=|+twn)CH_2M^VmTN zNXbw1*NW?){~Wjvtv-2^yT2f&lo$Qq;e98>``_XHUE#h4e*e(CtVHT?5!}??`R_=o zS~fNL27tshZP&Fdc}jVx3TygBebw}%Z6o`#J(RCnudxOARf=wpJHc5@A@8Ld>K&d! z+K7GUy~Z8_#paV_xB7D38*#+EQxam@Y;YKi>pS`o)L>2DeXA1QDcsMWAlo4gZ^fWj z^DJK&IiH!`ZoN(??y{Wdu;l#{LIRxDqtZNotXvrj%@|g8Il*1M++#HfTn(`s<&SSS zVH&dD9~YJ%RyT|eK4Yu8Sj%Eae{yy^Au#p(GUu6x;2s$o^dOq4dN;REVWA!%qU`U5V&>2-k`ZYQKL_yY{g1Nm` z`K6_Tp95N)&uNSLHT7@+Z3^PPY*F#Q2y3&Xi22;Je*SOQ{jYEBeG1$-H;?$5P5s(i zro078d>cBtw%xk^*N|=h<)cIMv9LjsO+$(0PV?PMkMjn+8Tt@9#)9kkHNlgqSzzlg;G_OyzqVxn0)ABESJR zOI@b@!nan>cgeYC*3GdoPBc!BFxfiZlBAXB0y4q$9R7a%_8=zZ`Fl{@F;V_d5+>w& zS5jm&eR3H4d9tm-nf_?j?JqC$fn+oVS3tQx3EiYDFaH}A@`KL9t;2kEC8yE*DR6a5^3MHlB}4VI2c2yxX7v93aYh5GMolmIm)2*y&Tw$R3!EEAq*9|F z^L}UF-pZ`%>t(Heu`%BDJeSPKG3JhUa+COo`fu2R^S4J5-m%BvG*l!x{J+G6`bREk7fMfeCZ{hsW=LL|*$#aFMCM6_Et%tTeaNhgU6!lz?ntV&WS(1zP z=a5(bj1hm@n|r5FY67>BWxqIA@Y7X_{q{6}{cEl&I)##fc5>Pc|C(iVPyM0j$8!R5|>2&^Me?52i|NGmbx8c@LTr>*mr}O6te65RUxp@LvD?6&$Y?0`i?gJ-QfMhj%jED0jyi zt5?92EFMvaoK0A=Gils-X1~<}`nanu_8Kz_C$W({)}Kz$i~(4~lkEG8ZDAsC^`p

+(d{(kty8CyVR?{OYtUpjpFwo*x9P9S}werC0XMxbxDA zVEOBJxHZnf{o!SHrRdY2}&*PWG2V*F5Ht=P+HUAvOrP8aJAn=c@iL|cGVo@1YWrcw)YnZ) zay4j}mmYwJW_Qeh`ubBPK5<6_*UWun1Iomq#kP{yaZ+eRi}h- zW1=4&3c7N@U`ZR01yRU81YpFX>(@R?LD&4Q9g@1Tk46=7F_^Q~J6%^c)3DsnHhhCj zppd?ZM!PRh_7~czLr1~^7h=_hJtoE_Qr!OIKF;I9jD$BqQpQzJwJ*V8PB*%uf`-%e z3XQ$iCKLc33*)P0z%opjcOAvS;aq%WlQGx(>ph5bL-H}vcMLoUGe!X_EPb}FVKi(| zjtPG4SG#ivE0RSWutx~C!x)YmevD5Lew@A}!Dg}LS6?;@;4DGk1CU?q!<{ep&xdRR z{y3Yo;Vc0r5lgi*4Fh==j%m8(;<>$p`$Bn*PJ+9Zppv?VpG%Ep#(|H@h(O1;rCDNX z0_~^bL;sj@cbjY}T3tsWz*ze19(Y9B^J?b*Ih zFETmKe8$z}+-va5rx5zJmbv>E0eXzlMnQCd5eY9M+wChUdVao`Fi)9+PFz$iWXxx* zI4NYQq3>S3b^h-3&e8lauR07Tq*!>qbiJad%>7oj5*E2tT{JzN8vI@_(s&L!bAHeS z!74Qh7-jr9S>a`kRFf3L(>=_}94S%Ye`^m*Y2|p-&q4cSs%dXTlGV#z5aIBpypu0{ z04arEfz82yc2%)6ee94z>HS^l2%~|bIqZ0smtw`%2poQH`n<_&m&OPok)ab((rsuY z+ZMVy-ua@XUa-b1_*%6VX3+i^;3MhOfim&T54=+b7h0;nH%v77;canEFXJ09O|GEq zwYXUAC`}Jog!>G;(@3j@wd_{mN81z70r_>I*O-LTkX~|8t5Y9Zvp%eC2?Nv}V{I_H z;?ylj*vVuakGQ*YRKDv$D-CDzEjPR44^;F2R9wOJ?7{DXjQ@x8bXh3Z_VLS3kfqRP`+kuv7wIO%g+N z5t0rv3=dRN{|H@moAA-f(L+njVySUUoSH8)`pj{6IuFi=3aoex`{c_o+f6nK5+}7pu75BS1W9@MB)tY&HQ>D4* zNRmU(HOwS+5XCHZp{{*$3@&bqHEm*&IOSk}RG&PEoNs!Fwiqr**E8*$ zX5`U5ic`j)=1|$ZR6!2O#YFS56rAK7><^1$@?y%1!hZ-DQ{wJ-x|n}=!^*DuSfyco zM*PUQ>87%AbJ=d49fZm^j-xUBaADni>x!oG_Lnl7Y&g#g!nOmi-ndu~i+6F1%(*Lc z60wF%^d_7)p5eS^lzwaJ|77uF>-V>)Gz&)wb0WQ(o65k*m=pL(*^zA^3Tf(4`j4)>C-7kZ`J-er!$c$OM$t zlZ*D8U0)u%kAA6Ux^^fr_l|t+#QAJbaKnFZ1PcagR>LD)J+9RCFNr~*^AAs~5xI5t z;y?V6uH}h+m{fi{e`@61u%FqM*kxL!M90~BPYYDu^l~t|EW$kkI#Jh(GRn*od!4CG zUpTya|L9}G6W5N$Zk22_=s-vKEqd_Y@=8W zev%lBxZ$?kB$7K5%Kl;MTKGPg2 zVb<+?!2L8q=Ljm#vXd*^wAyc6A*Kpvso znl0?__?zm8;>WcLJ!|HtFSkEm(8H;GBE#WCb&}tpurt0fDa5mN^l61}Rbj4yP7C~>$`@KxyCq!sRq2j*oVzv*hpAqZfDtM^W#C?&Zp{jwE#>PtBQW)=M&O?wOI@^ zRy5(K1n@6NhQXKhZJkOg`t>&`NUOXhM}UL{D4Adz52x7{4qA>x#tB|+jaj_9{K_*n zgSGUH8hAwT?ZQk0D=b`H7Qat?dHCuya5EQ$4Lx3V7pb4>ONDkBwk6yrujJ<0$3E#F z=uf`ZpJr3nHvR&(SoO0}#^E0KoFs>|b}p`LnY&@GS`W)|rSTW~6)f&fmuFYk1#?#S zYBaNH-gmehUY`v63NhLWwJVv=ZNkwG|I>$OoaSL!YUE5?tN zyLZnRk1^v+XUJ8kogI31F`&y+4>{jP$n$W-_YGyQV%1^6HPt1~%D;7$LV5IyL^mV& zKc$GWJx6Ly&&~CpI$_6oJEOgRQ;&`J;3u?7_xbfumo(m*&}FvAxC{n1y;4Vd&eft!@OgGo^C{oMzm)ZBL^Q(e9N<=ArCr2)MT?fP(a zyP&#{m60z~8s}abBrvp2uZn?+pu8yp$k6wn>&y{5@Er0Z(zhzJ~j@nrxWZCglz@%0- zT{k55Ay&^074nAF{`alRy$PMy+fAmH=VoF_XOqIM!0l$1OlcRd z$>^&o0XuTcBuMgXOo#FQ2d6?$xG+2zDzd+I0B+M@rf$)REPN9kKxg4Rp{(Er?eonY z9b61HCPHt$M326;Z$8N>i|;KLW&yWc`LHkQ5b9Rs%jusTm0C1>Bd$M8}?ATXQ=E6@TBZ3Sl``gFrtKTNX5XZBYc8($1ej zX$sij8v*9gBn~_79A}bnW-=qPFSPr4%^4Zc9?-VG$zq2G(3+ZkwWnACa~waDP}4eS zP0E$US~!nKvc%R_FaiS?0HPr<{v<3A3&$9JuC4n)g{{AQz+dSzkS@r&? zGKFi6HoApR550V_`cyp@Lv&Q(79N-uvclAv88!D!clCCSXI+E-9{Xe!qv}c*h=Qyu zW<&eWzgzZ4dDsF_W}$W|Q1hQrvbFU0wNuGnr3Z6y?A{>bCmdwSX~mVU56v|%Ej94h zMu_F+&Ug{l`fX8C<@W)tyxd%$vvFsA$YPHPB1C*(wAx?EhW~&n;^eX|XgyG34dzhc z={@f5t{iiz#jD>2-ZSBGw{inc^O6?5-i3aKL$P%mZTVYoV1gjh^}1BzET2DBLTgLT zYlu>CzkG##Dp1dXkbFUGcN=eb!3-@dy_OvfsB zFSe!HnHmw3^b%b_AHKM*u-)rjjj7duEZtEhO{ZQw6Iu4S-VIZKQSRt<^`5>J`bbw^o%qK_xJ z3|%YbI?RH?kJGgR(7 zB=ePcP1KbP0Eecq?N$aq-%KwgOQ(7c#>o0_pvH7&6($$PylbmW;BaZcYBV(o?%P$cWL7 zi8T3VM!Cw}Ox_p?yJW9R9DCA#mToqKS3A@Pju4Mg4e)ThvBVy%E0L~EB*$3@xRPVi zjF{4f!fV+XqqMFNN8=lU0io_F$R?}CECexxP#8PY`FHbDQf>RY5)VrAJt@C*HVQhG z?{;@1Def|?X;$fMGQfxq0yN-ytirQ98*k&pSDN5uA`Bc+T( z@GY;_V#iPr;aE{gQjk**hBho8rO>P!4%f4X>N8~qojAhgxp38U${+iMmh{2- z6QEvWSNk#!?+E5{#zxp zbcPTY^y^id!4dxT1A+MpLLHg#&4KfhMeOG*R-JMC4)+vN8;IxoEAff)gXY-dI92lL zxAr7NIk zBuRRvos)rZQ!({5O;splYigq@-IaaDQ)18g+l%eO-?>ZrM=AV25e>l*U@wLtkM`?) zxUFTx0`d_D;u09b0n$qW;eBLN`J<2L+TxWWHs7FY0B?QMg|vV&5yp@`a5fJ&bK(LG z3VK@qk3eZo9ENB2J#&V+ACc>VM1nx#mz3}nV{YgA_>Ag zq)fD--hfG1$I9_JPN$uZQn>lwf~^JQ@)50LAVT6@L! zu)@a@9;-JqL(MQN zCv#2OI;L8)u9A$6jw)cUr>Z5&>J`dJBl45itwP89~~>)KJFRgWWML1Pr><9d+}(N*nH4 z-C8e5;(0bK-TI4jph-YQAKpG^KU}F=y+qILYOyaD+l(+G&u4-f4h07v%)KQDI@U{- z)~A1eATxgWI_mo6l{zdXTxi8aH@9XuH_Y)_kHoMG%$M^TS#DNk``Q%_N9iZM(Rdvt zde0;7>LjR~y%N{Z^%0lSWhol>=Z|;c@~s)?)~vpU*g7X{7j(i+f9w3DJ`rk^uE+Yk z=`vvLy=kUbY^lt1y|FEJ)w@Y)F81dxLcIMLFGTH1+1PBl4*cHUmFZSq7?jj$PiiWx zeJ<~N&wC;kG0Xf20pY^0PO0;puK?AF6Pq=YZe(O;bKJ~zpY)ye?hMq$1C?3$V#F!ZAG;lBxHq|K-d}(1~vMt*t&mx}` zy>gJIx2`%PQsNJzIBkGhlmy|b{k)lqg0x>;5pLEr;mQ>s>r+k47f5Ei+XhXaF2;M2%ATrSn(qmeGz`B!FBVpr9Qo0 z?sPW~8CZK{siQ!-elH$5VZ}@}D+=u_x~v6rOHQVdbkpyS_hz=l$*= z`yrh~IgA{gU!P)yPPT(HrEHM4`Pd}rf_w2mGqX?{n~^A?W6W`K@r2YGDNNEvF3%2n zr{e~B&AZo;vFc;BQf_gxq|Kc?^C%?ITL7_pGECY;lLr)gCiwM_D>I1% z@kRE@1C9;$5ETMDM1nE(V7aU2J;29Of9o_IwkuVSGuhHpCQm%e-O0S43x7T&fR>xl z&MxE1Sn1u$C+0(G7N;EUW9OW?L)WeyoIg5@TH#*o$gK?CvEuteQ(FbGBA8+jz7x}U zi$)HRi`3uCNT<=!Q#-62ex;d9I#Jro`kA6gXn?U<# zNA$b_CO|dnFwJ>W5b*y@*20C5$p;qJCPT8JcTtf8t$*0pX~_P$MeR9_*-m$Vt>1IY z=Cm+rJ)L9C)_|Bh5F}*sB>ZYDsQ(t{-sc8b51F%Hnt{ZSlETTN`i_~NA5N2e*P1^z zhfH0y9w@q)EQz|3svW5rtD4$|OE*!q*}uQ*9(~G8M+QA;rJ}ShL9LQ&wt+@8xV!<= zf|*ei8-6x*F&-VEosiF~Tfn6|A;Q&OZhQ7`8ULT>+_O%7ETJjLcJ3{X;4?eAf6Z{e z1tViLv-eACi%Fe@;y6D_bA|PhPk-K zZ9nke;<=g&RXkmT?JtuLb5Y2LAAV5&6`~#Rt1`V50*(Lu+&{}d|J%%e?#CBx|DULQ z&+Pp}R0yc|6C}95%TM-}dwT)YX*qgQ`3rE2kpABE$Rug4w{Keq)Ex+Y&n!A`t)0_K z?_1OBO}YhgnJv!@7g@@o5w1srSR*^(j={zuIl?4W*mgqCJB7R3APu^a#5bCQ;`y!w zLy_;8rXEHB7bE;O7(w~Htl|Bj>w_(Kg3k~5?tNErg{r+Z+gtzvA;Sb4dR1nM);s>g z))Sc~eeF1*Kf#OoM<$2j4J09>a{ybZzEtl&-I*erKQ{hfYxvbrs`c*5S#VsECCe&> z)^60X)leEldS9DMeY+h7O_NoBaRGqLPmvzfA46pS{{DKG6*mQ`;N)yvxsl#+UBnX$@rI+{Ihc0c5X(LBuh1!KrV57yOpPRRGLm zjC%QHbuudZoGgaL-(ImjL4nL3OALGlAhSPi7XdCSUH6KAFv#ep7zy9&opg`|kJpNN z<@^O*s%(MEC3K?W?SDFMzH^G->}2t2H7Q00i@@)^{I=8l``=s#PJ$%;&BOlw z2jBZ&r_Dev=QyFRbK!d#_`iIcx&?OV|6a>K9sm%c0B^dS#It>_^LH%S--0(Pa}>?L zE`9sTKAi+Lq6l{lhV49)U&Zx%A0F(;8{YYkxBlK={q5a=xfu(ffTVvK`1*CNGCTTk zzqsqW9OQs}nX!iWd{NGy|Muw}bL;;L=k#Lk`G5h;kM|Ly0>a$gT2>De9JejeQd zOPtD`KVj+r_a6S|ZEjx&{oY(FSvEg+bMe>uWikM65sN>T2m7A&|FP)Yz8-B#-)H4x zmk-*}_aoaM|Juo~QCOYVv58i8-+b>+0?je520)m3hRIA)ROa7}|eCLB2ntFfq%;qc;^Iu2#kEj0VX+dDY_O+=%ccO94M?%gMJ>es|;m8T^=il#duJ6-?C;%LBAY*dhW z{qzSj6-3dRpLO@^r>y0DPJ5ZRHv@dtO{b&YdNb5prpb`=i^-{$<^264ZdM*t*cF zDji;rkC2*GkZn1aJBnTRlB05(i;$JtmZ7EHmZ4gy57D7sp*^xboX^BXOZ{}BGdJO1 zPQX(3G;}TZJZ;$=n?Ye6F(f}q((!{t3%~9o{KyV!}O}MMCf1py8ORBq#Xs;U{1*VXf%oR*S~#L zp|2l0GGxa4As^m!K9+Pk9 zI8AE+Ggz`u^9|)WD*UdM+shRHc{0;)(M!FmiVrk*3?5D#I{l4|dDl>6p*c7FPN020 z^ACGg)wZZRk4E33atf|BUWG3OKL6%O%#TyKdbGXC;CZ0ZFtAH$|8`CL>kH8}ySf(E z&>Fkazq2(yU~7cpcNFc@WMnM5`gKFU{Xoa@yb~hth>wkn?=u?_VL#3B&8n!V^Lc^h zM4~kJwHQ9q><`WV@jY)K_j7tkVOrV=*xIc8hO*DIZBqzj=JsEBpt7$eWH%7+Xxg`Z z)g3Z7bA=3z~5uGv)bFPdcp}yiNs1=-jPcZGZ7&8yl&8XF=FYLKTW)QoN0A` z*@nhSy6T<4H0xOFBE~LL=tieo8zcT>X}cr1Uqku9nzprI)Dfd?y+@O3Kx&Vge_R%QUvp$( z)(lf5&h^)Ee^riP;8mNak+GdtEjjlLTAW^5X^8yzrED0l?*opX^v98wC{o^F%j<8& z$yC%3nMCpMU8|qu8-) z)GMY^oE6)2xa9+NisvnAr+fQlew%-o@F-KrH}#gc`!W_lY8+>roStm^;XiF`KIi8- zWWHUKq4>SZeN_#GXsRxMFs8-LvJuyi0~1PI%b;94ZEAg}iRWu(#8 znybw~gDJS4^aBILqqNKZsFSPi(H_qIqpq!JMIQ33yL?31zL6P$5Mf>K62%5y%Z6Jh}gsuXnx5A(gkM`6Q%@raF%U7EOE`(=Tqsk}xHYN&Dq5RTVN3$Au#o}s6 zxOIysSC*Ik+AQ&eKO^r@w294RGqYv>yW!z3l2)4b5uE7A7@#p#Ilv-*9!5wt`eSvC zWvg^A^D?wq8e3NOpwy`m(8BUY3T@NT|9CNBB*mw;Kce5=5{~oS_>=zRZ=tjd4M-;_ znzO{A&8heR4ARyC?6{fJ7Dx$KLvWqWK3_I7Uxe2}Jv)S4^LFdrhr7`4Qs0qWy_wA3 zUhOjz7AD|mO2l`kzKrxeaPpKLynk_~$7DHuNG(;lb9s}Np=v;@c`8kZzovm7bqav1 z<`y!CwTB&RSzPJ;kx(Zbt2~?Y?_dZm)r*Wn+fCu02V?C*@eLrzxV84Zz<}cYK5<2B z35OyZC3ipFgA=@O^W{o=tYk(tW zUaxBeH0l0@C=ze=xJ_i36jVhYkX&QKaRoDcktI7yoNmmR+%DOwiD1oY61J~Ngd8ax zB%{mR+)R!`63KRHIQOyET0co&HkfwAx(}Kj`y=8DZ*uk#kinHJR z)OJFW_fLR$02j`C`{oYIF%Io@Fnm_o4v*ddc#d!*x?{))4VT+D-T?0ZaA95}Vbewz z0f(xmp7=KwXbLy`@)S!A0zoDbst4Bxn2&KvpG-~?il>2yS==nZIc^G1A$9`^NiQ6X zLbGLUky}%>(4!@7&uTd(k5D*Q8zV&^atNlAG;B_Htc%AP;=`?9PdV$*i+8>pJmIxg zj2#7Yw*x?ri5wsVHeQ*0VgH^?kZsr9j|rXvEnP?36IBts1wCg0;r46BSn%$p_a}*h z^eMw+w8YX>LPCc9Xq=+1hE|REt`&>1aRfWRMw{EsoCCKjL%6yzXlF7FK+!~ zzN||rn$p37C;|?C+O%9$V$UI_wKM>QYoMqjgf4n4P{CfDkPM27DMwBbCKU^w_&zNnARzzZb>e4;7 z%>^3FAZOHb)h!HLVNE;)uOLnOaHx!*Y(F#SzUWwSngCdPz3msfD{hB1L2h~DbdVDK zNb;avhTpquzOT}a^4#nrw&H0q2`DluXZ%r)iGkaP&Fub+(pS90rv$BX6-jS^nTl{F zYmHW5{r$Bvtog(N zN39@vaf^IYKa_(qE;^KmzPFfaWE9NE5t?yh_qdtq#m|JS+ly)mZ6dP%S^MzmZ zEy7~_Fv8B00KJEW@D5wlvW(6!8lC93l{np0GpmXyQ6F&9f z$hPxX<^616)GL*hW|>dqN!;~-Ns(#;gUsMx+sfkcDJ-8$gb>`_7p;WX40Z0#7wp_q zrAZ<%9_j{-f}T3MLmm06@xgv~Z!J11D$E0Dh&}3!pjox-7HL(p`a?CH@JLl(S`?h@ zBf43h$l#A`KXLQO{WGg#@fOIrGg}TO(iN}5BKF4>_F3LOgC8hf z9!2q!O^KulJw;a?jFX} zm5#Jm0D+^h^zeM)g;Kq0X7l@{}!;_Y(b$Dzefx#89S& z#o5G;TfrDoVifBk>AaL3&`v}0k2+vj*q=)glRejh4;q}a+nT+wyLMYe3RHo1O1tYnF?3@``%Zhx?n3@n9XZ*PVw(>}b_0sB;37Z%%?%Mji z)M$_d&M#Bn$sRD(pTD_ypUZ6!nkm&?1eedyW=qwmk~C``C}WmqU7Qxh4WI#BP-deDqI@+&Ay_W|uO$tp14S z3CKTmr9A}{R07M63g?U%ect=`81m0RBV6xGUfp%`&5lUkna8_ZRBw1*<||qlP3gYD z)kCTeMRO}Hq?g80y)Z zXMwiOp`KjLX1a7ITy!(eb=*s89y0u#5t8_Zs^9vUo%mXyJC)O0zWq3Z(?=@P72q2EGhJl-3`e}Brv@m zO^fOG82GrUVp6_=;(rPnea1`I<~zBYH&!@}M}vbM8WNE(4)WTTZIFrK7MqP!-rP2; z@#h}OFz?Foh4hlBC`jN?BBrs$`TyJMQ>{1mSbGDRj4P&NJv) zs}oB=>)+T^y~S0^&tHK38ro^*T=E74N{mN&DpW;i1najE1EM zp1o1LLOZlHf$^&zL)^PKu|HbL`NsF5c<=Ynj)C%m-Bx4JTfgYr(cs{BY*=Ay+tYxDyrhCf6{4AHFy+DjW_y%YKGY z*HNhiQ?&N_rneC=K&gRT{@!{vYT0+Z(i!;lPjr(69vWm_GHs(?3w z%fN;Xa@X9eF1bi@Z;g>%tg7Nng^l~>bj&Sc3J^#G*gZ<_X1JF$X@Zc)Z;}sfaSm-f z>8{m5l2*jg3S1R@dD83(!#?-&7j$&XhEQ-+iotv^y9r|-5Uu^e(%Z7&|L9Kb-Z3=H z5;KQn5xgV6O>3@1$=GPtxvaQbhU_q4-rchM325D`N_uf_6hx;JJ|%~wR_@Q1;)Z-W zg;wAAJrgn23-8>`=mpUBL?b)6mFMI&9Ac>4V|>uv^W!o5dK&4nnhapASC$7H+c91J z-=$P2T%%j4&(K1pS^vT0t4O>jGD_$5!&ZLeM8vP3E+^%lrP8HxqUjYsux(|I zd(%ok<~pu8V%B2f>y@*FkE3h{RPyI0n|kTWhK&fd#_HCgvwMct`VkiW%{DzL(85lk zCH``v1M}KsS$JBL<%kl0HE^5D&HM%c3fLU3CH%aU?5x`Bd3Pekh%7z?t@m9*LWomn zpXyDlG!%F8(H^?S#P)1#GcUxnx2E?7SJ9AFrqoh(GDKu(r7%Z%;+_|NK+Gt>A4Q(q zs8h{+D(&SFnvOdl2)d{OH9kf5okK`7tPgI<=oB*W8=mSW&XSIlnM3xx4;fiY9ob|D}{Js?U z)`^HfXAm@H8&~@kedaa_EUXxBY8B#EtYBBNBUiF%F^ZrzMrTLwBSeW=Me~PJy9}Zt z!=t1;sy@)L9Of@yaTs_`e+eBS#yu>|QmS^qV4%3ZN*>~%Yj`8lFCRq?w5ugl74rr&P66@?EYRk+#h&Lr(m|9Y&ppG@@a6NOpTrWZ@1EuQch+ zXNW)cHDIwALigZS(8?|I#>CftaYpq=-xh*CdC@ytq|q@~lpu`kpL&j7&S+!U zh=2AbakeX6FJgHU&4BF|7Jv<`EmG1f7%>=GoipBmp$R1>bxtI|$FH^^N8Z!!ir^*rh&x&W9+Ttn(p5J@qwTMVvq_Fii)({5|W#(AR!=KiU>-H zbZty;R6szbRAN&J>FzQJ6=8IbNq57DG5DTw3-|rm;Qjmkw}+0`&g-1(T=~47*YM|E zy>lpnbxirAopK_M$uRtM{CvAwAuF~i$E@sYJ*9^sl>}?NN5ren41gTwPZsa*lYckE zZr?*Gdfg#RR8=OKcv*T9B1{6N5Q`D7m|W!wV=pvknB@w|S*Nh3=2i&C${-d#h*j0S zzvyRX^AqgmmzlKG!sEGIXVCecvmpt~j{568jj918lUb}@d^HSWWclOt1OXcEDUAn? z`PW`2cFfKzPf6IJ^?k=rDP*kV6OJCWU*Jj_YIS%}8R;`tU@_F0B2#p8 z>FbLl84r7u#X*imo|r$kklE)R(hzBZdCUCqYJi_{iF@wyXCa-`7a@vK^!23NS1fJ4 zjpDT*Pph+7h7;7F%)9cq4jS0x-1_mZ%l-TNTWI$IyFHg)(f*K7A0?R_v$@);`!2q?uh-+Kj`$O&P9Pe!+SdYe|@VOyvks1YZ ziLn<(fwi9c^vx!$FNS)S%jIyHUTJ6e_Vx<4i#}!;7518D_|orowOz)0pKgHf{#?Ny4uUm@{OnOTUoMT4m40$RS9Y_nRM!}uMnf)vl z(qD>qr<8v?vD3p~=r9^VaG_fj2nn&wpVG+Q9)ffNr90anwvSVU1xSS%Cu0dIimlwb zYmWNJ`SJKzH>brDu(aH5UXmHSTZcMNl)tBaPgZ+EBTPynWf$`+aGGbN?L^hLtID~pTQxQNi6@tnP z=tg3isP5<>z4XDI$}<3YpmE6YeQYl%ozgOHv$TWiBb=dhbwJmq>W=n~O6~n0PXdKS z?R^H+j2fm=83=&20YzuOZ0~k|_do-huK|9ef$@L@8LmR ze^_2lvenC50385!BA_s#&-O86cbwgma~!93ln>Lh4E-aR*k+6#f(2$b7~DHX;e>OE z)!B!Za^dn+9LgOJBp38w(S3+4Qg-0X0u!eZ^5d4!u`;gWQ9=11@CEP0a0UPdp6?8dRk zPPD6?|4PYLx>4iRc^}FKD!rBh5K@(wGX4Ii{8VR2JyM|Nu#8q92rQnV=uP;v3t1`Z zUF(k$vV9yIoCqo0FKR=H!PvYT9ICu(-l-t#58y^YlyD;e+6gcs1 zcmnneR4nUgO+S%cRoIig60Tskn3FRBpum-`j`7hl=Z^BGu0t(AC0jz3ojm})xppnN z>6-+(Y@+wma1dyWeHf#M2bnfNI}xpmsGNN3)8{KW$!8jPQk8fLqwc_b ze}sI;2J-E}0jFtyTarBotlNpNt}V2*+4ix3cWQ)x=Z@+hd4(C2`A4YK?=!et!r6LOI&vUJFY zyHk{sbxFvp2c(xu>v@zxewY5E+I?voI-yBEI0>hb@~D<=@^SbLAtHi0GDwihlBuvOVHO1i*rGb#zyCIkn zrmtcl02ae3$`!Gr1klL7hbcQ;j&A^J1%5)C>JCL)i25A$BpzI-c#x(|l|Q&0y{)rR0TgP=>z?Z%_62f5P$&3cm8t9+}6>PeSkfokFkIPPjk5w%1L;o`^1>>DY-;6 zWx$@`CVoslzST|RKhA1t#1R=ADCT;R@-6-d$EY4am1>HtR%W5x6-Ow*y%K0x-tMDw zqsNrJjcsoGk?yCg*6)e}hTfU$YE|=Z9l)e_b1rx5J=^?1-684{cl`6)Pj;7!_Fbv) zP9ZpzACq1ePgEdW?~(3aD_F(^a8n$ptU75!_+lY3a<@;46zySCF;ZrG^H0fYg4y-a zsDu6D6SZ<~IUDw(sdJ}R=0{(Z81WMKT-j~~*J z-Ev(vj|%&}vKgdfN4g^k4xHW(bjXz_Y>3%%ntFKr?`#R3NLB#|EAIxJ70pF0uq?w0 zO_l%tqc5Lcdm)hPw$XA@-xHU~sOWU;SoW;{L@lRya~Ox!E6 zlvb1`Knv5b2(_v>PTCdAC!a}2-TxB#8r5lPPD$#6tPy(&oEC#$SN3xrZnUWFUghfe z%?+eAfxa*%mV}kt7SSkH_nWq^oi2o0ouHF(2#5ljnNC=*PIVZB?FNy5pjmlR>zo;iNYjuKL~Wy)Xyq%ifm z8?BK%AtB>zLJ`?*h9Gk`ED6xw4OVqsGzMdr&2|K9`uZlPz zm*g2rVri@%h7}eRGw#@CEN-4`c zmm%NM|D5FBnBF0f1kl43x#BhXEYzhb%%cs{!@T%rl{0DQtr|nk_;!9)JTnN13pV zIT%G5l0Jlj~PLaGp3f?7UMVv}jw={u+gseL+yg{j$U8e0+zM zw2O`>l=Pd9caQ|0=z~LsOHY^A ziUmwKw#f;gwP6O}MZilfbCyj+zbThXc0^lQ>>R(gqO0BfTF*ee`SeTG4rMGzegI%T zC|Am}3401~!rYl!@hy?W_0U^{*ddo18(cjl9QrBq_sODctuE;G5sXSe6kXH9a3mGE zm+AD6p#_zO;~!*;>7-mHyWT(%@Fah?+DI93^PeI43oQnH?0`1Nn8vHyZ78QBHJZ(H zE&}(0RY<$spnEp#Fcj_?&(&e%f@K9I7Ug{$5~sTtOBZc2;km*F93pdrR~#n_f0Q<| zQ{MQE(?srPw!DskYil1BJqfee4vLN4D}hfdil46d2_mBhW5QI04|Afu@a-h}_+AVa z@XP@=F{h(m^Ys~^mYTmhTiutKlqzU#9F79~WNN)vp({6U05%HEpef`Y?(YOQz}aiv z1&`zWaxz7EaWZL;9(8hz(iZ%qf{?0WFQEj1vc)KNsIvFue7x!&3dxu_L~_UGSC)6X zGwK6k`wv%xxGPXLd046a^3$L5$1|&Yp=*86*|EVflXZ8GRG!Y3{Lh&v6E=YnK9oG!`j-ZA0au?P)+f<3~es0^@t6100M4 zC_GGc(Yh4R+%JQ(EZ&2D=cNa&>beQtiRPn4vq<0Gx>Gv8Gx8z%Tr-afQsm?*sre<=Z;T%nsctX;@d6yx;>_BT6G(4gURkp0A8vK z&|BZcfs`Hw{PRa2ex^z}YFo0<;@NrkO~+RshPk=dalrK@sZhn0Q0-0M}nX?Qvje!a4!) z{XKqzA7@yW>Z=O$Mmvi3AvSidHz?U)79$d!Z`-(8A&{LW0ur z8z}RYpF3z9A`V0}?m{<&DG>Ck6cQU!RLJ!NP?&I%y9QvzdNbB~$^sBZS7vKKHg@?b z;5E$=^j2J7o$Fg)17z;0kJ6acSm*TKTzO=LSMFGxM5bnR60T z3=95Jm7B=+JmuA@Q?}CFTbf`hJK+MPgk1^))m+z5zT5?{Xhw=9snFE?UcaTEI;Bh_ z1bPuJ!W`f+G`?Y^tG(<-n8>Rl@fHFqbk+96?5RD9)5xW93#fr%^opMBq@yUk8DT^X z!2yckckMg1)V)R%;swzN}kLTgwvHnS_iz^)mKDd1~%jiw*G#lW` zyEGRPKRfX*UL_!PPpM!bx1*(_-1NZ;%&i6C6X_!~llg=%uEX`d8Q4#^XWlld*)CKh zz*geRmb~z&G*SC6Ly8;|?Q6;wQQSJ~lTTd*gmS$m4(+M1PlJAFo>_OUF6(WPo2>Cm z%L~YY+A9_1;>=pP^tsX=eaUIX9aV!8Jddtde$4EhI5IOu&>=P`-7W&)>58k+hZn4+ zAGxlMc5r6RD5&d(BI2mWTDcYyUB6lF7cnRW5`{l`>)xQbPbYM3S<>y0%gCtXnsd87 zq2aQ5V}j+%D2{k?vUKWI<^XZU_H9)7x9YIB+eBafu(?sf(z5o*+Y3J&d~(L`vyz!d zV8a4HewoVAIZV**@nzs&Q8A!3WgXtfQg<|j`T3<4&;BIM?1+gO2B4oSN~cSKDxdp6 z5~3wRMu_(Ss@pevlbR#i0pm0|AgkiS@IzIEBx8-k~d!Jw9CiKvEzX9sw=6Y}L) z4dcV`$_YOb&UrlJa(<571!$+(0&lIn^$TiriO&U38T9!+;-O*hz)}59UvM|H@5R~K zX40S?lJ#-Rm|ti$;Q`PH6XVm-4Y@etq{~pJ=V~7hh6!pC7-Aa5l)mQxcO?7u_)q{x zsm{BOh&ev8Shh|CPQi-}YD}jz52KlUmu@$U;<>1)UkpW>kMQ~i&foIx4;g*DiqD#_ zcw0d|95+#UB~8prihxpd@^?t^O5L zWM>u;K-?-7JtiaB&q1fBnQt+m8LDtD7^7K4QD>IdeQ2ws7uIC$P>ILFF9P&0Ww`3~ z#vrJ;48g_g^6Ky`uJY5Ni)LSgHSg$#=|`=+h94PRd&b}IQ;AsaoOsoc(5PnKsaut@ z8ZA-gIFh+EcmNR{ueCVZ&c~yy6c0b8oDFyUs%cL=n|G^I!~|caW5oGGR>8m1V=*f8 z@nVm-#pLQW+R3t|8dPgOij~~Ar=pIf)>~3hLW)`iERV;(_)Lkwsih%>AXtc%fSQEr z0;WDTp;mPca6wzQXD+qmm4@17_XWxgCe-*SXvjWNVxDYGGg<99fB@9R+U#LmPE9vw za`Q?=Z1a1bUQ4JEP$|fcz0k)Xn$N4D+HgqWSW}_yf`zUsctGFe+`e zFSA;-x-m`jkmIPw`;sZIsp{Y;yTXyUYZc8t)WgiG=Z@h{u!1EGQ|;Q_?^EkTY#`w~ zk58cdP{FOh_~{rDQ(a1gOu{`IWr#o2;2MT`xxTE3GI8y$rTF2(MR>i$JwxGjte9E5 zny4>#yw@F@BE75LpHDHh*~Ht|7rCVA7Q0@LIX=L5z=$|yqBMxO`!%MRpD>X#8qVEO zM5OYV3S)<1-YG~&*D$@gx{uTFXnS_@Lzl^7+GS5cS=E%1&LO#+o}kJ0vSpt2-$k?3 zL)mT|7AtFMUhA{EApr`k(6XMKXBFaCc{JoZ>eCd@)D}z=+#WAPEz0ZWK-|r^^4fe~ z`yy87Z~z93QY`81i!T)dCQZvwZmvRRW@;9?gA2r|783^Vf4qvVILp6Q{ zzAC?(zG@@MOxkf&WFKTeB|Mj5 z6+}!}nN%~sWvFIA*?El_%>4*)CpIXHv9hJj%>ik|U~UTrD$e~nTb-+R|5L(gg&d%P zrrb0f+jrl(ryq?F4fEnxZmRXG^6;E>sP7AD{80V!ea7m$B(njmi&pzLkoS|yf#um6 z&0YFEU$O|5ct1XddiR$I2w+|lBibeLT~5zDjXd&r6dqab>vA6R#D#n^?4TdP+>fx? zV;!3IUFkI9+{53j{D?QOpfNSOXMZ8e*PiVxu!g5==G^Ouqw3W>r zm9n-2F0r_z6~ctekpBTWOH^j>Q1-*R+|F{uT2+#eOZCt?d@PZei?h9?H{+n+{?TL6 zb+Hqt>jY(>I87QsQn_m*{isiw7XHLe1$s=G&{>?OBiK2oHaO7TS632RfU{e+H0e^t zdGXnPkyK+a(9HO76dOtBR}925S8;n-1CIvht5t5$UT8sU(A)v&Ld~X176Uz|N~BMz zMH_bYlOm6JP1(5?gET>Bp;S-v<0r4IFJln3%<%@9N?BUd1|3&k9KI>rd90C{U-egz zL;0brmjI&M04R$09lDK~7sMZps0xh8#@fbH4>mQN)1aCUGqBYwZ0CpvyvtuavB#br zWddWyALJOx>LlpOd0_xw>7DN{kEP@a7^OdID7Vzhkav&td?3MSGSE7wi3&Pt;U%oS zHioKS@YV^nwS5Oc)|^OR?=Gt3a)BPyj8|X>(@~zMfMy7f+23YrgQ%kMGg4~4qK;|A z&MCIm^@ZHx&ns=MT*l{a$j|?rVE`aaR)R%By-m9!F|R*Jx?8_3W$CS7wvazkQ^O%g z%J$cHS8?TdZm6?X%<}L=w+Ru z-nq{13C%B#f|k*ttQ=4|FCaxy=KwD;J4OL|cHKPKYq6_fA3CKo?bn(dVcnLf(_VW2 zR4j)M8!WG5IFwc;Z8cMQ08qK-nl#RSU6J(4UCbZjsP=!W^WLVUIgxtd>uQH$quAG9 zQANDC7zIMg#G4k1NS;HRw$@`0H_G7wAI&M%|^nMxy(;8q;QOs3s$}TBnC1MVp+wtnV>56(rKUk*`Gpu zvGPG2l8LT|*c(1*erf#}r1*~iGP{oL?{a`gp5CCZ{w|%E{vi+now$dI#-{SchKy>eDM*UJRegpmP+rb4aP|(68z?ZQt$VWP zKpvD#?D1%rY0dG{)C_NPXyu|WYMLJ^tkk$>r&{rgL>3J2{JHmw!N|Yo-6bC8 zc1F5P3?}+babDJ!wlcAsAJTUtlh^q$r!qbvlR< z$FqUInN^>Y5*)Jt>T6{}(0_GI#k!1$UtaZN6}r<~?rT0KSxJ++fJyQQ)GV-hKV4*c zv!Gj^ih4ol%-uTg!!n-NVsN4KdG~NfdYL=MV+=+>$UU zQ$&yyWVnuM%mv&7o5`+%jK7q>BwLf>l<4`$uqhA^S2U9XW<{@Rk-X%L-z#9?oL*^- zvB$)%t~3Sa`^5>8($aZuc^CJ~oWS9MISoqCjL+>5i`Bz`#`We|QZC9QjQ+dkF-P;F zvD6|#cGe+=>-Ej6`_KLM_AH99E0sBQ?_9ue&YoD)1P%(rBTDOM4_oQG7=} zW&e&MX2YcpCG6eKm*CvUm&9je9+bkaKS*csmM-pL%m9tb1MCZz*^NRFY->vm;iVyJ zalOMNKh2!BhC~H?7BqfISu#xuP%sAd3N{<3ETaS;c_gS2Na zKA~<2YLF?KU&v2Oh87}=mbJOoribK=Wo5Mld1*)MzAMTM9k{CEw-vs_g?2+!gX z6+1z=#YhIoC8>8(6Ykx|sHhmth73x)E^#pk?I@1B2?#hZd~sAls@jy5B*rVVm!_3; zvg4ClF=oaNmWtUPlL!gh<)JeFZ#OFX*H>G2%`A3Kii!$Fom*+%b0ugJYle?>vmdZq z)57Cw1u*jLI;*omu@MpEXedzDjet3e#U)F&bwaBvZJ$z9OX5M^-qFy8v*jHVno}5X z_DgkV)yfK~%8tb3FLrzMJ>|50-deV{P;gr?TY)&=$afO9{u@j}z^&o)GQh0Nt4c0# zFnZ<=0Ie^tW>j%^{`B-0$$gGnUt6?qRFNL=sRh1*?;dVf-UbWM_1+ulPb)+B%-uYZ8c6~0#SOW?;chyeY8RPbF1JbEPD z@X-%h7nO>i33baeRXjo84nXCd+s(s4kY*nP$4_GAa=YEfx?<*GAkE+pnwf11+M9Ju zq7ZSHCVZLsuL$~agY0R>caMgc>tMAWEG}wvtv+Vl&TY3dz~!qzy*2^nV)D?YQ4 zF$M$EW~t}3&8l;8}$pvsS2dP9x9AC6S@oOws}#N6{Q}NN5K>#*HwHF!oRHh zk=ax~H%hLC6;F|#(iE`Qf^yvtv(|Y8Pn1i3(fWIFq{Y7KOVOKYe@<{bF?n1$w z*DaRg;%9wtkC%KVQ`y@-)I}P z#Veo$QVL%>M>WJ~o_8?l0O@WnAH{fyQ7ucu)B2^8g=4eS0}rYSem`dDHRAyjC`Oxw zNbUBdRJgW!8=si5s?Q*8UdX&*$Gc3cX&^U_jsR4mX0PhZz$Sd!_OE-t-jF8hF!4vb z-T{qZVQxrQ*>2GC)AxDTfnN+QBnf8ElRoba^P*$%i_RNum97jpQc(LP$ASPR^i~=d zO}yc8Sd6L~xLjvNc#O9#%Qb7RE?kV9jypFvd@<9cV}x~%y_iK!wYJ;xC2`$fx)`5+ zZlp|q{j2)zu4i1?YM#HbRqXyz{N{v`)!E)Qi=e2!WVJ{pY^I4VC5)J+V}q54kqzFs z`y?f#3qYcj!+smgaHrSGMQ?V7jkVpLC_fhjP8A-F+ zuZN3OyiQJwf>|UQ8MaEC-S;AF5`TIU$4oE`4>jE#1-(^mfP$L=vt+IccB%ZRv#}AV zaRu}S;=t>_lkw1C(Wue6rab@y93L=KZzT4xg1ckUN^syZY5Ww4FC!!7(r9kBmPAw~ zs?=k=EkiHBs}sJ+yC5Dbf8g*LUTKp?xLEP@1>@C7jd;zKtSjE12buGGT@V2-+#Z)4 zF>vIuljC+T@U4h0Rz!XekA44pLY2YV+^`e;vPWK7KLWuT1U8IEemNzBAZn%Nt!mQU zJ<;0UBiqjF!&u{PuZo{~q`9x{UXpXbgD+phdj~H2n@xYFvRSjcQdIi6l02V=WCE=l zS1M=6YkYLpXLx3!^NMrts&w+p)tr6h8+0ksL#h19V)Eqbv37;*sddFW{wwbHvfRBX z0qvZk({24D;_&{@jL^DMvKR7H<`tsmtTaYkK<{ql4R6~qx>1n31?4YM8*FjD5vf1< zM|Fjd&6{fijU(}V27wF>3XqXc z2&B2*yHy((Z1{ofm*d5`H-Tyyibfq_j*jH;a$oc_ayDEnGnl}_ZM;(QoD$Z&>OPN_ z31_Ef;Kz#0V|XZ=SWFdY^xp|N|Fms#yl-&kdPN{58zGHs!UkSW5N&{^sjdx)FpZjj z)GR`ZK9}ZH@@C7O>dALWONgpzq z@^^UadZ=#!Y?jO3vXO`P_fW(b)~XvGi~vMLsG8VF7{$^E{ejO$-1-fK3oS--=b5sokgz%5z$W+yC^n3oJFT&8X}HrzXk$ot`{^2iBNN z!7$_FeM~1@t3IWdjJ={>hV3U%#a(WUZ-1^Eb$(`jdh@cl>xk^wsnYyg>;4 zK2G^FimtN;bNxg0e9z1)et0SAZrF_5vR%q1sWXmDRZiHAt~}m5f@D-SXCoFUX7TQn*;ULS-Tr_b@b?Jl@6I!U=^?Z zQ^$6E0oyQpMwNNXrW4pwM45;gO2PTT+)QVYSHuD9i`)IOAPHum<%TEyw4fD&{420{ zCd=theE-X&hD* zZ@Q&EqHdyNm6lZKOF@Ix5lomOMHZmNVB?$smY@~w6Ja{$CE31nn^k%NtrChD6Aq^@ zZSS%uU!=GyvW6RgI*TNlVe7Y?x4Gc&Wq2tHN}HaX>Bm2$0`uprKNb-vPW1CBHp_82 z#b(g6#Se==2cc96n-L@oJxKFTCv`G&`z9Wz6LoE*wkU0Y1$Z1Am}-BKvJ&>^rg2Z?w2*D!=gLAqxw~9^B(DT2c9p| zPL7WleKucxbK&VqBn*v*F3IyMlN*Vr}8t}S?4K@>hg6z*yUwShKrMV!r0JwMpP`9*G zN<^>~@4u@dTPX4=(=`AH2|EFc|Dx<|`$_q;DVbCPB2NHgA9x?y2s^jQOlvX0Y zD4QFER;2~JOj*yMfD?J%kduvUgX_MN5Jyo_D}%3F(Xm2bRMM}k5lqK-S{-1&?YCP` z1}d}HURMOA;YHE!ti?_oon(24Z#2)$r#CRL@pzHt>2IU zaaRHH>1*nj!bQ&5GdDdpt_d=1o>OWYfGLuL=~K9e{{5q|7Q<8ux|qL;h@H0b%ZLrr9zFy(n6sKuw7C+F~Y{4bCyrt!gRc*LlCee@z}=w0g&S zJ`aWArrhudU0&cTd+0UBVf=1C*<;;nhudos{+RCPSGp50I~wz6lso2(w2dg)6H&Cw zJnek7Y~u-9QwJ0i4v<74_1W6ox<2L4v>>W-JLiLt28%&)adE@1yU(C06xrT`!*{8D zdWZBJ2CJT^-S9OtEZk^Qvm6}0GU)MD}YJ7fA>#N z(xPM9nL?dgmX0~+B~?! zNVnMZ6-|qt*}&npGP@UCi=Oi0lWVS4wOyBGgPxFGa?&jnzK$GNnGbw*aSuSOGu~W{ zG&8Tj0Ni4V8@};Wk2Kjug`wZm_!&Wrgs3{ejUV0JdW7@{A!GPqZZuwRC;Fy<6uh#qVvsvk%j0#GJ)wKF#n2#IadlpaiqKu=u*S z=yv;be$D_55+% zjr|mQaBJU%&msWV zN1k3Ld!RS0Z!b$eM3%GsWF++&Yjs>@f#&>BA2s-yFM7&i$ zo~A{=nl$&?F$C}vehI=2#7})q?bR;B@v7VA9BdS7myu7s>j>%{;2_8c+Tu-w!Hzl} zd7Q54nzt(GK&|jPsvT3`O5T`;)}^k9o&hw}$wfw#G}N1tP|13&N4gmUzd-HSw?99c z-2M6If(Nj8OVEKa0^bn_R#Z1N%+|^O`2dsnEiYYA0;7F5o#t%_KzqkY_>~xQ*sIe-rB^4LWL#-6iqV65irAd{c z3zP9+>|iQtkKDN{IlZ6eZ=A4Sl4sM+f&pCyG|CA6W_pWF-uAuXq zOYc)BgN=;X6--@sW-&K#OSZ{BTxJ@cZdY@M#E{=T(6{xPwAqcPwb^0MSiG+k7A#Oi z`kPni^cz@G9)iuf+$o&QR-XPua?g|aNrW*v&LAd6gC;dzmk_&udTPnv)s|0t(cQnJP zxSO?`@36U$e|JcijhgEz?yf)`g_GwEyGX~92a#2Id@COEcPm=537c|ur{%yhX!HTI z|A5MpO2Jd}|7%MC5c%6)(vui(7lG`OfkVc1j=|cNL*(Du+*P1fzuNgpcDs{b4HkX$ z=jKv9YM9do2RPu|xv+j2aDMLaAoX}^$!H>IVvGYuE~)XAV>|ikk+gIyE|vTxR4G7? zniV5x4C)m6NCQ^?-Jk#N7;KRlWJ>f61k;3ANrVCt+o)g&>AqZ*V$fEg1Gz8uH!)PU zmPY@5$mUya9KD~QIvU)d)jA6u$z5YmJ8Em?M z&>5rJQK)Vp!@_>TrQHY?C!bT$H^9s`1RW4i1%shC>^pncFyN%+wVd{5gZFh)tXd+H zwAoo1$jIDdu$(Z?a0UD$E(h_dJ0(0?RftsLN+{pdZ2c|iWr@q{f}^FA9B22 zEjtFdPwwM<0B4sWSjNu{xAIY3j z--8A|l8FMmYmAnf_SZ+(om+O1AIzpCqSL7*nbAHt7CgMpp6pBL_q3#Nv_nHO|J0X6 zSTcpV*jnT0CEg_OR5-yx3Bd-}+?p)Zq@-#p1=b<`Fe#)oZ~*?;=R5iFkvopA;!WR2@}dA#wtXAMp*nTaP6YyY zz*u>}G>$I)Ua)EC>6WecqWIv%TlY?Za6cRp6-{JWve)I>7okiMI12m0GAukhR34lE ztx|DHFC^l-IGGCC+bHLM|i12}2S~#J5jY>CCI^2QM z+HR`Vuy04>ffC7B2sL^=9)OJqk*Q?h5-G*7m!)H`OjNB`{*A>2v3oK{`Z@f zyhska^&2Htwc9c+KV>3GmQiGE=K^^$ zk@x=m6(}r-EMSVuiPaERc?@FQ7$(Y0&6b0KjwX55PD=q`b|A<3R*H$D!^yCWBrk(R zdi1vwx)ydv36zJjx!A%`(ol@+>mfOywcKNE8~%nrY6tutU>{$94Z*5Q=htrj`PPnZ zez<(-J1D_vgIpQt#3zMXA+K7=I|tCNq);niBNaxE_FvRNSM4OKK$Qc8vSjxf;7=n4 zrBD)^Bm%=hno$=E(ZU|krceM|&vg=19|I$cmQ*zTklS1}ATSnuPWRrgyw-r|hg)wX zLD)xMk5eSxwvHC0o^C%`5$#mAtKnV~?y-PY=RPTo`uC3g(YI(7bUtm}E0xDJNdPTD z2ho6ZOfr_yIi61c#h)Qp{1?ymJNY^D;IP#DGa?|={3{@iy6m8nUe~_TVDiVOvyjpb znrEqGne9YHe`w_6Ja^0i!AyVb1^$yWEf_i$wl6n}La~OWkfg>+^)YM2-S+OlZC++m z0PARxqZZItB)@5d`qM>XDbAz{xZ8vvpyFjhlr&M%$3ZW4CVo{e80l z`5A*k2MEW4fe`_tyG9A$WXWBSO>u&u;WQ5beGvvhIVubkG>6;OOZ48<_6tDfI(X`v zTqS$d6c-%lhwJ%TjIFc?YtHu7DAD2*qNV+_tHP+&{$n$~yYN%JN4Shd)vd<6;e@ER zb?=L_STKQsE8Juye)gg;MaBFd^@Y4cPbyHl~vbD0kY)z#o;!I65-}`CBp`QK%Mi*24DJ8}W~Wv??e?KEMl5kWWA@R$dM_WJ9fY-LxP6g8J09STNJ4 zJl0norp(Ene#Q;Z8q7Bc&6Q{zngO#p^1S)NuvJ`oC(8gJ^Wb9FT-s92)Y`#kT<+>e z9p(?!cNH)BVKHEIm+MfJi{{Bd;%dEHud~j{LRn`cBD`v+b0}o`j$3QjaQlHBFHi%$ z?n)C+X4$rwEb@+Aw1W``Sxhjefyq@@WCRx;`*mpFbbi>FABPD#2Q+)QO{)Y|PUUh_C}H~3q*R?mTgoi~h)VknU1>OLhwNA~7r)nn z5NqBDXr^Mm%1vB$b?-V`|GK1QqGK#I4Gh?I>wmt4&nwlozi~+Wfu0fKn~Hsh8iG5^ z0uxwN*~P_f=z86AboyeU$km%wsh#_uGf?g*X@ST|5z@p=Wnd?PwZg!+yN}GIe1wvB zZG(4bj%_3aJE@<=2zsYpfKI)$aQ79l*&vj=yJ3YbCIF#$N;UG0oqyE zgQC7#alKyWAYD7GlUZ9j;ESHa1qnBt+~fiP%}GCBR8<74L8IJiU)<8>J`!P*d;P^x z@eg;(vK#8#aym0ApN8yR!+5N*GG}I>Waa|KSHGDN7g_?e4yW$mf*~teKB;=w0-i;X zm>tv|BX9f$wJ;#(@vp?xsIHAUX|G0#%H&9Dn-H-+<2dB5Jt1L@7nBqLnZ4MrJg&uM zOl8kAu1GPQbLWITJ`IBjhk7(wkQnrT`J?6-+o2bq?)T+E;j?m^S6u|(DUMj-YQxit z$G;wa#o8Q}r>A#*+C_Ewe3xq@u3EaPZrl)hZb2?%<_f2_wF#RLfZsb=7yhW6`TjAe z0th0PH13g=r)Qa$ps4w1_I>-W>jZuIx2#XX^Wub0_Wpjd|2c-o!O_@t?PrpvGWP(% ztIr_5KMA+G;+s)bgjySC7q_U5Y{<>71Jc@tC@bkxuHuQnKCX$y$O8JG z{anH?3JB5Xh!z%=G2zA!@~Zaa;zZRB@%(i+)*02llaU+MCk5r&Ae9YRk;cTGX0|-R zKOd0$X}Xhg$4#GAVhy9HUoK>;nmlo?F-a3*Y~0V&R+`<_?t@#MJiuCk`Ek1d5Xi@V zd13}zUyE&wxq!_UAxbP-BE}4-`5vDx{5+wa#MOV^36Pby63=z z`btYt)}5Z&Fpa2cF#m6Hl$E%$P~&pHM&p}U;Zo+gfhL~8G0+u#+AXGcI5(^zEBGer zS9(g66W(p+$+}F6)@t!jL7^c+3`SFbE;iigh`_7Dq=^}D16oVhCO{2b(6QU{8)N1% zuf>%~4hI+QY+}kAITu@+~<~_BAN6>I1~-S{^`6YT{IJS?_{lTCQfLfnAMnby~5Y ziCRU^(CR3A#*b5+1GGKTSWjioMUN>qEt7{mCuiQOAq3UJMY)P!G9MFO@U_G_0WV!H2Lcz)kA=waM?ci!9`>^r$%7G{F*wS{(zN`RY& zqDt6S>(>YqTwvawZ$n_hXFO`XSUR-;Z?~N5%WN{tMqBsoDWix{Uy^2gXqcw>Jhpuy zF1OcDsGPlQdRgPx+%v@`lbK%s;9dm6Np)@6T*r_Vw>J1=dG_(zTUnah@&f58_zp^lc6+;ZN7FSVfZ_Z@Q*Y9yzg58%nc^)zO z=3_6gH~pO&quY>h{j)KEj+w#AEzO*@P6aEsI#^k)|#=o9NuMUL9?6 zM(Nls&C>B#BuU~sorbvj%AiiV3zPoY-Ay6KdDa>=ILZ+nW#9FqwPRBY@;C*ZoIkrJt=4ahAUg3axM38WF$lJmnEjg`_*RVY=feUoY0CGN zACeUQ0Gt0t(vRBFN{=1}#x73+!ep#-XJrs#sifg^JPXcalBi?oI5S`mrmIz=L<=S2 zif12qP8H#VC$f^+HGbL~SP2M8*>(aFi{&By@@g@))b67ZcDdJ!Z2Svv{|wPldbXcK z{!{kq60@0dwRG1*%`RX)Vi$6Kv{oZK{DX}jbT*CP!0e!FhK?fxGvB`jRlaC79-Fsk z$m*lw!AVaR&rQAooli5rFCM5mbQPhvdwzq08NzOUE*haXT|fLZ++=%TyGZ# zQpML_fId3VH<*Zdk0ogx;5>+NhP$v!?HPt`s|<<%w;%S2}Yg z1{K)x;s}Gz=hY&d$-$xM#mB5@9Y`B?h^7s}Y&uLcVvJzb~JTfHu2GW>A( zVA`zKv|iS|fr^$^V;8R&6tKeOL7B%_RHWPUg-rT%w|`CEIwDOXGrE!0c`gs(485d7 zA@!dQAXk!K8y(GEKB4OccpaN2ZhmZe(X4HB@)U5JG`@`S1<7+5*vb@s#1<{!%>otg z_?qC}6io?uRkaw{-qh!ob+o*{{PM|x7b!m#g}kOwK5=m@N4g8}ZDwlaZbR#$I5%L! z`m%Yvpi*t7B@JKJr^?f=3L2UirkIqK&P>=vN3wn`<62xBE8U0!xLg8#Lp&9{R$iQ2 z^XD&L9*SZeOD<{YT~QjMFdBcv7<&;tfR&aRWDg#k1#b{!Z%@HUf~*iGIk+@>uOLw= zturUux{}*+QWi!U<8A7v1d$%=PKd7c&rg9uthJ}UYkB(aP4uta$=|sNvZPmA`sc>E>aWB>3Td$0;6V06y^=Bsb;pO@a zaLdLcNt!?Bl!O>XQ|y4HOWwVPh5DAQE)=@1Ez`wfI@mPC=RiCgW0Nyqq?7hnytH6c zoNAPIN19D!hg9*(Xw%`vUs*OuMk`SbWl)Fyq29);N10K?)fs?#>7?_RA3jtxo^96o zpjh5b>3%yk`CI&n6)pFI7B359J!(e)pL=fKOh>*UFh=BJqLh_q+jPX>EmoKdK?Bq+*@~qZOjSj=A@|2CDMvVy z%WUT-I`iiBTnsF;9@Nm6^Mlb!@(Po0T>(9ma(Dr-!WCdZ)m@-@fqZ>B_q&f!N%C|Y zhH3*oLR~zMI`t!}PI20?G@k7v@VK59Eg1KE6ONTusZk+CsHeG5k=?F+1)jul6BLi! z)O^ojnMbb4g+B!|Kqp@az6f8)nfYNX^p1axv_As6tYzpq^8X0??szKu|Np~Hg%)L$ z&=x|&$UfCw8KIE9qOzUr?NE1%PzYt66q1!KTZJOodz`Yj?0Jsg>(ZUi-~PcU+>rJIeJgNPhb&Y{F~pD71GG&+jnQWk(7!jId89&=%`W3oGyoVM(Tv~ z$OLCsls7+bxN}{?3aT{qdnnI%uH-#EIj+XEH$Z+sSew}n4g1+21SOKlNUCyxVH-l~;p|5ntb#d+!g+{$b%N@9Hk7k;N z3#hB7(pquE{B9mSQ9kFOXsxW1(NP0nLCTCoXG90_+x!B5ncY$IzTxfC|V?JG|`3>o;hEIYw% zi^H5Ng=Z#uaHX&Tcny>7&y$rWZnl&QY2o&8bdU};geGoubQfj*TpL-zL3-V}++XQu z*LgA+?K6Aj2oeJVG1W?X2!fFr7=5lFh9|D7>vUrzt14oGY>^e$c{3#ePcqZK%rJtY`j|BtBgpy=kU0~{Yy|LNnsh+}sdU8qqv^l1>wn^bx1+PD%yuckZGKVNqt z7#z42eH%w~W%@PTW*Q9Qd9xlGO5ttuaPND$zfHs`vNKiPq#ojWnwuyXtu}l!Q7t*b zs&r7wOE28bQuT?eVfu}@`nYWaL@8gf*|dpoV&k9u@YWX#Mq7-^`U{z7A_KpX+NP== zMXq!OPZXWsq4rvC$G$WBw@VHbo%!iOLWB&x7a4v3e9#84hw^@jr7vVP(?N~5RCxj8dma4fCM}0>1qTtvJypro z*$(5KDYKfdMBNIK#?I&$c^s#3!Kx{CJFXwce@o5PBx=oyh@~F2;TFX?4godk-$k?E z`MSCQpiY-FRqp8l#3riag71c1+AYWBJOeS|`IV_r(FiDsTRLHVLPrG*mLlqElYqY{)uGD~t<|b6!#elA5m-X&hery@4c>nu+ylJO&mD^i?960yT7Mgez zH=t*znCBhU<;D;y!0e3mz1tYA4RuMb=@?ZCTkbo5>b)osLSU#E5~5XUu_s0LjwLl7 zSoi2_--@7*I7|giW8UNe-n}w{6zHvv!Z`_eL6P1~6EHlf2Lx#vkIiMc{~jOILG8jW z0Bq~DU%GyQ)t$5+(CBsK%2$m@m1U4kRd>kgL?!3H@8-h;reNK^i6}fEmFbq0!==xs$9OLzaP;`fyR&#=f!nru>{(r#8 zW)41qVmeoKZz30uhb7;@t9RC$E7t!Umxo%R68&}(tK zy!f+&4){8h97p=u35$ZpCS*BU?8lDpqNx1#cfi<<-G7g$BDEybVL5iyv*)9>fJ|Bu$c7glvyn>50CPl~RPt9%<_z1R;9q`d+()zrB&cI#n#YeNOh2u<9|;{;00dHIi9Q_w)da%wLPj1F|kC~Ozpu0LNt zVSaB1`>*Ixjsmv;v00cAyq|<}KB<;L-j6eENakI-JS|q~KRAOkN2;$P65um}z8l@A z=>?S>4EVP{l-$=ow&&t5V`g_K+>tlcFrxA=QO+x0DFB}w8YFWxSlM2cDBlz9u)~a@6#VMF2OlmJxGBI(-5Gqd$-Ye zE|a|W?blyip#M1%d+bo+`VfQh)JDR4+;9W56x&{SRXoi}-Z;}5QY9?5DAM8q&}jLf z?jCA6_Q7)WB8pS*m-FPqF%T*QH)=Y=Y#6$PWNkMXt1C-fcdJVM)i1klh$tw%k6vll zh#cDO(PPA5UNd&^(#B5~6o+MUT@3@U!2cu)|8aG^Lot9o*!LCaFNA&182*r#{oc=J zjsOiX9w<6g1AyQjGTX1iyEcRWy&%|7mW0g=8Z#t7m9pQG)n((S%L%}4Mtq7|!Z&@% zSpR9Lm_m^$e+Yrg{Czp2>S!^ye8R@}8afN9M0%s+5`c|nPBa?k!6$Oz}7!3SEjTgYd7bz&oA#9e#}twF8*tYw=a!< zwC*N#H6S8ELcI0RkEP!OzxMy-&JzeohJ3sP8=PfM39Rk%v#Zmo=pe1Q1i2)8?gyt~ z-AvO%`9`hNL3&A9E1z%C^Rl4<#_#^2O6@71DC_RA{|=Y(^yWu z!_N{M1&sJvo}5ane)5Nsw|W;P$$9qiHdRNx1c5jB_EUX7SekJqi}H6AiiI1XoIV-} z2&H+q9y-)ORGdRr=m836jdt@@G}MKi$e@cO&QWs%HRmU6=r`$bpcaoE_Y?9*(sV#y zs*n!O$I+nupXTesKEvt4EjP0=Rdik0-4BHk7)nqD9>5;GV130(*WwM4^B{%ufrgP) zK2P{gT$CZ?r``d0tWUeB&AJyq^~8RNKoX8Wx1r@U*kdhOylGOy~YvsC5p z^m1Vs#7Ngrb8qeLLrSZMHWhE$O$>orVPg~-x2((lXz(DSJquXLYdkx$;*4q z?HjOAndh#mGu}rd$$>Rt(-;dFccu9>nRox4!af96t4Sgla}&uL5Jaf=*rB#zS}1-) z6qk7yh)Klc6ya%eHs*&VV-cdL@E-;8jL#ssC(wTzxG*ivLW}{gevFy^2dweVmN*YwEFe&Ygz8>GEunu$4?HG6a}(l;wfBgQ5Z{tM)Z;qE#jI+F0K7TN_zlFX*FRxR#(D^T2(Zo zSK9Bp0k!-sJXM1fP(HVneK~^KG=TDnBvY@N2s7$iUn^`_jR7qO6>31&n#uL5_2E{I z!|_>`#%$f>!Fb-^g&dy&i4RG8cCOZgwF$cJ0;azTC-#AnRLLG!iS;K&ucOHO1!8n0 zX!-<=FXYb6Y<#TQ4JD_JF|ZB)8H=RZdv9vb-2J_Ktqp=FwraIQ5#)5uO@IbD2x5b& zI$dq-FNaGW>I@SUTbvta<=M7(XFebiYDL)4&9-01A5*#;NV$4c$`tTS>?J7pCc?0Q zBP@V!p_2WJW^rk__!Oh#VoQH_rr5a8$vMg0%DUl=W15Y+HW|&9!w|)M}Y#Hu9TFCO~c2h+_N!%9%wM2*Q5ay@Q@=`2L;O1C$A3k(J9T= z3IX9PVxxza($jJ9oSBNy0i|17!s$mr$LW`CBA2w=U8gFe={Y1_9j8GzF~WH$jz!Gg zTpL9FtooiCl|sc_yES%zE||1%f4;R@$7~i-WQKpqPQ313mi3!^wq`Q19NA)nTs% zwnKkefr9v_k(RWngM%vAqzjMV&lTs*J5?8vtx9(&=;}|{WVBd{x$RdF8O%2RMxJ$_ z_MYl4364=2H$Wr6e@z`*1;8VzNdbALLqrUn9uHkXW=^6YFiyWS?x$G1$E^D>cf3GM zQHb1JCK*Ib4c4*OVC&5B9{1NuTlx{@%~!7IxI9tTf8iT4ZwBd*6+m3>6JC{0cbe)e zL0mr;6W-7T=teL|ks4MmaI;ADzUKe*`Nw%vrFO?*or(O&Ft#01-kn#C?<}w{92ITS!;@HG!Y+fW&Ew4+t|x@r%+m%2 zmIviH0jfC1&xG?auh5J1R!!-HZR&GLH)r?DlQN`)h6wk?K}Rq;n6#4ae(Ebn(zSfw+oc@2 zs8VuZJa0+?-iUVsjF!Y!T<>lZ`rM(We*K;oiRotVvXm}8{HRa2pXBk2i7B!VVzcMV z3rl*`VlGB@<{PH@G{(Ote&cY)i%))1wwjU}^Oe$bklUACW%(bU%=Q>k++-O@4U$;= zqI+IFvlvx(^}xPbtyV`;#e)T}-rdIL0R6b1h*V?Mc!%3uhcLgku0=+J!H0inoPLaf z)0OU2fh1_;PEz(MD~KFH)(^l(&X>6VwR!tvFjx@FY`GQcHEMDbq*AS>Yc5^l*5|{; z9a|N>HT07Z;x|{gP}IxIxC`ISN_+_Nyj8uSQ@twRU14cn;vV3|Su`ym<}`>`MBWt< zw*nC7{g#DshJKaPSvxt^-78;DSJjVP5>@2(EdY_vT7w9xaQ@}~NJR2j;mnVJLPTtC zE%dPn7+>l1Bh9uY8@OmXjRGY2;UVA8-s$mD?f4Z^H)2Y3yl{DvkwXW%gzxRR2Nbv( z5E)?df-Fy>%2f;r0t6J7@~4$bCgM&k!*4!L%xryYu=F88Ty%CYyPtf?AW=}&r^A7q zyuh9_cgf*#d@{*pB&U0Js$=~0gHdLOjwO9<+g`hgr)*L?NlS@mh$J_3PXB9dwbHLmQQ44s%%$%>t^{=<{c6zl%lL<%{r~h*rv#_=LS@EBC7ls zFHu)pT#1cvHjOx(2U5KKaphbhB1aA?h6?d+mslN655I0=nlu()S9%Lr7Nl zb7&C27ZM#uQp&m-wQxTC?i1e8ZWYV`qaR()4zv%WwTH#ql&3CsL^QT*IM6tZHg*Nn z`Y$F5bR)XIwIcVo?(vUR4c1d$m`mr4wRydJ7!QJ>6WtsuXB734o>7H+Jt(gfzTS3#Ze}Sb)Us+$s;8Sn>$}yGyLrE~6rJf`i!(lcqp9b$ ztpH)L6tZNH+#!`mIPbbquHL!p^G6(#UGKo}U2dsz!33eUq!NZ>#uT=*wCTr3vr=yc z=vVpx=F}@pS?~7yYeS7c)TbR{cL3UI!=;HQ)eq1EJ?{ws&^E)I2 z_!G#z{P^dwyRzJ7bBQEAP?aw!1QqJ*fy@V`z)}vN?3+tL&%Vu`pQKPy6E`oyI0HiB z8BZBvl;!R<0Xc#bR^IGGL^E7zXcDxsl|_>*4lqis^l(Z&^20B8TZA&ri;WgG>AIA_ zrWnDzCH9|Qm3R45-^8-yuJcK0aFZp$mvIt6uhk@Yl=ssUoRSld&VZ`>RQ)LE+KY_k z&vlBMh>kwVBsvh?5C}$Z3|H~{#OUtr5Qy8q=S_X{=6C%;XTkBzJywz(>^Giz)dFhe zYAYG$+l9RWD$C2@AtqV?u6Mzba@~QFxv+M-5mEFoJb59yis{ym6lll+a6hFa##{-Ke|3!|5c@`PQg|hN&V3s)>y!^G--a+I6ZZ-{{^T~gi$`B zby0S2f274ck%ZP#4Whu+5b4VIa7Bk3HMTXteJ z04b4C}9`&bCov`gO%c96~gz%-Cl;N5>Gzk zE7BKYY-(DroT_})!4!d~7xM5%+SbZk1-;zNL{LwTwjDuy;uLEY+A7*WS$R)vn6>PM z37bXnBeIBiHX^>9_c>=d#Fp*L(F`ri_t6Fk<#VCL$@cfSvh=~^lGazM75;H9Rk)_* zG{n@8Y`dU`WID%h6Sp<8J!5`Yc*10oaxUYq^%cQ?k0ft)N<&rGb;;#4#VkNUq1)efw?AZr)p+4<^>CVPA|tmCSPw+oY6RTDmwC+nyv^@5_Z(u z{$4tZ$Y9*?S8LHR&{}uX2IX(39BbL62rv>|mF|aas-LDF@x~~LV|VI#>gpC7ZqFTU z8a)24QPZrqKNt3y$-jrETOfFaF^9$eGaM+O6CZu9_r?pa=rSMHCd*)z+Z{n&I^^r3 z4yFKu+#D5zbBdaQ{JCPsX#M2lCZZrmeW70LEPj3>w(CPhawRQ+S-U=Lv8|BkHPLF8 zQI?^sXUw^NtbU#JK${{FlmS*|tL|*iv_zGhqwFu3z4~~=Mt@Wp1LUN)cPzgKc{wZd zDB>-L2iaXl=#jlZe6HQbis&|1qN-)lFncxDeGVcG|5&)VlXW`dmSE;4-+dyf%KcnK zE=J|p-F+%gmg|)jFL1vB4FI`U7NCOt)V%=w)q0w4&orp@4>lr34z69hA|I-J4PyvV zHskSNKWXsygJ4yi+vMu=J9?L5rbm1=fw*Ka|MSO5liJs=+Dca)jWpZd4n{l z6#%^|g`-c((lpW4A%|2V6>zTgGnacB3z?H+IJxI zwdMCL{9Y8c5Bn5p`60SBig#{ioxQ67=&P>Ga~**@U2A1HGjjXYw5>`)AaRRO&3gy+ z#~Xw5DwvL-#pO~~To3VS?BeV=acrqC>t%HG5yV~qyv|soxZ(-&C52oyjzu06V1eP6 zjX2b_7)6E?xtJ=9;X5J|0)mvQ^F zLxiS$G*Uj$j%$US-%tuG^?N9YqcNX~yNh-}$LefZ?YV>|e9lb0xl6yY@>%HK8>3)# z#XEC2n!74l2X+mo$%)Ad2fiO!quQ{OWL*DvzqhbWDN^~Q4R-=NWK{+Er&pF|vkEJ{ zBOh#Md%=lK&gyh#e2@=Tf!^Rewmd&E(HDyAqi%$CYF*-xk!YS?b8!N!OAi&ym++U~ z-66>Wb3pYtc;BX!bI12I`7^u~Yisq7Z1aj06CLXf*83)<35FVCtQn0{vD^DmbKGxL1RhAS%ZXHhP8_FmnbWr>uby`iPJpHl2nx59U zd!HDXV}XLKT)DDZSW7;OuyrXg+s@F;BET;=hJ+J4FYUAX`zwD3#7#wCI7mn+(NBXl zRr8?KBbCo>K|<}S?OM9hVYJp+us0|~CMQZS{rtGYZ>XzZA@arndt_JJi+F6BLplxjK`J)i|UD;dtU| zz!hrBdt=@WXG4E{pqG1_S4b9+l3d%6-8aMaR^M+uW&$&694# z!iJb|$x`1xXA{`{%%3TRqHgLkUUZ&K+qtXZ+9j>^^*s>{=f-VE5Klg7>Q)P0Mr(X8kKQ8@o4!wQ045_RXmU-F=U?64ddmg{uB|4q zB~sv^lzD!Vh!iST4Ipj0H7WjRhiik*!7lANa{Am#qSd)$(B$+pr^H*(?P^344< zgU{bRQ+jWW`{FCvEY^3sf2ZGUH0jbFV-HL1*KeoTS2WY+>D%p+q%^2)XUwW=Ju7{# z?TDcLr_IYunR4PzE7-&BiBB$Y76)tIr(U-e#V0;_omYizVje6inF=9%tyU_)5v0%L zD{sp`U7*3wio}N!G7P67oSxX9(h?AJz<%l~E)m3Pq{${42 zcx{04%Q5cw1O}uakO!8nPFH_^etO6dPRvvCW|j`M3+C!b)c`!Xy%4KPOUQ2Kr(>nU znRz(9RsIPR*L9sJS>DR^bO9_FlFzh(`^bwqQc~`i*ABOV^C=LAN}!5$h|xdm)}viq zj7x}}cge{(^=0tN@Cmid;qnCsF?9&Slj;3|t;-|8>{*JrGpv$b@Q#-)c=3r>Gn^a8 zk!s`=`Sm};DuLmPwv%5t`?>1rT*lH@pq6CNzoS6PGS3cbI(4HHDLPW>Rxg-!U+m+= zk3aUZC@h?>T5wjL<=C@46P3m-DaX@K{*f9&Y79HGsJ!{2Z1YBK=c02oh%+5*##FF{ zdDVPdzX&~@>5o}PU#C#QC|$+LQYw6@ieq_ynwL>Fma;$d&UcmLZH-EvfU-~AjpW=& zZnw|}Rh*s+Imkpk#3-$ng}4RrkK{u}caZT$Y-G9~x3$8(%DB&>j3q%?Dks7iq6#6= z`Gi!W5Ec;GiaV7I&ZjJhe~2sCl2m5J_VlV0wKp_^YW@67GM)|j-cxWW7I&+Xmxm9cV~E}THEV`#A!D;e{pof z0jYxSOPMcQC`T}DGW=Nc8K_83&D^+K@S07)+{#4u4PR^BF1<(F zF8PcsW=Kl$b^UYqAiLZ5d>e}b`A-~V`kL6`l5`8saB+)UTUqO~EHW(d9Nf^5D=6Jk+HGY|Nxhy(r%(gPz0t{s|!L!&a=D{}B z#-w9;Y5j2-da~aX`t@Mnn40d_TsmH!+0Uuq#gFg4RC6l%h{9s+(-e}>E9OOk6^EJz ztCmRI!)KSadPlDO>`^DXd5@3dUh^_mDqsMK3ndTc^o06;pHmY6gNBDXtXT~M|CAvvV}4d9)HkejEkAN{~I+~Ii`K#1+1#CiQmGP?Az_C?pk#xI+Pqz6o01I<11#qtBk`=-5xis z>&!g5fgBp)BsD zv~A=gZi^dN6Qtv+cOAX_xr*FUB?V>5YOrfQ-S~z-_u}mBD!peGu!D^p28{R*wJb7L}^e%6wdv|5z z$6Lk%D1G8;B4saRZbOl;&d>ziNIR$?XR*6j^|uy)nkQ7m_=EU#_8OM?jxKg{XF~Jh zC}Mi%n!GU8Uj~)1JzRU7A?MUCdFpQYw`bsD-V&c!Pvk}OLLt<_eKlXf-lesb@nCYT zBOHoDiyN}j1VY2L#&MgbpXHPEy2asSVz--GX7~I=_aV3A=qT~;pLmiPKiA?~>1e8X z6G<*KMrgnXixB0J@P)Y3NC*03UrhbZKYv^}9AJ~FYTKmR+SK;>>n;wqRMGB0x5ba{ zI%Y&+3mi=gTC60EP}G^eR#cL!j*HL)&L;(Op>RN zCPrfpQ`2p5{s%?F393n|f!^>o5d1RQK}7wc{NXF#Kvjb#Gw&9|@l{3Ts5VVC)Ia+@ zXx21|>0rVpy6FNnaKZe}x^U-2aQvkpe`Lfjf^D+Jpk^1-T7`E5~8mRSWXaZ%9 z;I*?_=-+*Dl@LZ<4f1nmXpU0k>>0wuUu7n;HH;tC<}S|Lblr9Hid>G&rriw}jV`28Z$ z^v20t9+qEd34jR^IG_A#-KWMbP?bXgh5=&=IG^k+m>vt3cnK75z3p;4Wf!yFDi(k#@3AiSpbqWs;B9K?qQ@U z2I@%N`!`%tMb&imF;cOBJY-)yS%bFT!O$YB-ixMM_pXq~T!`|YBL@pzsIW{e}}JC>?%+6m_}AOxqC( z(NHR=;YZFr`wzvzO)~pkegeSNj2UM7UUb$W&$+tVAKw#xd13fr46F9W$fzv>`B-*W zWyhZZz-=iz_ZvvFMgph~L|$|31WjY0Lz)6C0R8MOyX$VJTw94NO*#6Dvn z&{esAXp_oiHElypkjnj63Lq4DHtB{@Ron-l(dqUoMA_T(05eN|=^OQIW0~2~$`3rk z5AtsAU3-rIT@VVeFDf*%9c5m>PrR=UQSXDRwk+O~muUFz{yr%m)S{X`O9(qHRk9ls zpzoG#w{P_oXQ*N>hwV&@bUwO7Y)$96leGE9stMTd1-QE0irz6umsFYXna%F1`V=U$ z>;APi=gtt(AHpETCnv&jcc#5EVr@PC4t1rB#%Ap?b1A(u5I00laADl0ZCQ{7XUouR zSs~v&G>r3`X<}t&easO|DhzHkmf4~8r`_xRb8Phd!gHsp5{Wq}hU5;1rt6I#*o8PH zmbmT{U!OmMo!eP$iT?Fn$Mh&{_r4OKZ!~#IS^elEGqUmq(ux+ln;v!8w;xSc zFGbGv2TC7N-&TVD*mVk9;pDSGhznRMkwk7={g-E=P}{LmKUP+J#Da0V@RYB5-VKu- zzNvrM&OD15kx3A8%IaLia(i=06^!+P<)es^!Rc(_z<5*y-gK4V3aKYKK0lu)Mdn@7 zFQNuEl3IyjS~6E*cxvL0783+!$`Yyp;3w%0w5*r7+YfxM#BEJo4VJf6DRjaRMnr?E z9V#}hVb6-5!1e~lDf99Xm~h5F?rutif2gZl&M44IW*N=)cZ@Y zf7s;LHnF{kgP7%b>kXP}9eHyUYeL`=c7c`vKDo@C#fP!NUq}h8==u5UPq2ejL*h#^ z#lne4T(_#`q%>V$x7835D0{;eO!#+WV}JIm(p29h`C$uDkN)rNJvTAIl-R^BE|1EX zr{$569~3l(b**)ATE2Q?QVRv;`D0+i_nLd4^#Y}B;(c^GCXFUA86)bWA4~-)8RR=H zmX;*cDEy8^viqwoC~YC$Jk$SVhXN$+>Bm1Ljpz$6o(&)fTYVCxTbNc=rj39HTq6D^8E=bXug=tnn}^<+>b zHOf$I0TDMR2b96h??>8yg%WwD!`NW`cGSBaOGBoCGA-8SB!y^Oqo$DH1Y0$O?-(F1#zsvCs9sgh7#z<|2K6iKVE%g z`6$qeBvJTJjAzVlW3zJI!~|tnVh5=8F?x4rr}LOq8}}BXV$}a0Ai)G1B2=wR@_|3puXq$_ND2tPwF9(wS`Y{Xq zG}Ynq|CNB=!O|9T6_8G+K9Kr=+k1UF9knQ`IXx#C5ub-TpRWJNJ%8>V;G@WK^((&L zKX1HVcMeNfK?0*PKZPbOc7>?iF$zqP2>z$ zBJ*x~lR)xWt(gvk9qXsf@A%7pv4Y9>|@oD z*ziEOCGaeP#XX>t3|1st4<-Ap8-J_}GQGk#!O=44Xwl_6&!(j)I#3V)`;GT%5_IR~ z0hDhB5m#_p-4w+pAv~ajm>VZd6ZG!#otd9ODI14L{SY`obdsMxAO?<~Y(BxtSc!@? zTSKrSM((X*qIZF2+DIRswSWeGuSLrf%hXEq@)M(xPl5M8b+Y*<#|d6k>nEWAOJn3- zd$@V>jy7;=$Iqqxez*U{p|w8&iC%=iN0|<&3PE2@)QM@}JyxsA!NOkxe70b>GS`x$ zF)I$eA#H~w{~xb@Z&|1+i!_qltN8Ufvv=@uHedPrqo|MW=}-4q*HGp1^D_rBiPm)? zC)~qJ8^C)4j&*Uf8ek;k8yAE+*r^^sCcv8j%I|{4@!9grt4RHPddJ(1-B!aAb7kAx zESc&uTf`gpNpLT5v`U8#`n+^QZ|s}Y39k+@@o6$3$$nA}dA8Xt*21tNSbooU@9p)2 zxlXf(mTwV?!cmpF6Fro@JRV7*lusC=WhhuCL$Ce?<5#_vk_+Klab)-VrWDUxwXC?9 zRGLOIN(p~#9ztP&2rX2NCT8BFjeBkw^pC$R3K!Z4u|as0nUCX*zEda z!RA*o)$$PdMgJCSPS{c+DRczFH3K-{%Xz1P`yZa6Ut0CR6Y_(lL7;otH{VLj#`PJd zR3#;=mt6fg(GMk1lQdX*-|5`2ebU$$k`x4IX~o_K3Bi4ZPhKt4oU&0vm-FQ`?((;2E~w^H4L}elN!i^#WU9Yd%zE(o0iaAvPyD z6DzocxSFo5yk8eDe&_LecbQtK)DJ0+2=*q%DX$ASYe5d<$xfTj3?{fXkwMmyn}%P8 zbfE6JjrU5y^TY7fcY7ixvylQ*#Ckju#_8iq7lrX5Tf3kw)bWw5r4b-?+L0xFI zjPUUkO=Fr^sqV%P_v7dl*V%vuDLD^z%e${7*8f9K^6FtymSW%(QW_;W$cgMieU9Jn zs=t#u$89#?E#VLBw#sA3N*3^f95o&M@|518#&vB}_Fmo(it5Jv=^{Mt5SR43c-H?S z!HG&%9iwB!kN~;$RC}%S>aw$+bkMa>%n*he(Q1nAMt^vyW`Xd79ghLofI5=Z{Rj75+Ubh;7vCMw-p0@Us+YUlX zpZ+s+)1I@HsQ5jti98s9B=Z$0ZRHk@IlE<@SAGD{U=(xpFYc$^d_)leZh{=So_3l7f|wr_te1H?&d58H@VZD?TZ^qrUYWKl(saR zG?-DbE}Xhm6wmuH3&I*a87DTFllnWLsJ)Qx#8}}9S-rq@!DFklmX?+|pzW*xeo+Fz zeaZbzx0Tkfo!@iW1It(4i%@Xe_pE)fe=j_5Faw6$VL_#5`FfrUdH3(_F0=k^y= zSjl%aGR-yIeRkmIKTb3o`Uy_q&wnhyv1v?}_#cr|jSu%`;?+#--jH&(=`ukVKDa6- z{LjY?q_R^l=b;dw-%H4z@ABR}bJ4P@Hj_VRAnI&>jCbPB5GlO-KDX%_5QA1rXl|~^ zpr&K`bl|~01^}g*@%yEtgXym~W;yK12c#}LxyccuC;#Z6l=`7`S$=g!>o87Fx1FIz zbGuhdnvuik5(f7i;4m1ymn#a9{_)Iw+Rgl&u7J8XfR6oVDWp4D7?vi?DMNDX7bETg zJhg?r%N&WUKvK_hv~o`Z+)|>j{5w=J`rp~Z;^;ZXKu|NZbp6gcO1u6$P*BDns?HSM zEZmav)EU5M_eNkUWtGoQb1J?4$(z;A z5XX{v$SKKSkBIe+4haRowjfY?L%=K`w2j;`N#RaML)Yn796l+AWu-VkEwBKjGnj+` zV$Ur9{5UlV7@#@BrO~YMR7FK003gw=0?(r^cz2~%@OcB}EtB&>qHSc)vmlkf#hWVt z{lWpLFg@21Lk{n(yk1_ng5^!D<~yOAub_)@1GG$OmHTX3v+*mRMcabe&E$RFQd23$ zZQ}%%nIDSNgZs8`l>LTN59N_gLt84%Z=;h{`2Cdp{9*kdFti3h*;wn`3trIe)^MHw z$l(jHIiA+moI;7tnIwmjIz=fqfP!9l9n~GUv%SOLD|na}=t1(@wlxK_v3FVXwx>I@;&P${X(L0Q7N?}|TUv_jgg>%;!efgPUKpV*sZ zpDha-nlUYTI83m?-VD`Fhfcej4yUIxX$JIPS|y zS+D;YOh@p;Cjm_Dock%GNmr}Goix*=)?}upL}9C`yHKvyDE~02!{O#|sClZ)^1vl2 zFFL;L{j(ho#Al=(hkgjB~T0z2m=soK{Wi86T3g8|L;I9Kzd4!py z^w!2~N9|4~K5Z6+M>bRV5HKU3_85iHBQ(wUHdD2n+&%;YhETm6@&TS_w&P0^P!8Dq z#3!W@mgY)?f7CE9vdjzKD_zmSMMhY*-3-<-01V&w)ANc|BF#(DU4x(!x0q6=AU4z1 zTbDo4CtN5J#H+=G@bp~lJ4?I`e$cNl$Q4@MO0UY3ic*>vH}!dVM9u(2Ap)!%gaj`YaS1^5 zH^byN1b}EtgR0iGs;e3@Zc82G?!kC@cIcibE~}72y;7Bn?YO^2fc$iXXnxH_))H7- zT>xkEf?y&f)L~mUM9$!0(_pZ+mZL65ltB^RAHPykzJly~U5KdS^WX0-y!J z#o-zb<~pO&}?gRtpFai`~Hf{SbnM@sFJahZxpltp;Fej z8`-*qHZ!q}-mCd~v{-g>Z@P2I=eXN*cj)*YIutH-I9;`-h^=cvSTRl%IPN=qF&ARH zIs>=sXq(cxdKWeTVgjE#+iEr??=qh6usn*xd#mgW_xCZQa~TKRq4d3yR~LP}*c{qZ z9KFsAz7FUD0^~Q-PBFg)`b+!hBbVCy4SWPs4|m~@BgBS%E+Z)mS&^g>qX{pyyr@ZK zvhW_ag$h02-U_w6i^++Jypll0>%UhQmp|ytC6k-|`dpu(ugFpI_zF3>PBCtN8IZk+ znWTSqDSW1j;}MHK*ee@~uyx8PHt)N#5I08TjC4Jf^uF(f>przioZgbZS1v*s%bsb} z>P7&FuHXOSc+=)vUP>=kaH?^+CfQ&i5&y7Pn7FedRZ+7w(p6kjxb;k{?$RPlN?GSg zgVt})&M%{(wZD?n{9T_TcG*Ji9UgVK%H8?FP2Bpt25YlrwcM=rl0_(sT#gaWUqwX@Ndj4pG<%n0nIQMls?`Mc)CM){b82e#TWh9(7UwQA$Yngzq{Bbv&`w;Bz z);EJc<3oY^sJk=5{|!%2$z9bfezEa98(oZ!OdMZC;e7th_M95~pJuP@LPy_1_bBq| zIO$6IXxikRv99;7=uq-&r0uAO0IU(Q@~051q~Cijw6eJu4srzti?dow{PQ+h0LnYg z{(ZK;*CXO$V^$ya`)3EcAx`iq6^}sFc)}?aOEu`{He%RtejE_n2!+fLEO8nvN}fG~ zCxq@`NA$u}NLbHTSnm!Wp9o$`UVE7QK6b9yHvE zQj0ZyrC&HB_YpzJc!*uArP-gcWd*{bk1V|nx2XbA`T8_zju@GBh|#KW)B;zrLx%c$ z9L5>Aun4tPO(Ctk5W$5OC|cmnb`1FyT#gVIk-FKdnbALP?>1PgZe4D4D2VTopybRw z^~H?jPqoPrdk>{X4Fo-6wRZ{OSUVQ{--{w{#3ekONcFq~&Z)Xb!r1=r-$MrL!&BXw zEwASjAXiyAjr+cQedC^ujsT$A+Xff=Y9e~rYsil|E3c* zy&)=?2(NUt%-078WhZQI7OFhdk?|e7cG9Ys%8sl`Tf=jqyhLa575_7vxtL11Dk+{; zj)*-L$r8sE@3Jp+c1LyJV>b8_tT6K8v#xpiI65_6{S*Cblyop*Hqk5Gg{y- zQX@ zhrX}R7Ycx*srZ;fs-R*Jpn-eM5^8R`jNX^6xjmX0sE`kE?cPvuVQOiOT+Aa6yz=WS zvsZi45$Pslp}^GD^(E>4~p3BKi4DrEHf#iQPa*L zdAUH;Esi&dJgm2}R|}VK*I{-|*mob}t3qep^p%+uV-1%PqOcK(edf!qS2ue;8@K2y z*{Sht^!9UzaO|uBLCz_HG~HQ2zy9BOmNFyzbf61ELhgrV&%9@9c9m@Q%?ALa8O|(K z6>{pJ8`FdI7R_!yBq6Tp&;STlQtr;frdtZ+P4s=YKrliHA_8sL}+R z#r!;Q*Lf_*CP^jCdS9~=f$*c_&T7f3^cIq3P}9hfANDJ#XEKYm8m{s8F&vHwwQJ3= zD=!T%SlXztvv~N)2LSYeH6_Ji!77$TTiwm58s?U*T1Y{rDV(aJH1=?SemwU@_J?A2 z*P1S0sN@<1q8iQ@A&rkg@{qR&Ayvory$%FBl@3A6oWYp9`Gp9Vu`hUjCafBRS6gdq zmm+>qSy!NA@bCO(|5|_L(7tcsZ54+$Hw%#X!wBbQO>OOD_a&)eeg=@*q*J4SaoBsl@2W1IF(<9t{xFXm` znCzltb>w*te?LotA#!HP;qe&rD^P(>>q)!4oajpGzeNHi&#@0UP1$)CbLq_=N>J~1 z7a&K^BMoS=w3uUG4mShnI`!RfG3#uEZn6@_4YHq-<%Oy4XUVQNAF~Q4Rp4os#tZQU zqnuI;GOA^r?8x*^fXNX)D@V*~HH~*|gL%_7nAOUUM3T`a%O=1+N2~-fyd7pdD@B^F zJBjPev-BIU*ukYE!dnr{Ki=>I7;DIjc*XNH4PEMIC~|ygU;@Dac5Q^lk7T z)H>L-lO<2K`Ny4_r$>vuE<{7mzxO5Rx{MHfE-LPdMOM7@g~DfDt$%GlL$G93zCP9S zC7>HJ^>TdjZUtrsNub9~$*bu)-E^Ia*Be!l&b#r&e;(-NdmgaatGli&5&79$dtGFs zIkL7-!h*AMOCw zRE_@;@h~_~q#%MJ2sg@cSc|w9;Q%4z;*%Dw>5j06=t(q{t0ILK>3iLCL_GfW@JdDD zvRvM5MzT-fn`KZc_ykNiHG9Woyd3opICT2mtO)A0z?X@2(!&8^T-7OJG_#FQ$`U9R zR={3s?7-VCS%2In+|w@~gFbWoIxwD?rUZ7=gpU`9DvcZ{t`?R@3+hpA`Wq=jf+8rC z5Bmx=D^Ali)e(I(yQaS9=#W zPLOq1WP`|l7Zl61zP=FT5hA)yNq=czYxy)3CSo&bW10HpXoHR4J`wBaemOB+V7NDs zym=79Sl*9qxX-&{I4_4h$;!`G%pbqR?sNlDI+%d>LdMK%=k}h zH@O6q=jFH!$Wu%Y>6+avO9t(O6exceq`;yJa=-=4I7NQ^Ld6s$eLoPs z*#&Q=-ooe)U1aTAb$JjNQR22&r1J$vJae3*GkJNz3KTgUOceB%CV^yD3cF!g))B^A z8=<6%-XXdHuyPqB=Jqfd641N#Stew+2ApjG<&(S6!g;e~nY|mEtgr%kDLcpV_svrR zeMpV9E)JPEtDHGp8-9gk2vQAW(@R&}L>32L8N#7%0^w6R9k7jNi?0h_rG!l@3|3iK z9NFrZynhi@Kl^nS`lv{F<#r+TFgE$!JJdWhRstx|Nn~I>Exz3PAR9<^BILrCyU&Fr zuB`a@vYb4Kl-aU@Gux%NGNWe*+hw`(^Zv?EW~i(wA~Q@eND}IXo8QvpOCrKs-H%Uy zdk9G<--`C_VroQ*V!%wVV4)I+WZ4WrfH98X>lof7vetN5cd<1Pdy*pO29CV%m})=j z9KF@Z(;A>Ij|y~x7#OjBusg}kZ8rS~o|C7q#In~<6^y%$dm|-Fq-G?3bpfFw!geJX zABytPwzr%@CTWXZ4P1;E!|w?kgWmOV80_Ur_OAM2#Y> zR^?cQN^i%_lLZQJs?w~?d|ltKqSAh>0uHZD7Emq-R{8D*y%;-}?NS?b13h0dzL^?{ zz41f%{P6hD`X_^(?HF;X(2EQ6CC~2D_lg}q7%%zm+XJ#L?)z-3&!&J@#f*zwt;i0M zo+oF3TY6BZVxxR=%TAUPp3VS_E1%n9UgR1c@+;w4YyIs%v6UJCYSV(oh|pM=eXGgG zpF#D9*H>BA{udTU1;B=uj~qbop-4ydH^9xJd_fA2!;Ony0Zm7jdDQY*`(@+Zp1ui~ zoL7Absh6YMC^BA z*x+NFnp~7w7eWKok=vQPGXwsL1IUrmZj^Ja(k6OJsxlg?G^QAVI>BO!rcUgjJaXKF z4}vZ|@H!eFXq6pUzrO$X8LscYvbEsRNQ>Xk(Ca5oyjVj*{Jvm0gPinYcY4g8WALCH z@XY-fwy~wb32;w24QLCUTxpM_hIc4EE5NP7%`OSisA|CkPT<0shi}w)qmtbZs^H!< zNC*3MzZ7~rJYyJFcW8Q57DYf8c>EW-fXZ{ESn-m}%a{MFDz&Q9;3ETrZL+J|6>spW4WK#H~NKbx*G!Y6!H) zG$_({d%Vo=&_)O>mHa21eXge5uJIo*uHSsIQtEGK)Tv?rm7UTy8g$J3j|8$B9D!M+ z9O@b{v!4-5S7?&=vfg0*GKCgF`8AA=F!laAQ??qqQ@N`X)^m*dHxHw=t&Q=lLsicz zVPP!-A{U<54}y69|0C?HNa0tRF?wp%4{O@o`h&glS%4{(S}`P~|w@GiWqYsIB$=;<0q=*Vg^ zqGSn}M~jg?MHi^&6>6jzmaT5-0;|Au$tNl*WLmGyj=F!W#ockZm!J7tzw}0inyvVC z8#+u-<;at~Y6-M`E=Mr42cFaSy~t(IN6fMEVA8^j!_~}PnGYH;V@RuOnQ`GEkA(PwEa@wt!geJ)m3~{0PA4t<F#{09hdXqLq?=gTs)uF6fj7qt&wHpH=OznROT9=_yRt?AC<1_Ea1=8nN zC)D1(;CpLkOhcy>*6ICN#4Nr~*QlcB(R~qNi?eJ&mp?;i<$vLQmOf@*ms3n2= zyps%NmuFk`Y13d5r{lf&m78hFaKLH>AIVYr%}3ilf|Sz51Vy6=8Z@XGAiAZdo;ha` z3^m0uXZOmdU%q`MFH-cXRY>=x@6*{dxcuLLU*Jr)!ydL5|4SdN-Eu2FY^#W8b zOQY=u1))z(2G8l4Kq9&&SGNSUm`hK8h#fSw2j$4uj}Z4K9pW)>M@4S?t%ncln|BJBNXt>t>fTXhb5zJSj)(P}C2V{CScxj>iX%zCRufh;oSf!)cAnVGtSPFo^ zP=LWH$0&#L=hbJFHxwJJ#312Bn85s{xd%EeYIFczJgb0Nr5pX*rEviq6{=4#eVP)D zTX(q@m4m%!L+llByHP4i;=mu)V~)rfU8^Vu-x8F)Hq7vG2% z8{U*)ywY-(UK_iO37YBcA}=4v#IKSR9fTxvL(TBt7pA$=XzwSkbr%e-m^GF>qzIT^ zW_%FJnq7nu-w20^oC8?1ZAM%1uAaS;cb2x_(u)6UWOcv!OQ~s2Q|hm-pov<6w3f=v z@2zB>fyOaJ$AWk|&28yFBUjHjz1&>54zH8^tfV)E4Bmf;>JLWDc&f0CF*wI z2{3FiT=54>)(aoiZ;zTVjWi4eh>@u;99u#{=*Zo^?d;k*dpVYRMe^< zZcrt_xWLDFe4nIxP(sLP z?)#MAi7I6*FGk_fZC~zKUu3l(-babn_=M&t9$`4AF&p*|LH!F*<{0p+Y_erzz@6Fh zXL@y!nZl1|)&0y7;wV3)p}1%c%6HODw_QPJ?*HD1aa%0A$5V$7sZosFij}A!GNFRp zr!@K%6k9DV1bI%5T5WSh9Tb<%;qD7yF7=Otdz?7B^N2F)WHIp`o6YAbGw>P%Di?$f zHI=nX101qAD+H#?nYZ`W!IitOaLanwebO|U?A!3ENPs(eYcP8aMSt)aMq-c;Bp$+} z>AZeN)KX~sV93}ESK4ta!Gp%;6|R@xue}EuXjb2(Z?+uP?6y8f^9ZBw!>!A^)(vo= z6H#}>tIA-3Q?Q>0ZNJ#mjmUcqoWFA#nY<-(*EB!uKeECoEZ?03{flF%W(w*1Rwc<7 zlo9=>s=S}aU;+bPh~7cD?f+v4+hbvT3^c%G$=3_Nu7bM{U?>wK*R~(fvUqprKW4?P zKOT+^{sjYuHc8y&LUpM6-XKZIHWeT|0_jY6lr#4~jOiY>9RxM53qlp91alpAb}=%d zZ(;07`!o^v4?;GyMf#}2chzdwE6@KhXIp-=l^1wVhC}fZ8J?<5wW&K`Rl$vll|aVD`<|o3N&`^r$(QqH`j}-wC|+{@WN)&P6CmICP!BYT}BK&g>23v z425ti`PopvX|229Cy=2V3D(q#j5piOSFt)c-hkC@G7esxb@KmDWFe0oKh_|(^7pWs zh(m;0)>L=Ij*A%V`|Vy;hYQfH>!m2pg@u6$jqb>3uT4i?LQzNXzSKoyQP1D*)xhe` zXuoIWr~EgcDpcE0cNXMHV4h()6ggwh6gr?j(8;}ODa}z<0PH{Ye3b*+(wgIw>0usj zhNGpOQt57-!;U1>-`3P2A?+c86jPjQv)Y4k6uUk9@p7XL2evSES zyVqRi-TyecF>V1(F^u=?2PoTI*s*k)#D>Yz%q^_j{V;?@u8rVWrBHQyjAcQ>fO_{6 zsTzj21H(Wo;wb=3Q=I1drL@~!lYhB8R1IjYwG>8L>k)AOk80(GAv3Ke3;LB`(`Y?I z%iUisC++&LZY(^i>IDK?o}9gr)L|hF!RDXsAcJK5?enIqpFfXh4=(qh z)Jk?$q>?J5<|lZ&q70`)JB8j)y8rn2_t;Qd_N)|}pkA6z??9qAyX>@{p3{$mHkIj( zMd4D_P{A`Ue&}zR(ZL6e&Q_;hR_p4ahT+6=Db(oIB{Mq;Wwk%l0E(=>BMoH~SUjBP zK}E-MW8tp|dfk+3*9Eka@FVjQo(p%N$*9=LB0=N|ri=!3(v=iQbc|(W-fo$GteyIf zXjUJmDUoosyI;z#^P3ViawzY|-KU+uGV^S9C^8RMJGMDHx{d!;eVVT#K_3VfI~|Fn z5{lih10g_kVX!=T)>Qa?`@xIJv#$cGsxtF`BsCTRJ>*;ebb$wFENLoT4n2c~>GFDcS^x~#RqMV0w_hoSF5}_heDilhL z%&yuv!-Sjx31^($0FmFZ<4D2nhW@W}0m;e_ssOGLP#rN-^e00p;BhmvzUQ(Rzopt- zOttM>3+ip|ftwhLffhXwuzohHl2{(0YbA_l5Ql$3m|>5%<@ZLs-_B+>Yo|{NCH-dM z&xm_jWF=E;BgVhPDH_ATh1m>fwF`(hJ9W9uCpUZgX{VZY59(T{Uw+7)snX`sx(ktG zgh2wiC4Wsel>59hGcA#i9DTar3}}q5IU@0qC(*J|-*}==>>Z&#fif#RUE)4HFV!RL zBxI1$f9RNdK)W%JE#9@8U>m4``l%^9ZGWAp@9ZthKoC2RsZ;)W7-`E~QdKS~%BrBd zK`Y1pI*8d4QY5pK- z@`p_7<^6aFRt|FUdJdD;on-cfJ;d8>>--;h%5+-J&H-J52RxR-?A)EH@YnrBzClT4Ak=W3CUm}Pz;+}sNYbIKS)6PVtbHA3xK?otz`w|=YFtgFeSR$b`aXA z*n0a!x#|10gz+~jz3$+p-Vq2lf+JEd4T`=a2v#-wnvhO{DFztG;;v`T3MhK~zRr%=Ws@yR-v?&}Dab}{Ikd-2x zL>@{vbI6b3Csz5m2MZ@2VXpT1sF;|1CQjkX9|F1=0v9*h=)jn&oUY>T!T9|;Btkk> z&wh-B^haC6P`d4PV&J>*ASt^@fV<8TI$w@@=IZR!bJg>VkE!d5G8iLK?AZ;+3CFI? zPj*&XyPfO^Dib>c{Z#Tusv~?9$Nb6SUQhLplixs@y0KB)?B+u*sdwtOlM+?)8hTD+ z2kVW2G4)C-&)mj9HX>YT{%dz~L#RdZu~Apm#4266E5e#83!TBB5loHz67ek_u*EEu1CIu4GtV8^X_}@r+HEx)v>>4%N3IjV-isfD_mCt5dsP$Mwze+tk++N)toA z#RymVJgGHHtuzSY{eu9(+k~NP|NG&g(z3Q}yDmrqju0Kje{KR04$xXo@;uq08AXj} z>I59SPjCu-|GnKFlEQmNOP$F%)yAo2nk+DYYZr`eN!y#w>-XU#i^7xoxlA)suAp;{ zZwcJ2%$$z) zGAemm^>qIHX8ArZr^d&M_KsQ(u6z@6{iG=WPX<&~?XRRaHs$e|MJXob<3#lvNhX_x8OpOBN z(>>K5ciE#Gmg2`!a!wCrFbK?#f$R^o?Gsz^F{(s474kRs_l}x;L&^*V!IWPqSzT4R zot;WTep1!4+=i5oz3<4(ljqJINDvslzSVX|`KthVHdVPv`{4ZBEjBvAmi(#&sEA?vIwJ8gb`b!M^3>+f;ue`9jY z_L}kLVT;Xjl97NL5_*+f>n~&9-0*Z$S8@C{YnQGo;HI!q5ColZliNUAl}P9VOlb+# zP*vsWC@CVYX(o)AgU|8gJ8IxLzu{Pl<+Td8z87)r!k0X`A3mElyH3=#loCT+LFypP zZTW-RU!b5k=QcdpTQs=PFE;j8btf@t`lAs?4&%y$$3M~Qcoue}VgKQ~#B1(PFzw&z z-p`_9*E6Q$rq71T$Z1au2SMzAyVs5*Mf_4uO$%v7Y+)tQVK;XkX?B8C2GET>$Z)IO z8N>S8pFq9bFbD`!d{#NLL6n+6f43SO*-@%;bFBd@uiH4Wi@J+iO3BO}DTpbTZ@0{v z?jU#SQb`e%-bvo`_Y*0-N0I>sb;*%B!>h3E?TlMeaNtz9JPc(yrAH-mlTQ6=wIYZL z-(Bc_rdjmujnci#`(}*DS-aPG%Unbb#eg=Aw$GHuX?|rJ>YUJGJuEHEe(TMCCE?4~ z-Jo&&D#sw`83R+KZ*8?C|L6$JEP2MxkXd(js$<9`OylgrTw@98j~@-Yw-*vUN+P~K zzIY&|d)QhbPkqd8@-KHSPVfeku`Z>J^*l`cFceOPP0%3Rx*gQ@0T>tkxs`a^X(1an zN7qRnDS4{kj?;v|cJBR({sQ42)*|xP(9>QYD3}@ImE$qDtjP2f|8T#LcI68jsnK)E z%w=Vsa^U@t@^k`^$;b@mikojuJ)0jzndlvZp*Ow3=T8&hSkYk}%+s9l^2|aJVLqN% z)k@?&=Wbw~KQ?>a&~40m>=QLVZsed<)>!nwRA9KiE=5oGfZotxTQ=!k$>lhH?nw9B zR$z@k${K|{HE(yoM6%1%gwg70#T%}}wu6?Absq5vR56!e)g%OpKNf-cVdQ%Nx24VhJbo`vH9tfN>m>hM`}ikAPKZdj~(yW^XV z16rV`@=*F$;2b$(RR7X&2SR!#5Pn1>-qE2otiwqQkh;-x?hcxVRKm67isG~bdj2kY zd&?=;GSeUU;2NIXFpKFm1vgC)hRF~8&hJRgz2V%B)icIBlZf&#;pa0D8`!%tT1Ov( ziiPhDbr$Jc)BzWrx5I-0Lgcfr4-AiWHTofkIl$p*)Vq5+ch@H`%ng?CJGLBKu%*(C zeNqzkjfsj>pO@Qls!@nvX7ujULq*7d1%y}KT^V{eIS8$N-J-oFY{fRX!t) zL`@F*M9t4oAK@mPJ7(Xlg~nO^vzM{8>tFv0 z^UV8@+!6zVR>vaeFSXu8ttJ+)i6p5bAf0srh7Zt;OAs7RWYSUI>EHGb@R;##U+4(t zDfZLlH5eNo?&?rz59aY`Xe@Y4ov+HQ25LN~Jg8e-pi*)gul-#*2oo@)xByi92TUl~ zG|Ov!>qivb6j7qX`E#qZWxH#&TxSXo^#JjHGlMp#G$++xVd)4dEM|?V(-tA4v!N3$MVlihFUC2n1la1%hy@fEdY1aWPJJ)WDglyCE5jm$}EK7$?4=0t=P-gHU2S^XtWY#Y%gs6J% z%V=^-Rq4IX8NKbE>rjEN+jMJh3HN4KeE^Vs!8Pj9NHD>D=U+&T9TKs%R30<@@f?TIl-N2d4P!+q0hb+lCi^GVR%0 zT0wR1xWzl&k^NL!G=yA0OqI!=9`1FkKKskAO0;@q+xFo@Y_+Gue>Cf0XBU;trn{Ronq2A6svs$R_06;1QSNB#X?aPz=ObxD*0q}FcUM7Fc`ijt z)^dzUH-58E)J7r@G%iZwGdnaGePO)voAq0wc(%x0niu^S<@TwbmB(HEvtMJib=Qb+faH|t z{$fElWut}D=o<2X;IB;G=#sk0#y+mULMtiTlRM^zIq|*)H_B#O#pEQ)c2qw6G#HnE z`_ve<{gTKYNzoI+Dy0=IAxB(dpL{3^vq~9LyLYdRkVK9in;VRm_&LcWeH5loiEz){ zsj_*vRK8uR{Qb6sODaaO%r$Z(;*?glxW$&00mlnlXFU}&FJ>+$$9m`kaUFxQ`O8~Q$5u%f+!sYwH5dqd9ZEooVN;On$Z5q zu=b z7mYE0U|sx2Vk}D2%;+=2zz$5rQzN@Dz;1pYE^R)#_LE`px%56oQ9YTSJ)r@gCEDx% zzOi!aZqcH}xiDaP)kqdKA|uTQnzk}?2cwP<%b&E^3+t(ivDYYVspjb8KpWA+IBX>? zUipsS&@EfXH9tV%;f*lti9FY%pf(;h%ZA=Td;)5Tm_GlfMqPYu`Jrp~VPjLUy5nJy z`)G4w49X2JkLX*j%o*1+A5=@_#AlpMx-`a>_M-Ui{7Pe9-YB?a!AGUmb73M_Gt2n- zhr{yfGArMp@aTHP@YNa3wJ~?EaAc#}e#@WJNPGQuUj-0~@VxaHqr=!YyA%DE@A!@u zyxTO`mhiP2BWIFc8u9+>T0swXYvH#IX=Yv{NA}@OybPq(HBr6E94y{|6Q6o=E) zDtG(_?^s}w}>%+XNTQG9ZOLwpQOKcH6SXw)AFP*(={(3%f53zgy z{^R9ETfB&cUf5Lac8nmMeT1TS#>yuX+Zt;)VQt6e)hTFxEWv|bjEfk$CbIgHK0fhJ zuiC@eQ~PI?PkvfClmUxRp`G+uct(?xLZ|&{*)CUH;J5&}qM%GubKw+ry1`=h{oVY8 z(v=?`7fWPTBeu=9kBFI*1kvcgRZ&drvmtQRv(-%%} zvC&HfghSaJD zs|)*#Va{$WCjJYio$)G)p`a#*+)UBb%W9)n)xuEaVe|iT7w_psX0i#E?TUVRp#Z5#dvGq57>6>9T!H~T z6Bn~Ts-d}TCOL|Dt(pE&i+HQqDOC%F_`?~?|7+=@ej8#Rt+LOVYwEe{bk-C{tHa{u z#+1dS=#b$Pj1h?|+m_gN#A6FGVcSb`r&ex_7%f>ohjPx!U z6R#<*w8y)yjG!7&%Q*rED^3Lxn0048MEA8=q4q9^60I1R7jsR>MtuBpdJDQ_RGeSF zRUa)*Z>m(nOFXy&V>uk7{TUS|um>3iwqf*D?l?GY3O$>2Zu3n)6jo!6IhsV z&?1-aS;esN-)JW{c=>MzHGyhoNLty$wr`NS)zssie`vSL-$-WF( z@{hX`uA}~^GqO@bol*NmX^sa&VyDh?rze`cwng;az=_b=x3;Kik^2YaFFUVX*1~-o z>kiLlsx$Uo-FlwQ>-0`O6;xeR2-ytnL}sofiKJ9_wS(fu@U__OPSA&+_^O`C*f% z_R~$IyqLa(dOZ=g*b5l@z3q)b3|PiK6IqIEhD@J5{Y>p^&}sYWba) zFD~gI_AtwpHYI?$aNcXO;U50me(kkCW9WvTEvjcuNU&QdRC1xI=kNH`68ne+8Hjg& zFP)H%@{&sqA~pvrM7FQM=qGk3zH>~SLM^NGhB`CGSYyV%JFjEp=_44u+*ex7^4G$R zY(KmYFT;R!C7U_kj?qCaD%(lC!B+y}vdsU>W!+@}qw*wv-`K;AMa}ER;Lb7C$sprs z;MMs5Gg`dEngY6~FZ#)cY7wji4$b|EjYjN%?7JZeRy_n$ctA@`F+&5j1WUG1&(@bV z^|aJFZvIj(F&!19)Yc=OG&eU9j#qHD5?pq6s0;h}Li|sOq85O~-?nsoC%L?Wzb}j~ zFx=RVX+J`jhUq)K>u}Y7?3p7tu=Pkvv?6BW`M~~Xs3Q5pN60JsN+q3mYV?4Qsc`)! z!Aw*@U$(-BNm#}cnZX_V*6X0|v?VqTxz$O=zHDE2h{1paK&%U8;G>dn$D zj;vh9r7fto3t1#08)nxN;-whxbW~71ng-*T@l1bBA<5e|jNC-uE!5vEZJ0erO&O#Q z5|XDxO>>osmP})LPkcJ87KQ0k(Z+!E6vw?Mx@#H}{h15+`<}bQX>ytxb?Hy6q8J0I zkt)Xiwy|N=U+K>xU0Bo7I}WY&idei7vT48*AA(1#eKY^IW%-eQU*Jx&$Er?PS9wlW zT0VPBlT-icKLCij^kwN$1sN?Hy{uLV^uU@ie*PMxxrIV| z{o_?mvTnFJdaNU`phd9(x^7~c%f^kq5OBp!G1qACx2Eb%&A((^`MWsQ#V_zj1`KRx z#AsvAINi^dTk{JT(bI!n9BK3zNT-O=rdXkp9}d!D>UMlXQ2TzS!sk4%`A~4eWlzy} zxTdi&M}`g`Kc5!bgfjn2YDlzbc8(AM)aU!}NeycU|2KA(V^F@*aA ze}<+8KA|g{m+jWLGcdI9^d?sAjb3tX?{Ug@m-Td2Fmeq~lW#w2dOHSWIGNIdI@`z*XH z%Zr4%coRqu=~E^JjLK|YtJJfW-y3JOe^%kGbY?sWmK}TcgFE!ORJcpg?Aq=fvH|uqL)#Gj-GfA(JaqfF z2TGT#@9}s@8i0&r;Ped0+wH84R@Qw-&PFKw#;3nm<(hrI+}N=tpvvv$=l932cmCy6 zWg1qTrYylVX6F2V_xA74k7Ho6cOsjGP!6$sZAaM;j*qGCFeaz3c&ZV9`WQ`vdKB}b z#3#s`3NC60gRa!8#6)2ip9h5ib&{C^nUa}b_Z0LPPiZ<7PP2#X5$TgrV)R1%ZS0-G zeu9*Q$E|PFhc4;{b02$))@^n!k5y=-Lj^BjQ?6$QU@KSrJhRpe%D!Sl5RYiFz?HUc zx6_`@@-yGF2Hw3d+ba(R+a~*3St!<@}U**Z(Xg(&Ywdx(FtJ+AQ-~$zc3RD4)4F?jU>C*eo zZ4BsYal=~}aZ+Tje|!A}-wwT#Lse3};h>cFetnW zM36l4DBZ#Vt|QsJ1)y+L1X@1zw*HF;U=CMW7Ws)kmEKfIcDo9;?oS?D*iYChL3B}c z9&{b0_WmjRQEn9r5D0~YawO4gJnS@`Eh>28a~55K{7@hRo{0qH`tw zdv9@#!Sy%KIt8trl{hIdEuCHBHp^Td=v|ke|AuJ)o{x}D&og9HbL5j~w^wg-8H`T` zU9@7mNK$wf0Fk;t8#~w`2Q*%;K2;WffM_>?Tv>i`zwe|J=;3C;%<;~<+*bENn7bI%*bF+X zL9~2lmTE>9v^n`R$&tI&5zWd8_HFUiPQ{BN)4L@z$GQ<)wyT!Qj2jF*qJGs^Fyp>u zM)RR!Kki0JlVo{Buku+C0&={W(QMkC4=Nz>IM-_pqaZL!XjADmlP87Hm2er3wF8UO^WDiJC7!|q$|@~dCeJQ+ zW>>pgX%mVaDy!#v6?z#|O?gbuj0*@mmnsD{y%}SUS{X`yd)jTdsr0B=XlH~@B$%T1 z%H8eAY3`l?rW+LBST%mwA`;u6uvgAj0AicEMoNyYmYI^Edsc3Th}H$|>16)y4&qoB z7~3<5KhqQ4E!`GKQ2{$Nv|eea68t~*7Ojpl%sj7#_X6Zh>Bna#5 zCuH(e8#Rpr?#1M&ZC4H=-Z%#Gslro4PpXL5To{pJ%GxTg@ad#!PL-=*T)rP!OkPxJ zDi=h;MVKHf^e{CV%LMap0tK_Oc0^Tkr_E>9%9y~((p{VfD4^T)u3JlbQC^doVkzWI z$g{TlZc7?dA&UMfn=gXN$v*%5=-!2SB2}&f^s|CkzmaieE>BkDRsd3Pd{(%-7O^Nlan>QJIyk9{#V_r0B z=Fhyj%fh<&Pbcnq90kEehvX_9^-fQf*(*=$sj0(Bdr!P$k#Ix897?2=zpMF*8>1SF_vYF~A}GGuuA$2}f@ zM2*Ts%^@~)rwhK6CFgcmL~e)q`+SkG2Wv>b6Uet69u1=@c2+h$ zu+Y{kuW4^-9a5ijA%MZX3fjZW0tFzvx1a6FxHIXW<5O>=HWCA z+68mW zg?N6_lMg=-$tGw0sc!C$Uw1{Eq~a0nUy-9y)y@!^bUJPj-KPcV@Tr?3pf9JIa_ze< zqo2e%#=t12&If=9{wWDshWka`V)_F-CSHjgmLBx1I9768g=Z!YfL{2)V*S)A(}1XtYMLMBI7 zgPTbmIX3kGEBi{67dMz3f00^b=rYUG_0hN2Buim@|Gi8KcVkwRDmqKpxPH5}=}u_v z-PA~+u3C0}&NHdiZz|uO6~5j=ctSCVaW*K#_bO0l zO}s2kg{sC8v2y0AO0OQ~l#%U)Vbk*;*$dR<2{uILEmcv(`4LBxM^=m*gazl}OjViBS%y|poaJC{IhWp-KN(FN@=e0Zt0zr+(=SU8TuKKcr+SNW4 zNfFvnq8u^-CP!yA3&x*;DGWZrmHIugEP(kI<&_mJZHGC3MrgkU<+*MVyu0@%ar2!% zAc1OFVmG~NIBGzM5K5ULRA$8!bl!xjY-$ljfwe&^=@BK zrC|*2-G;Qp`MN!`%Jn&FuBa1+(mu7}iIU2FCTw1FCSH*cBi|;0oTZqB!1#2bI!DWSqN`5!AyQUXPU79`Nr;QaJKus^TU)>k6j4mOiaBN-NUS9 zP&W>){LpSs%9zNlEU6i(L_?Sj(sem8lsz!G8PBc}=`!$kF{sq0xcfn-;1F_FTGT)R z_7|OYUTUJqpl#3@9`UMbuMxxtJ*KIGAf#{X7!o2ak)jal9c5=2+4yB&Bxgjc((dxY zsh%eueja(?!NOQ(p>T^UVr#M?TXww>?s%0qB10s5nnce|g@rr*80{P&7-){jkG~of zrdr-qC=p+AE&=~~nqE47{?z07?9NhazHhFfsDw?64>`N=sv8<|YaH94LGRb_;@X~p zCxP!13#5@e(jqSTOx~}*g@>Gc!P39CGGDAZ|7q9+1gnR0%Z4Lvx4flPJS+rVa1!1Q zvV|~PL(gNl+3(&go23gN^WD@EECbllPa;aT9t6l^#*J|YTc00HRZ|U@w5iDs`QY^T z4voXpMCaZJZ-18bS2o1F0`*enN^K-Qf6Jw<`ARs^*fM8j+cqo$qa zd7}m7pqPwxSTnX>0YuP#HpKIqf}!hhdiT`F0k@J}j?8+EGf#|P%iWg?umq9C?jxMx z@o)+=y3QcK@MF4Yrqhz9b~J>Qmr7w5%q*uG?3^DqE_ctB^9*+SKw_k39%Sj^ruT5| zI6XFOta5*p`u+3F{2Qt!2y(&;gIPR*jq`I4Q@e1Un-{FrNn+?~ z?s}-p70je2!gNW11sv4f#`&WqXGJCA?i1GHB`pBte0_A|L!M$+zcJk%+l+>3YNV)_ z$DqbpFIf(u;i8Ao2oI9lIhTT1vck_doZs^xO)G+2rwb9Z?UkR-J{j5ShG!KB`%oKE zrbd>DXf3b?0a-tAY1K9`MJ1DmE3MreRIm*=KzX+n-<7>z^r%@WrVkkaKqJVK#`r(Ud34Pl|PFD<<}#J3S(^%e9na_5cC&moj?Xa zFnU|(jTM^|*C8pRtVxvn)b(&KXBE@GtHv8L3ml9*Nx{WqMH}d?>4`B9kZ|#4N0Za5 zOvjnpHh4+3kAs3rX~m;|01>@bX=4Y1Z^K znZ&$g1@Bo&V;QpOw2isxAH0IIxb!VD4Mm$bXLm7ME6RA zZmtf}j^GZ78iiU$@%3E_W);sbj1U0{D!rR$I3nbNl#*$*fmR5} z&MqFhK)6v@e&z#<(9pzb=>j;|7sGrGLq>rp`)_BHL6A`Bo5RV7K!=Ja%`u)+sZpC8 zbV}wSGqhI1Oh8_&AK4f_FXebVt~h{)2i#Hn)pg~LZdnl!2RUePW(gTOJKbt@yA%j^ zH+MRI4CwNb$V*s%RbJRCf7t)Iq|G00eZNjJ%1xH?niaJY=NCj~W(z%Cjos$9@$8oD ztt^^!9&!xU+pXwHZj$`*{M9;t6E6owP3zoBjj>vuT{213M~(%89opBP6nuY4EJ^02 z{E3p1fE4a%$3U2ZTu zi$OxTe}ajqO54E9~2nXer{j_gM=JwkiAG z1M=E0m?z{xrPR1B%VumqlaSM026UmW1rt7XQ{rpB4^AJaTs)-Lk}V=v_lws0CDF=0g+<6#CidFH7$UiTa; zMX%!PDy98;Hl(l_!;BPORns@XjGt^|q*eKa@DOhZOe6mLT|i};F63|I#Cg@~R%H2R znV~IDc~ynzK$Mph<(M}G#g`M=3UnSwTIS#T@N*U9^RdQ9e<5=M{4jlS)Q@G5(O-(R z1sL=h#tn{qj%_xI*K0fk=pLj_Y}%L*VBR);Pl0lU0>bt;2x)Cq=gT7!EES~a%0*w< zGlnAB`tZH-VctlmeIjc4`PU3b;4s@gQVl;p2JyL=6h)=r3TKLE-^ZntVekF|fmT<) zc5iv)h<<_`WUu(i+QvI4c)~ehKNc@di?C-|3P#&ay!~evSd3j*WAnfj6~7pjO)}n} zSkRMWOC>qBCs%B3_xPq{kfs}V^!mkYvVZOfmt@|cN^3AtRcbQW=If}C<*bA&1$7{~QkgTHzg&ew)@p6zI z=K>*Ds=n#=h0icW%J$}K2@&pb7<=<|E4@2>!PBpHBU;=y3G;b{=?wMVhyweypr6bi zVa z`=EEEs&xPBCKxor=*C?l?T!p9u<3hoFX$d}AS~84i>SA40SNs*vQ(-xa)uWyvE4ry z)%`?C=!gO-JE9B;@wU?;W|5qVJnr_smW-wUoOj-)R^NMdoRU&C@10`LT(Ygr8v`ZR zJgX?plGK>0a)YR0SxSv#@j3qZrsPshxm_6dE3BXMS|eRq=A4_U({oNYriR8_WJW{f zZv~v}a4;IWNPj}%0%c#h%;s6_&@W1GFC8FQg@IUq~)K3@P_`obA8Qyn8RZUxngH-4Qe2DPc2} z&HnjKupui!iWEN1o2o__+(l&@^&I{1xN(&(-z&kIz0lZq4h0I#!;G|ERPVGn6sfYS z7sxSTM+V~+w+=Dis4{9ugmcm2G&eZ6?GBlhQexaX3Z?(CuK^xu%yWW{;`5Jb>L8)l z3y0dpV_X5}sW1g?kyLxe3S>5=vgX68M&{3z0_9P2bupbUeTDdVT68DOMyiL3!fuKv z@b`VZ0W%*$E=$n`RZDg~#0ivf3czF$nP40dYRkR&)@w=jj91KzW`XIgNnbD5V5`E& zWhUMYd%D(S%j}zA1D)N5&@b6H8hoOj+d9vtTy)m%M61}P*)NLnTVWyrsngexa@Cp2>{k86Js)z8pbn-Sk67~U zmZ%fWAraD>MAdIERD_7e)V@V99Qap-kfLagj2>B-ul8iQ$EO}02VLMHR4;SS zQ61XT6cRo?3cAj64IXEFo6*p3;|uthFMXl4C-pB_<&YMdu68*D#U)I)agNoqD26)> zPzEK0MY=r(C-$Y-4N%-a%?x*}Gb;|PKg80t>)xmalJz3u>C8?B#(rXKgT=_yJ5Fqb z_Ujlp#0_W*i{6(J-ENlAxmet4PnF}Wi@;TI*5s#|favz);Wns2l@C=jNye2PDCJc*MsS8C~R@vR1qnd`|KgFWR;}^!dq9_7WZet^3^P?Wd zUr3=W*BZ!*yCbwmbc`p>#CiA#X1_=h1XsP;A%dPq2d!uJwVI;asC5aMFEK z3#h1A(9dsk8XRYr4(Yql#>za4k%cZ$>KW*p-ierReYHq=Z+O+B^@*Rh*NW75E#2 zbJ;kQ_9?^UlW^Y5ldK=35)P*p8K_@7*>7-lM{-UVSLG63Qf5Ex&=kMT;x;nr<800N zT+a1&n@4Xu9oZcn88{B&ULZinbl(dXe{rlV3qrveFqrz+1}u+o=IYWX^8J$oW78Q7 zW>bPc3&~jW*!4~oxhgn)#_#D<(09H(M7~ScB}OI)npU~ReQvttJ=xW)E^&mwGZ}B( zSwQCDz?PBSsOzZuR#1@G8*P>HweZ+#Cm1FCeJ?9jkEb81VXM5SlSN^ulPc(og;RM0 zro73%XOp0*eE84@7kX^KZB3_tSdv<7w1#s-yq$&KME1;%+loW^R9)k8L2>>L(b4K*NmHUtpI3*5$Jg#g0N+J-Q+pN-6Ze8a z+@*ohra@TMKhbTz)uy<)xA=0S9=DD1=Z!$1tCF!|U$@H%J2d;UUDqn9Jwvx7QDxr7 zt;g5Ump^gNf->1MxX#~N-txxIg%0noZr6faMp3Ke2(JWcG!GPB7lL|-9_Aw2#@`7b zb^pDhfR7l=pz-*!_ugk147g?6q4Rwi@7^y0?3q&w2SJSIOVnvW{ z1Ub62OizEtd^6N;4N6~(VL9$w;{afp8%HiAv8x-|vfc_(_(#MY`nBoNah$WMk|ymA z4gQo1=$9+LUx){VYMPq-29M%DM`KZRVWZFVH;&U?x<+FTvW*RqT&xe9j@lZp+z-pm z_rk+W_AX?zf*H|m-&ZY`Bfue6s_bEe!*GtpYHjovpHL04v7vC^jP`h#__i?AA#-2@ zf|2uC-v@BC)AvH@-*?0|>|5)(@N=}gM6vAfnj%tGWqb=|cQ^K`CBo5N8}stM7nDhS zaS4y%>%_h*?DdxvsFIv^L>et66(zfQ#!OX0j~|OnZH`VRb_jE?h0@pv+4(|2hPv%A zujp!4b9oUwHFedMu@CrFTxom()(9^LD@Z@((m(R}x3&Mz;Th+$0l>-n>$S*l8;{oL ztgs7w5N&??bq7-#a~7{EdQ1wY&UC%`DvR*D*Si2vja-_< z4{P4(G=jzlMoM#Bq>G^Y<=4Dos0jo~O#l;P7yyAyx{0eS9PFqsx$F;$A7bssxq%{f zJ~I|&Pe!kiqFBTeFj~3t2T7EZ=xDjT_I-S~sh<+G_}q8oOF=6(*`B212&{i3pwGf} zQz&zdlIU$c6n$*@PFil&mtXxyCs zc?!4{550zE&feX+@FUXF|l&@G8`S!DzMe!`8o z4CWdj715Xe1TIxFU zZ^c&HGVb(t1ebc}Ilb=ZD?g5}{JP7FR>;B50ZQ+G(g@C0a*Q6YM-^e11CaIhrLT$S z1g_ww>MgeHYu`*{tGP4T44|#*QEw7W4vZwD9_!d%WZ8iP=xN2Db2dqX1w~k0wlAC& zD**h=7{jCY(b;dii-IEK27tBzAhXW}(U`t{8?Y1p@2#qDa4!G*l@~z2IQ=V?x#ro( z6?AB1K8R!@6|_e)f#P)f8V$z{y(ZN)za&R1;5D-o-};!0hs_DNi>0?|u3QuZE-S`V zM?B8dpk8rjgI7YkSEJF&KU(?>cs|+?8tGSfZoo2%Y+Mc1owI25Ca_;sN$=$!rK50w zO9l%Vw_^Fs&kAOkiLB7Q=BR;Y_(&#Hal%#p{v#!4JjkRx(uD)3bHuZ(`rj4~R0=9ig)~rBz#g zA@oJgd4v_;;E@xze-+O7DcZ^PULy#lt~CV{n0VqTjmv{Ge!l42Ed7`Ai+dV9qz@6^ zmV9eWc|Cn|l1#ZC1kr^Em z&L(|0H1%%;S&rbpFLF*8)wC)=a1y~fo~(Ymf7u9sUl_e*7+}Th0^;T(+a<_lB5Rf5 zH%ou4y&jT9IMuq5V}44Mzm$+g!IF;-EPjONG&-1x*Z^@B6lZJsQJH;_?h3MEba+?a z)yQz;$gLJN0B%PMVB&Y9S)I!()4uOfay3NZljC7l{qmEjUloYQDg!el8jdSP1s!w8 zJ+H6x8C(S#`upjO759i@9nX1)S`A&gpuA)*%fCi{<~)8kYhefjzV^U#Odl(^mK91S zVEIFE97EWaq~WOiq5u@$c#j&$gCL-BCh@~`_6QF8X^*A{2MSxhuW1 zJ)=T7rv2NP`2YUvC6A2+z;=G4;TTu4N+oJRm4uIa^jm*D=*R(J+CORJHfm!=+;5o% zW8VH30|wz=^m9g}M+vcBL}&YN5QA;MzEvRC;V(LTOq_W3H*du?33kwhIKQXSGgOHa zqrW;khrKV}jfs1c-Wg6jcfcwY(&eQG|GDcaar=jAAUe!(9Xgwd%Eay8V3kdAKFk<* zcgtPZw#IGx{2#CBN`HXRA6alw9p!b7GS%(JNE5vpc4PDb%Duair{`GL?X|um24})w zbBxaZ!a*Q#TN0d5ikU`%^f$KBw1IQodvoi}z`G$O%X<)YaaSAok5?ESP+AGt>GkkX zP&OFhe0&2%8D2Jat>;+ih5|owwQ>iaFcLC`ikGO7F|*HjO1V(y^rf5C{fYnL0S-bC zOr7Z-it&v7n*m-+4>07D>9>s!VYXn}Z(LoIAGxPy6YWW$bjKW0GHkC=96{5j`seG*5B1eB#QMZ3rW5%boEy}B~iTx49bZGi97b-nDqk`W} z12G_=ZN078N`qV8%Z27l6Hum^caK-C9IBQR)1JFwnJu{T&yn~8!5UazV4U)miS1t+ z)=pbnXx%Mo;G|Y-F&xtpk>IergugGK(lPm*p-ccX44!$X)y=7wp#x!!gdu#x(Up(C^tO1$MTUa7*_O1m+_GZ@!u0P} z%w+t3?R{rhQ`r_MDvAxTj3Odn1?dVRLa2(O(v;pihF*mb0t9TRG^I*cY0{;ImIPF! zLnx8}fdr(JK!893r10W>-`sm=oS8e^fA4*lANj(`IeYKb%ie39pAh=1HXQhc6@gHz zU=oirA@gOc1H)cFg)3p3tkT=#9~#_`h|^d#lk;-ltA2Vd=C4ZT!?PbD>A_GKML!BT zu>bdKZ@kV*FHZ*eaaHR+TI-5hAAoAm$3M?k-q-wfJ-^5Aj-7so0#>XK%WYK^=SZto zhYkK@8x4$p@CNHGm5H!DeJFuP>oX&6hEoLL|cGlW| zD1nSiBHwH4)!pExpUkzMPh}4h?eyGAJ^|fpIng2nZ`@`@bNGJON#Y&|~d9~J8Gtlsie5C2Y9>LV-j+n;7y{&>Ey>#A&(w!gCeAK&v&+Wz`Q6|3`JvRUZDwgufA)|4(JhM)6Va;Q+d|@ApA#OF?04FU=8!;0K)<{c;N2lwWpco&Gqo zjvEX}Z(DBW@jMkytN<5X^IqR_o+A(B`NKaOcQO&RuMoYA!& z*~PmWL{*|53o93E7DbuJ3u&jFHu3j9+%mSo`;A%3Iuy$);5ZqhObIBer=+l|Qcn~W zi2j9n{CCsE%G*Ng9Rsy2p;0By6H9r{3n{rVIyYt3HzcggqQv`kS8)9G|sZveihsHMR`x5|L4ffherkz9!47 z@Tq{erWsN0Er9x^WEFpfsMNACnUcM$sLNZ?rB+8`ROE#VE1NFJumh)opHP}wgR(pi zydV@`3W!qwv%~sl=H}TERzJA-&PzlUiZP}oZMj1O)wJ*H=w`=O#96X0c}o_?KNGhz zYPsjcxu^vXK0*0uU!owbgOD`u*{32HRMWZ#{=O5XnKP)w13a|a{#EzCn|$Mu`B@{A zvNfHkN<E{#;lpw+vWm*Zjlj+An%*2q{;7?kg+-@^NPiIs{El@` z+_jdES>Dx1 zOH}5A)HtUF+HdC&etWa2vaQ~e{_+t@Nkf_-^YRWp^gyPcZ|OQo-uWe!y5x+Wwac_4 z&aeOz2@YoTV#V$=`cC*`tNy!bsv26EBLeNf`eR8NRZ3>&z(0?1e`bP@4|nPnN~Yt# zTUt6aNobz?>TO@|ozx7Q&;`hz&e-#vT&bDb(w}-69ei?a^=BXU=K+7cVzPe+E8Vcu z^SFp1BN}&Z>3s2zLR$ zlia%8kROF>zZ%#7^d-#p$g3TJZ%!voUX3C)+^{69-;*X&$a5Z&El8h(aVJb{IC&9Bu<5i+|TCV#J0tXlU-)i}2w-paJxSpK-waJKvJBI*Zq z#1nsz@M{&jF!i8%eRsrTm{O=o`_czkiz*@LFG9+n<~SI`8tBW!wMolO8trA{Oh)IL zc_QGs3_rh|2Hy4f1~429sh>e1k;ory`zOXV1Qs&x#$4CN2aTO6 z>kuf7jDs>G?gyl3{2T1QO6yM;{>MG6GhQq(h98(juc9<}@asY&TW3}#AQKYxr97k& z-!FqsUB~P``yeg@J)k3ARD16!3GS8{$-0X5plmnPZS*<8F(&yLXE>N^baiGokL3{+ z#pTI$R*mwJ3Lr|d5c#7p0B!DZSdcabv9EB}ug{nNVuj%l47#{jzZJ$h#4G%af%Et& z6Zgl9Wii-s4VL2l?j-T4R#zA*prEh`6qQ$zHzs->bDz4_^5;9-zcWcJB{akeR0V9Q%vq_v zvr?01Gy@c6R5Dk?7WO>K6b!c0v7lFTeE&{h@}fkg)ksy0cl+$Iz5c9HYD`@L{c5?p*k-B(6A(^!OgC+wY4w;vPl?Vv@CmGzx}!ObmT`W z?#3bY{l|VOI$r(g`|+<~dewtxO?qK^uE&bAhRv!&<1+bv;dpuA^FguK>4$C!IgkN( zUlMr|m&#{!w2}Z0}AqjbUn9g}9e= zZqCH@RcILVUVZ4*WvVEq#m|{;;^Okaw^E$3;9OCHy7^W-0&F zX9Zz>*X%(U0F`NFc@7ifEX-{+(q$Bq;U5A_t_Vo|C27zE2C+0OjaV+22^Negp|qGj zZb%d=e#K**Y;Szcecs*Y>l5#g!l;O-1Qp$SP5;HtSGva~VjkM+TrUyQJ)eE-5)?oM3J%V#Yroj3)n?kH|CO%Uh}GEWkLZcb&1m6HMBC(tTkk8 zqUWJF^Mu3*)QOpxA4rU=zgn5(rqvNAJ3X{n6%n^X=tPOHxOP`82~A4qgr5ZkQ|w3# zg=hUb(i5w$g2H8fXB`$`7N!*6M7K-!3SA)PQGo2LTV?lQ1eu9n%&TFM!~qjC*@AOY zK`>MQ0Q^%KWXa9Z;S1;lvvJ$l6r?WFs$K)Oh$9`e9^b5kJ%4RGdW1;B)&Z>1Ze59) zdga+4Yrf$o4vrOh-cDk_^Fh#A7g{N9>GJex+dh82L107yzoaW{@(mT%&-s}HXPwZ} zZ6fPO>nrrVxpm9D+T~1Abi>Ebjyfp;wVbM+_}4;wdU`qbH2%01B*a$QC2a7CCrG9P+LvsF z?*s${^w84doaX>jWU1pFum!+*Wl19i(EMp(PJ#1PF8p-l_wRP5OB=@J{-b+dL`TPZ zSSsAvLLzdk5Ov)>ZioLitN##*53hH!zb)LTavHFzPJVnz_;8`H7#QxZiv&Ex3JF!7 za8T54wW80)=;7Ius#ve|2!q53Xe7Uy%xnS05p-P5{c-ix!qxW{Arhum7L{Lpn=PzO z49><__jhm(QqsyliZ>C`q0KcVK6U%#T+mq z%@;XBBdK%p6Z|N|#a3^gqm?1xb~Z>GA-B%Y_I|#F0z3f{vFPBy)1I?MS3}CG&DtaO|G9 z>4dzrAvF(`!mJtoK`}+^-4BXUQX}Wh^34l<02n}$ddkNYs0UFPc+hD+&8NCh`}xKu zFz$RCJA8C{E!kgA(0ygjAWiZV1(-`lXfzIy9C`GCo? zyvcmvmTQQL72{wPVP}?>FV6TxuxR}xB@s`3qEc%^g3}7gTGStLXkpE_PM@= z44IMN7MrNP7208w^0>hyJ8m&Yp_ z=kIc#UUV&R&;>MT%5wulfQ$qs7`NGthQ2Yj+HjLyifC+ z`$)_35c`5ir7b2pXev0o_8Q%?zB+Nv`koaDS#g+>BrzeJ zxLKLPN9V7zg~Hlp<1@B5I68LqlV1O@Nzc*(9y#IHJ4%mo-tPZvvw3wD(9XtoUgD0r zn!)ey{E+`cuh6=j46R6~{LP=XKz#N)4!gRJ2=^?JUa}4r<&`YB79Q1j0ud^7V!pFH z+5T3ClgLPwq1;Jo%WVCq5-h^+v2K#FF$siNJ+1-0ng2RWyf*FHEr%tRg{0$DdPy50 z_McIHh=g<%x`^c!_JvNBY~M$UV0XdZ%d+c=KAXmUbGf?NsNw@tL%L9yJ^HFzKTVS8 zLQUUDqdgYDigh3>&HON_DhbDrs>FW+NySdO%fn=(&sume5MVBu=cE8BtwoYiNJz*h zA!omZ@CVw09qjs-&9p1ieeHbb@X9#fOcVpwA9VBE{y5!O|MqW5#vM&ii3Co-id#~* zFTo@xJ!5^e^Q%wax0}*S-6%(*HL?mbi)p&=o^xL-8^3OLlSWkQBFf$oipOD3_{oy; za!m0J2qT5kJ>RmrDx51&$37xsWA%8qVn{h%eu8(a+cMjWKxnM%8sYsr3H3rPEbY;V z;5FQR{`!gmczQZ-{m4yOPa|YI3=4jqj==@!m;3rm$_aD7-XL4WipW_C&t&@MDk?z| zNBpo35GqYDSaeRvi@(VE!aQ2Sy!A6TK0diWubmTPB|_@n$g~K+nNn72J(0$XFwevw zDH(yZ3*+Otch_ZN+ICS#?WgGoi_5lYa5?HtXKZej)5p!Q2IdzMj!xfMyHaOpg^I12BoTvkGk^WXP!ez-*640i178K6IK+ih74FH8UjD;xUJ zQCry4AoxeUmzs)xP=ba=>$_Rd)qrJn-uueNmVG*J53`dHb0ul8|0bS@* z$#l~Bp)z0tBBTrL#>X7MRyn__wGGxkg9TVcJaLk*iUA^qXfL%w!3p{C7H4nfwy#0( zB(EDofuyQD*jlEwZXj0E+U+%2(CVyi(8v2$TY-fDsKw}B=Oa9hrG4#KP4t3yi-|)4 z2*o`8)nHnuBC~1zVzn*?H0NoCrL7{Y+;(=R`cDrr74?TUVOu4yE)b}L%Ws9S zv$Y_p?x8Q4+%Xj_qk-J_J};R{tFFcj-K(PvNblG{TLBwr2xT<{f_!RmO+i=NUA{JB z9#w~Y!j4j5zm`(Pbu}Tb>N^<$(kTmbz+diG_Kj3mS0B_DGZv=#Z!D+m=D zW@$uyY@w0KU*(F5g;mxA-o+;-w$JKA#cqTjEXT-OE8v^Nga^M|z%!hnayt0F?5Q7) zjq{sVr$M;DINxE9FP#lqJ%_4bPcxyWwl-L+MxJeW$SmGzc+0k9)}QY3KH6~thsZgl~CDScHgIim;e0SYkh~B{LUhlw~5l)OJ&N%IzHP7@}N|GMZb7; zHHt7S+C|fLGBS^p=b6%XG$EIfk!uEF(bC7B=*|rdTIE^iQ8g=RrVsedjtzm3Vf;#G z^f}j%l};6i?m4L|?^wOLupX#6fP^djY_74kN4rD2N+sTJ-?$cS($f}?x7D@itt zps7`3s!|BY%rW@8D&#Jyxw{`QBE}cjYrn-})0Q)75956A?s<6e07-$NGm{uu4q3BM zyPq$v+2vE0lP~vnA#E?bp}eKLMmD(6uq_6b9@y?>zFe!{LRmbtd-v1WcxeJLK4=Fpl~kUi@m)WUdaAD?CS>p={;p~o}=^Fugcpar|hjp{gldPapBeDM^3aB zmk4X!K_#SSYQ_SX)z@!Pwc`(j!{RRsMHU@PA|w~|l;W@6ZdO@I7q=MSrvM;)uoScC z<{cR^xaJ|uav+`?z2ZWrxisqF`EvV~C-HtC!|gYP+aW5%R|3U$IgU4UkC_+0wXi7= z0Z70++~-C*kFpPZoa2#!PCTqN$Jb(04pGJjcUv6|D0-ZiJ=K24@(59}PPw?LXyFOh zvVWm9Px^>nGnaHi{H~Ovk?zgZ3)Ta>2Vq|B} z4DIjtlpK=O)R*oU^?M|Dv4sER7#Bs00E#!1TEt39j-`|jB-ah?2(}Zmpy`}+3&Jz+ zje5@NugQyvwHV!09tL)yq+WqZok=XcEo=^RPf~(V1QzZs2HPro2jM{m1_tL{V=-7l ziY%G_co$WOq~qX_opvR_X3W`ino|`@`HGQt`!?vq2z=iYS?b<_UXb=uRjEg9Q|e^z zoDLYS5-PsLj(&f}toVG8ILvI^_)9A(h0TZ1?B_sfLQ22au+Kkgs>ysHdMMMY z+&)!ndJM^dmJvi{qN5bg`0)Gcdc1?+Ko)plAE>Zvu9`#Hx*H54^yk$tZp^Qz@98v* zlBtnGN^4MN zW(3<_aUhJuG+pdh>Fq>BwN87x|lME8pgh7y>M=EMW)PBV@E1 zO-c0|km1-8|0q9lIIx1NYWgrRD&b-mzl(99mz!y>7{*7FB*Uln- z)sx3lOovbfsMtRlk-!^*@x&rfGSSsr&+?Ln{Qv~+5syo1#Kw)zZy{tr%VHy}0S-D^ zp`7QAN8tHEg+riWB2}(^rclezjo)Bb*ADEiy96rT-ygL=3EBXsuN9A^U9bmACbHX? z8rEtgH*U-^Qit0|7}%DMy#DYznIf5Y@8{1jau&r8OjmG-ec%zC!(2tWS?Gd~4; zjK|!!GDLmijfL|GY3u?-J7Kud zPl1O$L#~Cal>p>ab**;@5aS&z3mb*Hw)u-(4!e(qQ*%=9J$zvGx(QP#adMs^BCGH3 znCf?`V0SVGWC22SUsEd~4G4A5C3Mxp-vNCsS74{8LD~DBL*e41N+n*xUO_XT8_Cl( z;KxqRL{4i0+^lOOL8^K%#wecYjlRvwxrj*cpWdqU(EesBM_<7tY=Wrp zIlAox?p&Z}_h1M%blDQqoM+N6csek6@v;^Wef*ivIFR~TbfkB_v)CN=%8yS^Ybmhshn}nL)$H6-DKf3^&LE+4 zD!xf?*<3eo;acbnZ1ANK?;w94%lvhue65>ZF~4TQt+%D$r^=`3LD;Bhyy(5QLyZNjaLrHYapg@*wI=aYg9Ba+2hdof0gwGz)Cn$7+CC!Kys5X~=R zE%z>2`ltiie@etX$EZeF0)R1i#zlcgRDLdZ7HSZo#t^JL;0jf)ZPta(z`cBr{4;=4({4lGIbB>o&>du= zNp!!gvy&Xj7YZ%n1Ig$2adY!I*SL^cUU7rO(SC8_X=3Ln4n$;tTL!|CLNQ7+|Wc0g01 zPz`^P#0FD?7sAZ(=~$rFjRO%LJ^L8MsZ5E@yRn!OZvR3zT)APnZ#&alwI|}*i|r&% zLmQwTZ|IiZ;ka#PCs z(`ah}(fa_dzMoMiM;P4(Su9FY;gxzm+BaR?k3OqT#CWRQ*CE7RWDI}p7&wP**Py10 z%SFze7Sslqo_uq+SBIRgi`p#!z|5V*rz;pVbGtgWqy@MDz~hPK^EJBghWiwr#2Tt= z&-z@99&w>pD2Oo^iEmxAAJ&BG`+>C@a;3?!0xM`s;kI2o)Q@MJfC6}6zi$}9J6gpo zMe^y_915(0qw1A;i+`-7gk5&>zKj?^Z9*jfw-MgH6nT!PH*=&H1`@j8bzatqyH%aU zYGg)ioJQvvo;zwHw_vD$Utw-WOU09Vixgdv(Maz0wt*T70?6N*+-G$7C)3IrDm3ed zo;;mFC|TdtR3d5VPS5bP67w?Rr4KiDj;IV#)s`Xi-)=?xx7EQQ~{ zAv;?gX$Du9Y?u}j5nZ82?KyB85-$I}Ym!i!7`Qgy-frkRDODjrHm`VALP}@8;wKaF zkc_V6vDN-t?PF@Y)Wy{C>*4hsPv1h@zii zPn~O@hS)5g>>YdPHaZNuyFzrO)yXBq3w*R4S9o1TtX(X&J1;w`--ZS;$XaZhVG)qJ zGXyZ+ZS8>lrZPS;QZboM)JqO_SIGw!oXEsALaoUe!Vu3!o9M(wkzAiK!Q&i^A>Ca>4AsGUx_KE z%mtX;gqTz}`wV=5=}9SE7eK=4b;@_{Ch=u5+gh+2=^LGIN!WT1V6dZkdQnhAw>5gT zRi5J35xrLMn3{C+X~(T1X9!idzJvXd=HvoZ`4u3y`xP&DcWlOJeLIt}5xYr#V9sfJ z1BKCrU%wS|^1jCg2(LVZs}B0=!h6-FsQ6H^+AJ&e^&%!B;mw=Pt6K2O7pg`O8j$NZ zFfv*vXc^8jHy>k2h^?~K`Ce_br&gIO+FMspNl(a1{@utgGI_cQVkPNrrF@W2jucZ? zcagJqI*i+*D<7I)-dx0b!U&Qe8R6|2fe$-&8iXq6N{!$1?m0)&)kej=?mymERE=rJ zxcb*0OH6MWh5;Ms%To!`lZ(5B42b#agjM(9THRZyb-m-lB!8VD_Z9RhdG}2o=`9Xj zS#zZ!gkjN!WP>t4)O$q|k{ROcRsH?=0~!au_MWmuiV%4Bg~c4RWHT`X>!oVX$y!~p z{Vx+U@%)WMdZl-%#Y)VD*u-Q~2Kpt+ENAl@?f9K;X8A_iffcQr^Zi@&oDoXq`JwnS zRF}SM26zE>%KS`VXQb5m(P;3}#^Vh*!XY(M+E>a1sV_~YGmJgk5(~91GTwpPa8v6s z&<@`YB6(KfuAdq%vA$uj#PzcZGVZK?TXoR}-r65GM9ZP2`+X~NPoH%HPnJ?U9?L8y z2#nSZ7NGDU)U5NxCKp)QfT^Z1h9j;J)v=)OvA1rC+^yV?V`Zqz7Od+%9`oBbeTx5UErWmEYXRHtUTq;&Aqc+x zJ}ax86JO%)y3trfh>hru+su8rT0SK<^(BVqu8|Qe7!6gTe6;Xd9Q2`j@7&JDAX`|< z*+WJqCMJnRMIwa-HvEKYhuc(2m)LAEIM2R?u6uWakZMu1FC&Gm(CD?&TQwu4s|mhe zI-!f+$JPj~{HZOspNNdWb?p_* z^+e2?^_3;(4f|1$-^2%%N*Dr#`Lwo%@ob8DY}sd zb=hE?a$#r;3&P|y%2nW<$jqz_v$DYS)p^{8lZVng!q_DQ+eCr|chT*)ml{et2LRH_hxO7HhY zfB$a%9U=Htn)M3Pzpr=q@`eqFU~}}vbkFomjK4b@9ez^)<9g+V1Lp+@5_$cI3yN=1rV(bON;5Aj1?Fsbw3nN68*r+! zg-x((+aCHgh{UZ7d?*xtbt*^`>cyi}=)plgyqmMPs-ThCDS3*2A{_a-zZ|;juW;^z_FnRcw(8Nog$LwJlE}snN$9@TifHfYdkH^=){|*9;oyo-sStWSZy<_3^7WK)vWD9IGPmwla%A2dFo?DCj-qGJ zw&gjpZZ^nK4KUF9&Eu0>V9A-KVoQmacvV9hpq+g5LFdK zjM|QZ8{=82fSZ{Jzf2|b=;ccd0#OQB{LQ^v0$hZcClTATOf0&eJM?zv>R}uHt{fd( zdzgUIsSryp4YJ%9rR}8;PKP#rV*kJvd?{UY7T~4oO7Gk5N`9c^tte{@%VRGi!?ug` zA15PP)I<0840IM9d;8_HdL>uo(DUO@rccCJcaYxwmkekSS~8tfVheP~MRBV5Mz)kr zQEi~~pflSF%2_uXUR2#ZE82AMYP?Zs?zW$1Q9^ZK@4X#$E~j|6qa^qb$#wyMU*-N|wDn{AS?fr#u6veIHB`K@zb;3mCSu|#%A1hY z5d7cBAq&HIyF$xcG@fX_%V%@%FEnGhoF9vG-#< zk0?2@% zfkS<3k7)n1&ayxf_cMKp0@$KrFd%dDP-5Q!o z09qXZ19@}-iKhZ0UcPK}Y;5scr&ZF39E;JhkZ z-PvT(YbtX@4?ST;i_fy`?&dbh_J_A*m>Pi*TfAH6HkX&TZmtV5VjH*_T?9{PpXumB zUX9U{LQR_f9vPEwSgpQyuPPB}XsXVQ-{|-MB+GBlhCP3&aLt-k5Z-%ug+BVl;q$Ic zO=SM2g_+o;xAW{->9yDV&nucMMr&|$s%RXGP~6J1eg6--3aO92H$6H8_Y1G|7}Bzv z#}syYjhH{)eT7~`sx^$reNRf?o(5LExih;{G&cV|8F_Mcpi7Gw| zsT*9n86wMCPwMto!qSMJ_a8VAld8VBDZ$%^2qr&P(v4c^=#Wax!&#jxmC$+}zaXz? zpcPutj1)ia-?X#p+~*t?U-HV8BeWC>&2z+5ILt$zIf6)S@x(NXHmQr3&dg3sZ`D0g z;+lz64G4Inu5ojy$M?&V08tfk;Xmd5Kaq&x8FxBs;2?A}A6T(D2-*$Zu*4+OCd0V9ZAC Date: Mon, 9 Oct 2023 10:18:20 +0200 Subject: [PATCH 07/12] fix: [DHIS2-15734] assign effect dynamic formId object key (#3422) --- .../reducers/descriptions/form.reducerDescription.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core_modules/capture-core/reducers/descriptions/form.reducerDescription.js b/src/core_modules/capture-core/reducers/descriptions/form.reducerDescription.js index 85ab6638ee..30dd29a15f 100644 --- a/src/core_modules/capture-core/reducers/descriptions/form.reducerDescription.js +++ b/src/core_modules/capture-core/reducers/descriptions/form.reducerDescription.js @@ -230,7 +230,7 @@ export const formsSectionsFieldsUIDesc = createReducerDescription({ return { ...state, - formId: { + [formId]: { ...state[formId], ...updatedFields, }, From ee930cb734bcd90cf592dd1afe6ad758fe79ad9c Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Mon, 9 Oct 2023 08:27:25 +0000 Subject: [PATCH 08/12] chore(release): cut 100.41.1 [skip release] ## [100.41.1](https://github.com/dhis2/capture-app/compare/v100.41.0...v100.41.1) (2023-10-09) ### Bug Fixes * [DHIS2-15734] assign effect dynamic formId object key ([#3422](https://github.com/dhis2/capture-app/issues/3422)) ([85f242b](https://github.com/dhis2/capture-app/commit/85f242b2b0c6092b46e92f087e21e102a2e1e19d)) --- CHANGELOG.md | 7 +++++++ package.json | 4 ++-- packages/rules-engine/package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9b8e29d4b..e1e2b5e83a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [100.41.1](https://github.com/dhis2/capture-app/compare/v100.41.0...v100.41.1) (2023-10-09) + + +### Bug Fixes + +* [DHIS2-15734] assign effect dynamic formId object key ([#3422](https://github.com/dhis2/capture-app/issues/3422)) ([85f242b](https://github.com/dhis2/capture-app/commit/85f242b2b0c6092b46e92f087e21e102a2e1e19d)) + # [100.41.0](https://github.com/dhis2/capture-app/compare/v100.40.1...v100.41.0) (2023-10-03) diff --git a/package.json b/package.json index fbf2ef4982..348ef10bf7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "100.41.0", + "version": "100.41.1", "cacheVersion": "6", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "100.41.0", + "@dhis2/rules-engine-javascript": "100.41.1", "@dhis2/app-runtime": "^3.9.3", "@dhis2/d2-i18n": "^1.1.0", "@dhis2/d2-icons": "^1.0.1", diff --git a/packages/rules-engine/package.json b/packages/rules-engine/package.json index 411dcf5450..5aa6daf77f 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "100.41.0", + "version": "100.41.1", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From f17d087f368cf4d6b26923fd5cf4fb15d7795ba2 Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Thu, 12 Oct 2023 14:14:07 +0200 Subject: [PATCH 09/12] fix: [DHIS2-15827] remove effects of 'Prevent adding new events to stage' action from the form (#3418) --- .../EnrollmentPage/HiddenProgramStage.feature | 1 - .../HiddenProgramStage/index.js | 12 ------ .../ErrorText/ErrorText.component.js | 20 ---------- .../ErrorText/ErrorText.types.js | 5 --- .../ErrorText/index.js | 2 - .../FinishButtons/FinishButtons.component.js | 38 ++++--------------- .../FinishButtons/finishButtons.types.js | 4 -- .../Validated/Validated.component.js | 10 +---- .../Validated/Validated.container.js | 8 +--- .../Validated/validated.types.js | 1 - 10 files changed, 9 insertions(+), 92 deletions(-) delete mode 100644 src/core_modules/capture-core/components/WidgetEnrollmentEventNew/ErrorText/ErrorText.component.js delete mode 100644 src/core_modules/capture-core/components/WidgetEnrollmentEventNew/ErrorText/ErrorText.types.js delete mode 100644 src/core_modules/capture-core/components/WidgetEnrollmentEventNew/ErrorText/index.js diff --git a/cypress/integration/EnrollmentPage/HiddenProgramStage.feature b/cypress/integration/EnrollmentPage/HiddenProgramStage.feature index 4e6e427e3e..e13095474a 100644 --- a/cypress/integration/EnrollmentPage/HiddenProgramStage.feature +++ b/cypress/integration/EnrollmentPage/HiddenProgramStage.feature @@ -3,5 +3,4 @@ Feature: Hidden program stage Scenario: The user cannot add an event in a hidden program stage Given you add an enrollment event that will result in a rule effect to hide a program stage Then the New Postpartum care visit event button is disabled in the stages and events widget - And and an error is show in the Postpartum care visit stage And the Postpartum care visit button is disabled in the enrollmentEventNew page diff --git a/cypress/integration/EnrollmentPage/HiddenProgramStage/index.js b/cypress/integration/EnrollmentPage/HiddenProgramStage/index.js index edf6b833bd..f9e5cf69c2 100644 --- a/cypress/integration/EnrollmentPage/HiddenProgramStage/index.js +++ b/cypress/integration/EnrollmentPage/HiddenProgramStage/index.js @@ -45,18 +45,6 @@ Then('the New Postpartum care visit event button is disabled in the stages and e .should('be.disabled'); }); -Then('and an error is show in the Postpartum care visit stage', () => { - cy.visit( - '/#/enrollmentEventNew?enrollmentId=fmhIsWXVDmS&orgUnitId=s7SLtx8wmRA&programId=WSGAb5XwJ3Y&teiId=uW8Y7AIcRKA&stageId=bbKtnxRZKEP', - ); - cy.contains('[data-test="dhis2-uicore-button"]', 'Complete') - .should('be.disabled'); - cy.contains('[data-test="dhis2-uicore-button"]', 'Save without completing') - .should('be.disabled'); - cy.contains('[data-test="dhis2-uicore-noticebox-content"]', 'You can\'t add any more Postpartum care visit events') - .should('exist'); -}); - Then('the Postpartum care visit button is disabled in the enrollmentEventNew page', () => { cy.visit( '/#/enrollmentEventNew?enrollmentId=fmhIsWXVDmS&orgUnitId=s7SLtx8wmRA&programId=WSGAb5XwJ3Y&teiId=uW8Y7AIcRKA', diff --git a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/ErrorText/ErrorText.component.js b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/ErrorText/ErrorText.component.js deleted file mode 100644 index a885a48a6d..0000000000 --- a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/ErrorText/ErrorText.component.js +++ /dev/null @@ -1,20 +0,0 @@ -// @flow -import React from 'react'; -import i18n from '@dhis2/d2-i18n'; -import { NoticeBox } from '@dhis2/ui'; -import type { Props } from './ErrorText.types'; - -export const ErrorText = ({ stageName }: Props) => ( - <> -
- - - {i18n.t("You can't add any more {{ programStageName }} events", { - programStageName: stageName, - interpolation: { escapeValue: false }, - })} - - -
- -); diff --git a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/ErrorText/ErrorText.types.js b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/ErrorText/ErrorText.types.js deleted file mode 100644 index 07785c7e1a..0000000000 --- a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/ErrorText/ErrorText.types.js +++ /dev/null @@ -1,5 +0,0 @@ -// @flow - -export type Props = {| - stageName: string, -|}; diff --git a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/ErrorText/index.js b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/ErrorText/index.js deleted file mode 100644 index 2b26086840..0000000000 --- a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/ErrorText/index.js +++ /dev/null @@ -1,2 +0,0 @@ -// @flow -export { ErrorText } from './ErrorText.component'; diff --git a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/FinishButtons/FinishButtons.component.js b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/FinishButtons/FinishButtons.component.js index 1c0a36c1c8..465f807ace 100644 --- a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/FinishButtons/FinishButtons.component.js +++ b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/FinishButtons/FinishButtons.component.js @@ -3,7 +3,6 @@ import React, { type ComponentType } from 'react'; import i18n from '@dhis2/d2-i18n'; import { withStyles } from '@material-ui/core'; import { Button, spacersNum } from '@dhis2/ui'; -import { ConditionalTooltip } from 'capture-core/components/ConditionalTooltip'; import { withCancelButton } from '../../DataEntry/withCancelButton'; import { addEventSaveTypes } from '../DataEntry/addEventSaveTypes'; import type { InputProps, Props } from './finishButtons.types'; @@ -18,40 +17,17 @@ const styles = { }, }; -const FinishButtonsPlain = ({ onSave, cancelButton, hiddenProgramStage, stageName, classes }: Props) => ( +const FinishButtonsPlain = ({ onSave, cancelButton, classes }: Props) => (

- - - +
- - - +
{cancelButton}
diff --git a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/FinishButtons/finishButtons.types.js b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/FinishButtons/finishButtons.types.js index 079708e30a..dd3acb8e32 100644 --- a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/FinishButtons/finishButtons.types.js +++ b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/FinishButtons/finishButtons.types.js @@ -6,14 +6,10 @@ export type InputProps = {| onSave: (saveType: $Keys) => void, onCancel: () => void, id: string, - hiddenProgramStage: boolean, - stageName: string, |}; export type Props = {| onSave: (saveType: $Keys) => void, cancelButton: Element, - hiddenProgramStage: boolean, - stageName: string, ...CssClasses, |}; diff --git a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/Validated.component.js b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/Validated.component.js index 4f784d2b9a..4e3f2f96ef 100644 --- a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/Validated.component.js +++ b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/Validated.component.js @@ -6,7 +6,6 @@ import { Widget } from '../../Widget'; import { DataEntry } from '../DataEntry'; import { FinishButtons } from '../FinishButtons'; import { SavingText } from '../SavingText'; -import { ErrorText } from '../ErrorText'; import type { Props } from './validated.types'; const styles = () => ({ @@ -24,7 +23,6 @@ const ValidatedPlain = ({ onSave, onCancel, orgUnit, - hiddenProgramStage, id, ...passOnProps }: Props) => ( @@ -48,14 +46,8 @@ const ValidatedPlain = ({ onSave={onSave} onCancel={onCancel} id={id} - hiddenProgramStage={hiddenProgramStage} - stageName={stage.name} /> - {hiddenProgramStage ? ( - - ) : ( - - )} +
)} diff --git a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/Validated.container.js b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/Validated.container.js index c0245b477f..3d85e67cbf 100644 --- a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/Validated.container.js +++ b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/Validated.container.js @@ -1,6 +1,6 @@ // @flow import React, { useCallback } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { withAskToCreateNew, withSaveHandler } from '../../DataEntry'; import { useLifecycle } from './useLifecycle'; import { useClientFormattedRulesExecutionDependencies } from './useClientFormattedRulesExecutionDependencies'; @@ -29,11 +29,6 @@ export const Validated = ({ }: ContainerProps) => { const dataEntryId = 'enrollmentEvent'; const itemId = 'newEvent'; - const rulesEffectsHiddenProgram = useSelector( - ({ rulesEffectsHiddenProgramStageDesc }) => - rulesEffectsHiddenProgramStageDesc && rulesEffectsHiddenProgramStageDesc[`${dataEntryId}-${itemId}`], - ); - const hiddenProgramStage = rulesEffectsHiddenProgram && rulesEffectsHiddenProgram[stage.id]; const rulesExecutionDependenciesClientFormatted = useClientFormattedRulesExecutionDependencies(rulesExecutionDependencies, program); @@ -132,7 +127,6 @@ export const Validated = ({ programName={program.name} orgUnit={orgUnit} rulesExecutionDependenciesClientFormatted={rulesExecutionDependenciesClientFormatted} - hiddenProgramStage={hiddenProgramStage} /> ); }; diff --git a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/validated.types.js b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/validated.types.js index 932e61a6d8..a5194d88af 100644 --- a/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/validated.types.js +++ b/src/core_modules/capture-core/components/WidgetEnrollmentEventNew/Validated/validated.types.js @@ -25,6 +25,5 @@ export type Props = {| formRef: (formInstance: any) => void, dataEntryFieldRef: (instance: any, id: string) => void, rulesExecutionDependenciesClientFormatted: RulesExecutionDependenciesClientFormatted, - hiddenProgramStage: boolean, ...CssClasses, |}; From 5efa7e9dcdecab35674212f196568d63e78b4a90 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Thu, 12 Oct 2023 12:22:10 +0000 Subject: [PATCH 10/12] chore(release): cut 100.41.2 [skip release] ## [100.41.2](https://github.com/dhis2/capture-app/compare/v100.41.1...v100.41.2) (2023-10-12) ### Bug Fixes * [DHIS2-15827] remove effects of 'Prevent adding new events to stage' action from the form ([#3418](https://github.com/dhis2/capture-app/issues/3418)) ([f17d087](https://github.com/dhis2/capture-app/commit/f17d087f368cf4d6b26923fd5cf4fb15d7795ba2)) --- CHANGELOG.md | 7 +++++++ package.json | 4 ++-- packages/rules-engine/package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1e2b5e83a..ddcfc2c8a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [100.41.2](https://github.com/dhis2/capture-app/compare/v100.41.1...v100.41.2) (2023-10-12) + + +### Bug Fixes + +* [DHIS2-15827] remove effects of 'Prevent adding new events to stage' action from the form ([#3418](https://github.com/dhis2/capture-app/issues/3418)) ([f17d087](https://github.com/dhis2/capture-app/commit/f17d087f368cf4d6b26923fd5cf4fb15d7795ba2)) + ## [100.41.1](https://github.com/dhis2/capture-app/compare/v100.41.0...v100.41.1) (2023-10-09) diff --git a/package.json b/package.json index 348ef10bf7..64230da5bf 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "100.41.1", + "version": "100.41.2", "cacheVersion": "6", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "100.41.1", + "@dhis2/rules-engine-javascript": "100.41.2", "@dhis2/app-runtime": "^3.9.3", "@dhis2/d2-i18n": "^1.1.0", "@dhis2/d2-icons": "^1.0.1", diff --git a/packages/rules-engine/package.json b/packages/rules-engine/package.json index 5aa6daf77f..88cc2da714 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "100.41.1", + "version": "100.41.2", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": { From 8f7a017c5860104620c6b7fc8c20916b00037302 Mon Sep 17 00:00:00 2001 From: Simona Domnisoru Date: Mon, 16 Oct 2023 16:17:56 +0200 Subject: [PATCH 11/12] fix: [DHIS2-15782] navigation with program stage filter (#3431) --- .../TeiWorkingListsUser.feature | 7 ++++ .../TeiWorkingListsUser/index.js | 39 +++++++++++++++++++ .../TeiWorkingListsReduxProvider.container.js | 16 ++++++-- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser.feature b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser.feature index d3f07adfe2..b0bdfef1e0 100644 --- a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser.feature +++ b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser.feature @@ -186,6 +186,13 @@ And you select the events scheduled today And you apply the current filter Then you see the selected option in the scheduledAt filter +@v>=39 +Scenario: The program stage working list configureation is kept when navigating +Given you open the main page with Ngelehun and WHO RMNCH Tracker context and configure a program stage working list +When you open an enrollment event from the working list +And you go back using the browser button +Then the program stage working list is loaded + @v>=40 Scenario: The user creates, updates and deletes a Program stage custom working list Given you open the main page with Ngelehun and Malaria case diagnosis and Household investigation context diff --git a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js index 7e5825c8a1..760319bfba 100644 --- a/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js +++ b/cypress/integration/WorkingLists/TeiWorkingLists/TeiWorkingListsUser/index.js @@ -760,3 +760,42 @@ Then('the program stage custom working list filters are loaded', () => { .should('have.length', 2); }); +Given('you open the main page with Ngelehun and WHO RMNCH Tracker context and configure a program stage working list', () => { + cy.visit('#/?programId=WSGAb5XwJ3Y&orgUnitId=DiszpKrYNg8'); + cy.get('[data-test="template-selector-create-list"]') + .click(); + + cy.get('[data-test="tei-working-lists"]') + .within(() => { + cy.contains('More filters') + .click(); + cy.contains('Program stage') + .click(); + }); + + cy.get('[data-test="list-view-filter-contents"]') + .contains('Postpartum care visit') + .click(); + + cy.get('[data-test="list-view-filter-apply-button"]') + .click(); +}); + +When('you open an enrollment event from the working list', () => { + cy.contains('Linda') + .click(); +}); + +When('you go back using the browser button', () => { + cy.go('back'); +}); + +Then('the program stage working list is loaded', () => { + cy.get('[data-test="tei-working-lists"]') + .find('[data-test="more-filters"]') + .should('have.length', 2); + + cy.get('[data-test="tei-working-lists"]') + .contains('WHOMCH Hemoglobin value') + .should('exist'); +}); diff --git a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/ReduxProvider/TeiWorkingListsReduxProvider.container.js b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/ReduxProvider/TeiWorkingListsReduxProvider.container.js index 1017f47dcd..b0fed150a7 100644 --- a/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/ReduxProvider/TeiWorkingListsReduxProvider.container.js +++ b/src/core_modules/capture-core/components/WorkingLists/TeiWorkingLists/ReduxProvider/TeiWorkingListsReduxProvider.container.js @@ -38,6 +38,8 @@ export const TeiWorkingListsReduxProvider = ({ onDeleteTemplate, onUpdateDefaultTemplate, programStage, + currentTemplateId, + viewPreloaded, ...commonStateManagementProps } = useWorkingListsCommonStateManagement(storeId, TEI_WORKING_LISTS_TYPE, program); const dispatch = useDispatch(); @@ -47,9 +49,15 @@ export const TeiWorkingListsReduxProvider = ({ }, [dispatch, programId, storeId, selectedTemplateId]); useEffect(() => { - selectedTemplateId && onSelectTemplate && onSelectTemplate(selectedTemplateId); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + // This hook should only fire when you navigate from the search page to the main page with a working list selected + if (selectedTemplateId && + selectedTemplateId !== currentTemplateId && + !viewPreloaded && + onSelectTemplate + ) { + onSelectTemplate(selectedTemplateId); + } + }, [selectedTemplateId, viewPreloaded, currentTemplateId, onSelectTemplate]); const onSelectListRow = useCallback(({ id }) => { const record = records[id]; @@ -92,6 +100,8 @@ export const TeiWorkingListsReduxProvider = ({ return ( Date: Mon, 16 Oct 2023 14:30:46 +0000 Subject: [PATCH 12/12] chore(release): cut 100.41.3 [skip release] ## [100.41.3](https://github.com/dhis2/capture-app/compare/v100.41.2...v100.41.3) (2023-10-16) ### Bug Fixes * [DHIS2-15782] navigation with program stage filter ([#3431](https://github.com/dhis2/capture-app/issues/3431)) ([8f7a017](https://github.com/dhis2/capture-app/commit/8f7a017c5860104620c6b7fc8c20916b00037302)) --- CHANGELOG.md | 7 +++++++ package.json | 4 ++-- packages/rules-engine/package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddcfc2c8a2..7e6fc6a44c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [100.41.3](https://github.com/dhis2/capture-app/compare/v100.41.2...v100.41.3) (2023-10-16) + + +### Bug Fixes + +* [DHIS2-15782] navigation with program stage filter ([#3431](https://github.com/dhis2/capture-app/issues/3431)) ([8f7a017](https://github.com/dhis2/capture-app/commit/8f7a017c5860104620c6b7fc8c20916b00037302)) + ## [100.41.2](https://github.com/dhis2/capture-app/compare/v100.41.1...v100.41.2) (2023-10-12) diff --git a/package.json b/package.json index 64230da5bf..08fc321e76 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "100.41.2", + "version": "100.41.3", "cacheVersion": "6", "serverVersion": "38", "license": "BSD-3-Clause", @@ -10,7 +10,7 @@ "packages/rules-engine" ], "dependencies": { - "@dhis2/rules-engine-javascript": "100.41.2", + "@dhis2/rules-engine-javascript": "100.41.3", "@dhis2/app-runtime": "^3.9.3", "@dhis2/d2-i18n": "^1.1.0", "@dhis2/d2-icons": "^1.0.1", diff --git a/packages/rules-engine/package.json b/packages/rules-engine/package.json index 88cc2da714..2280715107 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/rules-engine-javascript", - "version": "100.41.2", + "version": "100.41.3", "license": "BSD-3-Clause", "main": "./build/cjs/index.js", "scripts": {