From ffd4cf9031ee2a8d5e4466c226b182799d1c0fe0 Mon Sep 17 00:00:00 2001 From: sova-bootstrap Date: Wed, 27 May 2026 19:36:33 +0300 Subject: [PATCH] chore: initial import for test contour --- .gitea/workflows/build.yml | 89 + .gitignore | 29 + Dockerfile | 17 + README.md | 5 + babel.config.js | 6 + docker/entrypoint.sh | 11 + docker/nginx.conf | 14 + eslint.config.js | 85 + index.html | 14 + jest.config.js | 11 + jest.setup.js | 6 + package.json | 64 + public/env.js | 3 + public/robots.txt | 2 + src/App.jsx | 101 ++ src/api/apiCertificate.js | 73 + src/api/apiContent.js | 117 ++ src/api/apiDepartment.js | 38 + src/api/apiFilial.js | 53 + src/api/apiIDoctor.js | 22 + src/api/apiKodoper.js | 30 + src/api/apiLocation.js | 51 + src/api/apiSlice.js | 44 + src/api/apiSpecialist.js | 119 ++ src/api/apiStock.js | 102 ++ src/assets/icon.png | Bin 0 -> 2703 bytes src/assets/image-placeholder.png | Bin 0 -> 29514 bytes src/assets/logo.png | Bin 0 -> 5726 bytes src/assets/photo-placeholder.png | Bin 0 -> 238657 bytes src/assets/video-placeholder.png | Bin 0 -> 3814 bytes src/components/Button/Button.jsx | 13 + src/components/Button/Button.module.scss | 10 + src/components/Docs/Certificates.jsx | 146 ++ src/components/Docs/Portfolio.jsx | 152 ++ src/components/Docs/Stocks.jsx | 196 ++ src/components/Editors/CertEditor.jsx | 25 + src/components/Editors/TextEditor.jsx | 26 + src/components/Forms/EditElementForm.jsx | 48 + src/components/Input/Input.jsx | 11 + src/components/Input/PhoneInput.jsx | 25 + src/components/Input/TagKodoperStatic.jsx | 58 + src/components/Input/TagStaticInput.jsx | 42 + src/components/Input/Taginput.jsx | 79 + src/components/Modals/DcodeModal.jsx | 246 +++ src/components/Modals/KodoperModal.jsx | 282 +++ src/components/Modals/Modal.jsx | 75 + src/components/Modals/ResponseModals.jsx | 47 + src/components/Modals/StockModal.jsx | 388 ++++ src/components/Navbar/Navbar.jsx | 82 + src/components/Navbar/Navbar.module.scss | 3 + src/components/Paginations/PageNav.jsx | 45 + .../Placeholders/ErrorComponent.jsx | 7 + .../Placeholders/LoadingComponent.jsx | 11 + .../Placeholders/NotFindElement.jsx | 10 + src/components/Sidebar/Sidebar.jsx | 34 + .../SidebarNavItem/SidebarNavItem.jsx | 21 + .../SidebarNavItem/SidebarNavItem.module.scss | 8 + src/components/Table/FilterBar.jsx | 53 + src/components/Table/TBody.jsx | 96 + src/components/Table/THead.jsx | 19 + src/components/UserBurger/UserBurger.jsx | 73 + src/config/api.js | 10 + src/config/contentResources.js | 223 +++ src/hooks/useLostLocations.jsx | 65 + src/hooks/useNewSpecialistId.jsx | 19 + src/hooks/useOutsideClick.jsx | 13 + src/hooks/useSortedPaginated.jsx | 43 + src/hooks/useSorting.jsx | 16 + src/hooks/useSpecialist.jsx | 60 + src/hooks/useSpecialistFilter.jsx | 43 + src/main.jsx | 16 + src/pages/AddSpecialistPage.jsx | 1469 +++++++++++++++ src/pages/AddStockPage.jsx | 208 +++ src/pages/DepartmentsListPage.jsx | 85 + src/pages/EditDepartmentPage.jsx | 120 ++ src/pages/EditFilialPage.jsx | 328 ++++ src/pages/EditSpecialistPage.jsx | 1609 +++++++++++++++++ src/pages/EditStockPage.jsx | 299 +++ src/pages/FilialsListPage.jsx | 91 + src/pages/HomePage.jsx | 7 + src/pages/InfoclinicListPage.jsx | 203 +++ src/pages/LoginPage.jsx | 78 + src/pages/LostDoctorsPage.jsx | 216 +++ src/pages/MainPage.jsx | 20 + src/pages/NotFoundPage.jsx | 14 + src/pages/PricesListPage.jsx | 207 +++ src/pages/SpecialistListPage.jsx | 281 +++ src/pages/SpecialistTable.jsx | 125 ++ src/pages/StoksListPage.jsx | 238 +++ src/pages/UserPage.jsx | 21 + src/pages/__test__/LoginPage.test.jsx | 19 + src/pages/content/ContentEditPage.jsx | 370 ++++ src/pages/content/ContentListPage.jsx | 210 +++ src/pages/content/index.jsx | 46 + src/routes/ProtectedRoute.jsx | 10 + src/routes/__test__/ProtectedRoute.test.js | 48 + src/store/slice/__test__/authSlice.test.js | 40 + src/store/slice/authSlice.js | 62 + src/store/slice/regionSlice.js | 20 + src/store/slice/utilsSlice.js | 27 + src/store/store.js | 23 + src/styles/_colors.scss | 2 + src/styles/theme-override.scss | 177 ++ src/utils/parseSaveError.js | 123 ++ vite.config.js | 31 + 105 files changed, 10772 insertions(+) create mode 100644 .gitea/workflows/build.yml create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 babel.config.js create mode 100644 docker/entrypoint.sh create mode 100644 docker/nginx.conf create mode 100644 eslint.config.js create mode 100644 index.html create mode 100644 jest.config.js create mode 100644 jest.setup.js create mode 100644 package.json create mode 100644 public/env.js create mode 100644 public/robots.txt create mode 100644 src/App.jsx create mode 100644 src/api/apiCertificate.js create mode 100644 src/api/apiContent.js create mode 100644 src/api/apiDepartment.js create mode 100644 src/api/apiFilial.js create mode 100644 src/api/apiIDoctor.js create mode 100644 src/api/apiKodoper.js create mode 100644 src/api/apiLocation.js create mode 100644 src/api/apiSlice.js create mode 100644 src/api/apiSpecialist.js create mode 100644 src/api/apiStock.js create mode 100644 src/assets/icon.png create mode 100644 src/assets/image-placeholder.png create mode 100644 src/assets/logo.png create mode 100644 src/assets/photo-placeholder.png create mode 100644 src/assets/video-placeholder.png create mode 100644 src/components/Button/Button.jsx create mode 100644 src/components/Button/Button.module.scss create mode 100644 src/components/Docs/Certificates.jsx create mode 100644 src/components/Docs/Portfolio.jsx create mode 100644 src/components/Docs/Stocks.jsx create mode 100644 src/components/Editors/CertEditor.jsx create mode 100644 src/components/Editors/TextEditor.jsx create mode 100644 src/components/Forms/EditElementForm.jsx create mode 100644 src/components/Input/Input.jsx create mode 100644 src/components/Input/PhoneInput.jsx create mode 100644 src/components/Input/TagKodoperStatic.jsx create mode 100644 src/components/Input/TagStaticInput.jsx create mode 100644 src/components/Input/Taginput.jsx create mode 100644 src/components/Modals/DcodeModal.jsx create mode 100644 src/components/Modals/KodoperModal.jsx create mode 100644 src/components/Modals/Modal.jsx create mode 100644 src/components/Modals/ResponseModals.jsx create mode 100644 src/components/Modals/StockModal.jsx create mode 100644 src/components/Navbar/Navbar.jsx create mode 100644 src/components/Navbar/Navbar.module.scss create mode 100644 src/components/Paginations/PageNav.jsx create mode 100644 src/components/Placeholders/ErrorComponent.jsx create mode 100644 src/components/Placeholders/LoadingComponent.jsx create mode 100644 src/components/Placeholders/NotFindElement.jsx create mode 100644 src/components/Sidebar/Sidebar.jsx create mode 100644 src/components/SidebarNavItem/SidebarNavItem.jsx create mode 100644 src/components/SidebarNavItem/SidebarNavItem.module.scss create mode 100644 src/components/Table/FilterBar.jsx create mode 100644 src/components/Table/TBody.jsx create mode 100644 src/components/Table/THead.jsx create mode 100644 src/components/UserBurger/UserBurger.jsx create mode 100644 src/config/api.js create mode 100644 src/config/contentResources.js create mode 100644 src/hooks/useLostLocations.jsx create mode 100644 src/hooks/useNewSpecialistId.jsx create mode 100644 src/hooks/useOutsideClick.jsx create mode 100644 src/hooks/useSortedPaginated.jsx create mode 100644 src/hooks/useSorting.jsx create mode 100644 src/hooks/useSpecialist.jsx create mode 100644 src/hooks/useSpecialistFilter.jsx create mode 100644 src/main.jsx create mode 100644 src/pages/AddSpecialistPage.jsx create mode 100644 src/pages/AddStockPage.jsx create mode 100644 src/pages/DepartmentsListPage.jsx create mode 100644 src/pages/EditDepartmentPage.jsx create mode 100644 src/pages/EditFilialPage.jsx create mode 100644 src/pages/EditSpecialistPage.jsx create mode 100644 src/pages/EditStockPage.jsx create mode 100644 src/pages/FilialsListPage.jsx create mode 100644 src/pages/HomePage.jsx create mode 100644 src/pages/InfoclinicListPage.jsx create mode 100644 src/pages/LoginPage.jsx create mode 100644 src/pages/LostDoctorsPage.jsx create mode 100644 src/pages/MainPage.jsx create mode 100644 src/pages/NotFoundPage.jsx create mode 100644 src/pages/PricesListPage.jsx create mode 100644 src/pages/SpecialistListPage.jsx create mode 100644 src/pages/SpecialistTable.jsx create mode 100644 src/pages/StoksListPage.jsx create mode 100644 src/pages/UserPage.jsx create mode 100644 src/pages/__test__/LoginPage.test.jsx create mode 100644 src/pages/content/ContentEditPage.jsx create mode 100644 src/pages/content/ContentListPage.jsx create mode 100644 src/pages/content/index.jsx create mode 100644 src/routes/ProtectedRoute.jsx create mode 100644 src/routes/__test__/ProtectedRoute.test.js create mode 100644 src/store/slice/__test__/authSlice.test.js create mode 100644 src/store/slice/authSlice.js create mode 100644 src/store/slice/regionSlice.js create mode 100644 src/store/slice/utilsSlice.js create mode 100644 src/store/store.js create mode 100644 src/styles/_colors.scss create mode 100644 src/styles/theme-override.scss create mode 100644 src/utils/parseSaveError.js create mode 100644 vite.config.js diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..56b91f8 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,89 @@ +name: adminpanel-ci-cd + +on: + push: + tags: + - 'adminpanel-v*' + pull_request: + branches: [main] + +env: + REGISTRY: git.sova.local + IMAGE: git.sova.local/sova/adminpanel + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '24' + - run: npm ci + - run: npm run build + + parse-tag: + if: startsWith(github.ref, 'refs/tags/adminpanel-v') + runs-on: ubuntu-latest + outputs: + full_tag: ${{ steps.meta.outputs.full_tag }} + env: ${{ steps.meta.outputs.env }} + version: ${{ steps.meta.outputs.version }} + steps: + - name: Parse tag + id: meta + run: | + TAG="${GITHUB_REF#refs/tags/}" + echo "full_tag=$TAG" >> "$GITHUB_OUTPUT" + echo "env=$(echo "$TAG" | sed -E 's/adminpanel-v([0-9.]+)-([a-z]+)/\2/')" >> "$GITHUB_OUTPUT" + echo "version=$(echo "$TAG" | sed -E 's/adminpanel-v([0-9.]+).*/\1/')" >> "$GITHUB_OUTPUT" + + build-and-push: + needs: [test, parse-tag] + if: startsWith(github.ref, 'refs/tags/adminpanel-v') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Docker login + run: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login "$REGISTRY" -u sova-ci --password-stdin + - name: Build and push + run: | + TAG="${{ needs.parse-tag.outputs.full_tag }}" + docker build -f Dockerfile -t "$IMAGE:${TAG}" -t "$IMAGE:${{ needs.parse-tag.outputs.version }}" . + docker push "$IMAGE:${TAG}" + docker push "$IMAGE:${{ needs.parse-tag.outputs.version }}" + + deploy-gitops: + needs: [build-and-push, parse-tag] + if: startsWith(github.ref, 'refs/tags/adminpanel-v') + runs-on: ubuntu-latest + steps: + - name: Bump image tag in sova-deploy + env: + DEPLOY_KEY: ${{ secrets.SOVA_DEPLOY_KEY }} + run: | + eval "$(ssh-agent -s)" + echo "$DEPLOY_KEY" | ssh-add - + git clone git@gitea.sova.local:sova/sova-deploy.git + cd sova-deploy + ENV="${{ needs.parse-tag.outputs.env }}" + TAG="${{ needs.parse-tag.outputs.full_tag }}" + git config user.email "ci-bot@sova.local" + git config user.name "sova-ci" + MAX_RETRIES=5 + for attempt in $(seq 1 $MAX_RETRIES); do + git pull --rebase origin main + yq -i ".image.tag = \"${TAG}\"" "apps/adminpanel/values-${ENV}.yaml" + git add "apps/adminpanel/values-${ENV}.yaml" + git diff --cached --quiet && { echo "No changes"; exit 0; } + git commit -m "chore(adminpanel): bump ${ENV} to ${TAG}" + if git push origin main; then + echo "Push OK on attempt ${attempt}" + exit 0 + fi + echo "Push failed, retry ${attempt}/${MAX_RETRIES}..." + git reset --hard HEAD~1 + sleep $((attempt * 2)) + done + echo "Failed to push after ${MAX_RETRIES} attempts" + exit 1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9084229 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local +coverage + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +.vscode +*.lock +package-lock.json +yarn.lock \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e474971 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +# syntax=docker/dockerfile:1 + +FROM node:24-alpine AS build +WORKDIR /app +COPY package.json package-lock.json* ./ +RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi +COPY . . +RUN npm run build + +FROM nginx:1.27-alpine AS runtime +COPY docker/nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=build /app/dist /usr/share/nginx/html +COPY public/env.js /usr/share/nginx/html/env.js +COPY docker/entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh +EXPOSE 80 +ENTRYPOINT ["/entrypoint.sh"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..6be0fed --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# React + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: \ No newline at end of file diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..fcfc5f2 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,6 @@ +export default { + presets: [ + ['@babel/preset-env'], + ['@babel/preset-react', { runtime: 'automatic' }] + ], +}; diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100644 index 0000000..b196602 --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/sh +set -eu + +HTML_DIR="/usr/share/nginx/html" + +if [ -f /config/env.js ]; then + cp /config/env.js "$HTML_DIR/env.js" + echo "Applied runtime env.js from /config/env.js" +fi + +exec nginx -g 'daemon off;' diff --git a/docker/nginx.conf b/docker/nginx.conf new file mode 100644 index 0000000..b8f9d39 --- /dev/null +++ b/docker/nginx.conf @@ -0,0 +1,14 @@ +server { + listen 80; + server_name _; + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + location = /env.js { + add_header Cache-Control "no-store"; + } +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..7f89791 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,85 @@ +import js from '@eslint/js'; +import pluginReact from 'eslint-plugin-react'; +import pluginReactHooks from 'eslint-plugin-react-hooks'; +import pluginJsxA11y from 'eslint-plugin-jsx-a11y'; +import pluginImport from 'eslint-plugin-import'; +import pluginJest from 'eslint-plugin-jest'; + +import { afterEach, beforeEach, describe } from 'node:test'; + +export default [ + { ignores: ['dist', 'coverage'] }, + js.configs.recommended, + { + files: ['**/*.jsx', '**/*.js'], + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + globals: { + JSX: 'readonly', + document: true, + Document: true, + localStorage: true, + window: true, + console: true, + }, + parserOptions: { + ecmaVersion: 'latest', + ecmaFeatures: { jsx: true }, + sourceType: 'module', + }, + }, + plugins: { + react: pluginReact, + 'react-hooks': pluginReactHooks, + 'jsx-a11y': pluginJsxA11y, + import: pluginImport, + jest: pluginJest, + }, + settings: { + react: { + version: 'detect', + }, + 'import/resolver': { + node: { + extensions: ['.js', '.jsx'], + }, + }, + }, + rules: { + 'react/react-in-jsx-scope': 'off', + 'react/prop-types': 'off', + + 'react-hooks/rules-of-hooks': 'warn', + 'react-hooks/exhaustive-deps': 'warn', + + 'jsx-a11y/anchor-is-valid': 'warn', + + 'import/order': ['warn', { + groups: ['builtin', 'external', 'internal'], + 'newlines-between': 'always', + }], + + 'jest/no-disabled-tests': 'warn', + 'jest/no-identical-title': 'error', + + 'no-unused-vars': 'off', + + }, + }, + { + files: ['jest.setup.js', '**/*.test.js', '**/*.test.jsx'], + languageOptions: { + globals: { + test: true, + expect: true, + jest: true, + global: true, + describe: true, + it: true, + beforeEach: true, + afterEach: true, + }, + }, + }, +]; diff --git a/index.html b/index.html new file mode 100644 index 0000000..22ff2f9 --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + + + + Admin panel + + + +
+ + + diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..164e746 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,11 @@ +export default { + testEnvironment: 'jsdom', + transform: { + '^.+\\.(js|jsx)?$': 'babel-jest', + }, + moduleFileExtensions: ['js', 'jsx'], + moduleNameMapper: { + '\\.(css|scss)$': 'identity-obj-proxy', + }, + setupFilesAfterEnv: ['/jest.setup.js'], +} diff --git a/jest.setup.js b/jest.setup.js new file mode 100644 index 0000000..4b78857 --- /dev/null +++ b/jest.setup.js @@ -0,0 +1,6 @@ +import { TextEncoder, TextDecoder } from 'util'; + +global.TextEncoder = TextEncoder; +global.TextDecoder = TextDecoder; + +import '@testing-library/jest-dom'; diff --git a/package.json b/package.json new file mode 100644 index 0000000..2a79f31 --- /dev/null +++ b/package.json @@ -0,0 +1,64 @@ +{ + "name": "adminpanel", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "lint-fix": "eslint . --fix", + "preview": "vite preview", + "test": "jest --runInBand", + "test-watch": "jest --watch", + "test-clear-cache": "jest --clearCache" + }, + "dependencies": { + "@fortawesome/fontawesome-free": "^6.7.2", + "@reduxjs/toolkit": "^2.8.2", + "axios": "^1.10.0", + "bootstrap": "^4.6.2", + "dompurify": "^3.2.6", + "express": "^5.1.0", + "http-proxy-middleware": "^3.0.5", + "jodit": "^4.6.12", + "jodit-react": "^5.2.25", + "react": "^19.1.0", + "react-datepicker": "^8.7.0", + "react-dom": "^19.1.0", + "react-google-recaptcha": "^3.1.0", + "react-imask": "^7.6.1", + "react-input-mask": "^3.0.0-alpha.2", + "react-redux": "^9.2.0", + "react-router-dom": "^7.6.2", + "sass": "^1.89.2", + "startbootstrap-sb-admin-2": "^4.1.4" + }, + "devDependencies": { + "@babel/core": "^7.27.4", + "@babel/preset-env": "^7.27.2", + "@babel/preset-react": "^7.27.1", + "@eslint/js": "^9.25.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.3.0", + "@testing-library/user-event": "^14.6.1", + "@types/react": "^19.1.2", + "@types/react-dom": "^19.1.2", + "@vitejs/plugin-react": "^4.4.1", + "babel-jest": "^30.0.2", + "eslint": "^9.25.0", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jest": "^29.0.1", + "eslint-plugin-jsx-a11y": "^6.10.2", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.19", + "globals": "^16.0.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^30.0.3", + "jest-environment-jsdom": "^30.0.2", + "rollup-plugin-visualizer": "^6.0.5", + "vite": "^6.3.5", + "vite-plugin-eslint": "^1.8.1" + } +} diff --git a/public/env.js b/public/env.js new file mode 100644 index 0000000..c7a5eeb --- /dev/null +++ b/public/env.js @@ -0,0 +1,3 @@ +window.__ENV__ = window.__ENV__ || { + API_BASE_URL: 'http://localhost:8081', +}; diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..77470cb --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..8b7cf4a --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,101 @@ +import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; +import { Provider } from 'react-redux'; + +import { store } from './store/store'; +import { LoginPage } from './pages/LoginPage'; +import { MainPage } from './pages/MainPage'; +import { HomePage } from './pages/HomePage'; +import { UserPage } from './pages/UserPage'; +import { SpecialistListPage } from './pages/SpecialistListPage'; +import { DepartmentsListPage } from './pages/DepartmentsListPage'; +import { FilialsListPage } from './pages/FilialsListPage'; +import { NotFoundPage } from './pages/NotFoundPage'; +import { ProtectedRoute } from './routes/ProtectedRoute'; +import { EditDepartmentPage } from './pages/EditDepartmentPage' +import { EditFilialPage } from './pages/EditFilialPage' +import { EditSpecialistPage } from './pages/EditSpecialistPage' +import { AddSpecialistPage } from './pages/AddSpecialistPage' +import { PricesListPage } from './pages/PricesListPage'; +import { StocksListPage } from './pages/StoksListPage'; +import { EditStockPage } from './pages/EditStockPage'; +import { AddStockPage } from './pages/AddStockPage'; +import { InfoclinicListPage } from './pages/InfoclinicListPage'; +import { LostDoctorsPage } from './pages/LostDoctorsPage'; +import { + NewsListPage, + NewsEditPage, + NewsCreatePage, + SitePromoListPage, + SitePromoEditPage, + SitePromoCreatePage, + DiseaseListPage, + DiseaseEditPage, + DiseaseCreatePage, + MedicalCenterListPage, + MedicalCenterEditPage, + MedicalCenterCreatePage, + ArticleListPage, + ArticleEditPage, + ArticleCreatePage, + SiteServicesListPage, + SiteServicesEditPage, + SiteServicesCreatePage, +} from './pages/content'; + +function App() { + return ( + + + + } /> + + + + } + > + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + } /> + + + + ) +} + +export default App; diff --git a/src/api/apiCertificate.js b/src/api/apiCertificate.js new file mode 100644 index 0000000..053a0e5 --- /dev/null +++ b/src/api/apiCertificate.js @@ -0,0 +1,73 @@ +/* global FormData */ + +import { API } from './apiSlice'; + +const authHeader = () => { + const token = localStorage.getItem('token'); + return token ? { Authorization: `Bearer ${token}` } : {}; +}; + +export const certificateApi = API.injectEndpoints({ + endpoints: (build) => ({ + getCertificate: build.query({ + query: ({id}) => { + return { + url: `/specialist-docs/${id}`, + method: 'GET', + // headers: authHeader(), + }; + }, + }), + createCertificate: build.mutation({ + query: ({specialistId, data}) => { + return { + url: `/specialist/${specialistId}/specialist-docs/create`, + method: 'POST', + headers: authHeader(), + body: JSON.stringify(data), + }; + }, + }), + updateCertificate: build.mutation({ + query: ({specialistId, id, data}) => { + return { + url: `/specialist/${specialistId}/specialist-docs/${id}`, + method: 'PUT', + headers: authHeader(), + body: JSON.stringify(data), + }; + }, + }), + uploadSertificatePicture: build.mutation({ + query: ({ id, file }) => { + const formData = new FormData(); + formData.append('picture', file); + return { + url: `/specialist-docs/picture/${id}`, + method: 'POST', + headers: { + ...authHeader(), + }, + body: formData, + }; + }, + }), + deleteCertificate: build.mutation({ + query: ({id}) => { + return { + url: `/specialist-docs/${id}`, + method: 'DELETE', + headers: authHeader(), + }; + }, + }), + }), +}); + +export const { + useGetCertificateQuery, + useCreateCertificateMutation, + useUpdateCertificateMutation, + useUploadSertificatePictureMutation, + useDeleteCertificateMutation, +} = certificateApi; diff --git a/src/api/apiContent.js b/src/api/apiContent.js new file mode 100644 index 0000000..271c9a7 --- /dev/null +++ b/src/api/apiContent.js @@ -0,0 +1,117 @@ +import { API, authHeader } from './apiSlice' +import { CONTENT_RESOURCES } from '../config/contentResources' + +const buildListQuery = (basePath, { usesLimit = false } = {}) => + ({ search = '', page = 1, perPage = 20 } = {}) => { + let queryString = `?page=${page}` + if (usesLimit) { + queryString += `&limit=${perPage}` + } else { + queryString += `&perPage=${perPage}` + } + if (search) { + queryString += `&search=${encodeURIComponent(search)}` + } + return { + url: `${basePath}/list${queryString}`, + } + } + +const injectResource = (resourceKey) => { + const { basePath, listUsesLimit } = CONTENT_RESOURCES[resourceKey] + const cap = resourceKey + .split('-') + .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) + .join('') + + return API.injectEndpoints({ + endpoints: (build) => ({ + [`get${cap}List`]: build.query({ + query: buildListQuery(basePath, { usesLimit: listUsesLimit }), + refetchOnMountOrArgChange: true, + keepUnusedDataFor: 0, + }), + [`get${cap}Item`]: build.query({ + query: (id) => ({ + url: `${basePath}/${id}`, + }), + }), + [`create${cap}`]: build.mutation({ + query: (data) => ({ + url: `${basePath}/create`, + method: 'POST', + headers: authHeader(), + body: JSON.stringify(data), + }), + }), + [`update${cap}`]: build.mutation({ + query: ({ id, data }) => ({ + url: `${basePath}/${id}`, + method: 'PUT', + headers: authHeader(), + body: JSON.stringify(data), + }), + }), + [`delete${cap}`]: build.mutation({ + query: (id) => ({ + url: `${basePath}/${id}`, + method: 'DELETE', + headers: authHeader(), + }), + }), + }), + overrideExisting: false, + }) +} + +const newsApi = injectResource('news') +const promoApi = injectResource('promo') +const diseaseApi = injectResource('disease') +const medicalCenterApi = injectResource('medical-center') +const articleApi = injectResource('article') +const siteServicesApi = injectResource('site-services') + +export const contentHooks = { + news: { + useListQuery: newsApi.useGetNewsListQuery, + useItemQuery: newsApi.useGetNewsItemQuery, + useCreateMutation: newsApi.useCreateNewsMutation, + useUpdateMutation: newsApi.useUpdateNewsMutation, + useDeleteMutation: newsApi.useDeleteNewsMutation, + }, + promo: { + useListQuery: promoApi.useGetPromoListQuery, + useItemQuery: promoApi.useGetPromoItemQuery, + useCreateMutation: promoApi.useCreatePromoMutation, + useUpdateMutation: promoApi.useUpdatePromoMutation, + useDeleteMutation: promoApi.useDeletePromoMutation, + }, + disease: { + useListQuery: diseaseApi.useGetDiseaseListQuery, + useItemQuery: diseaseApi.useGetDiseaseItemQuery, + useCreateMutation: diseaseApi.useCreateDiseaseMutation, + useUpdateMutation: diseaseApi.useUpdateDiseaseMutation, + useDeleteMutation: diseaseApi.useDeleteDiseaseMutation, + }, + 'medical-center': { + useListQuery: medicalCenterApi.useGetMedicalCenterListQuery, + useItemQuery: medicalCenterApi.useGetMedicalCenterItemQuery, + useCreateMutation: medicalCenterApi.useCreateMedicalCenterMutation, + useUpdateMutation: medicalCenterApi.useUpdateMedicalCenterMutation, + useDeleteMutation: medicalCenterApi.useDeleteMedicalCenterMutation, + }, + article: { + useListQuery: articleApi.useGetArticleListQuery, + useItemQuery: articleApi.useGetArticleItemQuery, + useCreateMutation: articleApi.useCreateArticleMutation, + useUpdateMutation: articleApi.useUpdateArticleMutation, + useDeleteMutation: articleApi.useDeleteArticleMutation, + }, + 'site-services': { + useListQuery: siteServicesApi.useGetSiteServicesListQuery, + useItemQuery: siteServicesApi.useGetSiteServicesItemQuery, + useCreateMutation: siteServicesApi.useCreateSiteServicesMutation, + useUpdateMutation: siteServicesApi.useUpdateSiteServicesMutation, + useDeleteMutation: siteServicesApi.useDeleteSiteServicesMutation, + }, +} diff --git a/src/api/apiDepartment.js b/src/api/apiDepartment.js new file mode 100644 index 0000000..93b3b87 --- /dev/null +++ b/src/api/apiDepartment.js @@ -0,0 +1,38 @@ +import { API, authHeader } from './apiSlice' +/* +const authHeader = () => { + const token = localStorage.getItem('token') + return token ? { Authorization: `Bearer ${token}` } : {} +} +*/ +export const departmentApi = API.injectEndpoints({ + endpoints: (build) => ({ + getDepartments: build.query({ + query: () => '/department/list', + }), + updateDepartments: build.mutation({ + query: ({ departmentId, data }) => { + return ({ + url: `/department/${departmentId}`, + method: 'PUT', + headers: authHeader(), + body: JSON.stringify(data), + })}, + }), + createDepartments: build.mutation({ + query: ({ data }) => { + return ({ + url: `/department/create`, + method: 'POST', + headers: authHeader(), + body: JSON.stringify(data), + })}, + }), + }), +}) + +export const { + useGetDepartmentsQuery, + useUpdateDepartmentsMutation, + useCreateDepartmentsMutation, +} = departmentApi diff --git a/src/api/apiFilial.js b/src/api/apiFilial.js new file mode 100644 index 0000000..5e9061d --- /dev/null +++ b/src/api/apiFilial.js @@ -0,0 +1,53 @@ +/* global FormData */ + +import { API, authHeader } from './apiSlice' + +export const filialApi = API.injectEndpoints({ + endpoints: (build) => ({ + getFilials: build.query({ + query: () => '/filial/list', + refetchOnMountOrArgChange: true, + keepUnusedDataFor: 0, + }), + updateFilial: build.mutation({ + query: ({ filialId, data }) => { + return ({ + url: `/filial/${filialId}`, + method: 'PUT', + headers: authHeader(), + body: JSON.stringify(data), + })}, + }), + uploadFilialPicture: build.mutation({ + query: ({ id, file }) => { + const formData = new FormData(); + formData.append('picture', file); + return { + url: `/filial/picture/${id}`, + method: 'POST', + headers: { + ...authHeader(), + }, + body: formData, + }; + }, + }), + createFilial: build.mutation({ + query: ({ data }) => { + return ({ + url: `/filial/create`, + method: 'POST', + headers: authHeader(), + body: JSON.stringify(data), + }) + }, + }), + }), +}) + +export const { + useGetFilialsQuery, + useUpdateFilialMutation, + useUploadFilialPictureMutation, + useCreateFilialMutation, +} = filialApi diff --git a/src/api/apiIDoctor.js b/src/api/apiIDoctor.js new file mode 100644 index 0000000..81d17a5 --- /dev/null +++ b/src/api/apiIDoctor.js @@ -0,0 +1,22 @@ +import { API } from './apiSlice'; + +const authHeader = () => { + const token = localStorage.getItem('token'); + return token ? { Authorization: `Bearer ${token}` } : {}; +}; + +export const iDoctorApi = API.injectEndpoints({ + endpoints: (build) => ({ + getIDoctors: build.query({ + query: ({ value = '', type, page = 1 }) => { + return { + url: `/idoctor/list?page=${page}&perPage=100${ type ? ( type === 'search' ? `&search=${value}` : ( type === 'dcode' ? `&dcode=${value}` : '' )) : '' }`, + headers: authHeader(), + }; + }, + }), + }), + overrideExisting: false, +}); + +export const { useGetIDoctorsQuery } = iDoctorApi; diff --git a/src/api/apiKodoper.js b/src/api/apiKodoper.js new file mode 100644 index 0000000..c5520d3 --- /dev/null +++ b/src/api/apiKodoper.js @@ -0,0 +1,30 @@ +import { API } from './apiSlice'; + +const authHeader = () => { + const token = localStorage.getItem('token'); + return token ? { Authorization: `Bearer ${token}` } : {}; +}; + +export const KodoperApi = API.injectEndpoints({ + endpoints: (build) => ({ + getKodopers: build.query({ + query: ({value, filialId, page}) => { + const querySearch = value ? `search=${value}` : ''; + let queryFilial = ''; + if (filialId) { + if (filialId >= 0) { + queryFilial = `filial=${filialId}` + } + } + const queryPage = page ? `page=${page}` : ''; + return { + url: `/pricelist/list?${queryFilial ? `${querySearch}&` : querySearch}${queryPage ? `${queryFilial}&` : queryFilial}${queryPage}`, + headers: authHeader(), + }; + }, + }), + }), + overrideExisting: false, +}); + +export const { useGetKodopersQuery } = KodoperApi; diff --git a/src/api/apiLocation.js b/src/api/apiLocation.js new file mode 100644 index 0000000..f2a39a0 --- /dev/null +++ b/src/api/apiLocation.js @@ -0,0 +1,51 @@ +import { API } from './apiSlice' + +const authHeader = () => { + const token = localStorage.getItem('token') + return token ? { Authorization: `Bearer ${token}` } : {} +} + +export const locationApi = API.injectEndpoints({ + endpoints: (build) => ({ + createLocation: build.mutation({ + query: ({ specialistId, data }) => ({ + url: `/specialist/${specialistId}/location/create`, + method: 'POST', + headers: authHeader(), + body: JSON.stringify(data), + }), + invalidatesTags: ['Specialist'], + }), + updateLocation: build.mutation({ + query: ({ specialistId, locationId, data }) => { + return ({ + url: `/specialist/${specialistId}/location/${locationId}`, + method: 'PUT', + headers: authHeader(), + body: JSON.stringify(data), + })}, + }), + deleteLocation: build.mutation({ + query: (locationId) => ({ + url: `/location/${locationId}`, + method: 'DELETE', + headers: authHeader(), + }), + }), + getEmptyLocations: build.query({ + query: () => { + return { + url: `/locations/empty`, + headers: authHeader(), + }; + }, + }), + }), +}) + +export const { + useCreateLocationMutation, + useUpdateLocationMutation, + useDeleteLocationMutation, + useGetEmptyLocationsQuery, + } = locationApi diff --git a/src/api/apiSlice.js b/src/api/apiSlice.js new file mode 100644 index 0000000..1058946 --- /dev/null +++ b/src/api/apiSlice.js @@ -0,0 +1,44 @@ +import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' +import { API_BASE_URL } from '@/config/api' + +export const authHeader = () => { + const token = localStorage.getItem('token') + return token ? { Authorization: `Bearer ${token}` } : {} +} + +export const API = createApi({ + reducerPath: 'API', + baseQuery: fetchBaseQuery({ + baseUrl: API_BASE_URL, + credentials: 'include', + }), + endpoints: (builder) => ({ + login: builder.mutation({ + query: (data) => ({ + url: '/user/login', + method: 'POST', + body: data, + }), + async onQueryStarted(arg, { queryFulfilled }) { + try { + const { data } = await queryFulfilled + console.log(data) + localStorage.setItem('token', data.token) + localStorage.setItem('admSovamedUserUID', data.user.uid) + localStorage.setItem('admSovamedUserRegionId', data.user.regionId) + } catch { + // + } + }, + }), + + logout: builder.mutation({ + async queryFn(_arg, _api, _extraOptions, _baseQuery) { + localStorage.removeItem('token') + return { data: undefined } + }, + }), + }), +}) + +export const { useLoginMutation, useLogoutMutation } = API; diff --git a/src/api/apiSpecialist.js b/src/api/apiSpecialist.js new file mode 100644 index 0000000..989f7f1 --- /dev/null +++ b/src/api/apiSpecialist.js @@ -0,0 +1,119 @@ +/* global FormData */ + +import { API } from './apiSlice' + +const authHeader = () => { + const token = localStorage.getItem('token') + return token ? { Authorization: `Bearer ${token}` } : {} +} + +export const specialistApi = API.injectEndpoints({ + endpoints: (build) => ({ + getSpecialist: build.query({ + query: (specialistId) => ({ + url: `/specialist/${specialistId}`, + method: 'GET', + headers: { + ...authHeader(), + }, + }), + refetchOnMountOrArgChange: true, + keepUnusedDataFor: 0, + }), + getSpecialists: build.query({ + query: (regionId) => { + return regionId === 'all' + ? '/specialist/list' + : `/specialist/list?regionId=${regionId}` + }, + refetchOnMountOrArgChange: true, + keepUnusedDataFor: 0, + }), + getSpecialistsList: build.query({ + query: ({ regionId = '', search = '', page = '' }) => { + let queryString = ''; + + if (regionId) queryString += `regionId=${regionId}` + + if (search) { + if (regionId) queryString += '&' + queryString += `search=${search}` + } + + if (page) { + if (search || regionId) queryString += '&'; + queryString += `page=${page}` + } + + return `/specialist/list${queryString ? `?${queryString}` : ''}` + }, + refetchOnMountOrArgChange: true, + keepUnusedDataFor: 0, + }), + uploadSpecialistPicture: build.mutation({ + query: ({ id, file }) => { + console.log(file) + const formData = new FormData(); + formData.append('previewPicture', file); + console.log([...formData.entries()]) + return { + url: `/specialist/picture/${id}`, + method: 'POST', + headers: { + ...authHeader(), + }, + body: formData, + }; + }, + }), + createSpecialist: build.mutation({ + query: ({ data }) => ({ + url: '/specialist/create', + method: 'POST', + headers: { + ...authHeader(), + }, + body: JSON.stringify(data), + }), + invalidatesTags: ['Specialist'], + }), + updateSpecialist: build.mutation({ + query: ({ specialistId, data }) => { + return ({ + url: `/specialist/${specialistId}`, + method: 'PUT', + headers: authHeader(), + body: JSON.stringify(data), + }) + }, + invalidatesTags: (result, error, { specialistId }) => [ + { type: 'Specialist', id: specialistId }, + 'Specialist', + ] + }), + deleteSpecialist: build.mutation({ + query: (specialistId) => ({ + url: `/specialist/${specialistId}`, + method: 'DELETE', + headers: { + ...authHeader(), + }, + }), + invalidatesTags: (result, error, id) => [ + { type: 'Specialist', id }, + 'Specialist', + ], + }), + }), + overrideExisting: false, +}) + +export const { + useGetSpecialistQuery, + useGetSpecialistsQuery, + useGetSpecialistsListQuery, + useUploadSpecialistPictureMutation, + useCreateSpecialistMutation, + useUpdateSpecialistMutation, + useDeleteSpecialistMutation, + } = specialistApi diff --git a/src/api/apiStock.js b/src/api/apiStock.js new file mode 100644 index 0000000..8be3fad --- /dev/null +++ b/src/api/apiStock.js @@ -0,0 +1,102 @@ +/* global FormData */ + +import { API, authHeader } from './apiSlice'; + +export const stockApi = API.injectEndpoints({ + endpoints: (build) => ({ + getStocks: build.query({ + query: ({ search = '', page = '' }) => { + let queryString = ''; + if (search || page) queryString += '?' + if (search) queryString += `search=${search}` + if (search && page) queryString += `&` + if (page) queryString += `page=${page}` + return { + url: `stock/list${queryString}`, + //headers: authHeader(), + }; + }, + refetchOnMountOrArgChange: true, + keepUnusedDataFor: 0, + }), + getStock: build.query({ + query: ({ stockId }) => { + console.log(stockId) + return { + url: `/stock/${stockId}`, + //headers: authHeader(), + }; + }, + }), + createStock: build.mutation({ + query: ({ data }) => { + return { + url: `/stock/create`, + method: 'POST', + headers: authHeader(), + body: JSON.stringify(data), + }; + }, + }), + updateStock: build.mutation({ + query: ({ stockId, data }) => { + return { + url: `/stock/${stockId}`, + method: 'PUT', + headers: authHeader(), + body: JSON.stringify(data), + }; + }, + }), + uploadStockPicture: build.mutation({ + query: ({ id, file }) => { + const formData = new FormData(); + formData.append('picture', file); + return { + url: `/stock/picture/${id}`, + method: 'POST', + headers: authHeader(), + body: formData, + }; + }, + }), + deleteStock: build.mutation({ + query: ({ stockId }) => { + return { + url: `/stock/${stockId}`, + method: 'DELETE', + headers: authHeader(), + }; + }, + }), + addSpecialist: build.mutation({ + query: ({ stockId, specialistId }) => { + return { + url: `/stock/${stockId}/specialist/${specialistId}`, + method: 'PUT', + headers: authHeader(), + }; + }, + }), + removeSpecialist: build.mutation({ + query: ({ stockId, specialistId }) => { + return { + url: `/stock/${stockId}/specialist/${specialistId}`, + method: 'DELETE', + headers: authHeader(), + }; + }, + }), + }), +}); + +export const { + useGetStockQuery, + useGetStocksQuery, + useCreateStockMutation, + useUpdateStockMutation, + useUploadStockPictureMutation, + useDeleteStockMutation, + useAddSpecialistMutation, + useRemoveSpecialistMutation, + } = stockApi; diff --git a/src/assets/icon.png b/src/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..79af38ca37aa52752fe45d0403e499c60e1b4527 GIT binary patch literal 2703 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 literal 0 HcmV?d00001 diff --git a/src/assets/image-placeholder.png b/src/assets/image-placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..021ca58a18d1942f42da63c8f3fa0c327346a9ba GIT binary patch literal 29514 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 V>z|3Ymj4SwRY~hvg`#!%e*x<=;N<`S literal 0 HcmV?d00001 diff --git a/src/assets/logo.png b/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e28063b54a572144d0bd90a90fde1c8d924b8ee4 GIT binary patch literal 5726 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 literal 0 HcmV?d00001 diff --git a/src/assets/photo-placeholder.png b/src/assets/photo-placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..afa85419dfa01f4bad263d3a44b5e01bbc18b8e0 GIT binary patch literal 238657 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%0A&0Sc* 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
_-#YNRA zr(5)S@<%IV+}x_qE0`7K^g-fhMJ~`#f~88nOkk|(^Q6bPh_xmEx$*W|-HENV^$G>m z($zC5-T8XU3K2zvqASu4JeiVo870*svY7RxTu{neXSLP3_T!Viz+I=ad=8mq8tFa7 zJj_SnruD#&9cj#+f9PnV(K`N~@t=MAm5X2d*V{W6Wm67Ue^*Ff?XF_E`%UO|`Hf;O zjBoHD1?71!)RTyv<+vj*^>!72&xU6-x+_flDnF7%tW0k!m16~wE}a1xv1goa+J9r?_2rGNtsC7-mo_(+w{Cv+ zZ`^x)VeI(iA<^AO51*Ji+HN0fx7(f0{M^j^+K5EQB80PoLL>Oug<&HYipt4OB~4&!p7K^_CSP z%8_0BIktEzNu{T=8mZ3tObtyYK#Iw^8m5z?E<{lYoI7StQC6qkd!ka3HKwN9te|O4 z9cj!=pa1ZG|I+{QwSWEZcE7x__1403g z*&v6Q?7*RLq&w2kDxa8`4cQ_GPJTs9K*xwyT)ksponhA{oTN#^CTW~DYHYi)8uP@q zofF%(ZQHil*tTtbr_b}w%s2Dv{9k9^>)LB=)#PAmvKX?S-LwRmgr5ps&?@k{pYU5j zDX|ndqiK^_h);<-`+n7wv1JHrrYJb8l+)Tuvrn0mykBk9v5S7Ip?qni(vt#JFBVW! zOqo$iS^0SU(Qg*i!OLsD3j;iJ*Ve0razbcDz9Wd9wcn?Ct z$7_4N+SXV2lQtB|LN+zY!)0Ap#jeaEp_tzguPBiwn1&#)*;I}!XN#_|U1U&-#%NK= z$|x6291lerVrRr*ePd%QrU_lRUuu7zrXf#yYPS<{$K{jcDifbpwvef(pgrxdy9cn( zVd8$={mk0@_RVWaOPZuR(1cFO}^ecvWjA=$t(wFvZa^N2l#DFAR4llvb^)7>R;uUnQ~a z2%ZpXbQAT?B&rsVbb`#3$ho$y{A1mh@-BA`66rh4EI|52ZIJ6SW@}v^zU<=2VFzvk z4HsTbAn`jf+@ku>FNsrc5+SZD%b>wp`qn`O9l?cG4pNfhU7;Gv%olOzf@Rn5z2XTv zea8lS{#B>I{X*_t*!KHnFn@Vee3Yj!I}+@jbbS*3BX+tdqJrzuSD zN>J;N@P0eJ+?j&&xy#|QGY%zw*#Y&3c^mZj>oM$#IQ8qMG@K+?Fyf-Um2bk7`jN;H zP=PlWPEoP{=UW*UT^F{}M)`$aT2N-3%Qd6gVJPgy&WJTfvo7Yg8)~HPM$-|-`5K`j zvWJ!}I9Td&R&6ZcR)qUS@?J|Xoz`sUqDp>QgSoYYfeGkP%CwpOZCsr5WM zFp+b#Qbv`l+;$x}0$S>3i-pkK;+kPy6Wn)2QqYI}&i{%0trCfO`R`nh&G$AZRe89a zHis}xd1Ym{4}x63fO0-?6hC3Z7@`%-XcuUlu8$aAq2P>dNd9K<8Zf01*`3py*6Z^c zYi@Be060B(h9kLex_bzW=?IW+iwu*w_zd_fI(CL_8i8bALL#ifSZWw;2HSXA9?^Nk z0r}bTZqK|QD=!FNzr~_Ef$t<+g(_C*hM*GJw~J1I_6P!>)amO~_YK2I^+2#!Y3|X_ zu_^AZ>j=;fsB`w=(DP1a^Ln_q*H-mHe@KX|a1arnn;QryI)|3Y^1NCz<=3RvUbm%r z>$Q6p4wN-Yg^0ZZGXB!Phj&_n{-shj838QZt$gO_fMkQffac(RrwnIj@yN6p8~`ap zQUj3_TJgH4d1hIfbsA@B`J9c~TwWY(Z#C|zEE*B~g9GEyeHfAee|f5d{XgHkFF0Hd z)yZ$f7F@&%U|17&zfx)yC9EV&2?s4ydr| ztKMi7_~10d_D7z*OhyQ#^6r^|XmCx?b=*MuX6yYXOMC*^IC1pb9N~*I7no*RfHzrz z;@JF#(V}(qrpRyBWkJCJaF;DHnE6@ZD5O8B?9CYry~6MEs+|R;^n6?F=8U87=Zho1c$4K^#z^tcyWxxps- zn$p%@)81acw%U3Jy6gBp?)Cej)9qp(J+USrz-^a8CL`T!*cFre$p`DT5&l^;|+I zNg#RTf~JtsOhJQC?mt2^d_Se3ddbVK4=ggN+!+$fpaf1z*c{4NUZ-&dtc|1`80$&7 z%c|%xY!_}&8}A4k+W&GynK7*6o=-WIl)=eNwO(^MjPi1PEV!Ql4gAqrf!T}f_P3gw zpPDOo+?WkBUlw+iPQfSkgdayB*Ej1CVfL?V^io?6;MI>NVH$`rvCtZ^sAQ{*lbGyW zg#PWFS%tLowV7tPfTIuh^noh(!q_7I$%Zk+kN`b6Oe9V(ey44tL>b^rRl=7Q3u85! z(V==BtZ5o2h2ZiM;+c>A_z&}E3!)^l1?hENzSbEOQV_tR$EoYlLEz4Y zyM#5V7`OT-wD-R$RR_z9VUP__9p}oy`tsl4Ml}^lqV=>o_?sP{q{QD>N#y17h7MO8 zC0Hy8y{VTFw%E}PpU4yy1NX;G&s&0FsK2rT!gDToj3Kk|CRq8GHHv{NG7e^?EbHl7 zCb&O&9ct}8&pKp2WQIpD8cK> zF6BX5O(S&A2)}*0Xk`pmBF>GYG*f5mD-FTn7)kU1{V_}#c4?`9zocgI*xy{O_4YfT zF12}n;D4T;{`O1KUc#7ER#H+`XrV-Urxa|TAuT4lPSFr&a>U<6fmb>sO^mmt-oX5+ z7m_BZdO|~|@YT!R7~QIqv`Di&(iJ1*-f4V|-YwrJM8cCSDnbh9P|EuEuZ^J_jBMu= zzm|imRw=e$$nrTZ(=#{e0k=iU?dBTm<2=k6}_Wm^-6i>_Izt(myU z?(xfclLF4w@AE_>`hN%2YM|{5_+H~=HOJ%4jvEXkv*_tc&q;j^aru^ zzBc&^1LBFLD@!-z)|?NzG)LUK&K?KM_#3ud(`!F~rhvIxV&!7M;`dLC(i3}AE0&fS zVbiy6z;*X8C;5~dLfh4>a^+&nG-e!GR!qY5){;4w=nXTrC}y%j8EHq(&&R0GU9XP! z(SfjTcf*9H#m4spo|=S7r>BI?UXJ-`3gTr?%KAd=kE)nrdlNS|$D_R|>&E$@dOM#Uzb-+ipP)M6aYr*As3Fzq7gL24=V6 zO&n^lA4*KKv&R%wfVGBUxvF444rc#-V2qydVUa)2ycJ*nj~?wv-ZBjEoq7HDvA9sd4_ zhpyx#Bs!?%h){?Rk5^P`d{3GZde<&X&U;8u(Z+SP+JZKoDnE7d3J^~bwr`XgQBpFA z)c#oXG5=fpbu^oIsdMAhvdW4nqjPlU>VA7L^zK`!5GRg9k1u1hu08GeCb*3|0HEY4 zvo6ZQbPBC>e-s~le_pP=m>>Y-GLG=3?ob=qUNCA5AQj}V6lTbnUGs2Kos-#TqjinRr z&x0oI&j7cL$G(V?;}A!CfkDnW#5($Kg?*{#2Xkk04zpOMQ~4de;HAyoHZ+Oj|6U5! z?bG~J2P#cP`lhDusyZaJkC0<9Pw2eTfMhGu^nKIwnew0$S)7VC6YH~iX!M8vy1p_{ z#48b^Q{T5xY>EQzg+g7?QEk5JpJdn_Y=BTd6f9kjdx*h5?iO11%r5*jt*CY-tbf9N zehkWOv)s?kslviKKA6H7IoekJE)2mVfIpPjAfhALvjl<@Xv>RvHv?IgIgPq0F>G5@ z(C&g-<8?D+dzx|3!fCXeXd4BS6v@@*nr2q8kJ;J^ij@<7F>SEcT{#b&+P<&+R@p6Z zphcsQvA35<3CQi3K#ycN)i9_WGTv_MEMu8Z4m5-~mOtUz?DsaBKqRf2Z?AXXDFQoj$0K3F zG029VMT?enmkQ6Pbb$B9oMi0l-D&R#A4Z{S6n})2kc$oGMAM>h8k;WRJo6RlwOek| zVfmpVZz-FTDW>|_%3QioE3W8q@#Nwnk$aNbm#cMBo-V>2BT7=lq;QfStc($^F+$`O zGI}6Tz%$jKca0P7?Ya0g(ssf1c^tObaq8tIcar|7)D|uo00&ya%Wv{c!JP)9xz-GU z76a*r@kcj)k5%WUp5LL6GEs7{5wXHTo^O*-=CF7P8lIksrwZq@=$epn(M0S z*FiGS?V!70k7hXVsC3neyByl+HzqRing!A5U2O)bLjA? z^+L=RxB=;pS|@AhMLVufP9mBTvsT?-e|mXscXnM(4{fkbCtEc@Hu&3nTN%oEY>~QH ztG=W2HT2##|DY>ZTSki>2S{3>%LY^3#5j)hO#%zc^aFCJtQO1xG$VxMtFYVEq@t0| zRs2NDhqcx{Com6aepzTLQ~Bjynm^DR$`gvOLcK1Y_FqX-YPscxWrZV%IVr?Ql+W@U zB%+3g2uVejU=k(*#66^?YU*Ip8{;-*( z?3ixEhB0_g?u42raFi;{6RF#Hm|snI9_2a*x#)6`2U{OGaj@lO07G!gn{bJ_#Hc{g zn?5@dIs)u#EkBXkDZ@?QdG+d~{6Is{tZZp`vAo=vtDo76JAPxHiWe6a;B;KY6rpx2?o>z%~I4gBbv4JwlEEP6j)2Q6izv!bKZR@-+gvniR& zMI#eOXmg1$yz03w=2A-S8_`U(15Gv)2ZgR4+5f!2a0d6w{Y9t}63e)R?U>>$?~AoK zw)7a~B$yveFs{2l!j)0QP*8RMtS7gzJTgqbV1NsWk$~{?*B5TsZ~A~hZ-^zQK>rl- zfmY4NS`uIL@+DLD?)mFX4l7ncr^>&a*0(QH6-k~^p%!_!!i@BQHmry|#o*XXI|*~o z9IR0%2Y4_G@?)#oeEQ{g7y>k&G0(QKqz%{CtoMGWP5VucNB2*UN0#SYHTZ^9_k9Qs zt}BQ`BwN$cBYUjQN(z+4h^vOfSn)sv{S5zs*htRV^NCkC!ZA7Z^Pm)p1Ayv)YAx%@ zhWTI7hnBPVYBl-T9~Z^0=^%*3^UP>K9Sw)T7?o(K;$k$!3-2A`AIWTIBk@*-&nfV< z`{MkD_Brxdg5?&e6k7VpDLu|vnLO@x?F_e-gLLkOPS?u=5@S`WMQ;7@8vdH$7Y6^0y!oVyFdx78ar35S9!wsV9NJ_^58!K-tE29JPo8qs( zYPv3mE+TNSe8F@qrVx2NS7@ex7YS3X!Ay|d`4xAte)lX=9Rb@Lu&3V`g~gR0+MceI zjC7Ybx!`h)j%1{o>kGxLjcc*#yv-!@v56STg2ypyw!uaMGufbyQ2cruBBq)Toyn2I zUUGE1m0`dp;xFJe4;!GtXpkS(ff(nZY25nb5|gqe)3kvY;T2+PG*s}vD8tm-Ex+nE z>>6c&d0aSEUZEwEW~$ zPOqcNl))_Sx82=K?AMgdx0RV$2|9~fG}gh80q>e>K`%Wa6(q<)xqOw_%C_+KU7gpp zG2Q;`p0^z}`>tL1%{ML^Fm}FP$Q63D;tvD|<-rZ^oWG4X_P+P$^M)f-j1IW(r~Nn^!H{w+N+k-v z3oH=luIrWcfJO(H_|AsPWf4wenQQ)*~3GS@;mE{*9JNmcE0|Fjn zzM*T{4fr0AaDnN0{pW(i^K!`p6*c3}0a+nF`nc}Azde)IbGOu0Ba0}jjfd;g_`oFV6AC9{lPWH9>U>8)>0dO8mIC>A#G*B)w~c689kJGl z%(Cr3YS07$EHp}x-;->(6%ZPXdpnV(B{YDg`?t}NBDxh!iDW(HsXH*(j+J|DB1BJr zx)^U7ETsJiD>2`ZyJ08+5s=7#OHQxV^G$vVrhimTt{AuM)_q6i^h5-+!p5_sFvHcN zQUdIJcw%{F$yMRT`s&`;>SK}&5zp&x>-rC=dd1L66by1)MN7*a$6hiyCd@vX(lh!rNCZzH_wAtNZnfpX{1pfFZw%@aP zZypj4!oD8WYO#7?6k{c=$mIMA&}t2dij=l&5aY3we-W@ti!Z$OeCZ^DoPpCnw?tgLW8CcREO8`R<)$3EfKj)A(&?nyr(7rcmnvfeT8ZTNRh2uLEI z3X6d2`ThNf?FIA}#VWeZ=4YgjoxL6>HjwnZRx+;yiXg0}rWt%gYi!%1LJX9Yz1JI4WHF+K zc)ZuJrewXLrbakmE;=#+-O z1m73oUBX-Y_>2A&COm6|%xvfO2eRWmHjcT@r^)Hg#{nKj81Y?n^)kiF%B!VvAx3|~ z3VUiP@%;#6{(3(AW4YI9UUt42s}Yl6@DnTND!?o^zSYmfUO|!PXsRZ`c#{sM8p7En zZ&7`I%Fepk*|eJF&6xM4XvovxY-{iOfT-fnl4vf|=834x6|?R)$zIN8UtE1D;L^%| z>LOVAF6PUrQZ^$NraQV*AFuTU3EDrPDe__@%~Kh1&y4b?u#zSn;?-tg>KXekgXUvT z48KC{l``gv|3mn{oDCt>kX|*rABI9Sp zR-?TNe#sYnYitZH6jJ=<5r4G&hb-4inHH)rtXOCwTE65kJ32I08ZpZ*=Lb?6VXbdO z5{6!TpfftN(2|Tq%O|5o3YZyDMH}dGx6>ZV59TLxpUH0%-bD!rRO~vWwtc~|m=FJE_Mi%{U?xJ6a{ z)P4be?HyHpx3*#k068ozkQ?n?DDuJejJ6J~c!A+I5ya~2TdR|~0H%O`w~q9J7|8vA zIfc^}p&#O;qR2b1)i7jxz5xh^N9iBixB>;=TxvH?HC>Ia9&R>2E-o`Qnw1e>h=wlb zZ_OL(cy`IT-&8P~CsTZsKHYi->S z8<5XZOV0+81g&LPp&4si@!_D8dBQgK=}^+=>NMhYF>+KDLmJtwE$wtc1dulKiDNwh@;*w7DQ}Ksm-OQgC?(2I=uG74YwiCsI%kSw2}P`T*pM@xyzgsBvONJXUi5kh1TTOpq|a- zxKd}qN{m{BY9?osLAH^&6L&n_SBnE@sC8fTRrn?YIDI98XzDvizGMbM@+!^|bIhv08N; zz1xjihep4dlA4-kk#61oc(m#HV-}Z$s*vr+z(i}}&3ByzXzH8Z&ON~+8~rQ$en#fF z8v|--3o6`#C5@n=3REOY_@vNbbG0vpq0?UCmc;=l`g;-1>eTNCnKxfVRt2eD>6&dj zG)OtBFttgjyq$j@aOfn-sw6e_aO`T3=FE88xg!{922J5xhv)fe+Plo&;3X=;LR~A8 zVBcI|tyz?5Ys#AHL}KfQ@w0?r1NCOka^AivAwRh)Mj+;7tGg4(-@tzQqbT+viwnXA z?i)4+wcRbOcHLus?m2x9xOFwPToJ|TN4P~fkrv^j&fF6$PqyS1&Ex`Z#px4~2Fi|1 zC(OZLpB>9AF*_$|u!~b>G|5)|z(ZsU#-sls%~^Wx2uo@lzYw!;XyCSGLQHz=>Dzd$94c1`I4EKe%6lb7|pag;BcjF?Hn)gII zIc*KA&>%TMmzc z4iWJ!c$u9nYPq>N*gU=_pXz=MZ@!ZG>)+lH?K8nz`(nV40VC96bki4zUrI{+FlYizgeXwo$>#jFP-Ms;Lkk;*YvdjoQ z`l=>0daMUJraZDhWekq7YBJv$KfzF ziwMANEwfZEduZfeTG?bG7LVEaGjC&(*L1Tl6K?^E8Mme+A&`o~&rHdD3%VG=#jwzw zFij|Ug7s;7@f5ea8YeQ>OCR6A_{_o3!Y(&7%vVH6OgU}7Ed0*;(REp}5Cbi}=JD8q zT4XE}CU~G&RpML{2xrCU0I(rgSo5 zS6G68n4z;8BVN!xgAVZOsvrLk#B@w@5Q1N&-i>1Pi2G2S?w`<0`Is8G7N`prVkQNX z6V^S1h%(}bWLqF8mZ?BXmbkF1waw$9SiW zjlm^lBT1HgfE;kB6fOM0Kd!V3SC;UaY8a?m`g} zvoHiG>8dM4E_D3^jpqlIqbwax16ygp4-e^vw@7XeeoJh>?txz-Cw|UeN|^89aSx@` zhvoVDDHSwdPC7gFPWe9dxpeiL9bGItn%Zskuhvc%Jv;B$C&+%I(pCC^2+8}RSc#t{rsuWcf(gP3CnoWIZ*$v$nFk|eJarv)%^rDO7mAi+5MCggJyp4HD`8kGe<+Of;XN^a!^0^F?e-IR7gOj-BDD8=t2mfvXqhI1s9B?rW{t^1lS5K+-$)5wJTDq5#8lVG zr6|eKicEXGa(zuPDtr>TDHl>~3Z|LgUbTf2OideYIGHjz)53)_DYx=Vx_1!2Tq{mx zTashUNN&{8r4$`z3}0lhx(*=UkY_?$ zi^I9^*9=)InhP#9kEFcKw)S?ruQZV<2gLFR6rz!|;W{@RhGDMdv6yV~wrzQHMGt6I8D6914+3)@C9$&afQ_+RLjE!Oii zDGiRe$w_9w?V4sT;vN=LFAo;UKZGcwaLo3 zPkqOD#A(W9u-QjGrDJbB71op23eAtMl!V+s*#45gF{P;r*C}7zN?ss9h?&qRA9p)0 zktuc_C=`-IJC%o2F_5?L!q4qT=)?RK%%Mc2lrjHGyh-+$vR5udYMYTk^q>5&n?c10+0f%4Tnvgb^NEz_qD)hSs;6i}wt6p_W$M%b-_*^^x z*0j^J6n0`&;{JKyv`nIhHb%70Ka67lD=I0#M=rurr29kw?qRO4+HgD~8F|lG5L>7= zr<|>T0vQ?Ku;;^2h>X^`s$W4JrWb*fPnCHwmZGX4#2PJTeMyNKb@B@}w{1=LIGeb% z)b8xQJ$z99tH5wTKu=3*h0?Vz-hCcvl2!X{%AX5&yKQ=pY&viA7JHVTfIy1e*HB zLzLh+vywbWfsH&T!Bzf;9Nb`V=EuRxH_Jh_6OxOQYbt<`(X^ema08X966)rRSR%h- zPE5(agbftA7uiX+#ddQQEfmL0k z24xJSS$N^}?8s#V+oK}6Ex|^7^&RNi^7N31WF(N`v|?4qnb*o2@oSzZKsz+Mu$xEiNx(&%0VKlpdb5g zWkAxb=N(6|A$ROrr8eL5<&^c>k{LPXRw^V!mpA>BYc59*d!uRE&)r5P-7U2b!T_}4 zW4>$6&F#rtCZZvWb1k#;^&$xWqr1iaU%wk`%0*pW@x@#Du0+O1Mw!WJEIQo9wAfBj zc@L2DGPw~dUJNqzd5Vj9ulU)FtSKTUddnBJYIoU4N ze5{e`eob!A0Ls7A>Q;Y-<}2?+8uTB|@^kGJDbwKhXHHlY(;dDh*lHMB8{$o=#$2XB*!(#R*}7h`X0;P?gFf zjv`odcW3~^1`K5b4S@t(_YW)C@Dgr27RR1=d~-51rEgxkd}PD$x_|14dhgFbn&KvQ z=6%xM@Ho3_sUurzb8%b|wdPH~BbZ{(be`z=rsNHGK_Mgl9Mx9k_i1L9GbsU_r3X>( zT%4gZ3D2HR+q#&wPcKXw*~5eY<-Rs$Gl+CSIfQhk?EipUF8dE$U}Y1RUj@Os^!Gn` z7*eI6*9_#)Yp8V;hN9lA0tS7mvm99ZFw=a=6|Z=i9Y6lMd7U(2E^4o=wKNjZCWOFg z*JXbjNSlz7B|!j5xWOIMtrPCKz1o+`yOsU!jQDuI@7q$?)Wnkp z!lipe9OwKP#pMd_r&{KmM_L>7z6Q_ey-23~I;BqD+TSsA{EbFeBK)57omJ*6?JDMW z%6lSZOFeJ^>U5S6cjmttEtOqx2P7#S{TFrrQoXF6UB9DfuUfGR2sKX& zWJPB`txtSA_S|R>EcoKOxMfzuF8DIWh$g#jQ7nM1<%i1g3%c=re@5s5S>s1?!H-yh z%!Qs4Pi{4!?w&OPXY|}wEryihPL4@o}saZ23hBcqazVxz+@5UkepU5 zQo7-=V|2BFQPEn6GE&5Xby^GM#CBJNn$aqfmr`XYoiItOo_|>chs*y9^TLh6D_~~e zJp2E_xsJDlfcx=5NRZt+)AYUfpoy)k{X@wb*wW@MY?45@GX7EYyum4LK_e^5Rvl}zJcDE(eU9sL4>qgCPXCT?}eu$&G`c*QKf@$ zxCmDRz>>1-ceiZdT>`q_Hb}{`jbd?X0QD>Hv;Pqm&DUZA{#?bk3VtQyqSkIw@eIh; zSe(%Z8?#0PD{N)a@*zkZOW7*{q+U`?ri^2hM^RKS1pBLub!%PL_mOJTNu&9Z(DU$l z!}bvd+5uXb_lI{WIg{ICr@!T)WmeLw@$SoC;iAGHKK8c=5323Y6b-|52u2ykg_Oya zb4fr?@h_S{rZ)^NM&-!llYuC5CUtIA^s=U<^U=B0%H|J6A2dMr)YI^@aW_WFn!x|X z7w-U&UKUqgP{R{Z{O$EsBHqfLvv#4%L|)j$;D27bb-GC&MT`;xu`|cEZ-4Pk-%_q+ zy6z_jlJesM)5hGT5LnSgyfYe#(#6_Ukbq-wEMN22vG!u^>PV>3T=>g#b)j$7FbP=o z1{NCi^h>D6t+4u8CEKqazLQE!6&>E0!btzAGR zghgHh5Sfn;pxe#3hrqr!a|A?-h=aBjId2CjeG9 zX}x(?w|q!HYCMbvzrW7SRpNQjYv$0MzQs?XuEGDG^6EuB)Hk_wZq}AbC4DE6U`u)->I_YZpJ$NEHbW8M zwcL9l?RGmmrDY#uFleczqWQPEs$Ff22K$leQDs)R6^m2*4H*?|Ntl>Pj@F*r`d&M3 zJa0XyFHUzV`lZ}17I0J^y>89$wS&*g3a(3v4>v8Iy@8LtW|2fyxlvbf$)r!Y2)UQ0|#gP%BZ=s5$T1{Fr2XS|!hHw(v=bZQ}n`eMbPGD)$d?P79Xa^6O5 zxEi~-T+b{-R2=G)!F1u{GIfGy5|qhz1_a(yw-eh0&&2GL$$Rr?M``Y)r*510GFHxH zD@s?u97oK5>lw)s4K;L(uN_~UcETj?BsET(l7!RJlqny1|R`HZ;GeeT+|BSf$^{F=HKc8)p5521p-Wob{3;X6zT z3|_5nwKcSCZm4O0I-9((ep`Bc>xSO+y7P1D`n(tkimbUO!XL`Yx>ZYjcG*o2xtkRH zh_6v#sAjj{+myn zDHzJpie_wPaso?PJhuP(Ko81%tR1Lts(8N4ux?TBm^ly>Iij)90zJ5pZ#QD$@w;On_a`&uR|q}Fjb|5Kx+H*1;n&R! zew%0xTt1+E&**?NQVVL;{r$2+D#o5E=Q16)Vz7%C@KmR`c0p@?;6{i3X0z>*-C6G<~@H4}+=faPd1<%YTK2O&D@mcMQVV z*M)!d0PWVOK{g^%vV3C7EfDU6CPyVeq_C_(o}^TD>}mT@QcI4>%*({f#?}h~DdeqDfxclvju|5tD#W%rrR7p0Gq?drh z@4V&_wLy&NSPrJ*XkZcNUK`2=sejBn%EUtGS2L3HA-b-Q&kWl_3ynONlk^(l^a8qO zH3N67kd)%)5n17Ju}r=~Kr`Q0ghe{d)>`}bgF{}&*Xf{*&yS!DuUwBiKQcT{Mz+O= z%BqUzN%t`eh{?mr%u5Hfogy-YX(V7Lx|_tdym|^6PIBN5lOH71Yzr4Q{~?~hkv$g zmqGlK#43Nap}|vlF7)p(V2$aYqys&2AAnKcV^He~%Qd%Y=N+uoWv!STUnufuq z9h6q|=X}|yi`N@4yJrK;j5Aqh=0H?L`=KC4!<2_FCYXcs?w0d!^+3VN3`lc zsDfQjjf~33%0h!W&L4yZew?pFcLH6mXMUgYK zsZT8hI~^ZdS)Vfv#LGKoAVgNDgx7>aeG)2hzVDtUjYLmvLAwo>soB+s(ELQ`F<-QhhA)9b#( zZK(5c!;RPZavC(AQ=_kNKJs?-rUNlt+gv-wO_kS7P?zrctYD)NdgpFQa!L&kgYyS* zM`ZgjaZ3^kOh>dJUbu$eQyZruhg5_rK(cv&Tj9S{3@FtIp3auX=-P4R z$S_N9-_4QXcDp^ePig|qtSq(KVUKB0!^iyyA%Og|cvi|wp_`T40ZAzwsmSnC-JOp= ziJsM9+`iwcgH&j1TqMzSKkPdM*34VWVqU&5g+RWQ{R!-umXpWQW0}F}da!pCZBy!H z`tuBj>!m7XqQCDY_+Ko$ZtY-fuW(qh+xq69bMh-S-t+2$H48KiePp^Dt-6Wb^M<)t zWw|vu{xp=2eSJjtXMy-NxYDXH8lDeNeOp`OWBj+H^Gl4$sEya2k-P|f&}?=TuEa$X z-jarvo?YqgX@{m2KO3G^j}HlvqDbRFQ0s7(I~MGu7(6+kcrX!^Mo_B+L!$amKWbUOW50ZbYTlKY5`TtjI+DznS4i4Z%Qd#g)}d10(%^hwp9a zzwl)#)l948o=Bs zNUi~HAZpS+@jYaSaxu9*&M=$64GJ%xNuVjglpH8~5!+J6tJdGDwkTLbFXq0PDKrd6 z*{$*Jn#KMAjy7tnTk`h=9pfb?Q2A+Y%ZE}RNLAzSj|9m@3LTf~*WXZk;UY z$V`Gq3bMN~&cel6Q5vTQRNBW(&4pCdioqq)w*U6se$RF@a@((_o@g-)1BVdFh5S;B zrh$y(4?16KCK!%b%Nc23*eBUk^SYz9s4imzAG8hE;%W`EKkD;N%}uyDacx@ZuB_Rpnbxxq3x|7yg9uzovJypHDba)QOUhwp^KWY~}i zrkiLQ?D6^I9M7JX+^$BAobVVs{Pj)iv;xU!BN_sQ5DBBaluFn^OGs`Yf!0I&&(I<5 zr^HTdE(19_P^oT>?HGa^=)AVz`_Rd`N&fb1T}X#qt0H_;#R>`$ zf^qtnsc&;T_*O_5NoT}!_bD;-O==j*c?Z{ee{-8nm89u6veOj=sFsE zb-k7=4|rvDI3SO`f2M={1G-&1^SOGgASxXOcG$`3^#5=vDPo>u8%!C)0D10L^x|@p zJORG*pbpoR5W9O6xD&Qhf%5VHo}8_)Z|B7J&kH$uZzS1vKC`pn+z_l4M~(*NGSJ& zNvp#11Te5www<5X@qTFasDQ%>%I$LZcY8cddB9?(t>76fwp3uol?f1i=?W#vL3OJ0 zzG`!T!4f7vL5l^akJU-4|eXlvXLWtMAXP#RfjTHAyTda5gc|vN$uV zy^be%S;>w4yq9X0H`Cqnk?agV-D8NU&LzwSdo!vvuVS1LQCd;P%v!yh5^|rA#Q!`a z|LNp;Bh&SoGxGb={c~w4WG_qEr?Mzz@+Pm`-ykszSU|Ymle^eA&g$eLmfkh(JFeW$ zn1rVBj%8Qk?Ve(Xx<7wJ^v}HQ_BeN}6ltiRvZqOCuXhZC0F9{v;#)A!{zYaO8qxpt zofF~7Et}?%7zHa84-Yy}@#MVkgx7cJb?y6xvNx6#ui&t*P-KAG>9^Y=X}K64qp~~? zE0VOjdc7N*)k_^4lGwZsmH*bKSOq0MYJk-|X~#_aj;KJPG&)V3coXLcKzscT5WRLq z(Cr-z-5RQm>!xZR`XOt@P!N<&Al69<`~R`^jp3PY%eEam>Dca=9h)87wr$(C-LY-k zwr$(G>9zLWXRmYaukY{sji;){s4;8SjNn>RKi6=`R_`lnM+}TqteA_)|3-JU+iufi zp}z&yXN#T}`%#GCs<9DbFiaiDN(|wggry6_DI~-FOZ<0~S~T|(>CTTm?E8UGTxd&5 z&aWi^)SjLjzH9?GOf*1xD*CY@znQ?J+1mac&&@pW@g(v?F#B6)~sxj5Ed z+=ktA1;B>iY@H?dwqhv+95fp$zsD=(MpbG1Dv1v0z_qR`u?mEqV7j2-_r&7leKXA$ zyomUd>vSmpKSX;!Tp&)>M903DOUFbUqqwuJd)k!LWl;{zrR=j6T4Y#E;&OSs9Lc{b z-%d?-+?~^OK9zg5w%xtti@hfpu*^Tu;L!rPL7Pcbb(hq~l)9Ox{Rj>&y>`hb=>3I? zR%YW~)RiQ?Hz9@cjG01PUJ(Ij!GuD(Wd*gF`AyDpQQKbls521;l z5+Fg7RR+mm#^n9u%k-}GJI(t13GnWR%i+4?7bKN#)(|D3l7?$W{2O%*@m3aln<>D% zeIz{@xPDiMaTly%x20jcijGxmYfRi-fU0zs6--G-{?I^REZw)vX5uUH&-RtQ{MV^R za>x>-Z@+eUlJO9L%>Gubjs5byeKk%RU;Z9Ru*_R0Quy6$G-~!!z9}kUH~<3~u0HP* z>rb4X&42t>pE9nsRlS`G(IZ(ADvZQ-o6PRKotcc%loHGY;N#lXzCU&&kFntVg z=j+BN#N(>&za+J2l8QJgzA!ABd+rS{N!BsV_fluR0A#^dyp$rUD94jxgSeh*qe}z! z5##7ahZTlUlF7?-Vj`VL2{K@YO#5XCg0#+A-KPnJ!qX--VVXFJARAvS->8OPO;X^- z;gVH57ZG`oJgw18Xr9B78}PQPu$H?N*}YsWBi68mpODu%{6haQ> zm2vZCUkGOv7c4(q?SJYqm%T82GdR;g+8~!350|uq8(m{>hTtA9gGD0Y$n&8lLLBjd zMBJFkdYObV98p@-BNO8VZ7G??zI*c^5qzU!vX>`683etm5ofC6odb@d8`3N!uuM~h zZ{4tXZJ+s$+H#0GtI~5A<7aUrt><_(Wk4o;*G%$*94TTM1Pcfumda@eOhwQxe>%%^ z`=FMa({V5a&hu(Ai^XQg58$qgRTy;&>g!}S+a|&s5Nn6^XMjMPB6~L@QX5Nu_t$_G z2-s=`b4?9fxjCxBp}`YT8Hk)VT|>kWZ}*=j|NZPC5oS>0iri?yo zNMP3BEeo>m(WIgSxEON4cHztsef^=+(o>41o`x{HCc>bSdwq}ZJcD2;L&zH7^1%Aw z0XuF%Pu1VLKxLpmNn<`Z(1yNo_TI7;qNogBlD4S!FWi<$pQ(;xo95$kz(`ix>q2)m zQXw7@J`4&pkvdl~DIY(6br~OLg_3Vw{9YfEpRC@Vk0ExTFX1-Sc~Xp{tV*ZgS^YR2 zt`kIGrmqVj&#@iuz4guusU7Eg3WKTMk>RWsLyq@JcnWQCtuF|oTT0f)*Cd@& zS+|e^R{gX>UMiWY(8Y*U30JC8_CFZ@AY!g0PZVyhTj^UV0^#$a%J)rK-9Y1j4n+40 zRHMoVu!Nf52qXnd6I*>2wKqm&D|SH%q>{=xQonY zip67$K+#mnypl@pG#iaG9f^tqA$hqTD@M!)Wc*sfqXUIY=_GlW&iy|xQTmd?6;e4q z-LZv)d8BrFjrC+GMi?W07qfk>4PoU6EP%W<<{Jqzt!;@gEkbYcgV^@*L`T`0)7JFx zYY>4Aj!(gGwy2_PPMi`aW$!ITfdx8~^ya5KqPg#^dF>&I>iF#2%R-&WpW?ReS>=X2 zf;g5dq;os1K1rg;sD{&boq!Bst$sr)pS(x9H+OLJmn(TuM<-x+o&Z>Xa&9vD1u&0J zuNSKyg5cI%$Gu{?Xwj+aRT?^Lm5vDKlV_|sL7&S~ue102FFaif{|?U@mp|b-19VSK z<*g6`A5k1nE2~?gp3nj0eu4Q1&wXE08;<@8=NaT@Pob9pkMPu8x$%$%t&h9LN~?R_ zQ^(~d&g<8Gi87Opv#!$89{7T)r6!)KlDf9)Fi@eWiU;aK52+L@MFdz~k0_hkG`0t~ zJlJ{TVffLRKylfi18UF}g*K32ZhD#TxYpJ-@d$G6;Lu%_>GBeyasko{!Z?01`gOOb zrOC?CoLz-^AZy!fIFNGCEt5)!jTXdHp&jY)QDlOv@@<9qL&86Q^tb5>zvtN&p^mFx zKEBep?}+@ylR@v4|*EX1MF#y zSu)`v4utWB==$b;;p|w2;tno?8N*I$x{M2u=b)M>QZ_cl6@I(!>Lfol>~bdqPP%;1HVz9+G{`+Uc)r z0I-6IXqp$WhBtWokXSVN;1}0i*W64%f5Q+O>qrX#`;ZY^xAoo+#RjA(TA(@nH*YnEde-0CNQt#?6f~lRvCq!&OF?YQ5 zH&)WTZ_|7nEhXb@Pjf%|a6baXwB5C)4X(%y@|khR%cQ>9EfGtnW!i}+B$y+8u=1Pz z?y}{DW4S2wx&QrzYz?)k<8|;zDZOC_VBEHh(F2{<$Klz7dv#%`-pltmy0C&ed3p3r z-R8;hN!s64%xAKmU!+eZ)TPe!k0?d{RQK|yBUU0FizuIR@}Knhmv9osI%Kg@_+Cqw zY{wFAG}&M@;iPIrJRvUbe)e*ow4r{+z35Ty_UB#GlM}ObOH=^}^}e|xDGI~tdT8Bl zZOmQ;@M=XY&5#gcc_K-2!8S_O?7BfyyQ-LwE||GL=dS$_;|5cyq^Z-hT3c=G z69a5K+s@Iq6}@*15V#3smPU?QgUB>h>jS)~Q~ky%QGNSwx?0F)3e{_LCHeA7WV6}y z6n`E+TZuBd5lJ3Yb*|$8mPID|n)w8$VM^=^D8}H+8EBK*7J2=y>*5=!)D)E&{nA$d z2;o4;!!9@)LNfUVVgD3cJ&HT*ZM!TMg%v3jd9sBrc861)sCK~sqsfen42$u)m2$<> z+N-Br)QZiw^ZY`vB+XUj4$9w7%q{E4I$YnV8v&Yg>CL@N}Z&Iy3!nzP;mBnuJ)cqi%sjdfdL%G=nT<*H$N)X7?lj!*# zObdyO|9v_X8{_WDK1OgmY#$?s4==C2AVrOUejlZDq+C|)q3A1^MU(f+PAI&<99vl| zeia|MChzuCh(FqT7~ZJ4q{IUOoFs`V(4)wDx{>#}mj5!i6*N_l%?CT#qWD8)4NAuM zMfFIA`!ah2ibw1{hg>!fNbCi&DB*q6m8~@G4>`^!TE%vtK8I@K^lsf2q z93CE3GaeQSJV|Vqj!O63)z>K6hIWiv5WT1E^;KrQ){VHFJPu#iSjK1W1LNm@t}J>p z>7Y34krVWjNLpvZBlK1s>2+~BMiaeuWsR(CG>yNmh{(Ja#KJ08*7O|G*&S={`{fvJ zmoRt6Uh{%Jeb-Fu6=RL12Vw>37x(s;1yC}L>ci(#xGupXC(lOT-&?pl!%-Kp9g8vQq|uWcBBo{yfa@y5 zLEvAucUHgOmq%=jY;v+JWTvHMa60Z-uAYOAH8<1 z6k^{z&J}nzkQa2kSPQFKdGNm1#N|1;`z+rRdM>JH8SB)wM@dD}9=T>2-__`5^98J7 zUxBazqfiKu1`e<;J0s8eqhrSaKJI;M<^fn2s(|6vtwoEJE_Ui($x;I@A&5SO;Fx1j zzN_afbSl!&mNJH_iUMLdw-DH zw6V6dyjThW!(|KN;(pvZ3$gneh{@Qc$FLQZsxP>UN96d~fEbpN(#M|9MH5x#JiUu3 zlsL&DycRQoP;ZVLJO&>~Elxf)hVfj$rgu;}1ZCvQqXKiLm|J_P-+rIp%-qg zEMFteJXnD47j0WRGa(7VDl8zI5WXz4b?xZu@QI|^KFk>p^@}!U-mC?->B_ zc4}S}d75)JwMB#@LrKmi8iVvTn~K`T%bE{&J*|_|>)JZ5^VJ$07paHm zg}?o)d0D)RFf1jyuhkdG_}d za_*XHQKmmZY#H&&B4^JRHMB`TZ=iqmM zb72aI|0&j%GWRLuoYIv-0A-@#(TUA&zl&hAXs9Yp?*_Y!a_A;9bqC|2R_G%sOWJ~C z$F_W%kL`Av?Ph3085b?7>?0@MyW*TAsj1rQ=1>Q;)J{8?qOUDyu@59W=pkjn)J*}* zEwBqc0$%+w0G8H!g5t}n+>rT`s+|D5^GS-diDXT&ECf5NVtEVbJb}o*GqnP~9Wx^b zPSK)Ij~d%cWj`vmB~GNq%YrGR0R4iIaf64oO-cdi%?r+FKp>yM$U)acPombq7Ncw3 ztj_Ct;2eOY^Q9}Qq*g)s{oQsE{qkKnhwN4C^Ozae<*{dNZN0V@@Wt!#NH|!lKBMiceb;b=1^O4-mqohSA$#`pHwMRe;$;e ze0Zeuit@?Y%2~uRc@G)PB0PRzICF?&TZ!nT_ep^=Kh_XyPoMvG!YNJrB+NN-a6YZa z`ybhCKUU;XCLV%2%E3o8MlAQ>C6cJvgPT30A^Bh=Y58JX)xo-hij2HHU; zH=LJ>3S`}p>LJ=nG%tM@GM?;-0&*zX+HH+9+>V|0)*U$#9i*$h+R=FP;G0zhdY_xk_DdvZzLAEi zqy4&b<4r2dZBP494>yzRaq6rWj{9i~Y@&X0JToJMon0Z^y#CGhm)CB{bBhGHq-R#umP|>1k=^>=;#WhA7Rmx!Zqa=LQ{ooQyJ8Xsx)Gwo;b1x02_D z1tcx@9~qm1j;7!^9TiNGf4-DhBdAIOLv!ek!*tEBvMRQiLrjCSZ;pmT74GP*YkPV2)20e?AURRjH)Ob>lDLY019hqaIOSq|^iJ z*W}jQ6HLe^<@JIXfZhr^imsF#r`4iNSu&Q4X;d(oL?N}qIIY8EPs&_%J{{nGJq6p~ zWM*E>Lo~ka>p~?CUuJAP~1hHRupqD*49+OVoBTnG558W(^jSwvkLZ}nr$wSU5JssgpizMIryy_emu&k8A_W$mwOdog zvV2=uz;(agjlwn^o5W7@Fn&1mn>m7OSe0`{p)#B|)JDi*FZk@I-GLD?(56+wLj& zv&~cT6M3*MJLiVNUc(wD4rrQ!Wj&jfd?7(`i-rEFB6N;^Jpv2-H?Z<1+$z%fNF-oA zLOE!`cB^mFO(;g-=Wt$I6TM%1whP%mXYadLY(FspUq(!w>cbYqPsF8p7Ry~qS)A2A z`}bdvG5Q_@fuSa}h{$snhrkN;JH~Kv4PH`!dq_?d{E_j?(3FI}v)o$LD8MJrLq?m& zh+bZs_^(=*fwb1&cVO907KXg7sHCzCI$sH*hvQ2lZyrXDEZ{CQ^$9{_k)DM90?rWu z6s}kAH-@(mkwtqVM@0n?>2kETjNRPL7M3wrqiGdd^s|EfY(1Fn%?R2<%U~x-KK1eh zloQN&Yl9Et`~vvl`ZKGg6K;m0d4iqyt=UU_Y=n4yE;P3NM`I@>)o)0i0D-v~p6Ze% zzD3kl#&H>zR0gV`&R$rPvJ7iu?8s^&H~#HvY()B*WU5F`F||Y@HAUw>;xq|xV{qg0 zGwM6b>d>Ob;K$k$6&|?t0^xH08>KU@&O`l;G?!Bc=-AW#}dii=vd1-7qB5bpI zCcK)u;v>+y_(VubJmuHC%u<+i)mzH!}L zH9%V^-{I+L9hkPx=6|_V8u?CGB(b-#igUGF=bPfK=M4{ls(3s*HN-MXyd1;a8rVw( z#*#na7n#IG>Rvaf&-o-fMV9<9le7i6e?Ve#=1eGALycadZX_cKxRi&NjJO2#U9Vb6 z*bV~QTtgkJaoKU^bw57BfFB*u)4=n|(v>zU$lEcf(!Jj4p8M_L^Xj^p9yi(JZmd5{ zDO2VB=#l&OthOc}qf1{r36g&#c*JD*Cve4&yI4-y-ZAoNw|Wt3@ zsgS0~*ayR1!XgamXRK647Q2NG0v&P$@kkpEbg$fa?8rnh(*X8Ru3Ur+u19`J#f1Q+kZ3?n8;IzG zQ|68>s8w!$oF{#(J*soue!y|KKBvqZb$Hz`8)dmXjGWY@Z$sUzEfdzVVjmT+&NDt; zx;$KLm<`;L&20ovRBFW!SPM_jyK~8uC$l0w(=`S{DwN)vK?W0)hJ=5DB@zKqAFU_@LDO)FZNhW#fzg<(?Tf&t^vQ=gTkr;T&QPP=K9 zAu&)_WxiN6vo3M2kaKBcapko8Q5 z96&%y8yX+z@e1UI&{e9=#Lb8^vKK6%h>OIfF!L&eEhA)Yb=I^E$DY?v6d!1*c{twR z%-EUT(u{dN;(A=Ges)E&k6sMm!QbMp*gFrtPg^vv^!Rm^Y{v=lq9b*K zQ7ry|xQWD2gE#|f)APgNnNtqWrL0t@w{|y}yzO3}Fz&o0+283$EbHwiE*K`KeONXE z{f=-23JdvG1~jyvhTnR4lN_u6r}vu~97epEZDxy<86qmdfr)Yq^1kcv^B4<~?g z-Q#67aH|JYbWfOJV9GGJRMI(wAx~il3qo>i58@C35>Yb$!U*y!TaQ+@&U06grPYK8 zqSbhe?c&zSl9|Va{#Z&rU;RCW$?a^VW4-0P#xA|Lv9#+LO$)#TlKa7Q(Cs`M6{vz9r47)p!C_#i zom9Sr4eoA@ICYO1clE>H4%^i};rp+h)7OD?3Gc^NQ1s>zd@Q?KDoSM3Tz4$HZ54Dv zbojC(BD2EZkj>4U7!j7D#*Bm5De0$=jg^stjj&vg_l=$}0fUAp6CC$G^oIx3RGP7( zS}Oa+UdGocqla%OOSs@iD09XZEnx{sv%o>F?d`WnevyApKD3YBDf@ zA$Xh#puvq{^38QTVw0%BRYwN6=-b~M8=Q8lm+22Rt=1P&ir~jUoiTxfXOEUq7jTtP zu$Ajr?)QhEW33Z39JUAiQ4KJPvh$DGAfjH+oxDw4a` z<+kk^vx$%%NG?TVLj{=aA2a!?KkbCm!3EO2vTq_H7%R!r`3Es#tVQ0u!zKwiw|jsp ziq_V$CZ3vr{P|vbeFUKFk=n8wT;~qI+DEdaI?`;Ksm>;O52%M?VF&&yCn8 z>43MiKJ^V07KU$QVf?BTo$A3S0ZaOXjbQz^n-jNw`@q7 zb4AZ8y*wy5NR`K>Y%0WkOUR4EEcbMTcrd$J^7-aRv{+<=ps~Td#gnsILNFYwON18F z;X@(^U}fW|ue0`~ z1C;&3$_gs#8&cJ89@i;is5F%~jzdOJ^*t1N~#^50c96yv~kK||YgDfxe@toqa(Lo<$pv|Yj5a7N${P%d3y2JDngcT1P+ z$+xA_PDlI8k5ZaV+?Rkd^ML*J)3HoWTRQhaL3nt#m2PaD4%7qAme)|jb?7ztWb4|L z)?=2wrGUB_NkG<9@u_Em8c~F$gpmR7{O0!U?g@Vqru*GYZ<22X;b^@23cM zei`s$o{6x7-MCf>-w;?cC%UO&NLDiipFBIUe3vvPZ&rE8GynmY!9#RfEV!_s1%U)E zaEbw6d)MDT78Z_9?$cIRxj)*YI6NH>^gO>Qz%-Mhn)oG&msM0~HP^TbI6uby>R6M` zt-t84f5;!pIjU17L_~fel_kvxsqrk(7OU4iklu@UcCpi{%u($u@Fuk{gNINz5+u*3 z$5%SAPYf1u>rG+C%Rlr`x6*KC(oCHW7x=$5;a4w5{PQ!CJF)3(ynQScX|YVY+}Z)*Ioa%2VI-?d0mJ{cF&@y2iY`hP{e2H|U+989w** zQn{w()SZp_fKbpUXGVj@?qf$wxT+3kyiESbH$HX}H8)*O_ zoq<$G_5k8>pAh3r2lb&Cr5T7-QTfIkieD&7QTO7vQek+)Xa1C|B>Vr;`c}RbiOgz6 zj>kE}WFTJj1&m*p zD6wdva>p#`G%b$PlR^YOoT%cpY!dZ*zz{0_xmsypA!skuDX-wk$pEwh&JuQjg*FuI z5Ug_Zb!8OH>fF3XqZF%Kp_gw9LrG)@wZ$UvOzaG4e zNZ5bgd`+@+zn!P)a53wWWU`8GEv298vy20_@YDTLJ_4~u6uJcwx7ZVwV;<+AVBx@8 zuYfl|197WY+x_;he(U@dJM(ZPw(b4X$w9<5V1aC5Hr}lQrFHX6qHF^uvz4X3mDa0STr zvgyiAC`#BF7Qb4fpXT}SjV?$zdH>E{GM1o3A`jC{>Bh1_572PFjWk>7z(2i+fXORQWm{m<~{7fl!W5o8IJ{z~)Q|54FDvWbu>uTmjkf4>f7oT$T)N zwekTVNKswu5g=-_Q!yyBG_%uDvn=)3_EGM8)ysjj%qYl^)I(Da0}SzG3u0fG6HDW* z%K?9lC6FxWLmWakbPwpqjb~9Tju*m?a{{FEKB(XR78;l#jX5yt+?a^~lF7Yfyw+*V z6j6Iwm=#?$%xiH<=RZ@b(;4|CcT-TY{O;T{mJn(U6xTqIj(zdQVVDaQZ6_gia{3+y zm*fFEpqWmj2WWsiylNUhX&f)#!WuuO-MBnoilf@CU+OTp8#`OgT+W*#jF_33n39x1 zsH`08RMnze6)=9wImEl0V4p}*-^;}F#Sj%qYX8Y)0=cnCM&$fH*m(gbU?0B0R0Kae zW0my6M)BkV@B(2ahV${qRn?kUQ5%u*+qPktb5dvie?n@U97M-WbDZ}d&1tv+ylUzI zEKa6@+U@S3<6xm@`Sk$D&du8zNyly+x04-*bBckJCR6VfB?q`=&(GcRuHg$AtDtK$ zQ~;?!MsS_Ey>dDnVihf@#^kxOTp@26PCVo*c}mo8865V|-sXV>%6QBz&aND8e_5$6o?gj; zD_{KyIztg^K%oJJER!9TgEWJWwu>fTqFeIH85Fzu{nn1Go<>prR0*3dAd-;)7{5r6gcZ5AsF*0C zbqjC?k^PX!!gG0fGj6-B81QgT%;N~RXHNUJ3#U!?1C+wjm-$r*MzeBx_c~6Q!#owO z49*=Dj+tK_*(@&zh+h}xS#J;qlv&8{eE3S6?#!aSqp{P=?dCzu>v@=Dl7=#!`}3_Q zRm(ngaPY`K**q+7MB|N~xDI)$LXWsn- z0&In~>*z1(Tk2L{QGC8D#byZ^V5J+$c0JoYEQ!qBIbxYq1a}A`h0y5ZCZgec^OIHC z-hnyA?D)Gp2BHjoC{a_SLd3EXh15j`D$z;)j9nrmGpJHrPfrcPp_`X6yHl^bORRNV zP41RKwuPjptz?h;?My9_UJNIeA)nffZtr|c7$5Bvc9W*-W1`dW!ls%VfG(spX&1{YPTKcLeOhAl-@FWkP)9g>R7W?2*O~yBES7 zYYuBK5SJAWl+2L5czEr3zP$b}M*#pHYq;i71`n_=@7o_=qZMAy`(BTjUiWXe^oNrZ z<6|Yr>nq0tHmg>}YAdk9>l+W*2UoCr%v8;4BM=qEQ$jM3j4?Pk4qJuUjwBIeW>SpY zG>8myBcSv6a`KgA?Y{gnNx)Vb!pu&pvKtHi)d{8vnEet0TN|ZBZE}~%Sgb-5^!d~l z2>E2)i}unnJNOfmVr*pN^0j&+AQBQ^U3qtjYCdFNT~W3R96qMq$Vi$o7YB2r%ZJqG z?5Fkp%C;KDIII?`xbyFRJ0pPUrmMmECzg|iBJO2);wyWgQ36XTAkN%XxveGSimUTC zQ>EA?{;gvKK^^at2r?gAWR?=MyL~{B8<5l2c41%ZB z~g?I4q2{f$uVqNvB=xC9}&K^-SoLQU6Pq?=Wt+-g;wnaj&BKkdH0-RnLo z%j*%U(8$n`i-q0oI(H4%tcB%KE!0@(aPHgy7sJli^g>34wVUxv8;WKV%aUA`2pL@z zp~Tk*)seHFTUE{i|4W5S93x|?>vYP~c{uW+#xFytjkv_{4iPwrB88TI7trps6~l_l z?O(6X=8{YMv1eKYpcq4dagaSWS-3?nlV(`5{Bz&8pkVm^2-q*S9S#y86;w@S&Hxr; ztl!bj)AJ&r5a%`I~Qc9x;;|1M1+0;!qJYoxJ8$dTGYb}51KsV=C_>(nBcNf zCONl`#j=j-*^;mRjb*ih-#^%E6nc9#YQ=-N$)+oLj5^Wi!WXZ$!v>b%2=nDlp5-En zGJ*w*bo#D3?{WoY1v=0mlT+ZK*omRE9x{ABn3*}q+{Sw>ZA1nsUyCxFZsH6%ET%+v zG&;GN-8|5|4-rODjiqNk`+ZG-`k~TLH}I^ALtQrG&H;!x6)fvmA!uwq1xwDNDN9)Y z#nf}ZPJZ?3)y}tN_eAY7wbqjamK%Dxc}&jBpDrSO|0;?3O4h>22UC%UT#50wif*?V zTsL+lylrEy;*ron1!Mop=s!Nj&sgsNBeAPW6zAuPF;s4!-hw16$7srjZM4)h)3efE zub!noB3`XJ-ewlM7f!Vd*dZ#V4lTq3Nz60_;lTlz_&E7Vn42Ozdqu7B69W64i52pG zjf_*`!R6-7&WoIRil~^wAneSZWeB6}j?vznkO%ZTS5R;)wgg2?Q*ya~?=+EItR45J z(W}KRnJ2moOM|XS!(j$FHvnJ$xHwgms^H{*D(Y-x$AAM}WhTos(y+Wd@ASBei{gBq zzK!y@dP{kPI^Jxoz-Pcv`1%a7^_h}cBzEYlyVmMDYK5>y0!2jiqQ6slT!fVu5!v(0 zX)fm!E#0IvEG49xe^Ce$&(^cZCc;Wzn~l6%hM=zFa?MFcHQ#T4Hbu{u3Z)1mDjVg9 zt*8A4Qs2bRG-qTQM=AmFm)tQ<$yi*=D_Lo_xGR?LQD;s0vVk)9JK?fOP214#D!r*Lzr zA=vN1QGAEJcAAzFhTLR}xCJkA5o-S&Smc?vbo-j0TN*q@5>YYAwU!zHHES<%Xr5I_ z{wJN{LPJn`68+7WlEO(U*@WmD-|$Ip)iwcWY$?DJNx4o7eAFF9J%=sQl6*Xz_S@(; zTGrFB+|Mt)c47ih4GoQOJ?`EwKRYg8{WxMwMy#Y)`;w`xD0hQaL5nh?R=01+;u-JL zYU2M3SEKuit6hv<_};{f2SqdTl0S|x-{1Ax~!qfzpV_o!0mq@TrB1yLX(^7 z3{~R9NcqQ$t%IhX#X> z0rqtGRHk_niBl|!luA5`h zpIKAIN8(q_es;NzVLs|0RI%9T>IU|CI?sKd)$XQqaJ>wt`L;Fo`nlB~hHi8cz+#EE zB__@T;v|qGagl{6PmjcXaA@KSHP4yMC!udQGXW3*K zhDK^X(bm?`+nKO5-e0y(7U3%12eh7^oIJ1IUJbdJoLn7k?#KE^r_=9zv5V|`M{`@; zm*+&jU=vs7wIh6${j8> z^XKqS^d1VuJhJ3V=$!d?{B4>Y;-dVLGp8PP;D!KGSTq?v42XQt6{15cC83j5GkR1Q8V z{Ve^ED<8fT4gH|qU8v*$)Z%aOjT-4t)hA}L7pvB-8%KzC-!(2ai93ahe;}jyx;cr` zEkA_+vMDKPynJq#H?KepS{1dea;Ul;Syl4dVR5*~jU5cQ`>siBhfd(m$X zk>UmEr~*gom9_sOLN>F?4( zp;&w!gD{oKOYgYZp=6*4eU~8P+wffrV8e~5$wU!V{$g-Bu_V? zuh>)5p-|uyPD$x`Qb4BVoG9h2Olbd2;PSWKV4U%Pd*f2m`ud;yP4N;wir{fJWGgrG=6v`voJU7Pt8Nd4l@!)XH6L{c`vAyc}S6 zdWiD;0wa;kM!k+J7G)v)2+{1rT((g*IUoP>)4t>V!DRivk!qSb9+vt}Eti$hlK+=U z^LL^?Q*^cy#*rP)GxGVAL*l~bnWv!vNv2ACll~VaP#jQw={_9`oRPOTURsX-^0s&d zEX0dN;aLPF0_>NfFF%H%4!zuO9!}e_aU?7Pck#6_KuSQ{f0~6~n>x_Qg3-nQVznm@ zt{NI>gbU_cy12Y}Y!V{IyOvZOFmUNz^{9e<(DO6*bF*9zYxkV-xO?M6+qInBtsJzi z$baU8E$9c%xLIc6&Ej~8+q~ecYAL~^iIZEnVn9PeI6+F;s|(BSd<=KCg1Kye z{}Oq{03H@P+iz=UFRWf;6~`dhCdLsPcR{UTDFv8lFqbF!r13xQH*GiGRmq%Zvm_e- z4k|au0okl}2xL3;!2iK111YN4ue|Y;xvGAJjf0?`KQ2URJm8k>Cx#}~ru=~od1%F7 zCMtdkOC7-vvf8qLn^<7I)*>X!zOk~YSj)hF#aBK#qnd%KDLL@u{qu9cpy$=K)LW05 zQl;dQfnmDXF@Ob+$oG)umhZam6e~gt^|rRW{KpaQa#lY|d2)CPJyk%JOao?MYT_9a z03l4b&f?uK*xR}@JZgGKLr5@^Qw9dbSF0S|4QXcXtA64o8#ro-tWlA%Vl~emnoaI< zT8$={q&$f*L-EM8y1BV=zKauo-kf{g4SseFZqnCQT~*(P*`;Pf9Wv;gG$m)bQObH} z$E6rrYDeg;3&b8|pUrs{`=x47^A>ZbSz1W4wJaS!B8{c!`^DnS{pGL-oU;WKH~cXu8prxyJm!2(sG}wX=UX zRsTi{F(x$?vb?-Pb6HvIYn`t7^KeS%(@eJlz7M{nG|%zt0EgRD0|Ve`T_gLJK{TlG zgZ+7>UBRs*grsCc4=DE0O~6w9!8DSspw5FfI{@+~=9EbvXFdDc1LoTGE+$sko~>Fu zAzs>s;a~%XV`~jNcag`nI2}RB81<=r4bGa_qIbmg687_~Oy&=UUo)ATT=33ZN;3ZNL zVG(Hys1{HeL4ZENj@Rt#>gq~zD!D@tqMTedHj=#0z0BdZsvv{`!^%kP<&)Q(BTQL5P%o4dJM8Bj90IjkrTJxBGWL$|Q zwoZ~P?_-}C*SiOgrYrP59Jg#b$4v~_O}4M2xOQfzj%TIK_vWK2+uzw}^QFv%!YER;9eT^qQ$NmLg?|VX1Vc^_6sc`|82JJrgJ`H5-9d{j2@uIqQOd#2dKT?SGvZ{|`T! zmdY;;27W~t)iafm7_^Mp02{G-8En7&gVWqJ>H}eMsy-8pH9%sb-^M6I89^dJy99nAB89x`mr+ zlZ;wOTE-rxBTz4fkIsg4$^UO@R`1K3qO`92k8@#Vh0^kfW9I}>Q}Q2~qnLuQ(qhd|p|S6FnPP{*l%l$uc*vq$c~~xA zw=n`h+gRJ$D9o@1nqbguGU2peur?WUduOHL7Y4E=C z!j8n;<9cT1ZHJ8~>iN0WRN`G}aZG74UZ8P~u!O-Yj-exK58Xpu(LI-YIn1i1{*SsX z+?1oe6M{6Jpf39N$>f*BSmEpFy?+RNg&>rI@e}_iY*cSme+?%5uf~(S#D2}eYLj1= z7-wd2ae*l-*=_sI>*G3$&DrfVp;3@#9np3P=`f!r_cslgQ}}J^t+F7qH^aaSz5h)? z#LLsKP#?;nsDu}3dJ_b2y)|iE0D-R;80@%$>Co3Q?;1$raHK{}+L#cRsbfH_6Ng;VnOvK+9N+Fou8 z-8G>RrX@Q>&~)|gW(G9>UD$NSCjTE_Z{ZMi-*gWv2nYyBNS8`?Nw<`AcXuyHH%PZi zcS(0Qi==dSNp~)_G|MQdp0XUJ+V&Z>1VHz=2>P#^XXl$Xt68x$nel@!ruQD zcDn3*v#QtvbF%EZn|V=#Mqjr}yd5OV(U8OK5x${H=kKy9DJGUsVxTQLz9xtRSioIq z@VvcR=DY3a@9%HxZ@Zbj89nJ{5mnI`qAe*pViX=4!tt6?uDIa9}8blX~q<#5&yC;WZX9*PB1`#YbH>lw+(hO5zM zn-vFUm>2e;tyJ#)wQhv*C^cZ*%%u+lMRVxz2a${)rq@3;bWoXgoY{~%2WOXbobb6V zLRLhmgV`?SXd)W#TbW+#g&J$ziTwK-*UX$~=GswNm3^F7tW}@nks7>`IJOotP5erGXX0c5_-&O1a zibZYH_Fl{j_E501HijNOvkZ03y6lb8dX{aeNADVlAxa0TifJUh{m-|_o z$LVpx%*+`~_||S8Zs71>XJ^cMq^5dR#ECnl?_5I~f+7mcGx^#rHh<=xTxGcD9hrF9 zJi-OzzQKui`%mz;9m!yvTze<{U--uPsed`;0KkTtHcU^Lktj@!0a4mKwG=V5d`lrx zx?r}lT@Z~?Y;`_B0truH<4hNu?r}~l9`!y+SE;y$HK#zlTQgH6EAb1{a9V2G@z=X) z9k*cGA`KTD+OJ*m^;4~W_{f|i!$GB%>19ZZ*vAJ-;Ux&&tJ&Dl1fvLeCX#h7YUsSY zYO3q#=cC<`(*=XJo6&WMQ~X>3s-;0l)k-a1Ax@r3H zvVJb-tjj5(}N&oD+9(b0W@p6WM&8VMAJL$#GPkTn2 z3n!NGJr|4nXh#j?$@V}7ZDH>r0=2M|X`i^uT-13qlDLkDz(JO3_E%;romjz_j*zW7 zV3FmF4X>f5HT+uI_0_VD>&-2Z^LWK-kL})1JDy>QR z+Z?ZmW}@S2ue>Xc&&BD<2CvLM+C-zLBSw2+dwYP6c{%u z?ztFquo9?Fl&^l(LC|YbszYcIStOO^YgZ2`hSQAAuAWzGjs^#*=E(^V?wXg#wa#H* zh1cnl?aqnsbnANQeyhQlO+t{PZ{Pg=P^!xjH(N{6}!)O zPk2yCgUjj2b_ON`(~);EXwJwHf;xRA|CnprxlftQa?g&O8i88T(exggauWirv+<~`U%nMJO(I_;2mE^fpBTi9l5@pVfKf0bJ|16q7^oDz3{qzPlH{|BIp zT7rjDvI;xnC{_OVBkWME=bBEf+f#k5n#0DhB}^>jR&kuSM3XDAwmvXe9)V%quI^F`}XRYYEdE{yNwl56_p`@&|O4J zAFZ)8R}uvlgL7ckpFmX`qnfjSSV)Qb5$sx>kkiKrgLwPgIOlVS_MZu8|HlB5PiSH7 zTuV!IAvc#$4J83KUlSr_#LdAQUF;$c&+pO1Is4!+{NIz2#}GNi6mqEKQf4dd4)LCS zlxeyk?*c6BUL?>UWl4?K8ZdQRpk{*CPLxFC%?yyOg>C!dI;!*wax2691tPZ8D_R&O)6P^=uZb;BFj=H_r2uLA5 zEN#{mT*GJhVAHzT5Vyoq8gJ=lFHP835ou(P|FY|cp#>4Dr&2cdMNQCe^&n3Q=nAd| z&;4qhOZ3QMp3m0Sj<+}iBUoqybp3+dJ(xc{(~m#5?_Lge*_mk_F};_IB5^R2f`GW{ zwoKy3=xy_d4(Cs3$~A#=xBHnt+?V5oKI*nb*i!s?WyP)kFHC~013a+K2lS3{0m&+Y zeBV-W@&UQM&PBcM@K&=%Ovk4r6R+3X(6UUqsox1bgLzAWvI7-vy!Cp6SkrsqSm3Ve zi&<5iJe0}j9nGvf*@IJ6zZSBitXqP~X)^6Fg`#PsJt^#i4N3i!T$g609$U@eYgcO71CcJ4zSgRvVKRhq~>kg(i}4ei~aAl-aEvUi(gUi^_*g z`u$IgL=H$)#lD;OE<2S2n|p{bkbEi#=GNp+icg~d(#tRU7{?6%G57yRs^Qem{@&Z< z(vvq9t&gpK)-u2cTFm7=)41q@y87W&#tHR`D+-rks|%GkD|+z?>$T=X7Vrj1R- zKgQebqj>y93)Kj}bp7XLeYdI)<$D1*-dtR(tskOn{go<4-2%hyzRkGA(;j_(MYhD< z-6lw26L|(@;jC6tm1sc1uD-1TZPRI4ExDp_2Qg7J9ClxD@vrzWS-2L(`@6%{1%iu>_9Uh8& zfr+@2gdURx$-fUwBp>(Zmv37d(@WZv)+~Or7QLrUzyGqye^AKf)Bml;P=Uzomda$t z88o#uHSWetytXC*&7Zw)z@tZ!66UVeaCDTk-89& z-s7n1E3ca?YMhk3SdiqQwt3J-LzZR7S$_0aK(?9w zUG@L#g(5f|aeSh+4)hf%?s<<`ro!Of-FW@^G0Z zX9}Z>{FCxi0@-#v<0D$JF{{gM8f{#}PGY?B+Ot1jj~CtX}`ys1Pu5+D0c zYVchU^mKsFw}Eb)Ux&}g0>Uz#^ZmagDYo3i7Q4Zt|ktiSAtTyWkGT`gVW=A31G?GKw#R{ESn_ifox zffB>mQp&W)1t-okRtlUnob3Hnw`LwS7;8@?mUnhbVdS5JPw3g^{C7OS;| zPB=;}$KXxzJ9eR@nDH)C$hMFZX;#?Ayq$9-McKX6ei7gPVM1sDZWBQG4RwL{bZJt_;9hqJh8v&X^#2;J_Sv|fZSTVfIbO}xJ~6$b?vK? zYOF)A<%uj6?XlMsre$UrMK4j)ecsNgF1N4ie&P#Bcxm6z8)~fjYSp@qvb9s|@RF(i zJLQMp2FR_L9Nz>}We~lky+XdM@jM&)Xb|V`2&)CVZ^K~7!~#AK-8Lk;kqWF@)yCem zI$%_YD=)Jf62uz}Ao>=A)rLrgc4Q?QpDEGi8&`YKd~yP~ALF~4M#S3iuW)ISJ?|a1 z4BaJaa32iE^pnq;GgnAfpl5I(#OZqkp;>n9Y8`c}m0iiPoLw!|;g}u-j^bDT(oCBV zyR8=X>1h2kEfcr<;Va+eGt}MCtKA!2a3N~bo4N-lUC{t!QvgB~bN_@$Gg6u%FYi$d zE;z~IA1E~n3eaw-vNgV~KlD6|i~x8ZcNK~j75g}7AHfpiU>T&p!e;K4lIDo>Cd7Kd z2=F_uH);QTRiC{dZJBrm%OM>41|`N~?eJLB!nLCV&)AQXZ-gmC% z|Cq-AlSPzx0SA6DC_J@w$B+-*mYsqwAW<4@PI~2sOX@V;2Sw8CgF%caj+;`?)kUKY z=K~waA=}-GGZdFSbL3ac2ItbrlY$t==#RN=>dt8s;$KnviZVVO&Os8gAytgy_v+)x z^Cm+$zKlf+7t3@#&XJ{!bK*mbi>bKqT}D6$)ac5Oqi<7)?SZ;lvX+qJ>QN(8SM*lA z;0^^Dk4t}WB%PJDrmA{F)yZD3XzHSB&suTWakKpFSdzd|Ox)DTG*tB6G z$b9NP{yPX@Lv|>(3I1iz?EfPsJtzRZNtceUje2?NVjt7EK=Ua5JhvJ3m0s%`Y}(B( z9nvT7e|jsi6CC|W7<9cbpKXHLr{piVz0;LZSy!ucpkwWt^}#H7@h+=3$!d?3nhB`x zI*(5F(-iXYG^jom^)j5WyJlYkZN|WRT{8wmY}g+!MO&dN2v{|d%g;QRK_59SeZmEG zllk6kj@Eyfc*k(FGgk^cIX@yd;dQ^uCy$*no-wFmx%ehA#Dmn5rWL%3FjP8iVRFN= z7!!uY53eJ9Z}?EyCOI#jm*=A-J%nq}p2w=U?<(qQ^4X>tsmt4P&EHAa9R$#S0%m+( zdO;tZ$rq7rco(6HNf)T0;-&NeG8OiXwPSo>keJ$_s^AKHV89>E*O%Oh9 zFp`zgk$Jk&*O={NT8e?;3kL#GgEmBxl*FZ}_*;~~Qi$tP{+`YA987K^J=CAl;vBK5 zR>IwQQl&x7drh6$!y;BNQVe4ogvI~nS{e@$Dr!M1&Gh#k3U%S7%mj!9vS%ruA(KPx z3T*QCW!p?mn#2IyjK@8(5g+j~L7f)=+kK>UHa!!&N%?a4yr|slzZyV2kCLj;pNYIH z+<#U|{v%cX&91}>y?FC-&riS=2TzxcQshNk0!^TYn~9T29Vk0xVIhSe)fie;05{ZN zy|3)pUY!qD4-lzVY4D51(=Anqd3fh{dE9cm^H7)oIT3TINmi@Q)e$EZWte+{d-%>kfpA$r53Ewf;~MWs36Phb zA$;jfSw1>wea-m1n74NE%5(bFFFdRBO%zA6-VbeYaGSLr7aCJ!+{{#t&xVHAJNw+< z1{WF-n&TX-3)?f!ju~pm@oXI6-*CqF97)exZ;DEW>0iHL)IvFIwSe(XI8GX>r)Tkhwz1+bH9J_s=ut^f0xAR_?T=L$X+rl(D58h<=dq@H`FN#SR} zDa3`n#CgBAeHeYn>vo*!-O`|!Ubs3pIYb+bfVZ2mGjU7r^33orO!aIkQJjxDjvqTS z4CgYkAjX`^x97k*to-;mS|*8xEll~aF84$`m#*&4*N%lWtS%ARNJ;0W>z8%@s!AaZ zJPML>L;tb&J()^rM|U7|0%-*zhytgy*ilPYX%uhnLq;$DW^yWSQzzbIE%IjU+LsNT z9j!tD9?>k>mTkVorLvD^0ctAkYpI<4)HS+P7Tj^B6WL1B>z3}WYFZ9h&N!>zpX8Ci ziGyw}bYw*t$FdSIcHRhZIqTe9=&O}hVF<_h3Z$smJ+vts;6UeXMdBQopD|hobYE_p zvU>Ix7g~PcA)(Z0>Qaig4<6P#q5 z|5*QgBKAO>9sZnS@B%&(XxW!P;)>?UlN6dmBU-dZFX!c-%3n!m`|MJLtF4&Lp?ppF z8PfefuWo!F-v2-TM-|#%|ATq%u$)1(5(uojbA?YcNLIg;(spX_-{ienzvGKl7&Tn8q|2rrW9=}e&e54cn;HPnU-X%p-sl`EQ3!G&r>xGhY97Z z8L&{@m<8GQm6#Gu17{t2o^Y8Mvj|V&-zGeBop2Tw-JWXxMO=WnUX`g{X|tQ8L`&6jZYxNYB^% zmN}N1`NtO2kik?6aZu$Z3ZwtCuhAgo0nteQba0Z@L4EF~VkRI&&>_#Y3NP2uE)I5sE0krkl**U z!<#T7=#nTbdgV-~srKH0Ig%$E)#H3+of#{wxgvy6w41z_HbIG9DrzD#Ve-7OrF2}x7}tXK+pIyqcwV7uHoH1 znWoHDe{5CdQan+meCxdb96muX6NboY|H0?D83;a$B{uzHI=H&32iGT%^Mdn}vUYuc z>ayTkUR(p#oG8wnkL$e|CoiY5#@BkO34_A@43w+~Uhvy2E!pmQW>P8VJ{X_qT_Hd*!CIY^^U ziY1T)r#u^(qX*vhlD8Ouph~XinTN`-b6J&ZKWQ-)$hU8_NUh2)2#@8=R!?%kmCtMr zbp6PR81o&(qgSxf@ywuD$%0Mg)&jdvF+%Ez!B7aIX^a@2p&Nc8pX>Nm8o zd!5g}KfK>EoV3&^3e`uOK-Z7sv zwjzu{+#AgDwIX;x&WB0Z;_F6Opt^U?0-TpOC2Cfw{IiRXv6tnXFIm1zq}inHeak`C zK>LOzBvUgMIMG_^`87PDe%=uub?NnV^X=9CTzj!fz=h|o!r|?uKcbyo=b^J*(`jX-Fz_BOy!7lthTPg-OIBA|eqr_O zddrzCAY?bZBSu#_I^_(;eJVx<{jU+%x&b46uTU1hu8MzxNE?>hdPP)ad?JXmYeU2f^w z-SwQabH`hyQy6ZpZk-bcr@g3~l=Iozm%S}V%es9^(XexNWOVBn`Z)Tv?t7VxGJb~3 zdf$uNUMB+?=NqoBnvYSux-VLe#&725ub4xz(p-!^&PG=fMFux~gSNBX>H$$F<60P5 zCdFzGnH5+hBZX2N?K&|rh!NJbvLOc5=}{9g3$tom8c9*YhNkj`l#!j=?{*)Dgo^PU z6%{+6*H;#A%3PZavKK#IroUXs5&VC>Ib1WVf28b3cpjLCz_XZ|GFxnkrtMHM&0q@v zyr% z_rUvlVE;`iJ4+4Ke3hFl4g{*`#w&1H(;ZyzdBL{E+Dlk6LB|-eK$Y|K{#a2gyxgGC zVpQF>a=w60x?HsZ6nSE@4==DY(_BUlVnZ)>`=!XHxS?dQ{)1(#0O#ps7~pAr=(paMP!Zy>;$&z7C(`s_on!9FgHZYf~8F zVRYI?V~^WysjF+5M-DVANw{VuUf9kwJ$R^UcF6jbLvyEz^sM6}581>ydsS5O1|?@l zu-Gx!_PA^7DNsE`lXvH^B-KI*2!pso4jbGsZ{W>gtS^;l3eLmgGaokG3pyWXw|`^w zXFKUh9iWs2SwK(0wj>B{RAmz67^dQ2KoA-;T zV*&KEFW0L9hd&)4Q}@6d@C$eSq_JM`+=V}L-C z6D#(jTnY?F*;(Z18Q;(6Iu&F~$4kb}GG8};t3#v7-Z*-FUTgAood1`i&7|`nz~na- z8srAuW27)1cu_+jq|tc5s3+b?@Z$qy@fEUB^B2$iEFqCnRC{r1a(4J$LW1weCp`P& zt^;s4yQ$Oc1)5;%Ue!L#tEDGWJ9;h~_RZ3sQPJ(A_PhLJ_jCa{1qVHuXP|ENxZiiy4LJH6(E&zAn&)Nx(s;QB6CS_freBCjbsXO;>mywJw6k*AXbKQ{&u3dc z8DL6t-Y0D{#!HUWl3YOC2*-|RnZdSjw+Yy5X<_EL?8;p{Yc}CKT9nalu-_Jk{0&zd zCxH`^<^akM#nIQSi6vvgYD)1RO$w?9IoN-Qls2YkM>yu_uEj9ePA#av4xPYrriD8OJ}L<^82|6(3Hg6>ZS*>=d?GjBXJT$7o=P(fE}Aiw%Vp?veP&&9c=wgG61p zsFCNbsSHS88PoAkwr0iZCg%l8pp^Y3H7eeD&WiX^M|QW)Q953}ik3^mI(NOl31_ng z9=qNbUU=@6=klH|SMu4I9iL=VFL|wxu7k6MrG{6@>}Q9+J1`_3{9vrAQ&6->No?Wb zqjzh{c#N8QET}UlFum#sKt&W~g`I0NSuO%c^^*qNKDU(0FAx1z;U`Cz9hS~GFy3+; zVg9I4RdJsZ;Xg5hoaOs}y+`|sXZ9nNL{~m`p`g&A6!0nilKUA1v#PU>FM}vKThSD; z`Py}0H-%mk`9c=Vr=eb6LoGxcA)d#Nb48#odaHcK?Clq#?4P#pMX5h9%i#$&F(F&T zgN9MhdW}lNdErD*KfkJnX^hq0s9)>fPDBmOt(1$=h}+4-NKT72`Xh_a<@Ub1vGP{r zzIcd^9_Zu=DKBmqi8zHVLqDXzm3I1+ehrT5or@}l_*o9MzI<~sh!&78d|+8`4gNMm%=Z}CgX;kw{ftFJZ6UolU!+ITh zsJQ7c>hQYM3(N)quG`Y3tp$vJa;HcZsEV&hBI`bGFtiH{%s~c6r)x9UTKWjdIX^?r zy$K3U!fvyAtaRkiBKvv_gH*%NE6ea02v_y(-bA5ZoOcARbNM$lkhSIN78agR8oZhe zRDI?b!&k~g301ul_5E`xJ9wCDU9`_npf@-yxzzpZCL?3XNs|86^CtowJzH z2*}4wp^0Oi+~&Wf9i#^(kK9~CE|x8MZWk9$l>mCQ&ifYk=&qFp-yI5spD_O9%ZIST@fvV_6qAHR^(O?{{|>MyIIK-YGZ2uz@flYj?(_U=gaSC^Z|6L z3LZ4F;Pe%YNH5)XQ1$|W3ly=(rUV*jo!;uc_x!vMctIe@Q$HtMt-kx9G_@2U&U%m%>`VUqrSa>VcUn+!nN&_lIi-CO zM2lmPxcgURe)XT2eL@0;2v7Xe)TtLeG%nnK2>PST%leNHfRP8ThU8F$iJBZeh-C6) z<>qD-;-z)F>zYC-T>`p-b|&^)E7Nl`?Aw0*a#IXOm=2$&it73t-qNW34bHsUAS*<%*wJ_9wzRF@7u? zD^W?0p(-`#wMDLH(jy;Z_dk)h{PK<@4$$U*4R*k0KNLlCi@as#=3_fxP9~4te0Ro$$1R<32)2fSUrc58E6{P-) zT|>4tNK^jbMQqE^*1K=G!c}2;bJ6aubLp;lSEaUeX?k|sVwRQyf!clMbsjhyNq5n0 zfPKQOzN~v|G{Lb{p$t;T`-KDgxP} z$uGkYfA{dbY(gjKQ9UD)YHFc_wY^`O3?NEAkNlV8{v@8x|i!3g&e zP~V5qztph}L)5hRH|xuXfKqP=3cHUwr+z30(S`ggTmD=Ns4|CrR7BqFz3~0x(V_w% zjNhmSgsV|fz%cEeg&W;2Y0k#GtaaZn-5X!;Ozf&a{|M_3OKB`ONnTFDlEij1dtvO( zdU-Pe7gY{R*~yAG7o9ez1DnNkTvLn&s*CCFh&Gg+{ zl8@}$a5Ug$aX+MQ9j`7f?-~l2^^KU~lbJs)#h?SL?apkjvAos`>02x|43e0c?fP~> zl_r=Uk}Kh3H7q)%ZRO_dLrUF9^2OUMiyaQ2k=4?62+hg19x)|JeoKbnhhB`RMxuXV z0H@X=@jn%6`2c`o{N_!v4DOJWX5NzU$iGVXf2;cs&!~!WA&2+R&{oU1uZ)pe2@~#Q zns~`0%5z?mmj|?|b05B|0?=%1A$@qgAa6H`DMizYK#;@^FN~EjpXjE0}=aqJYwb!_1qD`zJfh)BlS#$i!adPKQ zU93XK=4#~%R6#RevR3+fS*btI`X7G;q5@1Ph&-?!?r``vToTRcsGyjhrgE*;BJonMhLP4M5EUjVQDJ=R^k=h>pH$Hjbco) z@Vnsk|6ckHdzqzp*p>tnw@b9K)~UwHAd~m%Y^1N&a~12pup4VoJ6=a4ji-^<$=Fej z--`^TlJi?$kf%;@M{Igdn0FL;gXRCENlf9T}~cLuG?4n*L#koq0z- zvvh!8of?}MrZp~X^fb#}`FDREQ(NlFUq6-pwGR-`iig$>M;bU2||4#PFS{xE++q;Ss z)p{#3jPmQuiv>J3(1C~aO*b2m1=ht`-1BR=)HlAb=%an@9D83)Zw>l81EY_Ad~>2s zfcn;Dt&P_i5#!5p6M1EuHhU@lZ-OhsZ zM_?0Tx=Jx=9;4DEzh|dh`8|u&@R^-EH(<7YY*nrCkp$O{fj#rq>jZzjqNo|Bzb#;h z4}gD}8eBPcn>)Ld8Un~O#DowPvV}X6 z=)7qoA}st4u!3OkwF|>+xzX3~BhG{p#ep(z+NmAQ3v;_J{xXApl({5i!HMVk?R$6*C?q~M5=f(I(O^6Abi%w= zVmJ&YSwyATWNaiNw?%-Vjup-j|OGr4GrG&R@#t(5~`wTH1_c zS=1A7SF{ky@!=^JO`}lb#5@#z)%?bB6f8?5Vpsl9;yaIixp+8oyK$u)Yjg@3VIj+Qt#`g@w zY!P|e**~h}b5SO#R`^s4vwOBxHHX+EjW8 zq^SLSQdK51_*HAkFz;;3)fpC0;(bH1qxW6EDCCnvMp7eean6EEQdzK+8il6SH9Zr# z8JVatWc@x7U7P!-&XXk%E%tBffuU^J_3Bj;uS`A7yrh7=>g`o4-Xff)1sM3TR#nSJGO_pKO@RujJNBacA~ z>i}KKZdVUImgcYOnVWh%&JrdN~m#cmp-9T)K zPlA^7pUA8sIDQfM%TykvKh_0pS@PmvtM$l>?<<-dJw5lofq@qrNzls)Slm}IWwuM^ z@8(~AqH#8(F^1gEcP4@3Y!SBHR3#U5=8sQX3nH?#gA3c7srMzEa?i+6sGyi9SqisJ zwN>f&u4%GNh8jsVhWk7|#zX`t|H2~R4E@?o1$o0C&w2Ql#`djb#EF+t8kWJr{+YuK z0-&bx{4DL>KxQDB%gN3`0R$M_?MeB5~EG%8)^SN zU*hm}@`Xf_{F5JA$>r(ojO{By(3K*5Qvwec)&^~eKG}0^!OMsRYU{ean3mq=Y=$H1 zH}p$?g?U2(h0P`kk)TQbKEY{6n(xdN5j|q80~zF8?kpo%l0Vv(*kvkSj47Q z=XME84U~DY_YW>yio-WivnVh=q9FpLyQCXZ3^BrNCJ_kcQ%+qymah-$oNA}IIES~Z zY66Zu9h$!hrnTSu((Q`VP#Qk7p>@W#Vt~ zQBl{;%av5X;K);Kk7&rhiKbsa_Xm{T?gu|Up)Y=rEvQHT;d$)iop{KyibT@rUtV(Q zh?}oBZSNM7O@k-CS}z8DH9NX-GQY7JdB5qkwsTGk9JdOk&(6)LJ*%pR$1K|vRb9_?45~eItBYJJ-Hxxzu!B3U_D8(Vezh4SA%Y}!3nhk1cwGtGS^^} z^L^JPb!oWU>if4ZoEhP|t|OS~J9o$5A1xnT)f|cfjGW8+#OJ zG><&MX!=zoztHxOWDdn=+5CWP&rh)q13XPzsdnUy?Cx`W02C_72owxkZyJ^JIH-es z)(0Z#u1I!5&csPQUK8OIv-pxNwaxn18nDZx5g=8o^1#cCxn)4IZ}@;U+!tChHv`wJ z$8}DiEo!z8_->k3HrwC07`Ck}TB5SQW-5Hwp2b7iE;8Z9bs|~7Igc-gZqvoL5AmQA zu{ zc8W5f>M1iS#uj6zKh4VL2UIs?H{Oaxw?MBVE*W3X*|n~9^;LOhdjLf**+-ZJ9tM|> z*@2lGy9~J(@+Uc%0sjifgShr5AdcK|AgU3Ax&Etpg~MxLi{t%b%JJphNcbx?Abdy` z^0smntSEuEyG#~qJ0%|!7cC54 z)>u* zV8$X7^$IC>oZ|08v1*d6N6j#ef*deP`!XbCm6+db^mrANdKw5#QLmS}vmSVF)F7?tDm*KREuu@5?FFU#GWYCBSOGEgFOlo8MCVf{QGiVn z-WL37BjJ{m2=B}H8(*!gpgY4{$}O4CP;k>uL^a9W+V^>s=TqR>eqJgbKyw`J+2QRk zZp*N6eC5#HVEB#1?qvB~kct_qt@$Gi@u1bg@bSC zmNIgye!@=S4QI5g%4N8d6ho^dC<8%H83jmPlnST^>o|wpX~F-V2#D z_~-JRg;yg~_bhsEs=Mn%7sQP$^Yec_4hQVvsLf5`CwI{w$lM9rG*{<1qL$cX+thZx zpC9r7-Gy_BimuWM=nws3k&6Eex8?9N54FV+LzX*hs|4Rn^kdj26brRoZF7H4{5L>7 zVp+Litl35MT{5Vo)uLU%vhErh46ljCi$d{5Km*yEt^$qTO+W5uWR+wSY;F|6Ji@d6 z!%o|nTFthJ(thmb{pL31iLgN%>)*)x8l_R^l|6?2H< z6V9oBdAZ^}YEa#uilM&nxhX&)rF96ah2WyriSC2YdqFfD1=7@g9w7&}hrb^fUBX||J)qU~ zW8=kPm|R>|G@yb*O4#FA`m`k59=K^b>OATt7JZ8476$gd%M^Ej zcV~^BBRX-y%kVh^*6p%zW12PUd^&_0!8-TjCdLRIYiI@q@+^E0LaUF4Nr)Y&zO`QG zr;Vv;YN=^DnkeZ*(Dv2-Ng?SmB>~DbaFWk8f04nL`O_Il-a1&Km+}e#5otNjh|Jkcey? zJEf(mx#>So?sJGl^)PtPrUXe3CpNZtUamHvc2J>Ps`k-{Vy$bI)}tPj4<+lX@8yTLEHL`h_)S;liJNtj7vWSKhZa#X* z4#-23pEFlTqt&i9H1rlp2;=r6@B$sg%y*hWgiA!=bBYJge4H=rotN<@uh$~h%~JOS zQ#HKV<7>{n*{jKzW@lOZqHpS}bbXeuio#By>AHJW-#t$enB9!>aeqO`xO5^&sADzv zyo8n202a)s;oOBT95DtL-R;(kcGndCHPbSBbfry;=J|*lrzWQF=8gx)5tU$Ln}o!D3=whj9F3_}VmJ~h;NhKQnhD6ldXBLf?r7QQ z0JTIJDS*%DEEr+>%>){5j!8as8byZ>Tf6z<%7h$v`kpz`ls~Oe7RtlJ7tdH8w8CmV z(@02{6kc}rLGA!XhA|tT#q8j?|6v}Hm;3_%O-YR@q%nyxS1m|d-qY5UXwT1hH-6%h z0H+C<0`TyaVz4P?!9K|EzNNL@F|i1idD$H8w6?0ZE4t?Eta>>RJQ;+XW&GrpuJ?T!OhjT%TT+9~>X)X6LQ+4fKJJ<>~D0PHV4p6@?9M#y+ z6Omc;yP>f2BNe!Sc zE*usiiCh-T?RHe8P*y%y7S%D1DE(ga~BSs%pu9&$|63Vh(jy^}JdI|9U-; zdpaM&I-_M3hGNzsn}O@=c8Ax1h!)#T2=_RCUTL69+4}5V>;%l`RCpxAor>RMQE^gK z(l9#G3Edx~jPc2B_iPL}Jl(g*wb4^{+?D+ZFrtmv~TRqC!_JXk3Q3ugwCb;XOHjX&jNtSKdlRcNyF=^q4>q z3U4PzsXC0UYnh<+sLHZlys&yf@*Jf~AICN8cB-~6-}BId4}9sCn#RGyHU-0p9Den_ z6?I>3#~9Z^IEBM`43RU3GKc%OY{6ep0l0WI<}OcA>ql8%Raf_go$4=Ib68MFcxs|@ zg(MZoK^z8ek7~;n7xmkFme;#{*eia<=PP_;P@q-D-2AVRCk)rmbZeA=N0gC$9NPRT zJ>4K02}z!~IJS*-ThFbwA>dg|7Qh|+Yn35r-GT8-)Yq)%Gg;(?({Q)$)>UVsZsorQ zMw1xGoX@}&j85w{O{N>*W;&G1UkU<64Ja;o^KWCXaN-207|XhIDXhnQts?i#I`@e) z8UH`FzB(%IM#(ZExNC6t;O-FIt#KzLxVtw2g1fuBySuwv2=49<4Q%IoZ+70!&c7|E z&#A6o$*o&;CFLlkC{2j~pKF$nF}nEvwDPua@jpH{&@&B{>HyolR3fO{DS)L@#|7T5pkWeQeI(QJRXEusb2 zAtq;S=M^AvpcAX~Yr8ve{H3ixz9lZMu${!Wn-ScJx4QqXY{OO!yW`siA7wB6=i2aJ zg3oNBlP9xE(E=_d`&pQk~2>{ZEC(wjK?c4`IM_S$_)fdHvbeTj%pOhqF!%x#HU%V!S~K>9V& z1|%_2e#JPe&>EpX2nf?z;jh(U61J!C=x`fED;=(;rjJa4Fjd4}XV^l5H=uEqgDmaQ zuMcibZsw#7YU49=XIA*4Tzpw2J2ZgMdT!)B{b9+^(X)+{|K&C8796FHx-tGT9OVlU zqH=w6+iKYrvzO}YiP|9yHl;%I%B!joc(5t(zFh@(_v5^=MT0CQURxX)NpzH8tVk=p zHTz#Ag2aDqBZ3k675}Xi%)65Rr8a%cB z{x(KV9^T}a(fu8E;LDPp`vuAJg#{*ym!-obSUwaT^fNcdVrrvpj^Eyv=I7)lUFVfM zc00_^(yWS~48P7uLUlgKLCxOlhV&g1h`VJW`ixfPR?7l&BVKI$M|Srr{L5e--ew-g zy{z_Y0*3U#Bj#U6!%wm{zv@F1*PqP{s5v|xRgxZh^re{rGcFaUCWbYalp6`4koCmFagF1Se`QcdUA@ql>3ZJm{}J zqrX><9&9iAb9)whGMI?Hwl-cXT&L(WgaqnHme!(!7pIsb)z~>`KjLwx4F$%NIrGJP zk`k{~7$&V%k9ac9ET@|jJ$3tsl{v~24*iIT*xTY9R59F9|JmwN0V z*(25+_W6gV%H=-j>36K2zUJ7LJY`fqqS)gj&C~UZa$HrL+a|e+$#7DtkN)Ptcm3VR z-R(7hli~8A(_fRZdFkXe%=WFHT(OcNU9gK}$=lkSM@Tf2roo~;S+$}W(0WQ$AZ4m_ z9^l39v9!cKyiMIdu_+RfgNZ1ZF?m5@U835jy~h39*1$k|ltMOv1beSeO{W#i(2Z>sg*&E?c1G8`-fNgfVtWxZU~EnMIp{USlrWfLT+%6tI`%>1gDZ zEPNz@=LiHaUk*f{iyr^t{Z~u0_;?0?aMBvxDzLF*$=i~xy$$%AqrL)UrU77!=-8Sr z0U*N~ZDZ%bNc}&J5tya)H^BU>G4lUk8Y6If;3`isHH)`FsjcPiu}4n)e5)h5bA}HQ zWWS7I)j@SmS+Vt~WdBN36c{`B?b5otrrEj~H$%VnVr1)Ju&t^3M1((5B2{chg=k7G zk<2p>XEq^K%lG=sdO*6CNnTxXRVx(cZ1=u;lF!~t{D-}kBO3qS0rB^%O^-FCzw-+xj%Mkv{3Iy9j*R~4winEW%r0sX~LL=6RYyba* z6YdS2Zboiy$ZWS)%>4qt{l%gyxA@(GHrIb*sq!Ar=@f-tUxeXka=+lB|Y=} z!wG$uoWrD9dvLO!rlLpd%*Af_{(LuWoxRf6jHJ-uUt)J7rZW9nZ@HxRP1kWl86P|r zK^v#8>Es;G3PJnMdCH77M0WeU4tJ6E!phoNBe)vYqy)F(dG(>pZZfiEtLKhyqy6Td zPU!LRD4@=9Ox7_qkLeMgBLz^Vtq7oVp#kiM7=a(2aGM3?hzW#@P2FOact78&pt`O# zARp@r_|Q#z+A9mKd5IZ>u`XX_FyVmwKMX+BN7BlsgIa&iJ`b%{6H%)|HJ;mwe=?Ew zE$0N7dtw{{R!;%1=Yq#u0yxmOyHD;hT>m-KaRN(9ag01c-tIM^2)(YlzBg^~w_YtS z{9H6!y3l0LCjExmgd@}<)H)%+usGw);zOlo(*kV(#U31Mk>9iNF!_9RGpZ1HV|{$Z z-)b8-Fs8>ALM!C?`nKMPaH%GU2n9??m(>{OmW01psp(!1tE+3<<1(|- zd%f1_@br1_O4l;b)YM-|&&qmens#K{V~Up0DSE9EoSN6V`CG`qb&NJpLCJY7bX!N3 zi;fC+E2Dht5a>1Ja&{{J2DMQbN65-iWzX|JEJNoGDPK=30h@tjuJZ@>(e%ITU9H>_ zbBBMGcM@F0RgOvtT>q?5)UL2O&xR^wX0=hJ;j<%h8(^#yX=J{g6MLV%(LGe1U#`Q6 zLd!74%Xn^JPzeA~*oWbZX(@?Z%BSHnYsMnbGH9k(5r_pF2SXvXKCZdnu^kTWP(SDV zs^4Hh46`lk3vZ{$CBe;UKl$9h5}b?+^q+cKUTg+dx804VRjsx-UQoYvkAtfl*|apr zF$Davu{5OVUr~pAC(=%~1=17TIDeB4{%xX;%Js{RUo3LKAe9h1H6wdx;a@QCHpiLM1WT=t@R3R@#hYCm49TJ z|2+o<^G3TYGg<$$rmM9&1iOy(3BJo(QYP@3eB*V539OGdv%oG==Vo%ryufJ=g3<|f zM7OoTHy1NzOV2L+mX1```o&cr`L3D^&FCfk1_ybnz3$_;yNm&Dds!WeIBXJ7DQbZ+ z$7ItARnrhJ*PkbuFAATgN-0Q#Fl?Zy(mwdp^x)rg)wi*oT0clsz27HY5P07(`CN>z zf>uEY;8V^A*lyG9TH)XIG%Ab)LV_J|%JogDM#0{K+tJ<_aYCgxK1ZQEODg__gn@Y; zV@YJk^2{T`+s|y*1WDk?Zf{MO2-REBNl&g&P6j4x<8}%nC)e~zVPLxjda|fSymO9KSC}G z_*|q1jkTcnhjfpexws5s5U{kzu4gZ)X6do_f8of|^<~ez_~4YO=$P*IQy|()m~F1y7=nK?*a7L7L%;A1rxB~91$4L7vA)*y_DHO+pJtHm z?xe6#gp02^FnUgR2?T~o#?S9afI`F^_ZvusU zb~!#PxCJV+Q<_M=3_W3+>L0p4EQon&1!2G$_ehR`$$vbDQmqo}A5`OW zY)|HJRUU@F>;L~Sa+c3hc+JJBr>4eIf5m!=89Yrp5|3*ZOPHpbrxzc5Qa&<(~ra#f_YKMdGp#wKb=2pRe_e746)0Ll~^p-A>5jI7|X z7e>XZSGzQGOIsFvIDFNY+Uu5;dW?h%Fz=1{$`4D_Zy)~qG@SZ1gGn0wy!YXP@V4{1 z*Qcf$tf;{4c_nHS1bqlV+hEt|Du?q@@u2RSl$&qIV|kS7C{YH#V4<@#Q;k#2%ex7&De&tU5`4PScahL8h!S92#l!gdDow@IdhrE@09g|# z+sE(q%HC3RLDqi5Zg}&DH|uK~keevUn_|lEY0$SEQ^O_DAXMN(+e73%@W_)mjjyd4 z7#TFZz)Y7r4+%i)MLhPsad<>^CqT4V40EuJKeU#@zA672??i*>4cL@$){dz9S0xt@ z6Jz`^&NZ z&-UnBelC8b3V7k~KX?Y{yQ^j%WT{Q#sbRo1b`*o!*wZ4+8oEeNrg3o_Qnc+SUk~d@IQ3 zehw(Vm6#@3m@X^W4VDa~;8`}Kns-ZD_Ye1H`I=oHE_^N?`0ee_S7&E)%e4`18&kMC z=)z1awP!FrG*r$b;5$-|I~92`b&Y^;(~Bz@d)8daq4`ZpPd$%v5t{3@82l}_2QrxgoGrZqGmc<}7foJC*IDC#2axEc6?tS% z>p!iEZWl*#%Q|B*|4X|Q^EY_@N4obDyYSJ_=^T6bICdWCm)IGF%cO821SXHo+oGrvX`_WgU&A_o9gi!d6&0xH0hBkkLYd6#wu@JVLVqWG+0gcLkGKHABcIFWuLqFR^Pyj zp}H4$=db+_z>AbHQ*3N|8}u1Sbu^B6t`ay_U~<7>fr5sItXyW1#-VdK&Bh?I3@-&E zBpIVh&J_n3$SuPUnzcn)n_NqksmaoDbykj&npcvv|JP;^ICfO86OlVF7lwoqd^F*XH!tlS@fl>gs~GF$j+Dr%e(|zRq9G z9zJN`uwH*((;KD+G%H|h3D0TDre_m;YB7q?!iP5N4g5^szuBnC7Dtpx)?)B+!oP@b z-EA%oE7+Bt4nf>bC6Wx9`|~&2-?HG0%U0{w?kv-2+$*{4w7BFY%;VyYbbEfedB-RD ze*Jz8lPPqQ(=sq7d&4lT!iL`_cu?eQA)ZnBWA-;9`%J~mam(46b>lzL1MmJOTJ^|Q z`tKBobItZ))6^meBbKK$N8P_ySbFR?P+7d}zv`5CNljbDiR}*9$l<%v*01P=brN74 z_wsKw3pUK|Ecn_ixIK;uwc%D!TmNShVa#S~UYhRTcBvRsGiI?de>y5+swi*2IOweL zRuMHhlMI7I3*h-g6-%>jOPcf;PN?=e;c` zU@e5_o{5PG?8lYgZZ?jN-yI_sTxPcMCL^e;$s|BvYnX8$7<7HLt!q_}!%MUU3^nzu zb7rpm{vGdw_geilGXap6vn(Wr<;VwVudOP|;#=Y`S|ctL(yOAoI^OVPxnax2@;=h~ zp7_4XV97k7?T*k+NYE6^Wod?Sa%C+{cjKDlk*Qs-+`2IWhuBBc=($D?uIC%8S+cl4 zBZWe2%Lbyxk{gZ$Id2Dn44M=QLnPzFrh*J5qN9rCExBRUPiXL=ER z51YMlpNEJg8zdVfX!3{?zewh;rX&e-DMR9$-eEUPc~OC?A9tUayff85)wU-tOC>=4 zR-|+AD_|U`v#`n`uIuOG-_z=ZaUkpk28WEp+3#%iSi4M%z~FUS!(f&3LeLlA{CxJ2A~Rvxz+ycD8Bi#6!}e5=SL|UZW=)EWagii;ji)l=(ntH< zsk0;&D|EgFw{*JKIrCkcOI*YSV1H^BO(OKXRT{L~t-`LZ;x!LVTX#X=Jc+K=t@xcd z72K|2EE5KYj#m1Blh~%_%QtUP!5D4xy_ST7%)ZC+u!~e@HcG@;9?fWTO@pW>o;^PO z+Fpda-O@*agK%_PYc;2*(fwW&df;Z)>%@``0dkA3f>PQ?K;bRm3PjC-bk^v(83AnB=;&ej|i) zw+Eq;>btCUl$|)HYL6f9@2$!OsiA11>nRjTN@p(vvSc;N$^rcaL z;bP~?2$JCOF~*awE8OX-G`c5%#zj&SGNj`WGr0@p7;n;t@2n-{@?4ys{3v#zLvTvb z9DUdWv#qyWfm^`fNAg%zWfETwgJL2qnQJZ>HKM zUJZJz+j?{ODIX`pZ0nIf&J)cJg-Y#vt1x@)( z`P6WCkrhq9?bdn>E=XEJy;AbjmEDw>n!6Qr)St$YJe+P9xW7_sTc^-+Sq8;px*&B8 z$hN21EaNrRA75}tddZ&4J4bxFA$|(pDmG&3k%Kn*c9jdA65*_5_w6XwL~?u<*#yQz0^Jvl8rkhC_%8$P$qZ)cJEebYDLuc)zqDi*J}n*W z)BAn8kxfz;S-E?N8E~}dEeN2GbT=UzX4-ioX&}&Q59Uh0H7j@4Ev;}J{vsg_ z=_vfkIp|J<;``x4KBcsnu&SaEZ>q?t=T>@7^8BgUo=$P+!GKk2mL7ohg6PQwL@T0S z$!BEXZ97zz@J*jdeUE3@o>V$HxP)Wun+msj?PCTG@^i z9o%&7M?chkFoi!m=@i*CIv(V`=8`bW`P~i7Z;z&La>~9s*}I&tg3_z@pYhNv(j5`} z{Gas*d6`_00t2=O2G~ktS-TZig$VAHMW<$+!s-%<(2EZ=)ao2hWN%8pswO>(m9(-F zpciau)Mvejbi}eAm&*CGg24u5S7}L=baU|vN&^^pQNlZAbsnVH(_UjIXqS_dB=Wf1 z5#}V)EI!Bm_e)d#4j=HXjx}@#4~PuIPFKn4ki9FMg*n)X9_kv7MeuFq3gK1!y>OAe zT`!~69trwBsSgh-`9lzH2~}LFr`Jf7EG~mvyN!{f6}~{$Rfv)B*_b6cP$!)XA)9A+ z|L}J%*)a|y{`Xiruq^h84vf!94Rsb~CkIV)1P3ClFtqwl1VWKl9@#TMtV9qcuHW+5 zLBY)JeQRJ)vy-`C5eL4M9-F5EVI`u?t2k0OYg;(YG5f$5?RRnw*<)PeX&)A2H}z}O z$jU_@(huZyoBgE$Zc@_9?OIq#+X(2?YBEU}(hTvUQrX$l;4}D@6~CZszLdn^$Ksu6 z$b1IvPaa|JX=^o`UFC<=VILTW#b-4ti<$jUl?X&bGp|PgcLBH$X447FxJP*uGr@U? z#NU49>m3{@t0Xw%{z}aXzJ`*@&&<1m>s1mBLKr8e7$#}6^74qcb5{|NAV-m5995t*WLQkW!Nb&8m2uKQ z(6ZcAw%P6Jde4-RX)HBE57dzbI(;qsw52FxSMUE@e3dC6scOVfqi=nd(}Y zY@*`sqSE(nboL$g;wnbv?@NO<@Ri<30mwbaskYkOxrojWBT@8>#Xd6>2{Yzh(O3RP+;pdK zIgxZLwu9Hgp|d0u?0PZaC`Tz1X2qGmSO+lQalxptDZMdWAxYS;hvf@Ab>H&-s z2Au?WtPk^}t^yAMw(Yz)gshSW-hlF!3m72o6p~{!h30!MX>bFa0%Ni--%yR zfimG9zxAGxal#!raBHJ6hV8)&OzCx=OBa2mh_hkK2IRkT=*4c2Pty3ijr(YZ!qXJ& z(?GnsNL;g!eUSHm+J^WZv#o{)Z_db2;m?Oef<54W8H>3H@yG5k>Y3H31Ws3&mX;*e z^r1L#K)r?{6){U!gstBW=X=uKi8)j44D&v=6d496T&i-5p60l3rZT6LSoPC{nUy-0 zZ{ltqU!ocL9E|CDl?yt?r%y=8OyZR0^q-A3v0ir}jUEoeL&Kg&zojiDSAH2wPUrEw zR~~ujnXCQ$HDou*48P?zzR*TvFN{=0=wzFEEXN_y#QN?CnU}(2CwCXYJBMqZX~eO) z{4K%mc)RqK-TM27z%0jL=>?z^bCIsDn&2Poq?_5*fB`lK6&i)J*661_>Al$5F+irW zHw)r#6qdM^!u`g~-Y7vOzG~Kbx2F`fs#skQi<^$LE>Kk!!d_}FF>=$-O+hB0NhbaD zAbEj5kcp}OrLUlua;N5!M)$gUw7;|ca5`*rBrJ*|(}Qgl8Ra~kHSUAA;c6b2j=^?E zmDevd6_=^51d>q-rl$28Jd7s{`uCfA1k=I$-?!BtaS0o2jx=e@nfu)#|ui%6~o`xNmB@Z?dmYW{%nUb1r_Ex-K*o+{3C8Q7eUC>t1R} z>xP{;77bk79$_Zyv{zR**V_r_HGEg92xSC|;-*tYU6+Z;uQ>Fi(7_Y;Uh`(=^;ZetSD!9vE5|6I2$4O(10ZxsKSOFM0AL^*3p@a}Xpp zdxAMlGFfWuc&xx98q&mxRiXr^_!wh%_;K$PM<)qePPFX9UCUhct#NnRjUgtYl&f%V z$pHbGH#265`z^j&;Ah71qd!_W+92^e=JEZ{+s{^X^chvb?hW@(xJeMwkV~!gmp7Ub`imM!&$EU1LbWB_G02YaH9VC)opEgM_U6vt=U7_zCU zbUysE(B5QS`?q=GV+MHDmyDzV<2yAI(AAS-=Y{wC=0+DQ`YZ>$t^J0lZ8J))QSf=u zogIO5#Qm#)gmOfI-wla+KW^9@w~ZKHq`OZBDotYCih!*Im_dulHSQuA$H(uuxO3&w zOYuM=@Nu7?cnT_N0TdnUNR8ef;8J@lXBgVt(hS7egIuC_~pVOxMP z*%~^CnXJh4vx$iU6Qiys=^g-(;%J)1>v=DF>`*kCPr+uI6^$ks_5q|34jbs;YW!o- zbTUgqZ9XnH;mNtAl4JLDxuwo@Ka*96T9LZwAd?$O)bCnNRFhgW>DP&D(SVJ@JNZ=T zm`?0(#gHAXO$o^Q({==aB}=^5rM9-gTQy@v+tnslm*7pj3?K2HF)+74>x-9q=!G^F zPyE4Y_yAwo^#Qiwv21;&QU7CkWo-9|3ggUk&}1oECT|h$Vt7CW?@elW@$5 z4G)@kEm4vwMNldJ9_e5&Zir+8IT>6DY4_2DEv^aOv)0$<;;UZPO>$vf%ps?(-sL*e zNk8vL8a51JXf=zn-MZM2&kTR2{1~S)GNaxa%<73_i!&y_Xj>ZtKP%*i_gs|R+~Dy? zBVX}5Xo)Sqr_3F2%+mMTYCRtewB0#6DhhBs=xw~Rz29>n9f>N=3jfZWK4oDgN1P_E zMMuU&V#9^n_!3pXT)0^{)A>_M0i`zd!9|rh<-YeS`55S9r_-zoX~Xjd1~SuME1-+& z*uHIi-R07(#?|Q3#7a1pYlfHUeXPt6zi<$8ad9g(_PQL^$$E9{I(YD!N_p_vd?kMD z#xONu${HY=6yyZUBkq6%-X6b$`nPI^vfQ>qQm8W@e-KLqr%2W$naGzg}{<&u@XGG!l|zOf%w;^ zRTZ=(#+39D5@V9F7oMVUGIP}0jv?9@lqX6T+0e4*ugXy~X}sc)ZU@ltPn`z>7oHoQ z>o=XcH-p!W|XGbnk7@yPH$c zm2Rh}qUd(d+hrq+ywU)C>!8wxQCLxrvoF$V=VXO*<2Wr?VIIsrNRWz9(!1m70sKV}A5-Xp;yYm$5PaIHp6nZL zPF5fa^%v^*m)jyC(UQ*m-H@_oDb`n?t0EuxkND5G8x3+yK&k+t8@6Gh>qi4SC0Y}y zaD`25h~wg{EHV_o$7fT3J-lqRNGJ9J>OS@7FF{$&hAzWJ@o!tHwQq{s*%G2an%zXF zP-g|8v@rXgS0G-|tZ6Y#lcgsfASD~58HJk|diC{c0eiavC!C>^&dBcE3$a=fwm zGMC6STo5v(SkfEm+Nip52#;Vs`xKTX{6|rx(eslq*c9m(rulUFZ*7Z3X1!UYbqFDg zFZHor+7(~+ncl)x$UWwOsGwE3nctkZ!@A;TyKrvG?+O{DS&W#X_-i(TNFl{@FBi&iGuA$7q zapcr6nlz&P79t@P@q$z%+DRTXTaay-GxiX5Ue?St5`!`A_T}KMs^iFo;c#LV2>$Ua zTZdS8VGHD1vF}vd@#{`Jh4bjoXhLdS3q!0Y><0^1Ws|YwVxOh1OV}bEI?V(O9K1^a zy5@B8k@HJDSi!C0=$2`WZ&WorNsxZTNdPfNN)_FOz4+~uuBSAM*-h3e==@C@X-q#Q7>-W?cFIArQ6dR zvy|!sb7u{j5g10x7o*O4#s^`!o?bxG7!#Nn{Q_p`VDto+UdSxlQ35lOp5&@`{@;v( zjiPy59ef6zjt2=$?bpZHotNUT@7rY>1|9Z0&kGtt?@v?S`n$x3j#)3Ora~_*Q$AZa zSuaNN8U|{WOu(3YCZ8)u0}$vy@CEAion9k&3bP!Yk5KTT1^l9E*W=R^u(RcD_Q1eK zW~_#x#7j@D)+t0x;Vm|jsqexu%Ns7THBu}jp^|3b5le`%3lC&ioUBpn6{3pu=&is( zJ1PsO>m+6Zcni%c-ll$Dt)kKW5ixu#TB$)!R12!UaTcd|3YD8*lB}Hjh*Tv8#it@E zcvpotS%Kl@Q?PeXo{o0Y!UXJrBTMp;m&s(^y|rHEEqJ|lj+4Ql9ZjcuD*u|FbRVoc zPKPA~Wf%mp$T1hdBtt1)Ro}}2%B2|!F_3R9?_9`YDia`kFROz1Syr{)V^2H`Wdb+O zw}ZH3a@lA*o>Ieqv+~1?anvPhx-*ey7utztIZ`|ORui7K{`v78-LcZE|`_9c%k$!$tY~4j=r1=FcFf*JqABrBH(o9`vl9OW3_PO*4E<1~jkj;f;2^-kDBPSMZmP@wX zPA{o4)6P)dYkP+Wi&Eo;d^Y%}fxpABA-WZ>*Ob~enj?Rr_c_>{@XAwCS&)jCVpfJM zFu1j%B47vUZdez1So0U|T3XNtj6WnEdvZ5(G*g|~1g)%em3nd6bQTV$aSa|5nv1eeBZcIBMx4&KSeeKo;^}rU)nhgF*!nw4-#alvP^bJV$IWzw0DnJqZH8zs!n8kt0EG3m{J@n|!pu~17bPEx zE=yGPK|w;NPygbrqr9rH6syb`RcP!w=4b=bSOQO$F9 zvT!NaxuDx=yrN9qnm1e2iOFZye9};o2^}h==_S6?mtc9?GN%|o@LFVcN4e_9%^_q+ zq$OD#@;nV1{!WT83L1o^5GkZt4L3k=i3~mIH%i$|Bu`V1_5yG|+K)_p5=D=i_#Ph` zx7ma$4l^peKthQiF>N{eig#2|+*0gSNz6hpf^45s&1UC>=Zwlvt|Ho_h^?y=TZA~7 z*VkZq{H-Cmm(;+{f4nk=i6eg;{Pbh8%(#)6jz7n~>@)=GkdgVD(x7s86_Sd0jUG1- z@F2Ko&NQEgGsYEmxVSljQupo?ayuEN#71K`i_Q}SCTVRz#}iAD=MP=>PCJMD3oMEa z%pW^H89m&CO6EItt^4>HI&Uf*Pz#iGzHPimj=3!k@?vLDQEmH~{rFJJZ`eqkU6;0Y zD2Q|MO?`W<3KS#BO!UXEzg4hhho>25&lB!8#O*5wXV*Pd9@is1{((O2DxmYN$Hstx zA7_ogTs1L5JPw*ma;b0F(vY8Ebu}?Sg}^0}Ep8GS#@||mI5I6C#1-r{~Cm!-MfLI1sH&M}{U2CkYdSr==XHZb1!(><8-*=0SK5 zz<7>57#l5i)1>wD@&ttJxIHtDiaN$rRZEBi@aESB0|GS~)}pX9d5B`agm;zT0lh|= zW%V4?U0Esq_EGIA-ErXK2;yy5?YPtd0Rk^Hg#?%S!|< z;sMi8;)1xJ2VbNHz1wDf6!}QLwMpEI-tV*q&*&R88Zvn^D+sNoZp>&h<;xBh+tml_ z*d>dyhdQ}8i^8BXH{(M-YV5mNrIiYblFn-e!8uaQB_G^O69IR^%bbGRI8Q8`BUbIr zcElO-RH1|VdOoLr?+03!C zm{@8efTsiQRO!yFag!f9ax%9br>4;BfB{|}H~w&cTAW!yvhkXkO8&$1KF-wywL=+6 zLS?0+LX2aHu&XMZt6FZMUoH!0D8@|X+bE!pvPz1jG=ZX;rsp${)r5-;C&EGVUc25x z@D+kC!A2KhQ=8XPSOc?5zeiH~^y1Dpc7U(Mxkpgdg)i=7N<-3#fMiteF6Qs4rIs1% z*_3ujPiVeAO@}2rn}fAZ{)?usoH$nQ6-vKu6vUzjf$*Jme95-~PVuoG0MpmmSC=0o zT>TSU6@Avu@U%t+y|6ez0oWj0n}-SqO^J-srs+aM8W{_SsmBgln>-w@e2m4+cy8zH zu?6C_T{<59dDiO$J6ch6p6A>Qmh+SXd1R?l7~I_S^tO;lQL$32z85RTBFM;L#9gw| zNx_AD7<%mv%J6t=r^78dztkKb2G03lB8@y8?0_Ib8)X@MX>u%Oq`v0J)<5v5R;EYT2A(XX0b7~Jem>t z%ES4aE{)n0L?^11xU_y1y}Njk$gYsR^K_x)=wv64O5zf}MUZhjD_%cS+ZcLsDF#RD7 zFp74!b*mOw#h9e_p6F5)>PBObY;!?&pr&)|)9-bQ@Z9M%I$9&8oZZi2=8B_XkB1Alou*G)N4;P@O=>!W&0S_c~ zPS0Phl;;9a9CbsWV;XaLZ1K{_4Wvtko|K}RXKJ~ST}vw|D-e{9mTC@GX2-`@zd0OB z(eQ@yN_c@%{c=zyza-A|=H-0-hP;dzN7nOa7uxAu)um4Z+h#O`7{bVnM{tkTnJpg! zM?!>{J=kUpCKop9_+z7#oHs>zU|2ub!iN%TL-ce#!G34?BnRgDxsR`QRvaxPmC8Rf zrKt_WWwa!|%hv>03x-p)j@7%(6JK|TG9v>a>GU9b)`LtiJ>-!fKoS{BNSEFh>7=XF zgG4G0q>rl2$auf@MqWBtPWwoszLw((APbDU!bA{WuCXD#HGXNWFKSOl&4AyQ=sXK` zdqk-8eXdyB`X~jn7rpW`5x_Q$Is^NBGhMO65CPMP>YeusFJ-5{>p9HpS6v}p78Cwy zq!EL}8fUB@VMJrq#%$H9F%D&Ci|%`he6=4qf<7ZAeQm~P{rU?RVDv)B%cYM&Y|5IK z&S!63W%5+>m}C8vT7oLQ({jMY9Mh;InqhXjV?psy73)YpF0QPQZc_P%5#7%&!Dt+k z&uf1l&s*18@)V!zCksk7j7J7h9^6gGr40WJ0O0n2uMIplFt~TV{_!|KoG2-8i51fM zBNelNQ`JQ3Oo3#VG6Mx~%6bQ@I*k!^MKgx)_|rwPPo=Mst+eNSpv(tj@=52KwoD0+ zks|aA3K_LdfVCUAo9}ksj?|Qk^}b7Ck%O6jotSzGt7}O?$SjN(S`;APte^aD6}dHV=si)wwfG z(|V8<=C4LHhzy6F@bee_s0moN1Ue9 zlGMNwJs(#>vySTXltfLccD-^tw4$_wTDASwaI=wvvj?9A{UjXK!HC$8G3rUONY!l` zwlFpdmRf=q*Hdp zw-fZW_rEz@o4+%zng=0V_?XF%<}K~LJTBFe+6T!UC;U8zYYT^|az+~8Ae3+XBt(BI z`K7X0Su7`6`gCpUXB0;rP?EmjXy|1pHu5|YcP1rwD44PO`%<-E&BTxw1@}eBK>=s< za=dLp(4nV8zl|OtHSkv?D29latilx*!frW@@aGX(|5t&5-G15?hYB_zG!1rg=%Vel ziJ5EHzCM8&rFm#STwfAA5>T8iMdyk*c5&?q4x#`)wY<$I z==7q8exOC#iP`urr?3%wjdfRmr{;)ctiH9XoLfs|ZREY|g%sQNL>0d?qPVB)d>iY; zARcVMWXqH6(t4OqGvd-+=>)I-=2j9;8T%ofRyylt{nO$wK~JNmVxoQenKxbc+z$&q zU*wjM_<=l$^f$m*odH(};Z(@6NXTG4_}*qt^V!RMfl1F3`7b9}D>Usa7@A zio3=`-Idj~7^PvCL$)M)e!%(S7?lu&pRe5IqdmCi|wu&t=LjC^pHQ1V<8v7@o3~JHD ziND%|H-&Vl;Pc4W7$mR>MF^KqGwhZ&&e^nkq%>ELTrqo!W`KBsX4ed$xnc+oRE6bT zO8cEp)I?T@5GM@knemKTyIiFJQ==nztgpB0;MMgIGoDz$;D>bP?V5>!D9cvd^3)Px zbn&$2Ft2?~LGm1K&Xdif5xcuK$oj=m_1PTyiZY?6Mx)Uq3Dp9#&x>nVC)Q_gAR`JE zwpT@-{)VRS*&73QLe=6jyxaRlXzpp224s{(o78y7qNv7YNotf$H2t1=A^i+wxapYR z9E;t%_T>h7BHK(j1_==hx+qk5wumG!D3txhulKk$lm(MuB*JHB(rsp&zfM+fz*dd5 zgDhmJ;U8QtXnczEcU@Y3n;UC%e5 zEG=>3g5&z8`d-nVg$U;qu96`+b_t7XpV|(M-NQhsjI?7VvT;6&Q%ce-<8dq{`$%rt zW~HaB_EG;&n+e>9=N`^D$XS|BWu3h|!PH)yUK6PJf#ty%R;>ApNipYZS2gitO*h)S z7x?cSEq$rEtR-Ky+0c7K?m4N68slCGBM{=Y_4wK@9#FQu#r`JDEp| zy(%~#jawZ3&6aE#u2r^cw)kV9GC8SAUQKz&1pXK~nfyAp1?Zckufm-{`2uh_o6ScU zsN+ajrEh_WUb0_89w8ZN;0jqb6fSO9kro<3yP0$jlCFL@ME7p1IbW25>oQ z-r?NgNnaddGr+E(8fLjcGg>P4bdv6j#%itOk=@aX+LUV1TD|x9WuL4UedOa+a{mR- z0=o{%4dzQ0;K*kECVPYuh**hG5-QFEm=i^u8$JFOq=B8{0s^Y+C9qJj=?=%CzvLn`!c)9^&K)mt6KFL!&!J5WGgZwflx9Kk7E9qqMSU{R6X(c zN@vB$;RJjBP!8?=Dn(F^O}Q(w@5&~|8Vb(AXi(qQ;w8U6=<#H1EZ7Q_RpbW8RRmL| z-(I1KZI?@Eu;mF(SO-#Hf$N#8hhu!!bQ)XGl(x@x~=$^dnb% zx8V{NM$`ia{;FI!vE_G2ziv8wPfKt^eCho>RxGeMcKz_k`Lki$kkJ0LQju*{GT>2r zuh;qCRG2jc=iY4>q4zCAN@nVnDH?+vK&%Kmr&}Z5E$~MkqR!zi9-G#06Rd$zv}Fc;By;l zko35+cVp1W*2Y+OW2WlGTjfxyJ{@6+!q=jNKJ!{jM?8Iu_zKz(nI#v@T^G_+nHs88 zGl{pF0xU+V(ZTMWSTsP(_?(E^QF%RsNG^@)MFKJ48EB2mLS}v+0|S!03>82bv=g5P z$3Fq^JAPP87jn1v3}>|v;TXY{5+1(H!6?e-I)z$-0%(TEh#225y2!Befw5W+pfVsP^k5G6CBS^S;IAu&@pDq-?krC%X znO(wd&ySukftm?b3WL)=& zB;DKJ+E>>rFK@%=IRSGct@01|C%wJB+cHag`+F)eqQyWuw!f=Od`fcv4U+e6?@hiU z9y*=K1c^D>-q`E)_V#!0ipRbJX51@^kxGfPr6um}WJ|xhy?sqc_mNK_UqMnyqv@y< zE9c#j_;MmSG?tRhEU4aH%PO=Dd$;!`qKE=?Ma{I|m!vvHE_g^BhPb_b#33cgqYO2Q z`i<8cym3b{dz0I~1XfcbiJ#ACRTr#M#qtf>ruRl)0=?0ry(PN-~cXUvkYpT&C`a5`J9tb8l3)$E!gVV_VFoR%F<=k;z>h7_YKJpx0Af5QTYq}WknuMc* z#Hl{mXGx+$WfyfyX&zt^Lsk+S>Jn}7LKxEoE;80U3dhxacLobBOTdH<#iU=|n(k0q zNl|JKHHzkmM9>-Wmq^`27GX!|>#I8eYtj$n!%ARnBBk`l{in94AYbf-sesS|xTE$x z`hrM)18SjD1~3R$4fl7%qc63vnAjCzi!N1WGa63z)saAh{Ggf=DbKvs#hl1qp>+EI z1sg!ExMX26O~iPIra@12)xrWUrBQ0h0IS>R6()+@vJ7G^pVFpGiFl;}Ecc}gfR<|Z zWFPk7rLmV}oJGy4jMxhkGQ*N-qHd68i>(^LWhy62utK5==Yo=|te#rh-9}dUxPC59 zX9AYlxR2GK{Dlpn7H_!0WeU;Y{Vgu`_ElF<82EJ)L?g~@2oT;W^%7Q!`*dik)-Jg0%VPwh`6RXs4$q0!wMp0j` zlAN&8aFVo*dLskl=wQ#oqUTa3Da07hUZW=v;`@t|Uh#(X0DsI_j!}LbQI!fA&pEVP!`5&{edq_CLm)g)Y9mV#Ii<7R`(!1 z$BBh@Jyftnz@nqRsrLza0Mb<&9!}`Dt0OjW(htqe3G#(>2#cWsBpSILrvxr-Yadk= zywqb8p;}RfwsQ{Okk-OeqN^FyrOJe|qJdPxZApq9l0z1PhE_8EWECtY#jBd~l+asJ zy@7FqLTtc7ClR8{s1PPt!!%#pm1Cn8jgs!dz0CV5&We z=cBq*tz&%vS+o@JAOgL-o15Le<5q;7BBN6UYV`(vCtIkVcfZm*x~N3T%UA?6fr_w+ z-c$l5r4w){7@sMDo^#m;(sNZl)PkaA3eZ#1gcG1-7#U8H)Y6Jc5gPYP!Rtyha#C^5A&A41}M zc%np8st844G9|d=Gf+f>m^+I+T#hCz{RvUAYMYi=;#}4w9`NjMkURjmqCJ9YmPg%2Rvcxl{M8r z8I(xv8rjQ_GG#&{yJGP9qx765LW4c8#(34EH{sD+<%x9RN`$+k`GX>vk0?gMk5n_s zI*uCalI9o5#h?LnknP;(vo#Pi`;jc9uJ67%W+FaPH?v;ChCY|Vt_%g7oq8QnH(lwe zGbEANoBI3QzvTrU6x!SIY7Z+)2eytA8D`7Kwj?!e++Lz`%E2v_-p+wyqU%{la)XPx zX7VG6r<`)AE-~b?Z1hb+DY8ee}4)AyPNw_vM&3D-R(Yt9a5~de_SrI^k~SByQqN zMjD5xhN9hyc12_vBd?0-S+3C}ao6u?udjxp0SR&&mY&(uWF#{2Jq))KW$vnRqn&uR z5Ya3zrExczjWjl@Oulr6(@2cFfKG{!^p&e(WCX%OU85mF1zYpS$&_VP@LTn%00mj) z)MMzT1QXh24tyEOT@R7Wl~1siEc0_pb%Tq3{5rtsXzHgHP?MvWBnm)<0B%|}F+IUD z4h1q?kWSiW!(c94wpPadDsEme_48g0hN+auDSS@}qawjW<$P170Fm0v@f694RNccl$WpO7 zQzKE9uB&&@PwFs|{@tcuZL)B~83n^AsI@efxEU=Ib97{8)49h=U8HrmKg@NAPH|!; z;XYBA>Q3ak>wwe}aI)unlZ-GxMn!0Hp{%rBi7ItoS=9dn$+4mN?OHa?m*Fgzs6!y%yikj$7LlAFG_n0C8%qAV_Z%4--%rc;PG* zT%?-B-UwZ6#j@)lgoX#xHZQQz%Og#{-3hSE0 zP^1~=NgQq$Nuzgo)(Upii_sBpKtr+$P12Ca%gVex$pa}RMfhODWTYygUaQm zR+k8T=~j-_91YR0OhxFq6hTGB`Y*LaKiy2xdK3V!*iMcCah+i%yG6T-O;&tWZxZX{ zHcH4tLX{vm(Wj`EGQ7cwSF@#otW7AtE@J1Ti`K``5n$vxOYdcT%uEy&bfZeQFf~f4 zE8aq(t4S6wb;<7A7P+eKVHIQMZX-|*PpaT!dJAl7Eb=ID>r`YWmK>rBpu5x&|F~~bKO-!vLNaHxphjE>M)3E8d2gztRmFJZka@BfG0i3b@v=t zqeON;#M*;aIA*GacP3IE@-Pes2Wm#|5o<{ptq_56Lh0;A+bBYP`HJ9$&QKH;rpXwn zx#PO8EOHSQdl#LeH@vFCJc88b5}-h(EqX+#Idzp5j%O69ukT8aRk5Ux#k}%cUk6=Ev_^EZf<0w4OU4jVF}XrOZZ3rms)@D* zKV@Xdz_$UpeES4QG0OQQTry|z%ndH=m5j1oY-pNz0E8G8h#|KcAK(yy*Uv>-f}or; zv2#61Ol#;btVgchz&$4Z;RSAS`&x1<#m=czW15mmq=}QlZes+FS&9d2<&bB`)fi!< zW@!v@J>Z_^=qS2}Y32|NAyT`TqQHd&rytZA4C`PL_&W zm&p|lW~oWIM##T$E{@6<7hP8!qM>0WK@aFD=>$zeGdrbf$YtB3uoHc|cbTW^Z1-?@ zuzRQP{iO28DHb(yLb?Jjv=BkinKqtAV<9*hlHiI}?e^6SI#rC{V?@*Hl60BWNJ!sA za@jH(L8twZY&lHC$-LEbl7TpySPATWM!gj?VH4Os``A@$s)q-uuD{ztCQnbG`EX>rmjDz_L8O}ultXm`IEqv@Ymjg@8p;H!w=Ii)ylSVD?196L za<=eY`g^!`4m+9EqZiMSq~z2_MW{Nm?baZr?(gxq&6csMEYx19cY9vy5~rAfh2&ds z+SZIl`S9;m5)I*IcIB0REA~^$7nFp zNC)UeiGskM6sbu3JzvLh(+I3`CK%o1jEDge$3TZAn8YfIa&cko>bPu0bm`enblsYQ7@A*?AD1#Mc`tc-3IO ze-VT#DFF=ZKO-)>9lb#@D2;`+HW8qCb;&a}rII)#RtTlnDS{vs9Dqs8z{!Dvx#JBl z);x5UUU_^+Xx5ldRl`BS420jIfUO*Et(6t2S>_9ISkt3SvDwE|lR&<@Wmm5>z;-jC z-gK`zmLbNsb}VU#AKFFOVmjx6zq0NksEFb~VK6-WRuXbQiPfddw^fjsx>8ZL0tTtHj3w(qEJdS zxkJU=V>@tQT`7oMFi~@P4qb5YF0%`-A*zTisG%X;jzlgN%srQsy3EY1Jqky(BUo}QlJ8jiq z-lqKW31qfx)6^8=ndIO&R*a`L63#<8LlVX#iEhK8RwiZKJ#+z7L061MIt(AvL|DI! z7$J!Ql@@^sHf;_m9L?}@V8xGO6K8rrn(T|IW0s>|%CC*D~5v3x4w+r6Y5X0mn zb&)u_7oCO#t`jY;E3}A)YN>&Mg&(8p%cWKUR&w(rEiMC1O`k=ia(n!BC1fwvE{2OR z?kO?REXZiGt>S>GBJ5`CQhxYBf-#<3Oc5etE@ENR1zS<&E9J^a0B?aswmoT%66=%- zawfW~WT~YwUsxpTiLy_a6*Ee>xy3jh|H`H7sFc)FQEaS10}LP7>jEx|JKe>(r&ZtR zf3o;_6~=wVgk$9tbi85fl~I~Xl>iH*cp8r9nb zE}Z0r!2KYs2+lKQsO~gz5W*v?MAT>&P9ffOQ1f(1u321(%KFJ>?$$H9W7-r=*MkPk z678Wt7*3I2qDxQEP2n3!9a1;j6|wz@%Up$&`zvAsY|>Cow+IMS1!CIM%RfvaCDhExFQ%Yr4u{lu^kmR^JX&BV}+Y~ z(CpX|hC5`WCB}qYy6^aj$ft|3-YR|y<4M@&6T!oJ)CDN1ALJP5oC+c-)8}XyvMD)b z@Ge8hj*%)v;yr0KJ*T)>TvA8S9O9&wQTi}}Bl^Z}F>JXmwUf*kN`<`JLUUkRX?M7f zw*vWTwjGV{lw^t%F(0`0yS*JA-Vz)1#_N+nX|Tug2mwE&1rv=f8c-PAC4d}0^Fc>t zAUsg38HGT2^B|?=+VT>Q;&?*OK*uxpn8_Ynppl4dYO2DZAjzmP6q6K) zz6~2LaTS(g>0I+Q+DY~a;nYMn(O^N+lLRp!DkE~pD?X~Ft%gtCGtt4+)JrjDMq?;? zPuS|CeUVbplfgkeTBn+gdy~md+Ki#gpev*f?|}UXLLqZSPcTw%ghf~KWE1h*g-OBZX=ywxNSE=3Yxdi2QXEp6a`b{wo(ruhf(Yvp!+1H+76Ea z`>F=FWy)P{>w;P0Ph|@)Vwwt*p0Eam1}QEE7<_Sr_Rkol=Me)KMqR z_(PjW61B(F;y2OJHrMnDm5F{(8#1cH+4FI=0%?3V-J_L~d4Y_83=UuvTYI~@XuOZH z!JL7kfg?AGIi%6#bF4fLsBy^4ACZ$?6tMMILSPh7jv|VyphP`c4xoYa%w7wZ! zF!7R#x8tE99@T9e)e5!|`jIRQ##|;B9;!mYM3E?SXusms2_xp6%7{vYKxETUq$HA5 zF#%*urhZhU!c9Yu(qq*Do=|kPcIt4GMWONtC}QB%xt-Y1O_jz0>lxL=&SbAY&=vzi zL@^Yq#YmvC_vD&*HbN(WBZRQ@!>k*G);P0NiBlBs@Pp{9MjsM&O``@p&s9$!3=s?ufSsWR4# zBxiYK_?BLQ24@Uq%&4Bi2$9jEHZ@kw`o-CnzI-rb)nt{8&NNv`5U;u+Lj6IzY@#E0}3t(o8M<9QiM%(Ef zsBJt(sQ{WY#B>Q7id8m4I7@M=nAbPs4ODWRqw%GMyj4qWCY0j(?%Ir~r@iGUL{lAQ zBr&$Muu0K$blR!IZ4~iWb;9E%QUXMO;||DF-U)SNHo{Zx(q?swm4!dcgmfw}?iQdD zjgE-&CL?PeUiG}6{B{dTn1S+RCElEhYNK1BAh9;xipZ5QZ0=U zUEoGe(!2vUeA1j!J6)k*5kK-Gg)E&(@pd$Bkx_rj$r*|f;q-%K(G^tEZ(A}+Gf2xa zDO?q6DcuBN@Hi(oN`p~N8U5_HvI;Hgca{eI)H^-NMiXAjgh>&JuX|M3@-Ept*|vz3 z6R?kwN5@FXbC3#Y=B$>0hijM|JUkN4qO#62KGbi2ueVJ#B+DCuk$myEZ@#oRf}7r&A{K=F!=mvkv6X-{U$j-Xuon1iaN(!GXYZ&fj21`tRty`V+K zQ7K#!uBmFgJ}?ry2*-QSkF`-+-pkPb>=M-o7gPk$1J~k2M2PEYIE~3nEt+(XjQ&xV z>=P-JN9P7~bP`-`j+{j<3u}35(!S5tGOCJEKVmZnhD9z8YN4DeMwP&7>AEKz9(yqs z>O0j7mP(+jx)g#Y-$8M#alW+4ff)tP`_zy}dlp|lTh1GK^#{RiW=kNZh2a1a<8 zl!EGEltlJ+hTE~@QsvY7uBoDVJizN0G?l|$r?*uK15nfsPGDUL4q6ghy zSpA+9G|HqUkwwBQCD%h=2#FIfobqbC9U~}=yzE6}1csJEKD{~8i#t**;t*MB;JGDN zlhq0qFw|-T%QHOM-(e}=n!#(r95 zUw}bVzit)v16(F@kDO`925q&yTQSVG($V^^S^z>`u!U#3&uqq*olunn&6!*Tmf7n+ zkx8+jJ6-fhgE#7S^KGI8Sm{oJF)0{xqfAXzU4UdWT!RF38Av;eA)@{!>TYGCTcv~I z6%7`-^`}7*M_bH^F-3Q}Z;?;xyTy9FBTtf~gKxPTLhx+JDa`r(R%_J^7GQBMm zAmCc!FhIhaS4+YN2p5rkV5A7$OO*C>dks!U50YUGu=F9MU)pOjTD+dSYzR zCB^UgK0k=%NSs^K6Qx5$fopUt1C2LN$=-M^!|s?GiDxL{R;jH7boKgaEwCogTd6=DrxdSkg5<%UTEb+iq37E@;myOjTLy&mDO!C3hwT}xT z#wqw{+NB>RAkl+tC-EW_E(JU2HM>O!%Hg_LP}lI`Xj|MP>lLwXbXKtxa+6910mP0w z#Fsv!iJ1+y($GY{5iYxBryqvuVRVq>RzOw@#Z!6`9m2g-aY@D#i>Rug?xC#8pVE1L z7gksDjbc=wEha4E#ta|?RCUz5nuV(>$_t;kfQD#TRgbBOSmqq4JeoW#m->;n@nAz} zs6=!S5+j`ERlzSeh8NeAcy}D$DCfKRhsh%130pGxAZ@`~2vrZ>>Pqvlb9gN96&FZzhNZ zCRwoNOHqL=q-hX6X#prF%j_oa>2%Sh6C%sx6hF! zJEYB==LZHkMO(<_S{~Z(&{l~n=%JQGw3v6qd-A~qmp(fgV}jIU*%rM218&tqntTIx zLAT2w-yJ}#N~a3^u-~K%|D3Vfmb9RyMkYQp4D_ru59fxUpe0b4LFhv?`pr>y9=Bxw ze0{CI_~vU`HH%=fw_Iz;8ZlD-hn~}G=J9vOOgccZ*bW=7s;YT*8u)xOx;MObHX{&( zi&uB7mzeJPa=A!-V}#Fv1*i&{rYOrN^K>#zxbY#kbW<{*yzXD$8BWz~b1H6mC zmh@!{Uw}Lzej0o&6g|1_NFNk8sUZ`>_gvkAyUjDg$kSV)f$a-R|8D((Wm<8@Lu|*5 zb*wrh!A~xr-2_k!{d_I8m@IOpWT+0$M(M3xQ7;-XM#d*z5Ucgr1d!ygy5pSO-%Yc& zNm;g)LMhG)W10c#!m8klCvqe2&;K*uT*R@N)X^P7G`^JTGBgz{6rkpFTsKqsUNF#{ zqWSjgJa!SmN$URP=&6EwFcK;_Rhy>tpm$txL#hI|52Xgk)`>Nqr`KM6YrQ1oSgsL{ zf1#QiE(6GXRvq_BgS^)GKbE-2Yvue>=LS>@#)2LSk6r&>FfY?ZQslNa=fESKY zXLOyPmgr5eyZB27pdIh?Eq6oCm@v`#a?mdw^sT)RPX6fO+Gh23@&i zdwXT1#qHqM)sW4gk_?sge}dr8MeBTnQrKCB=%Okr#nA0;zCZWV>aTSXPwRrVay%ic zWmk%23y3&pl15EK?iw>A7o?|p8mFUd^G!?2-G?^-DKzc?bxy0v(T>AOo6Q^*$&x+h}18CkRJ{(x=*| z8MqxTY^bvu$RDh>y+(@ynp%7KQTAiT=blmkUU8{w`Bc!3Rm$U5%<%oVT-{${S8F8P z(POq#3hueA>6AplF{4S;CiwXKY_<(if&jlhr*qY+dz0ZiId;O;S?hok01@va0qX!G zw#x>**60f#g?}#nlf40QKY80Uw_re+Fx5IfJB8S{AKTnI{VE(x6(jgtTzd|(pm>dosGW|B!DQfrgD2GJ=yz~tT& zR)AvzEs{+C4R^q5`DEbb?+Gh_rZpJ z=a)}tbSPX8m2e*@KXE6Bt_jjoy1GSw#RX@G( zl5eWJ)kCT1&L2#F)sAOcA_tfLWj76dBIa3ti#F|j9N?369(Ett+`BguPD+63b$sU* zHZjalqFR`TSzz(V5ft>HV^yD%7%db-dOK~^Ez#AUB<@BcV-0{@Bt*J@35~35#0}zx zb8cEGn9>hrJO9mgcJVwI&ei53+u5RhR z4zp4mEV#!;|1Th>Ei{r+LsJoJ;5kvJz0(Ut1k1M7JsKG*HS?_FhwXQk)LW2sP)7!Z zJ;qH36$p}@+|2;5M4xT~QQHQ5IzTRwjVm@P#O+KQob@=Bs;+OzNGm`Tq-B)I)5=qC z9#+_4Y_e5ISPT&py0$^S-ZfC;&h=uB9Ed-t#NREv$BJ^=#ObG+t0O025<>dcegDG(|{qgCyNd74pW1%R-D#8lJ{&Q09>4Yxl{e z4r&D2+_>OV*yCdjw(-=cO)rA0f5I=7&AoEFc;AsoFFnFxk6fixuXIMCCmTf+#Ubew z@wV$dAbw~-5ka4bCczy}WV*t&)e zKGgETvpSABG<4t=5Q2?OF_}goikp={z$Y31zz_BpuS%)+_1E8eZs(;QPH^>>-!5 zy<y0Mr_cB2`$q^*~#(-a61UGoEx4crD92q7p@0c!%|vC(u96 zhfL(p=9cguMhV`-%1g2;pO>QQz;d(+T|N+HC52XUsy2G7!Y2r17wHYj!}K9@A*ly% zc!Gd_P$ZR7-N{plDbM(&&q{Pwz=3jXxg$t@*MwO%wM2>`= zMUOFCql$Z(icV8YAwwuyF8xXan85gH1I9$Jh8LoPRy`^Um-ybGM4#G0<0VHckaX57 zfeKs+9>8vG`1){;z)cgoekQ0q8wm%O9!~qR z$+G8RHv&2vq=v=tmgr!k3mqOdO*03=jdWppW2wlIaast4Da|A>n1FGTY3=4Kc2Dxu zQpCP~=7;XBPQB~Km7C2n8p-T&CJ;LWS<1f;t^I{q?rA$sqm|DV&ON#<55_cKxM_ds zqAU$Yr{|{>gielXLQsS`h7r|W9~i(J5M0y*+y`8}zyD+KP@w>Kg(J2*SPW3^%=eWW z@MPhXpeHuEp7Fyv;0UGC0}CMV&EAb5ka3DwHN%M`Ga7q_Lm>o!#8)**H{T)=`JZx!D37!5{b7be1YkJkDF zPG=v$x`z|z36XUv$B!8QgTV~lCD(AE1Xe_gYrGTwm`>+pA9bvgGXU;cZ6He|HUGzL zUOg=Bv}!g+$uR@O0<$$@v^EoNeego;{u{p~&CW1zPjhox;TMywnO&>jmxKB*S+uM^ z#Y{*T=Hg*Bg@MyTfgb4Gas0IJp$IW{_;Ht#G-SQ9+3Im^aO%A8o`?0j4NHnWj*Gsc!Kle|=6x`$&41=U=_ajd zlhySW&Y>*uuFkY-&0B%hY5h5?k?9H_B+}9;vLzr0be^X{}iTm4MK{;?20_p9@ z&J`;m^^ z@EAf(p{!PyaSBd6_xRK_UUyfBU3KM;jsWm%j`DNr$-pEfA>W3Z~M4-_SEk&;c z&cv#42*rheBn%xS@DiTT(YJ^Jy+es#)KENvpy`Q2n}Q6Jlbn}RL>E?w+vk;kcIJ3D zYD^V|s3DEoBHJ`gZ{r#2E}S2IUQlC=h1_i1bWZZ%l)@ai62FXPv8;H1wC?mR&+S>q z3K>+dz!4sWRhHh2!ULeh489ABD&3Y((Suy4-BIbH|nv9q9B)4uS(o` z=-_f9b|}_*VH7gOlAq2kJV-wcZS+3jqHfbiHuAVOvYaqP0;520CFdkv_I=bYol-Oq zcLp(dU1+LBK&npHP)5KPtl8v_?&!(@mvB8nk>XTQ*Z|-QU<)f1$QW&U+U8#aww|j@ z3_TuDa>NHfcZRN3Dag?s$L6b|lImLqY;>4y9e014IBS3;B{g_K=ocipPu$LJHv*G8 z1voBUu>!sYX+X69Xhod|>2z`6emIj-JRtw#P^%Ij9T$q#>O~^?Z@98WHVlydE$BD~ zi7~R8~RIrb7Fg_PttDl4#RdMPJpk zci}hUgAd+saU9ZwMB>N0^LlGsUOvaRL2TTzSy0kP-MEQf7|W@zf~eI7XG(>tUcI}! zFSf8?n-% zF64E$T!Vu{ZpM?heRBG!)8?MrMd$k347pjkW$3_`g$Xepv%}kyOXIG*b0a4qemHb^ zVwWXGbp6h`8(<;Y0ytY~wE;i&z(j8?$|{FHZCh2r6p( zFMt%Vs+*&(BA@S1uV-}k0mqzQkhYSf0GRTcZ{SgAA%8kOUU0;qr^O3hpjxv1FR~vD z&o3;#7ju2s%kRg|=0H@QlYUb8)i5~+8jg{qB=~dHFmL%OJ4Ea-)dYoeY>B*%grj*& zHa*!AjXqsj$8dY5Z=e~rK^O}m>ns7W0 zEke2U$yc_qX5LLKT)9H|XFqZ+naBsKL3J8q733e=xoig+Tu8VqLsbA}yzu9T1FjD~ zsifL4VkF-e`$7?2(?O&XKT}vO&Lx*UXAIRYS2hO6&TIMb!8BV|8oN+BPtqvc{})8ibo$%M60!k1JKv zeA!?Qe}2iy#KRwBio=+l0}?>anJoEw8+&JnQ|S4pL}4%pR5&3}11=wKw*BF`rQyA| zyr7xc2ZUjVZrWs?j?QjI31q7(>ynmTw<7~z8!?yY-cQdnw)~(pLAQPFDaWht``OI( z(sCv2fbDhLhC+{>pN|f+U7DOS_k;@xT!9USjl)No{w08Jp-CpT7f%;-lYK?;egmG` z)9#JEp>m>i@A4xvCS-M;$cFPS9$^vpC)swt705XYCUigro&FJ+rtAbRqA(}pv_l9> z#vtPIWh|PIim<9i>?r*U!3bA1j8A%sVM`e4AeJdYn#dt9T>Ja;&l7#YQ3%9QBv-Pm z+qkF-R;A$50D@0%<%RjArZ0BxO)=C%ONRl{An7kbp5XM3$)o_LAy9 z_&kHk-f-?>kz$D=?D;e@vQDY>za*K$g-Fejxi{+cv%b;*H5e%_+(bwX)}?O;EF%;C zl>P!~#cTU?`3Af3wgsRGVIqjk>?24U( zS}iyw@~(#slUyo#K?Mo`mHk>JdqF4Wo*blC0e1{@d`JP~H3=Xrwt8DH+$EUI-9j1>ka!7+DxV*XK(JIt&ETS5_Rebv>a7UD zz>z+EF217?9+}=fU;FzJUgzx9(=(h1x%IyKn4skrbz0>?`(~ukt=u~u)(>rF7(@^b z;5AeP4#m|3o)5Bvk%x*U3f0pu+>3u`af|)`8>Tm+*haNRfU|y^a^iXqcU4sKY!Eu4 z)`fp*37Sx;3zfQX8aAMi?r*)+8YHeJWtZSbYdpnPE>?$=KbHk%Jz5Sm#f9cW=W*T5 zO%oqEHTvm;FUo zj^Tx*?;VX=GwvA}zwbo$`3Aeyh2B1NaPQycb5X0#RVb+Or;$aVHD-xXkX)-(;o?az zDN?uFU0TYs`PM0lkx2T~M%|exs)h?QlbDL7A=lNC(P1K64xjypcSgI@2G#2z%Qx)t z1|$c@aP$OVbgV@F^;oyao1Kce1RE~Dz_z0L6o2fF3zFMoH-^`){aEJ)>ci<{v!!Dk zD$MFZ9Di7$dpTDdx^uG6_<$Ll?6iX3K-2F2E_qgX(x1j1YA9cIwT^yDY4-9aH7E$5`l% z!7!bxdalPfvFL3jHoxFelhL{0&m?Ti zaox5+zx^ZXPk}6oA+; zXPXM|^n*{rV6D~nvH!CZM-QRzd5*=F89K5qSE#x;aO$9%2*(uVcNxAld+QCf5Qu;? zEN(L4l+1j6(MNM}~>pQAMg8PwP=m!Sz$Wf17EgeIe8ku?==; zZVc3;Nsw#+jObaiWliY5?FW?tDUWQ3+Sd{sx+e+HA4J=)Jp!-IV^IDi+k1sf9f!1D zCtZ4eJ@cWlx?bu49wLsrA+Ug@S@L}+%y}Zd)XuSF zxI#K56XIsp>WX_uyp~NO-0SaVA82CAlGvxPw+w3 z$~hN{)&Fn=k-gOl9GObZx=G}1smhQ2TwS3=9r!|cAOmhAk#wp`jc8&x7!}F4e~Muh z7EF57X}<0874#FXSwsT3Xxn&xb+%#V6$2!SX3F%cr^)pP&E|3gf4!EOa?;nujBfxymyE}SsPVYEP#Mf|(hw}gzU4Vr&8kTghlf9V zQHF%zqp0rLU^>5{Co%&O02##UKixM%p*`S?Q<@_sr32^o^U0GehO_|97rYYETl%}x zt})9`pkQNR>eJpRpK$Z=)Z^G(W%14Pmtb`U*{bDPLE-?&Gry9V>INGB*2-mTGHTb5CFX`|?uUc4ohQz~2 zzgGRhK^MsW5HMgc7cA#G6Kv#bsYf07zqXAXeyPOe>^TNl@&{*4Et%8PpDKsS%)Ro5 zyS@<$1yrbp7bYFW+5|%u;n%}Ij3r3X0|rDUz|rE!KvLMNnv^VaSvYO=8!5Ff(WDr1 zizBF>qd3FuzD8N;)@DJ`wL&e?{V)a2Uh4~>9~y+nnZ!g*@|#bTj9nN6Lp4*XEd zsw`2Mfo!BQD9Rj_;l$WA@OuM#7DuVZQM&XUAY92K@w9I*oyP)=fsjzhnsu}t8N@>@ zk>s44AZoh>3HoRf^5RagBv40^b(>VqER#8Tx=TRP@&lK|9hJ*I`Zx6I1UQ;fNFqBA zt=N(R5|WXk8H*tNzCIhD|Fo$))u)qOgqMD}0Fz4umOsMJynSf@zWsyPWobxInX!~e zlpwn3&mIQ?d5yth>Tk4!IeHJat6)6grzD3M-}zV2+v-@A{BYE4^a5mP$r$Pbwst+z z?BJw)a+VHA#q~e&;?{AA|Jpq<7H^vw2Euo6Cuo72L;bJ>VcVSoK-{`nd$bn9Ng=tX z+)mG{pwm&wtwTHm{kdX*WtcOCRs|gAUVKW9O0LtsH&u|WA^`-*^c4X%gByNb%T|;L z3%|}+iXIbj4C*~eb^0_mW+0%&T_-CG@_mpjG>rdO<5xPo_^;LZ$aA2PL+|$=vZAFp zfVhwpChpAGlU@KqTD<>C?xVYWcW!fPG@pQ%yB0@{99PZwS}4oTy#Q@-pQF0kf&sVn zf3^!rz!q&U#v4W#BQlab}-aYi{VQ1@+^lCCHGbi``QRfoWWdXTw8wx+iod+i~Wyds~T(qq2E^mM?Km ze#+}Z^88fD63!@Xk0P+dO`z?`fkvNGv`30lx~CqQc7kWaqw;#t$4_ilHp7VK{Ds+# zVglrYukHSbpDqCUn9HJ!kaGWyV;n)WmLlr=Guff#EvzM~jDb07uY z7>v>{2+*Ll9WFBb+&xO5FWl-d8mH!CtI4p=1m(r+=R^Jtx9lkb`qx(VT6|1lGkqjg zc$laFI5RKh(QmyzUN2^k9rAZE=k820&lP)qd1aGmj>6?uaMtetR|ESP((~rTEr|qxNu(iQUm@v}gTFoDrVjv~zSI`Im z_(rvHs;Ej)SmDV*xLDxx5tq{`W!rz(H=L9uk(=33DduP^eBEEMZ>Irz*>uRXMfE?= zKW~paQw4YQ9I8*f3L*u;e#rmvt_m@lZcNh3tm;0iL<9VwT^oZ-@uzWftpC zEe9~B;8h_^$Zjg=2Ev%Ms3W0(7J1nMq)YSV#L1=>4bdQcxdvnFEZKI_(^J8W>Sq`= zACGh$6v3*qj$_@EUb2rpPK^Y`?PTGFkmG=C`kUx81a2>F!l){3I~WA_;QZ3RFAuHJ zxT+{5HRe26VzIL>+@gLbUhw105`h@E(3npJ7KblDghD4`c2=&Be;iK z>jXpd;3?c}63PYORKEF2MJ@iPSz5iPj#_@qcWt(4r964S+MMVWH?X3PD?Z9B0IIGUoV?J`jqdFBTMKFQq zyECB1KxY8PyQm_thNU_~N*f&w>5ev(Q%@qLm@c&ds)#;-3e&O(3K)!1VPq zg6P4(+sk8X8AChZYBDwAXC1@D7AlCJwL-I^bFP>Vw3>UWfWX#3OSgQYl2rsm4?aV| zl&n)v(x*t}MK(yHVhA|uSqJQ$Q(ah0NiHkoo?j$vA48{4f(2V^j+u|=>Dv2%Rpw+Dq9Z{Q99jfi% zpMGKnPm61UL<-{SYi+O^&2^eG)z=HEEwa$0-hZERkmYvWFD~Ha54XDZNK0`eD(E{K z&^Ub+iLq5jtbzuS4iIAXL8bY$!=hDv@ifWy>)xa=xd=3SO@JfO)@OD%Nw@q6RGNm%rc z-Oy_WmIsdo;;t#KCKKr*@5v-^IbCSO!E|n+4;vdI6S)YH5rv`q+OK?o&&{C4Zq>}Dv2dw{vT@(!KDw-pSC;6U z|Hg(Z$V;8zS*jB-iEQ(xv$9RsCn=9$AwD3ypCjbH1=wa&RP}d_1)3bjTm&GhcV~NF zj>w|~Vk>JfKwPeTDa!KKzI#mM;MxnJb)f!GsyVrdglRW2&zrdqIOp+w6CsNMYX=a? z5gFOqpet-Wi|-R*C^T?vyQJX?#dBgp{WzAICmU+PxG4#7p&M&1@d)@}WB;`)onyDo zIVAiK!3tgKRb0aYk?H~No8%I7CV9|2>O1Bnx1zkp=AhXqd0vaF&S_ zPrv1N@p1{;dsZ;!l029~a|JZ8HPH!|Q}>Xj7BT=3@G2-DNiubwXxQ5cC9yGn@03tCWLtx2263JAg0k z+e;_$B_R4B^W-Hpk=jA)3b-6w^*#7*^s2lFrLe8h2a+i7xtzNawoEYb(2Nt z>4!q6E+2Jp-)~o>N`XnU{KDMjp0~)K%F!2v0fDKaYJEbb*;QqHi5Tp&2XsUsy&)_l zG~TwU+xixw)3w!VKj;YZy3C)#=I^A2vatEe5-fwxY_CM0SgSEqEt^{&H6R8>6ub0c zp|Pbk5t5Z)1DXgAz%p8ZWT{=Mfqc@AxyQzqSP{X-=U<36cpYu;7+G#WZ&ptpKv_<_ z9J><0l`!;8m_(3D*V9V3rm5ukD}&2($qEQxeLI1+z&^+{41noy4mMpcAuCBFxoB5) z4A2dwN&Vh@G?yD==93m>0o}R(7sir51yz`HI4eXFM665kB#MRvp`e;wH%{jIg#^)2 zVOweDw(ilQ>o67#fIv>*k%;_IaEd?}eomAl-Iqr=*d z6O0OyKB~o)N^E454IDsV+QBpFDJpaPIc_tqKqK>Lay7xP@kDTQMtj5m)_g8c1nC-v z0l&9G+nZn|04g3dD-DmHk*HKUxp;&Rnxav2RgE{n>OYGDO2#FaH-=-GoE#++7&e-| zYB?}WS&-RFV!}){(@=}Bt*Nr)3~Z~tct>>sR-lL4TUki}e|`f22LaKDIGYK|(IdO! z3us3;HA=?HXhHAa6ld~ff&vK-tIy8meBOFI1b6_?Mk(^5NJ?!l59UTSW~Agkor#X6 z1$S@D*+?RU@x$YnN_hgLwGlz!;lQW5Q7aX~T6c~neVbl9Fk}0)UeP^WKe}o>D*xiB zPNxfP8KQb4B!0*dp9DdEG4gy#7bHNi_^v{3tctSNLNH$NJ+-}36R_sR)hTT`5Qr`d zr%3`$NDO2bYUrBH>9q=7%zLE5vCP@x;KurMyNM)FB zOpgIEY}BS;9Y&m~gh?Ol4fRw>D4FJ8%Nff2o6dJG9-jPwja8{<4@h#=kJXeHk4Zok zl{UKY=l%{;HTV;n=vPl{X|u@g^vcM67^Z4GU?FHB!$I!^CVK;xWISMCG?wroF2Sob z9($o%a~(0!rmwxJya2c*6~D;!?4}B^_WyY;8*Dr47gXgAT0cIYdps%M2Efg>EjP`F z34h~bVtCmeMbIk#M<+;FCVuosO$UZfB#4m>frqlG){d;Sl!(vs`&GhMAzT?Iy=-4n zf3%20yQW7qK~g-{V7WXUgRHU_4z-b;JqU_PK}R5hLS<(GYj8#-n}fBUArpi-K1WeP zSQ<5IEi)F8&@sL(6***~ILcjtgPVT9d>i|waoZp-1Y&3nzL3g|8bgT-a#Obgg~pn| zszxS>&I9;IP3~jf(|fNpISb&BuF|~pcIkLyM(%<~)%RcsLkBkb} z4x&;CnV&`Kcqf>{_gCd69^JV>BGz#8&qhxTr%HucVxxZW-!P9t{u^PY67^^8Ny;l4 z5q8?Gpwv}2v6xJ?^yNl?r}u#AZ(vx(Uw1N5_ge@Ii!TgGnttH`$voKZW9Kfx--+Hr z^t_qHC;3v1=iOzq1rTjEI@mEiX>yU7FJ{s#o z2vo5p1s$NS1s5@axsc^JPP&n+=MD3GY~Egipl`A>&)W|<1&LG@hdRE_WGqd6&ZZlU`KGD5 zK~HbLZ};t;uCu(MWQG(t4^OeTR+{5gzxl)UenG9#k^cFU$?ygLZ{@WL-tod><8$T5 zEM$0HoUrE@_|Qz5E<(@`<}@sud`#^*Tl&9h67O-T^2KHA_N230930WYxUB z0BnMhaN+3_`>Nj))-O2LKKqU)Ww=6E&*kMvR5!;8e?$a07XW&Q>G8-plCDnGxxzD9 zp&ogI%99%}X+{eG*(c0VHIn)#(G7<403T&0IjL+HntxANGCPtah~IuREw$3dKkMzO zVN%WwEC=w317v z)snXVIBhYc!6JU@p4I@>zfLvdMt4wyl%_qNf9QlcRldw~MwlY$N#*o%G-?L%2g4OI z3|MppKW@K2XNM-n{&N*U-&{hnz9HeY%p)g#2|?2NB${x@puQ?(@6E0y(OD(lKuK7) zlMV7*Eu!V4Is~HQq{$JOn>_v-0fMod(J2tpajNLo5!2o`NJ77EaHIZgO{TIDBr4Jm zJZW9)Y~=*NnJ!lzcfb2Xj@FBhy8^?BzuW2>S`KPmLCMprv9{W00p#x$)>fUyqt^rU z49d5G)cZ#oo2t|=MnQ&HaTeGCL> z;3m)a+Z(w!{jVDCbpUkzTW3obqYb{PTRvgHy1;1vMr44^A6S{L z@-v~dZ{1QiomR(xxbEP6UL-gF{0*ej7L2C;MCPbXaQGmo6tWWmv9T^~%u{T)&Y$)J zcAh^0J99C#?RYW{Zmi42WX{nhAZgFbw8vg2Mk`Jk)Rn?cjru#drjO20GvQosuf613 zJ#x1RI#TU~y*|y5N0CBJxeVP2+Oi3?34p_dXsI<`efp^BY2y!o0wWA-CAL}l2fa?? z>C=bf!Lzy-0$8(Xk?bY)E7AxyNSPwR} zZD@poLdPW=dA)jq{;6|Q=l}$#b8@WLA{=d^ooBH!mu56A0c!O{O6kB^x-hW38om1_ zCoVNYhHcM^i0vVrZvbJwdrN?dNahJIkabJRVv^u7d$^3a? zPu}Z4g$WQU_bXLlAn?BU1Zy1?!@8T5C*O3P$qFo`e2y`1x9{)IKlhS9>L(sSC3^bh zzj;!j4AU%k;eOxpc&)}jDjD@`Mzq2`r{Jc@9x_Op(kqLMD6UclSENx z+Yv9x0BFI6q)gO$i1~8rCY+|&YhEPtFt_@rs{N^b(o$HbreV@P9V@m}Tc?uf&>BnZ z-wA_gs2Q}@UHF+i=y5i~cg-ogJ<7UDb!1-9cGJ3{inZi6QV!Rze&GWMY~YNJ(cKj) zonhVTV7NWzMtHujO~o7-1Rl3fPAkmX%IUf5gE)7Ik|-?dOmN1<;KqH({Cbg=vP`!3 zxK(p53T>#Lftp|SNXPkqbxMs2<~lqhn}v(AURuu%e8N&$gwDyJn#%aGRv0R+G*!N2 zeI?D1x(4$odOT9UYDO9w_P%_N796E2Zlb{a1{uX ztMLpo$4x7dlFP7#h1=C~uC^^KKpkgd^BUSxB;hQdYJ-Abosn2Ve_j2sX2|hPf}7`n z)+W>{F||Abd#HWIAk_W(iB!HQ!&se*aAiAB>RL{#oc^1?E^iZ9kXEkE+T%5#l55~f zX;beV?!7&r5R_VP5f(T3^8KH$^pYY5aFN^G%NG8@hD-4q%wiG)6qVKME79BWHrE1@ zBB(}UnP|AP2f-OFoadYaZb{wr%7t<0h<_yv5UuwnySk9&pzXYN=kK;+0?2(aw$N4E zKbxZgNQzY))hE&8fxLwChy`fB`_%_Pw~VY|4qO51n0-(ZX)p$0_3c}n$p5V-9g4N3%^?ROQnXx4Zr(I;4We!Dpx z7WvDH(P9V)wXKzOzE;g-!}vigqMU53GJM&WreURs$?$h1A7OH(scD-|C8WDD}Z4 zEvm(9@O8PUvd>HXLhM>-fHUm_k@u4h3TYe+s;dM*jV$~1AO*hKXh4NKIzdx9WQc+x zul+p9q0vGIGb|vp|1L>xHBmv{7GzNc)lGBV;DP^l;!=9N8TKdTqPB$LH^4(291O+Y zzx!O62vK^>w=e&^pke1Kj^3#tah5-FU|Z095d{1(P3(9Ec|r$P1D_%u@p*rKD75$O z@(L#lx0MQFz+yB0N)$?4bj)(b8p$SbphsA$?wZdm51PPden{tz_&?p^88+m({6!7; zsVpLDQM`Dz?nssy^<#u7Y0}+Z#F?bo7W^4;K~Hw*;cIbJt=?p)4uigp9L4BxQMyE0 zyS188n%z4ZR(@3rCL<}6P#0N&0i)s?gx-2ipJ-9cB9OuplYc(ShL(P8&|piNOHc^K zXlRW7Tx<9??Y@+uH0SH|LJ54WfRjsA#6>e_RjqU?jD~wiNRu)xH*$VLpDmqVZ>tt9 zCBXOj$wESh2ztE&E)h6hl>)`DB|eC))-AigL~dPrb@zxHTKPyMS9%u7A+Q$7dZqfI zk$&VjSxH?Als(cAc8+~6&4lQ@XtEJ&WQKlFbUbH95`H?QeQ@mnbP0wm0DSmfdTJP@ z=?fCI^3;JW?P&@UyuzYg*{bK0QaTe(x1>-13% z8MnaOaZd8|1Jg{UwqABvG^dN6BvRTrOv|g1)Fut^FA(_Kot) zM*NfaeJOcdQwJo|E1C*Pjaf~vG4Q0~>XZ_us67IQ@p!4Sf$zgyT&c#MwtQ&>K?-l~ zoQWHwt;-@O?Mf+TiCU(0R6#%GCj~B}cJGSYfcsn!b#HX)Jhx&>6zfDk&xkDc+e7x? z7}Ewu;fBXU%s_Nz=^NS}xhEtt1Sp+)9A3Y*>&4OYKt4Oi$_%6Eo` z96PQxGGqgIrMw~t`_&Q1pri>i5@V!q;;zz20c-$g9sHDDjVED+$6iJpk_!Qn00q)lFxT)T(9xZvdPn@Zx@;KxQlA`p4V#dL$r?0vK z#496&fdfc{c9R(r!=Zzb8Fc92$j!xh)lzi9H2GlB znSAe$_P$_!K*m3CDrOTn0;_yPIDF4ZbW0L2O^j=N%{bL;2#BW)y?Rgsd+4}3KY%P0 z-BFB>4A9o;T>I@@VZJg3Mnh4EKi^*Pr1|s-hNL7x!$p=WDXgAMe9An?De#ibF!8RH znkN(|i_PH@IhwLnRZ3DY5(Pjyfko)vnY#JfZIa6_00RfCVfZYL8GP$1Kg zSxw%rdN_4?H7k()3il1bEWy8v)nEY2&K1TyD@LxPFt?DN$1=RZSofegOtLC z{~Y~nRpL5rY^hcfry4I7-m6G*%gt{js|fiV*;bI*4*cTehqM=Z3>i0}E0kkKWI&EL zrXX4_fcy+>L9LxOJCUuM=b!Fq1?>N%_yZ{A^8$ULWXM74=`}deD#}G&rH4l#n^u-I zw}>~8$;i0&l}!R0T*Y6PwT4HIKE*N;v$u{|p`f8Ie8S3a(Iffx4+`Ad5@IjYZSp`2 zSA``n6$?y@|ps{g?7S_aJarcsRQ48N;!wJ-C>$$g`?xGFka71FXx!g!ipiRO@Rx0S z=X#)ga%yV&S})X|h7hURS^TlngqRnBP-jl{N&=P42a{vArGRKMFsFqAa|i%X^|mw5 zRWEJS-bLMv>$P-t{OK>?h`XaJ@E)|XM1WJ@E8(G_`bJCh80kTWrXcQ_7=xCWv;!r1 zCsq}x&2ZP;r^BEfV=1)==36hp))Bs$P9)it`3kHlUQP-xQFjE5bS4TWN0ueoT_9rI z?K{M)VYj|ehO~vToj`Sc8pYG|hXE3gR5@*Jl?)Wc*)gnhi+c)gJu~Es3u9+&*)c+& zDs}-|E~3W562MZy8XZ$qq+t)_@;5~H^jaC35j8yOsac^C0Rpe0HImV@1@RN8@c>J4 zA;cQp=MsPaO4`o(BAr&Nq6!hErY?ZlU`k$m~Ta)k|5x3-Dq01 zheu5$EnL9~$xIW3I_8(34oO=%mKew++QIXjXjO1C6AMp!n$cJBkn5_XIfYM?>l7e!n<%)+z_s%Q~55gH|W`u^cwpj8BtM0z)fqm($%15QeACa z$F9ozfSw)fSKUZoW}Vc-26153+B{l1|0uW4!a>#r9nx| z95$_0cY@aVP2hR`VqQ_aCnHV_b5fujF`{6bS150X}Qc}^V(D}U5TQzZxHxKkYT1yQu{RSjh2 zGPV}72-?#O7OWo%`S+QlhS_LH2aUEYJxVT=g5@_kGM}P{Z3HBILDQG$lI2j61(14o zT{4@CBN>v^C)EO>`Q*h+KG&^I_(lPzdwPE7L2W1eo9B5w>(*!Jhup1P-0#>gTYvGhL8gM}o&b1`3%g3!+p~9lum<`b|Fa#OM@2LA+5nUl|>jwqe92->0r~&3ot10ZVyA0a!-)AeA|zl!${%s#nV`W^@sH zRk0mX5Q>753Si@Bix=NeM*P>uvwM0Pc!MkqRSd2;RJ$=)X#&A_fq{)hr;6LpVpJ-uMyj7=B=Yly zXR8emTzwNtA#GpC_Vn8O5P98Lx_r?OkN}(SqEo;A+3uUatn zUHoX#Uc~_Z=@hUIPZnb`zKe}64@9^O^GG6-zAKt?qLJwR>&!7)?4AQIVnV^F;>KtJ z@lc{+7u~83Sa%etcflJP?TQ(hAU)WAjB_KAB-j;VUMfnlooh>jY+(7`m# z2vcV;^t9TlLc<$SH#p7x9bJr~4vO@i-8h(xy@flAbl-4;oS zVBZQDUjMjddz>1*#w6lrCy<7vq8ri#BS!H3y4 z4_5!1B;4tSNlyE_f?)g47ePlU`P1UyxJ2z_B=}yBXG?NZ8wRGP_U)AP%Pr(4>`*ox zV+j92E&`_@Jwy@w&6iS-9s@y!LC#?;35b9Ml6-Z|)q2)K*Tqut^`3~k$KdFmdvl*( z81+7&&2}NOq0BYORFjIG&AHI6R2qqVL0~bQAClifyaJ-Z9@=h$i3@bHU$weqNNs_3 zq_q73pzL`K5~1L=SPv&4G14*`8MhMfRIa-bDB{Y@twI!Pvph8=%1*phyKfdS_F(E{ z9p3A=Wuc_$L~i#PK;xZx0jpuVnHF6#5di_TSzKVR$A*(rZJnI`Naob{h2aNDfg>Cp~W zQn=nFlJ55Kq4#rlD!Q@TR0bvLA>!u8@bF^tu?%nI)k)>;fKGFS@N2eSoP|@9@|atw zq#o~i2mQox>hEpY$ertP5t7QjvDNh&6ZlXcAkID`^_-a%6cC)gE45#;1b@@n%s8+l zC**PCLyH9F89uhO&E54Btl0XaXNkaFEGYQc+?xna(ZxW?PR~o~l0d|hc_&44o4Fw- z3`u*n9e?Ya5omM1lhj$7yVCZ+91gxcv6Bu;D>>2R z=Mz3$UNw!VZ)b>oQQhBj)wB+qBdnLPNG&T-A()5iaTx^!F z(Q@O5-+CQDoEf0i|0UK0p0gJcRRh%=DS|{L?F-E4f5N+aU?!OrMICChLz*|a zi9krv`A}dFu3V#z)zX=5HI+pB^j-rjV`>YtCTx=WC>H7+>`Brz94(UWFTDY?0`Vcm z$ka_3>fS#(2z#2MWuVoay9s!=x`o3Ok{)CNQ$}6q2oFixzmA~A82BQv#as>{eAU*e zh)+*?sfR&AmB084!^VY64!(9XtF|W)H=eFk_u`dU_i_%uqK_Qe{h9{2 zqS5J{BeM$owgkz2csRj)zhxydch+&Q!yuo(nWQ&v z;*YdLlAIz002!Nd|~Hz!vHV9Gf-&*)P5bNmB&9Z-2%Th@H_5mNoeLjwMI-I1O=#8oMdD2LR|xKynX88>u`nzR53fc8{KG!A2iXk3CQI3AFVPL<^0K+-Zx?0+JKPdZ{?qHV4c z7DsFI4n@_5BJD~wpxB)Mf> zlCzGZ<6sf{#X0tfWKeQhkrf8Q&4-3*)0*UELwb3;zr5{zpOm|ZPj#aF&QEZ?iSR{% zZdA_t3Yhno#x#H0;X8fKrvP|}e`^ie!Cs#pt1nLEi|6=Wv9rU39!o%Po0qocbryLO z+0l=~6{C^N5G1rY6ph$DOWjb@py?o@Jx<3p!7NQ>6ra?g>8p33X6IbXik~fF+1QGJ z0En~Qj)l_Ai8U}1rwR6vX&kMA#qh56R%yLZpk9&OL?IUejp!+&R~TM&MlE?(*VLrb z;Cm0d0hdW{`YAayzql(w5TW&%Gb$rqtwSe3-qqQe>q$qQ4rfWCA0av>Fnxe}d$(p( z&j!_(SM)%IN!e&e@dt6-`JqpLiLqb&apA{q{5a_NX;O*yqjo9+HRuZx0Z&Exd6Z*0 z(hq`bnEQBZ*+Dekzq`NidVfe89KT;TwjaL~z&4hmaQ;830?&;G%7+Oua;=3qk9dK*sBbI!Tm>T&q7N3v*;J(g2sXI^NnK zhvR8lp{N;OF(%%8vx@l)Wp;~Rq^A0N)G#Y00a1;Zez&N6ku;#qrRgipJ-%QBLNV6lLOZ|2>cMotC{6k&J@P-3t#Uo2tpTdix z(Y0H}s$2#r>wnU!x0Obo%gnLljv|2 zs`MtlNT*`v>lw?XqK-wUYTXy?zsJQb@i7`4JB)V~jnN#nff_tn$X82!H7KRC`l2Fe zh)&BTns+Y^B||zKZqMS!0nqoGET`dLC-aLQ@`_Sx0G5A=_a;S&YRGlTTvBh)C}?OI z6qx%B{X@@^D#1N18Drvi3seMU>I-wEv-5p%LC({$Lga=^Fr+{Qj(YKxA z!0RakedIx05g5^{N4*2Z4y~Fq8x5nFxk3?$95p)f}eg|hLQN=+n`=ejhh z1LQ@FZ(3-C;OfcWvYdaS0svorfBs(T$4{$0sr)_+TP=uXaE(l zi>nt$cHc?ncH&FoK$jZm49ZEaTmQ5`XXyMwDi;M&)%`lU{y&j#O@W~HQ2UhRM{*VI zrXKTAE-=>@hb5Z)1?gB31Qo_a*<~6toO_Q)O>vvl2|OBXJq>eS=pbdW4434p@>NS0 ze)LvU)3d@)*+vSii*yVhAA32K9#D{Lex-y-&Y<~<>91b;6cxT^Gqly08(~HeBi;?h zk}Z+8Q`=~gKQ|njnViJ+o9`<8{R>#mM}GifaV2<6#j7Y5Jras$OhXTtP(ee6^?6K{ zrk*KGPwYZ#;X)sB{YafMtF^)I{aUD50!NTG;#N@W$cSEo$!{9$yJ*P9c~k-LXtyp8 zfMxXpT+ht84D3*(-c%XLRmCCVrSI>>BV7*8m!YKfsVu?z~@KG@j^hG5d`(nOl-<-lU+c^ez zMwK*3wM=0L$?I|$%2j9sHWHCDug_c6v!NcYV@5gaBJ*4lm1CCId>@>03bHC4FK94i zC3zoXJ5>;j^RfzIH(wo&>c-WZD18Y*sn_)NX7p|M6wQFU6g zZPYzqk7EUcCnvj9Qvn1-h*JxP1=uFGe8~{<9vCLV%!+nt@cXXG?GWA!-KO?$5+?8s z>-w!Se30)|Ab{JL=?0@L>KqJBf%l~hTRYgw@8Ib`X-3z$1|XVitmkPTqd;y?)JDFm ze;zKfeKx^G&tc{iMGPs*C^bo5#{kn6TFqiQ$uleqM3l&wy0lq{Yqi8csdT@Zwb)zM zLX|-=QoYu#Puu!)O!0}Bw88NY3&Xhb7pu3&FQDD%a%cYJzP6UmIB_O@I;iF^zS8Fp z@YgT8rZ{j{=Zvs4J{0?92&5)`bA%r$w&5T{6mOi z8!BVt8&M34l!$HTZjoOCiJC4~4g z7?iytz?jzixc0Le{iuKVH{Ad<%|!#ft={!+lLo;m;%ON+xt2#6y6YXSG9)y-T_GS) ztW|=Eng&Fx8M!#k5@1!ysu`S_#14fJ6T?^n@*tu+AfJz#-Oil2Hbq5L{aH>mN=NG8tz=`sx`(% zi^4%2D;<|?r<8ITSm2%!*bjNe2igs?af{*v5&2$4>RrXlg$W+2lIYmBpx_+(2h^6%z3Fb%vsr7ypwP~!BI+Rg zH|b&p>GeJnT~Dvse=FeTfQ|e1T$@iN*beLV)(IJMcmSyjSPuJC^=%_7rV2dG29~nG z4AsVL&0SH22ZoXOAaBKuQx%)`mMQLmy!~d6Bby+{=HjqAaBSfB+z44&--Pjhra-=x z&?>`H5uCakUQm%X0-4?*+@lcl**kf0$v5sG0jiGI?P)O6J55aMqPS7|G)^T}cSZ%L zLZ6KNzHdGq^;Tz{GPFwV3XC^YH~~yx{8(!yBh$)ggK892kxFJF5|p zv3$ez&@F!T7Wv?JYeUEQ)us?s{wt}J_KRvRe0T790|5Q;-TWe6@o9AjRCuvfJXN9B z4sorVv?G)$;ILtB1CKqSxrd6+xE&?V`07cmS)qR)CVLs z;HyI8gV8HDtx}aiF;^g6l^tS4aq!>aRc&(a&izYFw_G=RJfXw=^^6tb_1R`;)g-mm za;K*t0^VS8>QSjdnW`{IuFa{cN4DjQxJGHDr8dN#vLhLlZ;G%CU4P8>cqW-8hGtRlM;49MSa*N#UwnQ>Ip4=(;$nPB10&M5g(cUq z%{C$l#IqB?HG1aqg)~7~POCEAf62h|=+^mZ!$QG=OE+t)Sydl2FKkK+9Vyl< zBo9IspLabUB6~tep1$3F>I>bPncJj3|G8wI=js8iz<`eRp-M*-wGMR%{&0!gqNc5> z9LMQl>Mxnan&|*qWHpCga;Pb&no(kV2+ZeY5C{Y_Qs@T=|DI=v##;oEp7f zRjK2#WB-r6q7g6C9I$`GL>{eOc@Vvnk**)*SPoZG4na}0;?7-avgVaQ4C|mex=9(N zULB?-MxHl^ir7J(fQ`#lPIHb3VVFQMrGqv|sDt9XU&f_aK86uvIwMZ{Y`TB=u0Ypr z!|XVFQX4@&U4|MIchK5?70QEd6$N)nnFsJy^HA~j!Z_Vb+=xQ$2T%d45(kqenVMXP zQ*8Z@o0?7C?dPLeF)w`Ov>(R0{9&jA!n zl1h$ki1U8{|8(cP-UQ+&bTpY>IDX|uiX~()%b*{FWmBJaU*u{#an(C`gCGC&7b|E# z2$cKkwt$+X6{K~Gsx29BuJhs8^L>toy`6A~U>=bTNASA~b4LbGv_x}e^5@|*PiskMA0000< KMNUMnLSTYX#co~z literal 0 HcmV?d00001 diff --git a/src/assets/video-placeholder.png b/src/assets/video-placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..77e3218eea898ccc2fe477c1c6e3180ecb070297 GIT binary patch literal 3814 zcmd5 zQUO^xp|CycsS64|uoelH$D+&2A|L@|5iN=WMKFM_>^Fc_x@XVXv!^}s*S$0M-rxOw z_xrw?d(#5_y)@J~Y5)KYZ=QQF04h*LTNpGbCW|bip>PQF4e@~T`Sa&BH8l!_Vrput zzrSB1k&KLt*xTC=4Gr=6{F0KAyLazG>!U}Hu3x|2*w}dJ&>@*jwk1oG!eS=|`+scP zE*7?y@Ebq6$&1S?u1LxZ5?skCPX=JAx3{}X$f2&MZR-&^&H@)>tE&W|^c8#~qjK<- z;27{ju`-Mi&1C&u8<(08xDQF31}SS1G$M?2Cgiqqgu(iS;lD=wI);B<_*fN%3j@br z{Y~{69_2&IAtOr!-HKvYFvdP6t5X}lU_wN`M}xfc91Wp3y1Z`xjL$+A5w$mUS;%nz zVyN01YH#+E_p~jADk6y=8*;Ha@jf^7m(<=IGo6>h#C~fQ7Id)v!s-2Ile-_TI zkcl^J)2VqGBfwZEOh{raf<-ZLmJdh?M;SHR1b!Nz7k@L;K)fQhI*dhFbtqnLA63Dm zwOY7=_{fk>%z zP;pG#@jH~Kv83<7wyr{_w5baT>&!G%cCb7xj;{~;>GDkN-oVlZT*!*udehZRVusU#mCBMFv2O9Pw{C&!NQEJ&=p`jL7t&Fu-oqO;E zPIQrvAihceJi%l)n*5pkoF^d4j_1 zH`cB9t zXl`-dA}Hg0ftkpjEO}sROcpys-jiI2H6Q*e9p*7og&|*}xo{UWHE*C=gt>&G0gEtp z3@S^IV#P^hQ)Py2wit}v>NOa!Q?CtNwt*HH!mNHBcKd|2%k&FeQkB$XRMKX5^szt( zt}@Y(bl;~76$ZY4+ba1+e!U@iDUm+9c~xo|i{Nab@^53{T1j-MpgiZ>;MU|ni_BM63$W7|I49O5*YJV_kRs^iR7zA5e!s5WdI*Jp@YnRV5 zXjr~{mi=-!+6VPY#k!6-20oL|nSJMzFq=Nw1so1Sc{SZ&nt2M8S#Ka;V=f?q!y!tm zaq_%GU8YwEPaK`zVzvV1HB|tP8vz>5=n@Ix417;H8pF~-iX(%8U%xS#t*$1^G=eNo zF=fqBMr4QvQ>IyDOm+_!fR)EIXSyp5$znf7U&qww$PYdGD6jW5Vs}Ig?zq{Io~0FM zf%Zia=z&h-pR37QEjTQ~$bKnQFllHgbo9`3e%c+hndY+0y>-luspZ}?6Qz>>NB6pD z#t((`ridDG>QNJt>!i_FO@ZfcrDE6!_uft**=|VM9dQMko~10p+*0LW*Wj0>>lnD7 zE-hyKq$|oR`v!0-U4fasE%~SB9ClF{1ON0j)-tGb8Iwk@qk!Of&Os8Dp0*Is4Fdk; z1CJ!d?iLe&tO=z*^w_F8Iyfw`g$J1d-%K;{bCgF3ye;u`92 zDPU)WdlpHyJyMIpFkNKRje(7 zG6_0l(nlM6^hL8-B->j9fHy_;Vg?8vP60>tE29i3YJEG4!iIY*{N4gQ!diOt{{=r3 z>V4C#-)M?r&%cvCVLr>xPRzNr<*|vPuyHnFvj)tE!ng{@EZqU#=sNDJW; zg6ez-Y1IU-=e~Fv+qZp?>%!*j{rB8&sr@_&ST8K&;+qo)T=+zW0f3PobUI&(t)^cU zhtH2!zs|5UJE{F&P`yAE@52}^-1(XB-oje`$AE=?G4;Uct|_~oI=9{){_Z8Nk;nfH D(_0VV literal 0 HcmV?d00001 diff --git a/src/components/Button/Button.jsx b/src/components/Button/Button.jsx new file mode 100644 index 0000000..4d330e5 --- /dev/null +++ b/src/components/Button/Button.jsx @@ -0,0 +1,13 @@ +import styles from './Button.module.scss'; + +export const Button = ({ children, onClick, type = 'button', className = '' }) => { + return ( + + ); +}; \ No newline at end of file diff --git a/src/components/Button/Button.module.scss b/src/components/Button/Button.module.scss new file mode 100644 index 0000000..957e1ad --- /dev/null +++ b/src/components/Button/Button.module.scss @@ -0,0 +1,10 @@ +.button { + background-color: #1cc88a !important; + border-color: #169f6f !important; +} + +.button:hover, +.button:focus { + background-color: #169f6f !important; + border-color: #12855b !important; +} \ No newline at end of file diff --git a/src/components/Docs/Certificates.jsx b/src/components/Docs/Certificates.jsx new file mode 100644 index 0000000..bfcbfa6 --- /dev/null +++ b/src/components/Docs/Certificates.jsx @@ -0,0 +1,146 @@ +import React, { useState, useEffect } from 'react'; + +import { apiUrl } from '@/config/api'; +import { CertEditor } from '../Editors/CertEditor' + +const isValidImage = (file) => { + const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png']; + if (allowedTypes.includes(file.type)) return true; + + const ext = file.name.split('.').pop().toLowerCase(); + return ['jpg', 'jpeg', 'png'].includes(ext); +}; + +export function CertificatesForm({ initCertificates, onChange }) { + const [initialCertificates, setInitialCertificates] = useState([]); + const [certificates, setCertificates] = useState([]); + + useEffect(() => { + const certificatesWithPictureUrl = initCertificates.map((init) => ({ ...init, picture: apiUrl(`/uploads/${init.picture}`)})) + setInitialCertificates([...certificatesWithPictureUrl]) + setCertificates([...certificatesWithPictureUrl]) + }, [initCertificates]) + + useEffect(() => { + if (typeof onChange === 'function') { + onChange(certificates); + } + }, [certificates, onChange]); + + const updateField = (idx, field, value) => { + setCertificates(prev => + prev.map((cert, i) => + i === idx + ? { ...cert, [field]: value } + : cert + ) + ); + }; + + const replaceImage = (e, idx) => { + const file = e.target.files[0]; + if (!file) return; + if (!isValidImage(file)) { + return window.alert('Изображения должны быть только формата JPG, JPEG или PNG'); + } + const url = window.URL.createObjectURL(file); + setCertificates(prev => + prev.map((cert, i) => + i === idx + ? { ...cert, picture: url, _file: file } + : cert + ) + ); + }; + + const addCertificate = () => { + setCertificates(prev => [ + ...prev, + { name: '', description: '', picture: '', type: 'certificate', active: false, } + ]); + }; + + const deleteCertificate = idx => { + setCertificates(prev => prev.filter((_, i) => i !== idx)); + }; + + return ( + <> + {certificates.map((cert, idx) => ( +
+
+ + updateField(idx, 'name', e.target.value)} + /> +
+ +
+
+ + updateField(idx, 'description', newVal)} + /> +
+
+
+ updateField(idx, 'active', e.target.checked)} + /> + +
+
+ + replaceImage(e, idx)} + /> + {cert.picture && ( + Сертификат e.currentTarget.src = '/placeholder.png'} + /> + )} +
+
+
+
+ +
+
+ ))} + + + + ); +} diff --git a/src/components/Docs/Portfolio.jsx b/src/components/Docs/Portfolio.jsx new file mode 100644 index 0000000..ff8897f --- /dev/null +++ b/src/components/Docs/Portfolio.jsx @@ -0,0 +1,152 @@ +import React, { useState, useEffect } from 'react'; + +import { apiUrl } from '@/config/api'; +import { CertEditor } from '../Editors/CertEditor' + +const isValidImage = (file) => { + const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png']; + if (allowedTypes.includes(file.type)) return true; + + const ext = file.name.split('.').pop().toLowerCase(); + return ['jpg', 'jpeg', 'png'].includes(ext); +}; + +export function PortfolioForm({ initPortfolios, onChange }) { + const [initialPortfolios, setInitialPorfolios] = useState([]); + const [portfolios, setPortfolios] = useState([]); + + useEffect(() => { + // console.log(initPortfolios) + const portfolioWithPictureUrl = initPortfolios.map((init) => { + if ( init.picture ) return ({ ...init, picture: apiUrl(`/uploads/${init.picture}`)}) + return { ...init } + }) + setInitialPorfolios([...portfolioWithPictureUrl]) + setPortfolios([...portfolioWithPictureUrl]) + }, [initPortfolios]) + + useEffect(() => { + if (typeof onChange === 'function') { + onChange(portfolios); + } + }, [portfolios, onChange]); + + const updateField = (idx, field, value) => { + setPortfolios(prev => + prev.map((cert, i) => + i === idx + ? { ...cert, [field]: value } + : cert + ) + ); + }; + + const replaceImage = (e, idx) => { + const file = e.target.files[0]; + if (!file) return; + if (!isValidImage(file)) { + return window.alert('Изображения должны быть только формата JPG, JPEG или PNG'); + } + const url = window.URL.createObjectURL(file); + setPortfolios(prev => + prev.map((cert, i) => + i === idx + ? { ...cert, picture: url, _file: file } + : cert + ) + ); + // console.log('==================') + // console.log(file) + }; + + const addCertificate = () => { + setPortfolios(prev => [ + ...prev, + { name: '', description: '', picture: '', type: 'portfolio', active: false } + ]); + }; + + const deleteCertificate = idx => { + setPortfolios(prev => prev.filter((_, i) => i !== idx)); + }; + + return ( + <> + {portfolios.map((cert, idx) => ( +
+
+ + updateField(idx, 'name', e.target.value)} + /> +
+ +
+
+ + updateField(idx, 'description', newVal)} + /> +
+
+
+ updateField(idx, 'active', e.target.checked)} + /> + +
+
+ + replaceImage(e, idx)} + /> + {cert.picture && ( + Портфолио e.currentTarget.src = '/placeholder.png'} + /> + )} +
+
+
+
+ +
+
+ ))} + + + + ); +} diff --git a/src/components/Docs/Stocks.jsx b/src/components/Docs/Stocks.jsx new file mode 100644 index 0000000..edd1471 --- /dev/null +++ b/src/components/Docs/Stocks.jsx @@ -0,0 +1,196 @@ +import React, { useState, useEffect, useRef } from 'react'; + +import { apiUrl } from '@/config/api'; +import { CertEditor } from '../Editors/CertEditor' + +const isValidImage = (file) => { + const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png']; + if (allowedTypes.includes(file.type)) return true; + + const ext = file.name.split('.').pop().toLowerCase(); + return ['jpg', 'jpeg', 'png'].includes(ext); +}; + +export function StocksForm({ initStocks, onChange }) { + const [ initialStocks, setInitialStocks ] = useState([]); + const [ stocks, setStocks ] = useState([]); + + const startDateInputRef = useRef(null); + const endDateInputRef = useRef(null); + + useEffect(() => { + // console.log(initStocks) + // console.log(initStocks[0]?.startDate) + // console.log(typeof initStocks[0]?.startDate) + const portfolioWithPictureUrl = initStocks.map((init) => { + if ( init.picture ) return ({ ...init, picture: apiUrl(`/uploads/${init.picture}`)}) + return { ...init } + }).map(init => { + const dateStart = new Date(init.startDate); + + const year = dateStart.getFullYear(); + const month = String(dateStart.getMonth() + 1).padStart(2, '0'); // Month is 0-indexed + const day = String(dateStart.getDate()).padStart(2, '0'); + const hours = String(dateStart.getHours()).padStart(2, '0'); + const minutes = String(dateStart.getMinutes()).padStart(2, '0'); + const datetimeLocalValue = `${year}-${month}-${day}T${hours}:${minutes}`; + + const dateEnd = new Date(init.endDate); + + const year1 = dateEnd.getFullYear(); + const month1 = String(dateEnd.getMonth() + 1).padStart(2, '0'); // Month is 0-indexed + const day1 = String(dateEnd.getDate()).padStart(2, '0'); + const hours1 = String(dateEnd.getHours()).padStart(2, '0'); + const minutes1 = String(dateEnd.getMinutes()).padStart(2, '0'); + const datetimeLocalValue1 = `${year1}-${month1}-${day1}T${hours1}:${minutes1}`; + + return ({ ...init, startDate: datetimeLocalValue, endDate: datetimeLocalValue1 }); + }) + setInitialStocks([...portfolioWithPictureUrl]) + setStocks([...portfolioWithPictureUrl]) + }, [initStocks]) + + useEffect(() => { + if (typeof onChange === 'function') { + onChange(stocks); + } + }, [stocks, onChange]); + + const updateField = (idx, field, value) => { + setStocks(prev => + prev.map((cert, i) => + i === idx + ? { ...cert, [field]: value } + : cert + ) + ); + }; + + const replaceImage = (e, idx) => { + const file = e.target.files[0]; + if (!file) return; + if (!isValidImage(file)) { + return window.alert('Изображения должны быть только формата JPG, JPEG или PNG'); + } + const url = window.URL.createObjectURL(file); + setStocks(prev => + prev.map((cert, i) => + i === idx + ? { ...cert, picture: url, _file: file } + : cert + ) + ); + // console.log('==================') + // console.log(file) + }; + + const addCertificate = () => { + setStocks(prev => [ + ...prev, + { name: '', description: '', picture: '', type: 'portfolio', active: false } + ]); + }; + + const deleteCertificate = idx => { + setStocks(prev => prev.filter((_, i) => i !== idx)); + }; + + return ( + <> + {stocks.map((cert, idx) => ( +
+
+ + updateField(idx, 'name', e.target.value)} + // readOnly={true} + /> +
+ +
+ + updateField(idx, 'anons', newVal)} + readOnly={true} + /> +
+
+ + updateField(idx, 'contnet', newVal)} + readOnly={true} + /> +
+
+ +
+
+ +
+ + { + if (startDateInputRef.current?.showPicker) { + startDateInputRef.current.showPicker(); + } + }} + onChange={e => updateField(idx, 'startDate', e.target.value)} + /> +
+ +
+ + { + if (endDateInputRef.current?.showPicker) { + endDateInputRef.current.showPicker(); + } + }} + onChange={e => updateField(idx, 'endDate', e.target.value)} + /> +
+ + +
+ +
+ {cert.picture && ( + Портфолио e.currentTarget.src = '/placeholder.png'} + /> + )} +
+
+ +
+ +
+ +
+
+ ))} + + ); +} diff --git a/src/components/Editors/CertEditor.jsx b/src/components/Editors/CertEditor.jsx new file mode 100644 index 0000000..35007b3 --- /dev/null +++ b/src/components/Editors/CertEditor.jsx @@ -0,0 +1,25 @@ +import React from 'react'; +import JoditEditor from 'jodit-react'; + +export function CertEditor({ content, setContent, readOnly = false }) { + const config = { + readonly: readOnly, + height: 400, + toolbarButtonSize: 'medium', + buttons: [ + 'bold', 'italic', 'underline', 'strikethrough', + 'ul', 'ol', 'indent', 'outdent', + 'font', 'fontsize', 'brush', 'paragraph', + 'align', 'link', 'undo', 'redo' + ] + }; + + return ( + setContent(newContent)} + onChange={newContent => {}} + /> + ); +} \ No newline at end of file diff --git a/src/components/Editors/TextEditor.jsx b/src/components/Editors/TextEditor.jsx new file mode 100644 index 0000000..0472ee2 --- /dev/null +++ b/src/components/Editors/TextEditor.jsx @@ -0,0 +1,26 @@ +import React from 'react'; +import JoditEditor from 'jodit-react'; + +export function TextEditor( { content, setContent, readOnly = false } ) { + const config = { + readonly: readOnly, + height: 400, + toolbarButtonSize: 'medium', + buttons: [ + 'source', + 'bold', 'italic', 'underline', 'strikethrough', + 'ul', 'ol', 'indent', 'outdent', + 'font', 'fontsize', 'brush', 'paragraph', + 'align', 'link', 'undo', 'redo' + ] + }; + + return ( + setContent(newContent)} + onChange={newContent => {}} + /> + ); +} \ No newline at end of file diff --git a/src/components/Forms/EditElementForm.jsx b/src/components/Forms/EditElementForm.jsx new file mode 100644 index 0000000..a22b613 --- /dev/null +++ b/src/components/Forms/EditElementForm.jsx @@ -0,0 +1,48 @@ +export const EditElementForm = ({ + navigateBack, + header, + handleSave, + handleDelete = null, + isAddSpecialist = false, + children + }) => ( +
+ +
+
+
+ { header } +
+
+
+ { children } +
+ + + {!isAddSpecialist && + } +
+
+
+
+ ); \ No newline at end of file diff --git a/src/components/Input/Input.jsx b/src/components/Input/Input.jsx new file mode 100644 index 0000000..513f999 --- /dev/null +++ b/src/components/Input/Input.jsx @@ -0,0 +1,11 @@ +export const Input = ({ value, onChange, placeholder, type = 'text' }) => { + return ( + onChange(e.target.value)} + placeholder={placeholder} + /> + ); +}; diff --git a/src/components/Input/PhoneInput.jsx b/src/components/Input/PhoneInput.jsx new file mode 100644 index 0000000..a6e8ea1 --- /dev/null +++ b/src/components/Input/PhoneInput.jsx @@ -0,0 +1,25 @@ +import React, { useState, forwardRef } from 'react'; +import { IMaskInput } from 'react-imask'; + +export const PhoneInput = forwardRef(function PhoneInput(props, ref) { + const { value, onChange, className = 'form-control', placeholder = '+7 (___) ___-__-__', ...rest } = props; + const [internal, setInternal] = useState(value ?? ''); + + return ( + { + if (typeof onChange === 'function') { + onChange(val); + } else { + setInternal(val); + } + }} + ref={ref} + placeholder={placeholder} + className={className} + {...rest} + /> + ); +}); diff --git a/src/components/Input/TagKodoperStatic.jsx b/src/components/Input/TagKodoperStatic.jsx new file mode 100644 index 0000000..be80249 --- /dev/null +++ b/src/components/Input/TagKodoperStatic.jsx @@ -0,0 +1,58 @@ +import { useState, useRef, useEffect } from 'react'; + +export function TagKodoperStaticInput({ initialTags = [], tags, disabled = false }) { + // const [tags, setTags] = useState(initialTags); + const [inputValue, setInputValue] = useState(''); + const inputRef = useRef(null); + +// useEffect(() => { +// setTags(initialTags); +// }, [initialTags]); +/* + const addTag = tag => { + const trimmed = tag.trim(); + if (trimmed && !tags.includes(trimmed)) { + const newTags = [...tags, trimmed]; + setTags(newTags); + onChange(newTags); + } + }; + + const removeTag = idx => { + const newTags = tags.filter((_, i) => i !== idx); + setTags(newTags); + onChange(newTags); + }; +*/ +/* + const handleKeyDown = e => { + if (e.key === 'Enter' || e.key === ',') { + e.preventDefault(); + addTag(inputValue); + setInputValue(''); + } + if (e.key === 'Backspace' && !inputValue) { + removeTag(tags.length - 1); + } + }; +*/ + return ( +
inputRef.current.focus()} + disabled={ disabled } + > + {tags.map((tag, idx) => ( + + {tag} + + ))} + +
+ ); +} \ No newline at end of file diff --git a/src/components/Input/TagStaticInput.jsx b/src/components/Input/TagStaticInput.jsx new file mode 100644 index 0000000..ccbcdd8 --- /dev/null +++ b/src/components/Input/TagStaticInput.jsx @@ -0,0 +1,42 @@ +import { useState, useRef, useEffect } from 'react'; + +export function TagStaticInput({ initTags, disabled = false, onRemove }) { + const [tags, setTags] = useState([]) + useEffect(() => { + setTags([...initTags]) + }, [initTags]) + + const removeTag = idx => { + const removingTag = tags.find((_, i) => i === idx); + const newTags = tags.filter((_, i) => i !== idx); + // setTags(newTags); + onRemove(removingTag); + }; + + return ( +
+ {tags.map((tag, idx) => ( + + {tag} + + + ))} + +
+ ); +} \ No newline at end of file diff --git a/src/components/Input/Taginput.jsx b/src/components/Input/Taginput.jsx new file mode 100644 index 0000000..9bbf321 --- /dev/null +++ b/src/components/Input/Taginput.jsx @@ -0,0 +1,79 @@ +import { useState, useRef, useEffect } from 'react'; + +export function TagInput({ initialTags = [], onChange, placeholder, disabled = false }) { + const [tags, setTags] = useState(initialTags); + const [inputValue, setInputValue] = useState(''); + const inputRef = useRef(null); + + useEffect(() => { + setTags(initialTags); + }, [initialTags]); + + const addTag = tag => { + const trimmed = tag.trim(); + if (trimmed && !tags.includes(trimmed)) { + const newTags = [...tags, trimmed]; + setTags(newTags); + onChange(newTags); + } + }; + + const removeTag = idx => { + const newTags = tags.filter((_, i) => i !== idx); + setTags(newTags); + onChange(newTags); + }; + + const handleKeyDown = e => { + if (e.key === 'Enter' || e.key === ',') { + e.preventDefault(); + addTag(inputValue); + setInputValue(''); + } + if (e.key === 'Backspace' && !inputValue) { + removeTag(tags.length - 1); + } + }; + + return ( +
inputRef.current.focus()} + disabled={ disabled } + > + {tags.map((tag, idx) => ( + + {tag} + { !disabled && + + } + + ))} + + { !disabled && + setInputValue(e.target.value)} + onKeyDown={handleKeyDown} + /> + } +
+ ); +} \ No newline at end of file diff --git a/src/components/Modals/DcodeModal.jsx b/src/components/Modals/DcodeModal.jsx new file mode 100644 index 0000000..a115470 --- /dev/null +++ b/src/components/Modals/DcodeModal.jsx @@ -0,0 +1,246 @@ +import { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; +import ReactDOM from 'react-dom'; + +import { useGetIDoctorsQuery } from '/src/api/apiIDoctor'; +import { selectRegions } from '/src/store/slice/regionSlice'; + +function DcodeModal({ isOpen, onCancel, onConfirm, initialSelectedItems=[], departments=[], filials=[]}) { + const [searchValue, setSearchValue] = useState(''); + const [searchParam, setSearchParam] = useState('search'); + const [selectedItems, setSelectedItems] = useState([]); + + const regions = useSelector( selectRegions ); + + const getAdress = (filial) => { + const curentFilial = filials.find(item => Number(item.id) === Number(filial)); + if (curentFilial) return `${regions[curentFilial.regionId]}, ${curentFilial.shortName}` + } + + const getDepartment = (department) => { + const currentDepartment = departments.find(item => Number(item.id) === Number(department)) + if (currentDepartment) return currentDepartment.name + } + + const { + data: response, + isFetching, + error, + } = useGetIDoctorsQuery( + { type: searchParam, value: searchValue }, + { skip: searchValue.length < 3 } + ); + + const items = response?.data ?? []; + + useEffect(() => { + if (isOpen) { + document.body.classList.add('modal-open'); + const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth; + document.body.style.paddingRight = `${scrollbarWidth}px`; + } else { + document.body.classList.remove('modal-open'); + document.body.style.paddingRight = ''; + setSearchValue(''); + setSearchParam('search'); + setSelectedItems([...initialSelectedItems.map(item => ({ ...item, key: `${item.dcode}${item.department}${item.filial}${item.name}` }))]); + } + return () => { + document.body.classList.remove('modal-open'); + document.body.style.paddingRight = ''; + }; + }, [isOpen, initialSelectedItems]); + + if (!isOpen) return null; + + const toggleSelect = (item) => { + const key = `${item.dcode}${item.department}${item.filial}${item.name}`; + + if ( selectedItems.find( item => item.key === key ) ) toggleRemove(item); + else { + toggleAdd(item); + } + }; + + const toggleAdd = (item) => { + setSelectedItems([ ...selectedItems, { ...item, key: `${item.dcode}${item.department}${item.filial}${item.name}`} ]); + } + + const toggleRemove = (removingItem) => { + setSelectedItems( selectedItems.filter( item => item.key !== removingItem.key )); + } + + + const renderItem = (item) => { + const key = `${item.dcode}${item.department}${item.filial}${item.name}`; + const isActive = selectedItems.some(i => i.key === key); + return ( +
{ + toggleSelect(item) + }} + > +
    +
  • dcode: {item.dcode}
  • +
  • ФИО: {item.name}
  • +
  • + ID отделения: {item.department} +
  • +
  • + Отделение: {departments.find(department => Number(department.id) === Number(item.department))?.name} +
  • + +
  • Адрес: {getAdress(item.filial)}
  • +
  • + + +
  • + +
+ +
+ ); + }; + + return ReactDOM.createPortal( + <> +
+
+
+
+ +
+
Добавить расписание из Инфоклиники
+
+ +
+ +
+
+ + +
+
+ + { + setSearchValue(e.target.value) + }} + placeholder="Введите не менее 3 символов..." + /> +
+
+ + +
+
Расписание из Инфоклиники:
+
+
+ {selectedItems.map(item => ( +
+
    +
  • dcode: {item.dcode}
  • +
  • ФИО: {item.name}
  • +
  • Отделение: {departments.find(department => Number(department.id) === Number(item.department))?.name ?? 'не найдено'}
  • +
  • Адрес: {getAdress(item.filial)}
  • +
  • + + +
  • +
+ +
+ ))} +
+
+
+ +
+ + {searchValue.length < 3 ? ( + Введите не менее 3 символов для поиска + ) : isFetching ? ( +

Идёт поиск…

+ ) : error ? ( +

Ошибка при запросе

+ ) : items.length > 0 ? ( + <> +
Найдено:
+
    + {items.map((item, inx) => renderItem(item, inx))} +
+ + ) : ( +

Не найдено

+ )} +
+ +
+ + +
+ +
+
+
+ , + document.body + ); +} + +export default DcodeModal; diff --git a/src/components/Modals/KodoperModal.jsx b/src/components/Modals/KodoperModal.jsx new file mode 100644 index 0000000..e058604 --- /dev/null +++ b/src/components/Modals/KodoperModal.jsx @@ -0,0 +1,282 @@ +import { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; +import ReactDOM from 'react-dom'; + +import { useGetKodopersQuery } from '/src/api/apiKodoper'; +import { useGetFilialsQuery } from '/src/api/apiFilial'; +import { selectRegions } from '/src/store/slice/regionSlice'; + +function KodoperModal({ isOpen, onCancel, onConfirm, initialSelectedItems = [] }) { + const [searchValue, setSearchValue] = useState(''); + const [currentFilial, setCurrentFilial] = useState(-1); + const [currentPage, setCurrentPage] = useState(1); + const [selectedItems, setSelectedItems] = useState([]); + const [selectedObjs, setSelectedObjs] = useState([]); + + const { data: filialsRaw = {}, isLoading: loadingFilials } = useGetFilialsQuery(); + const filials = filialsRaw.data || []; + + const filialOptions = [{ fid: -1, name: 'Все филиалы' }, ...filials]; + + // Query parameters include search, filial, and page + const skip = searchValue.length < 3; + const { + data: response = {}, + isFetching, + error: queryError, + } = useGetKodopersQuery( + { + value: searchValue, + filialId: currentFilial, + page: currentPage + }, + { skip } + ); + + const items = response.data || []; + const pagination = response.pagination || {}; + + // Toggle selection + const toggleSelect = (item) => { + const code = item.kodoper; + const exists = selectedItems.includes(code); + if (exists) { + setSelectedItems(selectedItems.filter(c => c !== code)); + setSelectedObjs(selectedObjs.filter(o => o.kodoper !== code)); + } else { + setSelectedItems([...selectedItems, code]); + setSelectedObjs([...selectedObjs, item]); + } + }; + + useEffect(() => { + if (isOpen) { + document.body.classList.add('modal-open'); + const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth; + document.body.style.paddingRight = `${scrollbarWidth}px`; + } else { + document.body.classList.remove('modal-open'); + document.body.style.paddingRight = ''; + setSearchValue(''); + + if (initialSelectedItems === null) return + setSelectedItems(initialSelectedItems); + // setSelectedObjs(initialSelectedItems); + } + return () => { + document.body.classList.remove('modal-open'); + document.body.style.paddingRight = ''; + }; + }, [isOpen, initialSelectedItems]); + + if (!isOpen) return null; + + // Pagination controls +const renderPagination = () => { + const total = pagination.total_pages || 1; + const current = pagination.current_page || 1; + const pages = new Set(); + + // 1 и последняя + pages.add(1); + pages.add(total); + + // текущая, две до и две после + for (let p = current - 2; p <= current + 2; p++) { + if (p > 1 && p < total) pages.add(p); + } + + // сортируем + const sorted = Array.from(pages).sort((a, b) => a - b); + + const items = []; + let last = 0; + + sorted.forEach(page => { + if (last && page - last > 1) { + // разрыв — вставляем «...» + items.push( +
  • + +
  • + ); + } + items.push( +
  • + +
  • + ); + last = page; + }); + + return ( + + ); +}; + + return ReactDOM.createPortal( + <> +
    +
    +
    +
    + +
    +
    Добавить услугу
    +
    + +
    + + +
    + + +
    + + +
    +
    + + { setSearchValue(e.target.value); setCurrentPage(1); }} + placeholder="Введите не менее 3 символов..." + /> +
    +
    + + +
    +
    Выбранные уникальные медицинские коды:
    +
    +
    + {selectedItems.map((code, i) => ( + toggleSelect({ kodoper: code })} + style={{ fontSize: '1rem', cursor: 'pointer' }} + > + {code} + + + ))} +
    +
    +
    + +
    + + {searchValue.length < 3 ? ( + Введите не менее 3 символов для поиска + ) : isFetching ? ( +

    Идёт поиск…

    + ) : queryError ? ( +

    Ошибка при запросе

    + ) : ( + <> +
    + + + + + + + + + + {items.map((item, idx) => ( + toggleSelect(item)}> + + + + + ))} + +
    Мед.кодУслугаСтоимость
    {item.kodoper}{item.schname}{item.priceInfo.price} ₽
    +
    + {renderPagination()} + + )} +
    + +
    + + +
    + +
    +
    +
    + , + document.body + ); +} + +export default KodoperModal; diff --git a/src/components/Modals/Modal.jsx b/src/components/Modals/Modal.jsx new file mode 100644 index 0000000..127f566 --- /dev/null +++ b/src/components/Modals/Modal.jsx @@ -0,0 +1,75 @@ +import { useEffect, useRef } from 'react'; +import ReactDOM from 'react-dom'; + +export const Modal = ({ isOpen, onCancel, onConfirm, hasDangerButton = true, title, hasButtons, confirmText, children }) => { + useEffect(() => { + if (isOpen) { + document.body.classList.add('modal-open'); + const scrollbarWidth = + window.innerWidth - document.documentElement.clientWidth; + document.body.style.paddingRight = `${scrollbarWidth}px`; + } else { + document.body.classList.remove('modal-open'); + document.body.style.paddingRight = ''; + } + return () => { + document.body.classList.remove('modal-open'); + document.body.style.paddingRight = ''; + }; + }, [isOpen]); + + const closeRef = useRef(null); + useEffect(() => { + if (isOpen && hasButtons) { + closeRef.current.focus(); + } + }, [isOpen, hasButtons]); + + if (!isOpen) return null; + + return ReactDOM.createPortal( + <> +
    + +
    +
    +
    +
    + {title &&
    {title}
    } +
    +
    {children}
    + {hasButtons && +
    + { hasDangerButton && + + } + +
    + } +
    +
    +
    + , + document.body + ); +} + +export default Modal; diff --git a/src/components/Modals/ResponseModals.jsx b/src/components/Modals/ResponseModals.jsx new file mode 100644 index 0000000..ed67d97 --- /dev/null +++ b/src/components/Modals/ResponseModals.jsx @@ -0,0 +1,47 @@ +import { Modal } from './/Modal'; +import { LoadingComponent } from '../Placeholders/LoadingComponent'; +import { ErrorComponent } from '../Placeholders/ErrorComponent'; + +export const ResponseModals = ({ modal, setModal }) => { + switch (modal) { + case 'loading': + return ( + + + + ) + + case 'error': + return ( + setModal( undefined )} + > + + + ) + + case 'success': + return ( + +

    + Изменения успешно внесены. +

    +
    + ) + + default: + return null + } +}; \ No newline at end of file diff --git a/src/components/Modals/StockModal.jsx b/src/components/Modals/StockModal.jsx new file mode 100644 index 0000000..33c0d69 --- /dev/null +++ b/src/components/Modals/StockModal.jsx @@ -0,0 +1,388 @@ +import { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; +import ReactDOM from 'react-dom'; + +import { useGetIDoctorsQuery } from '/src/api/apiIDoctor'; +import { selectRegions } from '/src/store/slice/regionSlice'; + +import { useGetStocksQuery } from '/src/api/apiStock'; + +export function StockModal({ isOpen, onCancel, onConfirm, initialSelectedItems=[], departments=[], filials=[]}) { + const [searchValue, setSearchValue] = useState(''); + const [currentPage, setCurrentPage] = useState(1); + const [selectedObjs, setSelectedObjs] = useState([]); + const skip = false; //searchValue.length < 3; + + const { + data: response = {}, + isFetching, + error: queryError, + } = useGetStocksQuery({ + search: searchValue, + page: currentPage, + }, {skip}); + + const items = response.data ? (response.data.map(init => { + const dateStart = new Date(init.startDate); + + const year = dateStart.getFullYear(); + const month = String(dateStart.getMonth() + 1).padStart(2, '0'); // Month is 0-indexed + const day = String(dateStart.getDate()).padStart(2, '0'); + const hours = String(dateStart.getHours()).padStart(2, '0'); + const minutes = String(dateStart.getMinutes()).padStart(2, '0'); + const datetimeLocalValue = `${year}-${month}-${day}T${hours}:${minutes}`; + + const dateEnd = new Date(init.endDate); + + const year1 = dateEnd.getFullYear(); + const month1 = String(dateEnd.getMonth() + 1).padStart(2, '0'); // Month is 0-indexed + const day1 = String(dateEnd.getDate()).padStart(2, '0'); + const hours1 = String(dateEnd.getHours()).padStart(2, '0'); + const minutes1 = String(dateEnd.getMinutes()).padStart(2, '0'); + const datetimeLocalValue1 = `${year1}-${month1}-${day1}T${hours1}:${minutes1}`; + + return ({ ...init, startDate: datetimeLocalValue, endDate: datetimeLocalValue1 }); + })) : []; + const pagination = response.pagination || {}; + + const renderPagination = () => { + const total = pagination.total_pages || 1; + const current = pagination.current_page || 1; + const pages = new Set([1, total]); + + for (let p = current - 2; p <= current + 2; p++) { + if (p > 1 && p < total) pages.add(p); + } + + const sorted = Array.from(pages).sort((a, b) => a - b); + const elems = []; + let last = 0; + + sorted.forEach(page => { + if (last && page - last > 1) { + elems.push( +
  • + +
  • + ); + } + elems.push( +
  • + +
  • + ); + last = page; + }); + + return ( + + ); + }; + const [searchParam, setSearchParam] = useState('search'); + const [selectedItems, setSelectedItems] = useState([]); + + const regions = useSelector( selectRegions ); + + const getAdress = (filial) => { + const curentFilial = filials.find(item => Number(item.id) === Number(filial)); + if (curentFilial) return `${regions[curentFilial.regionId]}, ${curentFilial.shortName}` + } + + const getDepartment = (department) => { + const currentDepartment = departments.find(item => Number(item.id) === Number(department)) + if (currentDepartment) return currentDepartment.name + } + + useEffect(() => { + if (isOpen) { + document.body.classList.add('modal-open'); + const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth; + document.body.style.paddingRight = `${scrollbarWidth}px`; + } else { + document.body.classList.remove('modal-open'); + document.body.style.paddingRight = ''; + //console.log(initialSelectedItems) + setSearchValue(''); + setSearchParam('search'); + setSelectedObjs([...initialSelectedItems]) + setSelectedItems([...initialSelectedItems.map(item => ({ ...item, key: `${item.dcode}${item.department}${item.filial}` }))]); + } + return () => { + document.body.classList.remove('modal-open'); + document.body.style.paddingRight = ''; + }; + }, [isOpen, initialSelectedItems]); + + if (!isOpen) return null; + + const toggleSelect = (stock) => { + /*const key = `${item.dcode}${item.department}${item.filial}`; + + if ( selectedItems.find( item => item.key === key ) ) toggleRemove(item); + else { + toggleAdd(item); + console.log(2222) + }*/ + //console.log(stock) + //if (selectedItems.includes(stock.id)) { + // setSelectedItems([selectedItems.filter(({id}) => id !== stock.id)]) + if (selectedObjs.find(({id}) => stock.id === id)) { + setSelectedObjs([...selectedObjs.filter(({id}) => id !== stock.id)]) + return + } + // setSelectedItems([...selectedItems, stock.id]) + setSelectedObjs([...selectedObjs, stock]) + }; + + const toggleAdd = (item) => { + /* console.log(item) + setSelectedItems([ ...selectedItems, { ...item, key: `${item.dcode}${item.department}${item.filial}`} ]); + */ + } + + const toggleRemove = (removingItem) => { + //setSelectedItems( selectedItems.filter( item => item.key !== removingItem.key )); + } + + + const renderItem = (item) => { + // const isActive = selectedItems.some(i => i === item.dcode); + //const key = `${item.dcode}${item.department}${item.filial}`; + //const isActive = selectedItems.some(i => i.key === key); + const isActive = selectedObjs.find(({id}) => item.id === id) + return ( +
    { + //console.log(item) + toggleSelect(item) + }} + > +
      +
    • dcode: {item.dcode}
    • +
    • ФИО: {item.name}
    • +
    • Отделение: {departments.find(department => Number(department.id) === Number(item.department))?.name}
    • +
    • Адрес: {getAdress(item.filial)}
    • +
    • + + +
    • + +
    + +
    + ); + }; + + return ReactDOM.createPortal( + <> +
    +
    +
    +
    + +
    +
    Добавить акции
    +
    + +
    + +
    +
    + + { + setSearchValue(e.target.value); + setCurrentPage(1); + }} + /> +
    +
    + +
    +
    Выбранные акции:
    +
    +
    + {selectedObjs.map((stock) => ( + toggleSelect(stock)} + style={{ fontSize: '1rem', cursor: 'pointer' }} + > + {stock.name} + + + ))} + {/*selectedItems.map(item => ( +
    +
      +
    • dcode: {item.dcode}
    • +
    • ФИО: {item.name}
    • +
    • Отделение: {departments.find(department => Number(department.id) === Number(item.department))?.name ?? 'не найдено'}
    • +
    • Адрес: {getAdress(item.filial)}
    • +
    • + + +
    • +
    + +
    + ))*/} +
    +
    +
    + +
    + + {isFetching ? ( +

    Загрузка...

    + ) : queryError ? ( +

    Ошибка при загрузке: {String(queryError)}

    + ) : ( + <> +
    + + + + + + + + + + + {items.map(stock => ( + stock.id === id) ? 'table-primary' : ''} style={{ cursor: 'pointer'}} + onClick={() => toggleSelect(stock)} + > + + + + + + ))} + +
    IDНазваниеНачало акцииОкончание акции
    {stock.id}{stock.name} + toggleSelect(stock)} + readOnly={true} + /> + + toggleSelect(stock)} + readOnly={true} + /> +
    +
    + + {renderPagination()} + + )} +
    + +
    + + +
    + +
    +
    +
    + , + document.body + ); +} diff --git a/src/components/Navbar/Navbar.jsx b/src/components/Navbar/Navbar.jsx new file mode 100644 index 0000000..7dd3f23 --- /dev/null +++ b/src/components/Navbar/Navbar.jsx @@ -0,0 +1,82 @@ +import { Link } from 'react-router-dom'; +import { useState, useRef, useEffect } from 'react'; + +import { UserBurger } from '../UserBurger/UserBurger'; +import { SidebarNavItem } from '../SidebarNavItem/SidebarNavItem'; +import styles from './Navbar.module.scss'; + +export const Navbar = () => { + const links = [ + { to: '/', icon: 'fas fa-home', label: 'Главная', end: true }, + { to: '/specialist', icon: 'fas fa-user-md', label: 'Врачи' }, + { to: '/lostDoctors', icon: 'fas fa-address-card', label: 'Врачи-потеряшки' }, + { to: '/infoclinic', icon: 'fas fa-table', label: 'Расписание ИК' }, + { to: '/prices',icon: 'fas fa-receipt', label: 'Цены и услуги' }, + { to: '/promotions',icon: 'fas fa-percent', label: 'Акции' }, + { to: '/departments',icon: 'fas fa-stethoscope', label: 'Отделения' }, + { to: '/filials',icon: 'fas fa-building', label: 'Филиалы' }, + { to: '/news', icon: 'fas fa-newspaper', label: 'Новости' }, + { to: '/site-promo', icon: 'fas fa-bullhorn', label: 'Промо (контент)' }, + { to: '/disease', icon: 'fas fa-heartbeat', label: 'Заболевания' }, + { to: '/medical-center', icon: 'fas fa-hospital', label: 'Медцентры' }, + { to: '/article', icon: 'fas fa-file-alt', label: 'Статьи' }, + { to: '/site-services', icon: 'fas fa-concierge-bell', label: 'Услуги сайта' }, + ]; + const [open, setOpen] = useState(false); + const toggleRef = useRef(null); + const menuRef = useRef(null); + + useEffect(() => { + const handleOutside = e => { + if ( + menuRef.current && + !menuRef.current.contains(e.target) && + toggleRef.current && + !toggleRef.current.contains(e.target) + ) { + setOpen(false) + } + } + document.addEventListener('mousedown', handleOutside) + return () => document.removeEventListener('mousedown', handleOutside) + }, []); + + return ( + + ) +}; diff --git a/src/components/Navbar/Navbar.module.scss b/src/components/Navbar/Navbar.module.scss new file mode 100644 index 0000000..3debd97 --- /dev/null +++ b/src/components/Navbar/Navbar.module.scss @@ -0,0 +1,3 @@ +.navbar-background { + background-color: #e9f7ef !important; +} \ No newline at end of file diff --git a/src/components/Paginations/PageNav.jsx b/src/components/Paginations/PageNav.jsx new file mode 100644 index 0000000..2d21761 --- /dev/null +++ b/src/components/Paginations/PageNav.jsx @@ -0,0 +1,45 @@ +import React from 'react'; + +export const PageNav = React.memo(({ currentPage, totalPages, onPageChange }) => + totalPages === 1 ? null : ( + + ) +); \ No newline at end of file diff --git a/src/components/Placeholders/ErrorComponent.jsx b/src/components/Placeholders/ErrorComponent.jsx new file mode 100644 index 0000000..981e049 --- /dev/null +++ b/src/components/Placeholders/ErrorComponent.jsx @@ -0,0 +1,7 @@ +export const ErrorComponent = () => { + return ( +
    + Ошибка загрузки +
    + ); +}; \ No newline at end of file diff --git a/src/components/Placeholders/LoadingComponent.jsx b/src/components/Placeholders/LoadingComponent.jsx new file mode 100644 index 0000000..3b31cc2 --- /dev/null +++ b/src/components/Placeholders/LoadingComponent.jsx @@ -0,0 +1,11 @@ +export const LoadingComponent = () => { + return ( +
    +
    + + Загрузка... + +
    +
    + ); +}; \ No newline at end of file diff --git a/src/components/Placeholders/NotFindElement.jsx b/src/components/Placeholders/NotFindElement.jsx new file mode 100644 index 0000000..5b6b3dd --- /dev/null +++ b/src/components/Placeholders/NotFindElement.jsx @@ -0,0 +1,10 @@ +export const NotFindElement = ({ message, navigateBack }) => ( +
    +
    + {message} +
    + +
    +); \ No newline at end of file diff --git a/src/components/Sidebar/Sidebar.jsx b/src/components/Sidebar/Sidebar.jsx new file mode 100644 index 0000000..954808e --- /dev/null +++ b/src/components/Sidebar/Sidebar.jsx @@ -0,0 +1,34 @@ +import { SidebarNavItem } from '../SidebarNavItem/SidebarNavItem'; + +export const Sidebar = () => { + const links = [ + { to: '/', icon: 'fas fa-home', label: 'Главная', end: true }, + { to: '/specialist', icon: 'fas fa-user-md', label: 'Врачи' }, + { to: '/lostDoctors', icon: 'fas fa-address-card', label: 'Врачи-потеряшки' }, + { to: '/infoclinic', icon: 'fas fa-table', label: 'Расписание ИК' }, + { to: '/prices',icon: 'fas fa-receipt', label: 'Цены и услуги' }, + { to: '/promotions',icon: 'fas fa-percent', label: 'Акции' }, + { to: '/departments',icon: 'fas fa-stethoscope', label: 'Отделения' }, + { to: '/filials',icon: 'fas fa-building', label: 'Филиалы' }, + { to: '/news', icon: 'fas fa-newspaper', label: 'Новости' }, + { to: '/site-promo', icon: 'fas fa-bullhorn', label: 'Промо (контент)' }, + { to: '/disease', icon: 'fas fa-heartbeat', label: 'Заболевания' }, + { to: '/medical-center', icon: 'fas fa-hospital', label: 'Медцентры' }, + { to: '/article', icon: 'fas fa-file-alt', label: 'Статьи' }, + { to: '/site-services', icon: 'fas fa-concierge-bell', label: 'Услуги сайта' }, + ]; + + return ( +
      + {links.map(({ to, icon, label, end }) => ( + + ))} +
    + ) +} \ No newline at end of file diff --git a/src/components/SidebarNavItem/SidebarNavItem.jsx b/src/components/SidebarNavItem/SidebarNavItem.jsx new file mode 100644 index 0000000..5bac31f --- /dev/null +++ b/src/components/SidebarNavItem/SidebarNavItem.jsx @@ -0,0 +1,21 @@ +import { NavLink } from 'react-router-dom'; + +import styles from './SidebarNavItem.module.scss'; + +export const SidebarNavItem = ({ to, icon, label, end = false, onClick = null, }) => { + return ( +
  • + + `nav-link${isActive ? ' active' : ''} ${styles['sidebar-nav-link']}` + } + onClick={onClick} + > + + {label} + +
  • + ) +} \ No newline at end of file diff --git a/src/components/SidebarNavItem/SidebarNavItem.module.scss b/src/components/SidebarNavItem/SidebarNavItem.module.scss new file mode 100644 index 0000000..f10e337 --- /dev/null +++ b/src/components/SidebarNavItem/SidebarNavItem.module.scss @@ -0,0 +1,8 @@ +.sidebar-nav-link { + color: rgba(21, 87, 36, 0.8); +} + +.sidebar-nav-link.active, +.sidebar-nav-link:hover { + color: white !important; +} \ No newline at end of file diff --git a/src/components/Table/FilterBar.jsx b/src/components/Table/FilterBar.jsx new file mode 100644 index 0000000..3d844df --- /dev/null +++ b/src/components/Table/FilterBar.jsx @@ -0,0 +1,53 @@ +import React from "react"; + +export const FilterBar = React.memo(({ regions, filials, regionId, filialId, searchValue, onChange, goAddSpecialist }) => ( +
    e.preventDefault()} + > +
    + { e.stopPropagation(); goAddSpecialist() }} + /> +
    +
    + + + +
    + +
    + + +
    + +
    + + onChange({ searchValue: e.target.value, page: 1 })} + /> +
    + +
    +)); \ No newline at end of file diff --git a/src/components/Table/TBody.jsx b/src/components/Table/TBody.jsx new file mode 100644 index 0000000..c679328 --- /dev/null +++ b/src/components/Table/TBody.jsx @@ -0,0 +1,96 @@ +import React from "react"; + +const maskElement = ( element ) => { + if ( typeof element === 'boolean' ) + return element ? 'да' : 'нет' + + if ( typeof element === 'undefined' ) return 'нет данных' + + if ( element === null ) return 'нет данных' + + return element +} + +const ElementRow = React.memo(({ element, expandedId, setExpandedId, onEdit, onWatch, columns, pageType = '' }) => { + const isExpanded = expandedId === element.id; + const toggle = () => setExpandedId(prev => (prev === element.id ? null : element.id)); + + return ( + <> + + {columns.map((column, index) => ( + + { maskElement(element[column.key]) } + + ))} + + {isExpanded && pageType !== 'specialists' && ( + + + { e.stopPropagation(); onEdit(element.id); }} + /> + + + )} + {( pageType === 'specialists' && isExpanded ) && ( + + + { e.stopPropagation(); onEdit(element.id); }} + /> + + + { e.stopPropagation(); onWatch(element.id); }} + /> + + + )} + + ); +}); + +export const TBody = ({ elements, columns, expandedId, setExpandedId, goEdit, goWatch, pageType }) => { + return ( + + { + elements.map(element => ( + )) + } + + ); +} \ No newline at end of file diff --git a/src/components/Table/THead.jsx b/src/components/Table/THead.jsx new file mode 100644 index 0000000..fcb3a26 --- /dev/null +++ b/src/components/Table/THead.jsx @@ -0,0 +1,19 @@ +export const THead = ({ columns, sortBy, sortDirection, handleSort }) => ( + + + {columns.map(({ key, label, width }) => ( + handleSort(key)} + > + {label} + {sortBy === key && ( + + )} + + ))} + + +) \ No newline at end of file diff --git a/src/components/UserBurger/UserBurger.jsx b/src/components/UserBurger/UserBurger.jsx new file mode 100644 index 0000000..cfde5c8 --- /dev/null +++ b/src/components/UserBurger/UserBurger.jsx @@ -0,0 +1,73 @@ +import { useState, useRef, useEffect } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { Link } from 'react-router-dom'; + +import { useLogoutMutation } from '/src/api/apiSlice' + +export const UserBurger = () => { + const username = useSelector( s => s.auth.username ); + const [ logout ] = useLogoutMutation() + + const [open, setOpen] = useState(false); + const toggleRef = useRef(null); + const menuRef = useRef(null); + + useEffect(() => { + const handleOutside = e => { + if ( + menuRef.current && + !menuRef.current.contains(e.target) && + toggleRef.current && + !toggleRef.current.contains(e.target) + ) { + setOpen(false) + } + } + document.addEventListener('mousedown', handleOutside) + return () => document.removeEventListener('mousedown', handleOutside) + }, []); + + return ( +
      +
    • + + + {open && ( +
      + setOpen(false)} + > + + Профиль + +
      + +
      + )} +
    • +
    + ) +} diff --git a/src/config/api.js b/src/config/api.js new file mode 100644 index 0000000..6a6ff0d --- /dev/null +++ b/src/config/api.js @@ -0,0 +1,10 @@ +export const API_BASE_URL = + (typeof window !== 'undefined' && window.__ENV__?.API_BASE_URL) || + import.meta.env.VITE_API_BASE_URL || + 'https://api.sovamed.ru' + +export const apiUrl = (path) => { + const base = API_BASE_URL.replace(/\/$/, '') + const suffix = path.startsWith('/') ? path : `/${path}` + return `${base}${suffix}` +} diff --git a/src/config/contentResources.js b/src/config/contentResources.js new file mode 100644 index 0000000..02795e1 --- /dev/null +++ b/src/config/contentResources.js @@ -0,0 +1,223 @@ +const baseContentFields = [ + { key: 'name', label: 'Название', type: 'text' }, + { key: 'active', label: 'Активно', type: 'checkbox' }, + { key: 'regionId', label: 'Регион', type: 'region' }, + { key: 'alias', label: 'Alias', type: 'text' }, + { key: 'anons', label: 'Анонс', type: 'html' }, + { key: 'content', label: 'Контент', type: 'html' }, +] + +const json = (key, label) => ({ key, label: `${label} (JSON)`, type: 'json' }) +const text = (key, label) => ({ key, label, type: 'text' }) + +export const CONTENT_RESOURCES = { + news: { + slug: 'news', + basePath: '/news', + title: 'Новости', + titleSingle: 'новость', + icon: 'fas fa-newspaper', + listColumns: [ + { key: 'id', label: 'ID' }, + { key: 'name', label: 'Название' }, + { key: 'alias', label: 'Alias' }, + { key: 'active', label: 'Активно', format: 'bool' }, + { key: 'regionId', label: 'Регион' }, + ], + fields: [ + ...baseContentFields, + text('shortName', 'Короткое название'), + text('linkElPrice', 'Ссылка на прайс'), + text('timer', 'Таймер'), + text('timerBg', 'Фон таймера'), + json('formOrder', 'formOrder'), + json('linkServices', 'linkServices'), + json('linkStaff', 'linkStaff'), + json('photos', 'photos'), + ], + }, + promo: { + slug: 'site-promo', + basePath: '/promo', + title: 'Промо (контент)', + titleSingle: 'промо', + icon: 'fas fa-bullhorn', + listColumns: [ + { key: 'id', label: 'ID' }, + { key: 'name', label: 'Название' }, + { key: 'alias', label: 'Alias' }, + { key: 'active', label: 'Активно', format: 'bool' }, + { key: 'regionId', label: 'Регион' }, + ], + fields: [ + ...baseContentFields, + text('shortName', 'Короткое название'), + text('period', 'Период'), + text('timer', 'Таймер'), + text('timerBg', 'Фон таймера'), + json('clinics', 'clinics'), + json('linkServices', 'linkServices'), + json('linkStaff', 'linkStaff'), + json('photos', 'photos'), + ], + }, + disease: { + slug: 'disease', + basePath: '/disease', + title: 'Заболевания', + titleSingle: 'заболевание', + icon: 'fas fa-heartbeat', + listColumns: [ + { key: 'id', label: 'ID' }, + { key: 'name', label: 'Название' }, + { key: 'alias', label: 'Alias' }, + { key: 'active', label: 'Активно', format: 'bool' }, + ], + fields: [ + ...baseContentFields, + text('previewPicture', 'previewPicture'), + { key: 'hidePicture', label: 'hidePicture', type: 'checkbox' }, + text('readTime', 'readTime'), + text('diseasesName', 'diseasesName'), + text('diseasesOtherName', 'diseasesOtherName'), + text('symptom', 'symptom'), + text('staff', 'staff'), + text('bibliography', 'bibliography'), + json('tagsImportant', 'tagsImportant'), + json('tags', 'tags'), + json('linkServices', 'linkServices'), + json('staffList', 'staffList'), + json('staffPost', 'staffPost'), + json('staffPostExclude', 'staffPostExclude'), + json('linkFaq', 'linkFaq'), + json('staffCheck', 'staffCheck'), + ], + }, + 'medical-center': { + slug: 'medical-center', + basePath: '/medical-center', + title: 'Медцентры', + titleSingle: 'медцентр', + icon: 'fas fa-hospital', + listColumns: [ + { key: 'id', label: 'ID' }, + { key: 'name', label: 'Название' }, + { key: 'alias', label: 'Alias' }, + { key: 'active', label: 'Активно', format: 'bool' }, + ], + fields: [ + ...baseContentFields, + text('mainLinkStaff', 'mainLinkStaff'), + text('plusText', 'plusText'), + text('plusTitle', 'plusTitle'), + text('processText', 'processText'), + text('processTitle', 'processTitle'), + text('servicesTitle', 'servicesTitle'), + text('trainingText', 'trainingText'), + text('trainingTextTitle', 'trainingTextTitle'), + text('whyText', 'whyText'), + text('whyTitle', 'whyTitle'), + { key: 'hidePicture', label: 'hidePicture', type: 'number' }, + json('kodUslug', 'kodUslug'), + json('doctors', 'doctors'), + json('services', 'services'), + json('articles', 'articles'), + json('txtUp', 'txtUp'), + json('contraindications', 'contraindications'), + json('indications', 'indications'), + json('linkSale', 'linkSale'), + json('plusList', 'plusList'), + json('servicesList', 'servicesList'), + json('servicesPhotos', 'servicesPhotos'), + json('sortStaff', 'sortStaff'), + ], + }, + article: { + slug: 'article', + basePath: '/article', + title: 'Статьи', + titleSingle: 'статью', + icon: 'fas fa-file-alt', + listUsesMeta: true, + listUsesLimit: true, + listColumns: [ + { key: 'id', label: 'ID' }, + { key: 'name', label: 'Название' }, + { key: 'alias', label: 'Alias' }, + { key: 'active', label: 'Активно', format: 'bool' }, + ], + fields: [ + ...baseContentFields, + text('previewPicture', 'previewPicture'), + json('doctors', 'doctors'), + json('services', 'services'), + ], + }, + 'site-services': { + slug: 'site-services', + basePath: '/site-services', + title: 'Услуги сайта', + titleSingle: 'услугу', + icon: 'fas fa-concierge-bell', + listColumns: [ + { key: 'id', label: 'ID' }, + { key: 'name', label: 'Название' }, + { key: 'alias', label: 'Alias' }, + { key: 'active', label: 'Активно', format: 'bool' }, + ], + fields: [ + ...baseContentFields, + text('previewImg', 'previewImg'), + text('partPrice', 'partPrice'), + text('pokazaniya', 'pokazaniya'), + text('preparation', 'preparation'), + text('protivopokazaniya', 'protivopokazaniya'), + text('bannerImg', 'bannerImg'), + text('bannerImgM', 'bannerImgM'), + text('bannerImgUrl', 'bannerImgUrl'), + text('downloadFile', 'downloadFile'), + text('fullWidthBanner', 'fullWidthBanner'), + text('kodUslug', 'kodUslug'), + text('linkPrice', 'linkPrice'), + text('photosTitle', 'photosTitle'), + text('contraindicationsList', 'contraindicationsList'), + text('customBlockText', 'customBlockText'), + text('customBlockText2', 'customBlockText2'), + text('customBlockTitle', 'customBlockTitle'), + text('customBlockTitle2', 'customBlockTitle2'), + text('indicationsList', 'indicationsList'), + text('plusList', 'plusList'), + text('plusText', 'plusText'), + text('plusTitle', 'plusTitle'), + text('prepareTitle', 'prepareTitle'), + text('processText', 'processText'), + text('processTitle', 'processTitle'), + text('servicesList', 'servicesList'), + text('servicesTitle', 'servicesTitle'), + text('textUp', 'textUp'), + text('trainingText', 'trainingText'), + text('whyText', 'whyText'), + text('whyTitle', 'whyTitle'), + { key: 'hidePicture', label: 'hidePicture', type: 'number' }, + json('linkVideoreviews', 'linkVideoreviews'), + json('faq', 'faq'), + json('hideSignBtn', 'hideSignBtn'), + json('quiz', 'quiz'), + json('tags', 'tags'), + json('tagsImportant', 'tagsImportant'), + json('clinics', 'clinics'), + json('staffUp', 'staffUp'), + json('advantages', 'advantages'), + json('saleId', 'saleId'), + json('sortStaff', 'sortStaff'), + json('linkArticlesServices', 'linkArticlesServices'), + json('servicesPhotos', 'servicesPhotos'), + json('linkFaq', 'linkFaq'), + json('linkServices', 'linkServices'), + json('linkStaff', 'linkStaff'), + json('photos', 'photos'), + ], + }, +} + +export const CONTENT_RESOURCE_KEYS = Object.keys(CONTENT_RESOURCES) diff --git a/src/hooks/useLostLocations.jsx b/src/hooks/useLostLocations.jsx new file mode 100644 index 0000000..c054a21 --- /dev/null +++ b/src/hooks/useLostLocations.jsx @@ -0,0 +1,65 @@ +import { useState, useEffect } from 'react'; +import axios from 'axios'; +import { useSelector } from 'react-redux'; + +import { apiUrl } from '@/config/api'; + +import { useGetFilialsQuery } from '../api/apiFilial'; +import { useGetDepartmentsQuery } from '../api/apiDepartment'; +import { selectRegions } from '../store/slice/regionSlice'; +import { useGetEmptyLocationsQuery } from '../api/apiLocation'; + +export function useLostDoctors() { + const { data, isLoading, error } = useGetEmptyLocationsQuery(); + + const [ lostDoctors, setLostDoctors ] = useState([]); + + const filialsQuery = useGetFilialsQuery(); + const filials = filialsQuery.data ?? []; + + const departmentsQuery = useGetDepartmentsQuery(); + const departments = departmentsQuery.data ?? []; + const regions = useSelector(selectRegions); + + const fetchParams = [ 'filial', 'dcode', 'department' ]; + + useEffect(() => { + if (!data?.data.length) { + setLostDoctors([]); + return; + } + let canceled = false; + + Promise.all( + data.data.map(item => { + const fetchString = fetchParams.filter((param => Boolean(item[param]))).map(param => `${param}=${item[param]}`).join('&'); + return axios.get(apiUrl(`/idoctor/list?${fetchString}`), { + headers: { Authorization: `Bearer ${localStorage.getItem('token')}` } + }) + .then(res => { + return ({ doctor: res?.data?.data[0], emptyLocation: item }); + }) + } + ) + ).then(results => { + if (!canceled) { + setLostDoctors(results.filter(Boolean)); + } + }).catch(() => { + if (!canceled) { + setLostDoctors([]); + } + }); + return () => { canceled = true }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [data]); + + return { + isLoading, + error, + lostDoctors, + filials: filials?.data || [], + departments: departments?.data || [], + regions, + }; +} \ No newline at end of file diff --git a/src/hooks/useNewSpecialistId.jsx b/src/hooks/useNewSpecialistId.jsx new file mode 100644 index 0000000..aa276bc --- /dev/null +++ b/src/hooks/useNewSpecialistId.jsx @@ -0,0 +1,19 @@ +import { useSelector } from 'react-redux'; + +import { useGetSpecialistsQuery } from '../api/apiSpecialist'; +import { selectRegions } from '../store/slice/regionSlice'; + +export function useNewSpecialistId() { + const regions = useSelector(selectRegions); + const regionIds = Object.keys(regions); + + const queries = regionIds.map(rid => useGetSpecialistsQuery(rid)); + const isLoading = queries.some(q => q.isLoading); + const error = queries.find(q => q.error)?.error; + const allData = queries.flatMap(q => q.data ?? []); + const newId = Math.max.apply(Math, + allData.map(( specialist ) => Number(specialist.id)) + ) + 1; + + return newId +} diff --git a/src/hooks/useOutsideClick.jsx b/src/hooks/useOutsideClick.jsx new file mode 100644 index 0000000..2ccbc31 --- /dev/null +++ b/src/hooks/useOutsideClick.jsx @@ -0,0 +1,13 @@ +import React from "react"; + +export const useOutsideClick = (ref, onOutsideClick) => { + React.useEffect(() => { + const handleClick = (e) => { + if (ref.current && !ref.current.contains(e.target)) { + onOutsideClick(); + } + }; + document.addEventListener('mousedown', handleClick); + return () => document.removeEventListener('mousedown', handleClick); + }, [ref, onOutsideClick]); +} diff --git a/src/hooks/useSortedPaginated.jsx b/src/hooks/useSortedPaginated.jsx new file mode 100644 index 0000000..9e5453a --- /dev/null +++ b/src/hooks/useSortedPaginated.jsx @@ -0,0 +1,43 @@ +import { useMemo } from 'react'; + +export const useSortedPaginated = (data, itemsPerPage, sortBy, sortDirection, currentPage) => { + const sorted = useMemo(() => { + return [...data].sort((a, b) => { + let aValue = a[sortBy], bValue = b[sortBy]; + + if (sortBy === 'experience') { + aValue = typeof aValue === 'number' ? aValue : 0; + bValue = typeof bValue === 'number' ? bValue : 0; + } + + if (sortBy === 'locations') { + aValue = aValue === 'нет данных' ? 'я' : aValue; + bValue = bValue === 'нет данных' ? 'я' : bValue; + } + + if (aValue == null || bValue == null) return 0 + + if (typeof aValue === 'number') return sortDirection === 'asc' + ? aValue - bValue + : bValue - aValue + + if (typeof aVal === 'string' && typeof bVal === 'string') { + aValue = aValue.replaceAll(' ', ''); + bValue = bValue.replaceAll(' ', ''); + } + + return sortDirection === 'asc' + ? String(aValue).localeCompare(String(bValue)) + : String(bValue).localeCompare(String(aValue)) + }); + }, [data, sortBy, sortDirection]); + + const totalPages = Math.ceil(sorted.length / itemsPerPage); + + const paginated = useMemo(() => { + const start = (currentPage - 1) * itemsPerPage; + return sorted.slice(start, start + itemsPerPage); + }, [sorted, currentPage, itemsPerPage]); + + return { paginated, totalPages }; +} \ No newline at end of file diff --git a/src/hooks/useSorting.jsx b/src/hooks/useSorting.jsx new file mode 100644 index 0000000..5cff5bc --- /dev/null +++ b/src/hooks/useSorting.jsx @@ -0,0 +1,16 @@ +import { useCallback, useState } from "react"; + +export const useSorting = (initialKey = 'id', initialDir = 'asc') => { + const [sortBy, setSortBy] = useState(initialKey); + const [sortDirection, setSortDirection] = useState(initialDir); + + const handleSort = useCallback( + key => { + setSortDirection(prev => (sortBy === key ? (prev === 'asc' ? 'desc' : 'asc') : 'asc')); + setSortBy(key); + }, + [sortBy] + ); + + return { sortBy, sortDirection, handleSort }; +} \ No newline at end of file diff --git a/src/hooks/useSpecialist.jsx b/src/hooks/useSpecialist.jsx new file mode 100644 index 0000000..78f7d38 --- /dev/null +++ b/src/hooks/useSpecialist.jsx @@ -0,0 +1,60 @@ +import { useState, useEffect } from 'react'; +import axios from 'axios'; +import { useSelector } from 'react-redux'; + +import { apiUrl } from '@/config/api'; + +import { useGetSpecialistsQuery, useGetSpecialistQuery } from '../api/apiSpecialist'; +import { useGetKodopersQuery } from '../api/apiKodoper'; +import { useGetFilialsQuery } from '../api/apiFilial'; +import { useGetDepartmentsQuery } from '../api/apiDepartment'; +import { selectRegions } from '../store/slice/regionSlice'; + +export function useSpecialist(id) { + const { data: specialist, isLoading, error } = useGetSpecialistQuery(id); + const [kodoperDetails, setKodoperDetails] = useState([]); + const filialsQuery = useGetFilialsQuery(); + const filials = filialsQuery.data ?? []; + + const departmentsQuery = useGetDepartmentsQuery(); + const departments = departmentsQuery.data ?? []; + const regions = useSelector(selectRegions); + + useEffect(() => { + if (!specialist?.kodoper?.length) { + setKodoperDetails([]); + return; + } + let canceled = false; + + Promise.all( + specialist.kodoper.map(code => + axios.get(apiUrl(`/pricelist/list?search=${code}`), { + headers: { Authorization: `Bearer ${localStorage.getItem('token')}` } + }) + .then(res => { + return (res.data.data || []).find(item => String(item.kodoper) === String(code)) || null; + }) + ) + ).then(results => { + if (!canceled) { + setKodoperDetails(results.filter(Boolean)); + } + }).catch(() => { + if (!canceled) { + setKodoperDetails([]); + } + }); + return () => { canceled = true }; + }, [specialist]); + + return { + isLoading, + error, + specialist: specialist ?? null, + filials, + departments, + regions, + kodoperDetails, + }; +} \ No newline at end of file diff --git a/src/hooks/useSpecialistFilter.jsx b/src/hooks/useSpecialistFilter.jsx new file mode 100644 index 0000000..f788398 --- /dev/null +++ b/src/hooks/useSpecialistFilter.jsx @@ -0,0 +1,43 @@ +import { useMemo } from "react"; + +export function useSpecialistFilter({ regionId, filialId, searchValue }, queries, filials, regionsMap, currentYear) { + return useMemo(() => { + const flatData = + regionId === 'all' + ? queries.flatMap(q => q.data || []) + : queries.find(q => q.originalArgs === regionId)?.data || []; + + console.log(queries) + + const formatted = flatData.map(s => { + const experience = s.experience ? currentYear - s.experience : null; + const location = s.locations[0]; + const filial = filials.find(f => f.id === location?.filial); + return { + ...s, + experience, + locations: filial ? `${regionsMap[filial.regionId]}, ${filial.shortName}` : 'нет данных', + filialId: filial?.id || null, + activeLabel: s.active ? 'да' : 'нет', + scheduleLabel: s.displaySchedule ? 'да' : 'нет', + }; + }); + + const byFilial = filialId === 'all' ? formatted : formatted.filter(s => s.filialId === Number(filialId)); + + const search = searchValue.trim().toLowerCase().replaceAll(' ', ''); + if (!search) return byFilial; + return byFilial.filter(s => { + if ( String(s.id).includes(search) ) return true + if ( s.nameString.replaceAll(' ', '').toLowerCase().includes(search) ) return true + if ( s.experience ) { + if ( String(s.experience ?? '').includes(search) ) return true + } + if ( s.post ) { + if ( s.post.replaceAll(' ', '').toLowerCase().includes(search) ) return true + } + return false + } + ); + }, [regionId, filialId, searchValue, queries, filials, regionsMap, currentYear]); +} diff --git a/src/main.jsx b/src/main.jsx new file mode 100644 index 0000000..046f08a --- /dev/null +++ b/src/main.jsx @@ -0,0 +1,16 @@ +import ReactDOM from 'react-dom/client'; +import { Provider } from 'react-redux'; + +import App from './App'; +import { store } from './store/store'; +import 'bootstrap/dist/css/bootstrap.min.css'; +import '@fortawesome/fontawesome-free/css/all.min.css'; +import 'startbootstrap-sb-admin-2/css/sb-admin-2.min.css'; +import './styles/theme-override.scss'; +import "react-datepicker/dist/react-datepicker.css"; + +ReactDOM.createRoot(document.getElementById('root')).render( + + + +); \ No newline at end of file diff --git a/src/pages/AddSpecialistPage.jsx b/src/pages/AddSpecialistPage.jsx new file mode 100644 index 0000000..34a8acf --- /dev/null +++ b/src/pages/AddSpecialistPage.jsx @@ -0,0 +1,1469 @@ +import React, {useEffect, useState, useMemo, useRef} from 'react' +import {useParams, useNavigate} from 'react-router-dom' +import DatePicker from "react-datepicker"; + +import { useUpdateSpecialistMutation, useDeleteSpecialistMutation, useUploadSpecialistPictureMutation, useCreateSpecialistMutation } from '../api/apiSpecialist' +import { useCreateLocationMutation, useUpdateLocationMutation, useDeleteLocationMutation } from '/src/api/apiLocation.js' +import { + useCreateCertificateMutation, + useUpdateCertificateMutation, + useUploadSertificatePictureMutation, + useDeleteCertificateMutation, +} from '/src/api/apiCertificate.js' +import { useGetFilialsQuery } from '../api/apiFilial'; +import { useGetDepartmentsQuery } from '../api/apiDepartment'; +import { useAddSpecialistMutation, useRemoveSpecialistMutation } from '../api/apiStock' +import { useSpecialist } from '../hooks/useSpecialist'; +// +import { LoadingComponent } from '../components/Placeholders/LoadingComponent'; +import { ErrorComponent } from '../components/Placeholders/ErrorComponent'; +import { NotFindElement } from '../components/Placeholders/NotFindElement'; +import { EditElementForm } from '../components/Forms/EditElementForm'; +import { TagInput } from '../components/Input/Taginput'; +import { TagStaticInput } from '../components/Input/TagStaticInput'; +import { TagKodoperStaticInput } from '../components/Input/TagKodoperStatic'; +import { TextEditor } from '../components/Editors/TextEditor' +import Modal from '../components/Modals/Modal'; +import DcodeModal from '../components/Modals/DcodeModal'; +import KodoperModal from '../components/Modals/KodoperModal'; +import { CertificatesForm } from '../components/Docs/Certificates'; +import { PortfolioForm } from '../components/Docs/Portfolio'; +import { StocksForm } from '../components/Docs/Stocks' +import { StockModal } from '../components/Modals/StockModal' +import PHOTO_PLACEHOLDER from '../assets/photo-placeholder.png' + + + const regionOptions = { + 91: 'Саратов' , + 92: 'Волгоград', + 93: 'Воронеж', + 94: 'Краснодар', + }; + + const sTypeOptions = { + 0: 'Взрослый врач', + 1: 'Детский врач', + 2: 'Администрация', + 3: 'Стоматология', + 4: 'Мед. сестра', + }; + + const getYear = (date) => { + const dateObject = new Date(date); + if (isNaN(dateObject.getFullYear())) return null + return String(dateObject.getFullYear()) + } + +const formatCategory = (rawCategory) => { + if (!rawCategory) return 'Не указано' + const categoryLowerCase = rawCategory.toLowerCase(); + switch (categoryLowerCase) { + case 'высшая': + case 'ведущий специалист': + return 'Высшая'; + case 'первая': + case 'главный специалист': + return 'Первая'; + case 'вторая': + return 'Вторая'; + default: + return 'Не указано' + } +} + +export const AddSpecialistPage = () => { + + const navigate = useNavigate(); + const navigateBack = () => navigate( `/specialist` ); + + + const dateInputRef = useRef(null); + const patientAgeInputRef = useRef(null); + + const [ locations, setLocations ] = useState([]); + const [ initialLocations, setInitialLocations ] = useState([]); + + const setFromRawLocations = (rawLocations) => { + const selectedDcodes = [...new Set(rawLocations.map(({dcode}) => dcode))]; + const arr = selectedDcodes.filter(dcode => !dcodes.includes(dcode)).map(dc => String(dc)); + setDcodes(arr) + setLocations(rawLocations) + + } + + const [ stocks, setStocks ] = useState([]); + const [ stocksFromChild, setStocksFromChild ] = useState([]); + + const [ anons, setAnons ] = useState(''); + const [ content, setContent ] = useState(''); + + const [displayKodoper, setDisplayKodoper] = useState([]); + + const [errors, setErrors] = useState({ + lastName: '', + firstName: '', + middleName: '', + videoUrl: '', + videoCardUrl: '', + patientAge: '', + prodoctorLink: '', + }); + + const categoryList = [ + 'Не указано', + 'Вторая', + 'Первая', + 'Высшая', + ]; + const categoryParcer = { + 'Ведущий специалист': 'Высшая', + 'Главный специалист': 'Первая', + 'Вторая': 'Вторая', + } + + const [isModalKodopers, setModalKodopers] = useState(false); + const [kodopers, setKodopers] = useState([]); + const [sertificates, setSertificates] = useState([]); + const [certificates, setCertificates] = useState([]); + const [portfolio, setPortfolio] = useState([]); + + const [ form, setForm ] = useState({ + nameString: '', + lastName: '', + firstName: '', + middleName: '', + active: false, // boolean + displaySchedule: null, // boolean + // + hideSchedule: false, // booleal + // + alias: '', // string + post: '', // string + experience: undefined, // number + sType: null, // number + regionId: 91, // number + anons: '', // string + add redactor + content: '', // string + add redactor + tags: [], // json + highlightedTags: [], // json + videoUrl: '', // string + degree: '', + videoCardUrl: '', // string + scheduleText: '', + //isCastom: false, // has autoupdate - boolean + category: '', // +++++++ + previewPicture: PHOTO_PLACEHOLDER, // string + filialId: null, // from locations.locations[0].filial + kodoper: null, // <<<---??? + prodoctor: false, + prodoctorLink: '', + prodoctorText: '', + onlyOnlineMode: false, + // + isChildrenDoctor: undefined, // from sType + patientAge: undefined, // integer + initStocks: [], + //isCastomChecker: undefined, + // + isLeadingSpecialist: false, + isChiefSpecialist: false, + education: '', + academicDegree: '', + professionalCompetencies:'', + advancedTraining: '', + certificates: '', + certificatesGallery: [], + adultsReception: '', + cost: '', + hasPromotion: false, + onlineConsultationLink: '', + onlyOnline: false, + hasProDoctorsAward: false, + proDoctorsAwardText: '', + proDoctorsAwardLink: '', + postTags: [], + operationPhotoUrl: '', + }); + + const updateField = ( key, value ) => { + setForm(prev => ({ ...prev, [key]: value })); + }; + + const [isModalStocks, setModalStocks] = useState(false); + const [displayedStocks, setDisplayStocks] = useState([]); + + const regexCyrillic = /^[А-ЯЁ][а-яё]+$/; + const regexRutube = /^https:\/\/rutube\.ru\/.*$/; + const regexProdoctor = /^https:\/\/prodoctorov\.ru\/.*$/; + + const validateField = (field, value) => { + let error = ''; + const currentYear = new Date().getFullYear(); + switch (field) { + case 'lastName': + case 'firstName': + case 'middleName': + if (!value) error = 'Обязательное поле'; + else if (!regexCyrillic.test(value)) error = 'Только кириллица, с заглавной буквы'; + break; + case 'experience': + if (!value) { + error = 'Обязательное поле'; + } else if (Number(getYear(value)) > Number(currentYear)) { + error = 'Год должен быть не больше текущего'; + } + break; + case 'videoUrl': + case 'videoCardUrl': + if (value && !regexRutube.test(value)) error = 'Должно быть ссылкой с rutube'; + break; + case 'prodoctorLink': + if (form.prodoctor) { + if (!value) { + error = 'Укажите ссылку'; + } else { + if (value && !regexProdoctor.test(value)) error = 'Должно быть ссылкой с prodoctorov.ru'; + } + } else { + error = '' + } + break; + case 'patientAge': + if (form.isChildrenDoctor) { + if ( !value ) { + error = 'Укажите возраст'; + } else { + const num = Number(value); + if (!Number.isInteger(num) || num < 0 || num > 18) error = 'Возраст не может быть меньше 0 и больше 18'; + } + } else { + error = '' + } + break; + } + console.log(field, error) + setErrors(prev => ({ ...prev, [field]: error })); + }; + + const handleBlur = e => { + const { name, value } = e.target; + validateField(name, value); + }; + + const isFormValid = () => { + ['lastName', 'firstName', 'middleName', 'videoUrl', 'videoCardUrl', 'patientAge', 'prodoctorLink', 'experience'].forEach(f => validateField(f, form[f])); + + const a = form.prodoctor ? ( form.prodoctorLink.length > 0 ) : true; + const b = form.isChildrenDoctor ? ( form.patientAge ) : true; + + return Object.entries(errors).every( + ([key, err]) => { + return !err; + } + ) && form.lastName && form.firstName && form.middleName && a && b && form.experience; + }; + + + const [ tags, setTags ] = useState([]); + const [ highlightedTags, setHighlightedTags ] = useState([]); + const [ postTags, setPostTags ] = useState([]); + const [ dcodes, setDcodes ] = useState([]); + + const photoInputRef = useRef(null) + const photoOperationInputRef = useRef(null) + const certificatesGalleryInputRef = useRef(null) + + const [createSpecialist, { isLoading: isUpdating, isError: updateError }] = + useCreateSpecialistMutation(); + const [uploadPicture, { isLoadingPicture, isErrorOicture }] = useUploadSpecialistPictureMutation(); + const [deleteSpecialist, { isLoading: isDeleting, isError: deleteError }] = + useDeleteSpecialistMutation(); + + const [createLocation] = useCreateLocationMutation(); + const [updateLocation]= useUpdateLocationMutation(); + const [deleteLocation] = useDeleteLocationMutation(); + + const [addSpecialistToStock] = useAddSpecialistMutation(); + const [removeSpecialistToStock] = useRemoveSpecialistMutation(); + + const [createCertifcate] = useCreateCertificateMutation(); + const [updateCertifcate] = useUpdateCertificateMutation(); + const [uploadCertifcatePicture] = useUploadSertificatePictureMutation(); + const [deleteCertifcate] = useDeleteCertificateMutation(); + + const filialsQuery = useGetFilialsQuery(); + const filials = filialsQuery.data ?? []; + + const departmentsQuery = useGetDepartmentsQuery(); + const departments = departmentsQuery.data ?? []; + + const filialsList = useMemo(() => { + const arr = filials?.data ?? []; + return arr.map(({ fid, regionId, shortName }) => ({ id: fid, regionId, shortName })); + }, [filials?.data]); + + const departmentsList = useMemo(() => { + const arr = departments?.data ?? []; + return arr.map(({ did, name }) => ({ id: did, name })); + }, [departments?.data]); + + const [previewFile, setPreviewile] = useState(null) + + const isValidImage = (file) => { + // Проверяем MIME‑тип + const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png']; + if (allowedTypes.includes(file.type)) return true; + + // На всякий случай можно дополнительно проверить расширение: + const ext = file.name.split('.').pop().toLowerCase(); + return ['jpg', 'jpeg', 'png'].includes(ext); +}; + + const handlePhotoUpload = () => { + const file = photoInputRef.current.files[0] + if (!file) return window.alert('Файл не выбран') + if (!isValidImage(file)) { + return window.alert('Изображения должны быть только формата JPG, JPEG или PNG'); + } + updateField('previewPicture', window.URL.createObjectURL(file)); + setPreviewile(file); + } + + const handlePhotoOperationUpload = () => { + const file = photoOperationInputRef.current.files[0] + if (!file) return window.alert('Файл не выбран') + updateField('operationPhotoUrl', { file, url: window.URL.createObjectURL(file) }); + } + + const [images, setImages] = useState([]); + + const handleCertificatesGalleryUpload = (e) => { + // const file = certificatesGalleryInputRef.current.files[0] + const files = Array.from(e.target.files); + if (!files) return window.alert('Файл не выбран') + const previews = files.map(file => { + return { + file, + url: window.URL.createObjectURL(file), + }; + }); + setImages(prew => [...prew, ...previews]); + + + // if (!file) return window.alert('Файл не выбран') + } + + const removeImage = (index) => { + setImages(prev => { + const img = prev[index]; + if (img.url && window.URL.revokeObjectURL) { + window.URL.revokeObjectURL(img.url); + } + return prev.filter((_, i) => i !== index); + }); + }; + + const removeOperationPhoto = () => { + updateField('operationPhotoUrl', {}); + }; + + const handleWrapper = () => { + if (!isFormValid()) { + window.alert('Пожалуйста, исправьте ошибки в форме'); + return; + } + + handleSave(); + } + + const [certsFromChild, setCertsFromChild] = useState([]); + // setPortfolioFromChild + const [portfolioFromChild, setPortfolioFromChild] = useState([]); + + const handleSave = async () => { + if (!isFormValid()) { + window.alert('Пожалуйста, исправьте ошибки в форме'); + return; + } + + const getDataCategory = () => { + const a = Object.keys(categoryParcer).find(categoryKey => categoryParcer[categoryKey] === form.category) + return a ?? null; + } + + + + const arr = []; + + dcodes.map(dcode => { + if (arr.includes(String(dcode))) return + arr.push(String(dcode)) + }) + locations.map(location => { + if (arr.includes(String(location.dcode))) return + arr.push(String(location.dcode)) + }) + + console.log(form.regionId) + + + const data = { + nameString: `${form.lastName} ${form.firstName} ${form.middleName}`, + fullName: { + lastName: form.firstName, + firstName: form.lastName, + middleName: form.middleName + }, + active: form.active ?? false, + displaySchedule: !form.hideSchedule, + alias: form.alias ?? '', + degree: form.degree ?? '', + post: postTags.join(', ') ?? '', + experience: getYear(form.experience) ?? '', + sType: Number(form.sType), + regionId: Number(form.regionId), + anons: anons ?? '', + content: content ?? '', + tags: tags ?? [], + highlightedTags: highlightedTags ?? [], + video: form.videoUrl ?? '', + videoVertical: form.videoCardUrl ?? '', + scheduleText: form.scheduleText ?? '', + dcodes: arr.map((dcode) => String(dcode).trim()).join(',') ?? '', + category: form.category === 'Не указано' ? '' : form.category, + kodoper: kodopers ?? [], + patientAge: form.isChildrenDoctor ? (!isNaN(Number(form.patientAge)) ? Number(form.patientAge) : null) : null, + onlyOnlineMode: form.onlyOnlineMode ?? false, + prodoctor: form.prodoctor, + prodoctorLink: form.prodoctor ? (form.prodoctorLink.length > 0 ? form.prodoctorLink : '') : '', + prodoctorText: form.prodoctor ? (form.prodoctorText.length > 0 ? form.prodoctorText : '') : '', + }; + + const formattedLocations = locations.map(location => ({ + active: location?.active ? location.active : false, + dcode: location.dcode, + department: location.department, + filial: location.filial, + id: location?.id, + onlineMode: location.onlineMode, + nearestDate: location.nearestDate, + })); + + // console.log(data) + +/**///////////////////////////////////////////////////// */ + + + function isEqualExceptId(a, b) { + for (const key in a) { + if (key === 'id') continue; + if (a[key] !== b[key]) return false; + } + for (const key in b) { + if (key === 'id') continue; + if (a[key] !== b[key]) return false; + } + return true; +} + +function diffArrays(initial, current) { + const currentMap = new Map(current.map(item => [item.id, item])); + const initialMap = new Map(initial.map(item => [item.id, item])); + + const deletedLocations = []; + const changedLocations = []; + const addedLocations = []; + + for (const item of initial) { + const curr = currentMap.get(item.id); + if (!curr) { + deletedLocations.push(item); + } else if (!isEqualExceptId(item, curr)) { + changedLocations.push({ ...curr }); + } + } + + for (const item of current) { + if (!initialMap.has(item.id)) { + addedLocations.push(item); + } + } + + return { deletedLocations, changedLocations, addedLocations }; +} + + const { deletedLocations, changedLocations, addedLocations } = diffArrays(initialLocations, formattedLocations); + + + console.log(data) + + try { + const {id} = await createSpecialist({ + data: data, + }).unwrap(); + console.log('success specialist update') + + for (let i = 0; i < deletedLocations.length; i += 1) { + await deleteLocation(deletedLocations[i].id).unwrap() + } + console.log('success delete locations') + + for (let i = 0; i < addedLocations.length; i += 1) { + const [day, month, year] = addedLocations[i].nearestDate.split('.'); + const isoDate = `${year}-${month}-${day}`; + await createLocation({ specialistId: id, data: { + active: addedLocations[i].active, + dcode: addedLocations[i].dcode, + department: addedLocations[i].department, + filial: addedLocations[i].filial, + nearestDate: isoDate, + onlineMode: addedLocations[i].onlineMode, + } }).unwrap() + } + console.log('success create locations') + + for (let i = 0; i < changedLocations.length; i += 1) { + await updateLocation({ + specialistId: id, + locationId: changedLocations[i].id, + data: { + active: changedLocations[i].active, + }, + }).unwrap() + } + console.log('success update locations') + + + //-------------------------------------------------- + const initMap = new Map([...certificates.map(c => [c.id, c]), ...portfolio.map(c => [c.id, c])]); + const currMap = new Map([...certsFromChild.filter(c => c.id).map(c => [c.id, c]), ...portfolioFromChild.filter(c => c.id).map(c => [c.id, c])]); + + const created = [...certsFromChild.filter(c => c.id == null), ...portfolioFromChild.filter(c => c.id == null)]; + + const deleted = [...certificates.filter(c => !currMap.has(c.id)), ...portfolio.filter(c => !currMap.has(c.id))]; + + const modified = [ + ...certsFromChild + .filter(c => c.id != null && initMap.has(c.id)) + .filter(c => { + const orig = initMap.get(c.id); + return ( + c.name !== orig.name || + c.description !== orig.description || + c.picture !== orig.picture || + c.active !== orig.active + ); + }), + ...portfolioFromChild + .filter(c => c.id != null && initMap.has(c.id)) + .filter(c => { + const orig = initMap.get(c.id); + return ( + c.name !== orig.name || + c.description !== orig.description || + c.picture !== orig.picture || + c.active !== orig.active + ); + }) + ]; + + for (let i = 0; i < created.length; i += 1) { + if (created[i].name.trim().length === 0 && created[i].description.trim().length === 0) continue + const response = await createCertifcate({ + specialistId: id, + data: { + name: created[i].name, + description: String(created[i].description), + active: created[i].active, + type: created[i].type, + }, + }).unwrap() + if (created[i].picture) await uploadCertifcatePicture({ + id: response.id, + file: created[i]._file, + }).unwrap() + } + console.log('success create cert') + + for (let i = 0; i < modified.length; i += 1) { + if (modified[i].name.trim().length === 0 && modified[i].description.trim().length === 0) continue + await updateCertifcate({ + specialistId: id, + id: modified[i].id, + data: { + active: modified[i].active, + description: modified[i].description, + name: modified[i].name, + type: modified[i].type, + }, + }).unwrap() + console.log(modified[i]) + if (modified[i]?._file) { + await uploadCertifcatePicture({ + id: modified[i].id, + file: modified[i]._file, + }).unwrap() + } + } + console.log('success update cert') + + for (let i = 0; i < deleted.length; i += 1) { + await deleteCertifcate({ + id: deleted[i].id, + }).unwrap() + } + console.log('success delete cert') + + //-------------------------------------------------- + + if (previewFile) { + await uploadPicture({ id, file: previewFile }).unwrap(); + console.log('success photo update') + } + + const initIds = new Set(form.initStocks.map(s => s.id)); + const childIds = new Set(stocksFromChild.map(s => s.id)); + + const deletedStocs = form.initStocks.filter(s => !childIds.has(s.id)); + const addedStocks = stocksFromChild.filter(s => !initIds.has(s.id)); + console.log('============================') + console.log(deletedStocs) + console.log(addedStocks) + + for (let i = 0; i < addedStocks.length; i += 1) { + await addSpecialistToStock({ + stockId: addedStocks[i].id, + specialistId: id, + }).unwrap() + } + console.log('success added promotions') + + for (let i = 0; i < deletedStocs.length; i += 1) { + await removeSpecialistToStock({ + stockId: deletedStocs[i].id, + specialistId: id, + }).unwrap() + } + console.log('success delete promotions') + + + + setModalSuccess(true) + window.setTimeout(() => { + navigate( `/specialist/edit/${id}` ); + // window.location.reload() + }, 2000); + } catch (err) { + console.error('Ошибка при обновлении специалиста:', err) + } + + } + +/* + useEffect(() => { + if (patientAgeInputRef.current) { + patientAgeInputRef.current.focus(); + } + }, [ form.isChildrenDoctor ]); +*/ + const [isModalCustomOpen, setModalCustomOpen] = useState(false); + const [isModalDeleteOpen, setModalDeleteOpen] = useState(false); + const [isModalSuccess, setModalSuccess] = useState(false); + const [isModalDcodes, setModalDcodes] = useState(false); + + + return ( + setModalDeleteOpen(true) } + // addSpecialist={ navigateAddSpecialist } + isAddSpecialist = {true} + > + +
    +
    + +
    +
    + Фото врача e.currentTarget.src = PHOTO_PLACEHOLDER ?? '/assets/photo-placeholder.png' } + /> + + +
    +
    +
    +
    +
    + + updateField('lastName', e.target.value) } + onBlur={handleBlur} + /> + {errors.lastName && {errors.lastName}} +
    +
    + + updateField('firstName', e.target.value) } + onBlur={handleBlur} + /> + {errors.firstName && {errors.firstName}} +
    +
    + + updateField('middleName', e.target.value) } + pattern="[А-ЯЁ][а-яё]+" + title="Только буквы кириллицы, первая буква заглавная" + onBlur={handleBlur} + /> + {errors.middleName && {errors.middleName}} +
    +
    +
    + + updateField('alias', e.target.value) } + /> +
    + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + +
    + + {form.isChildrenDoctor && +
    +
    + + { + if (patientAgeInputRef.current) patientAgeInputRef.current.focus() + }} + style={{ backgroundColor: 'white', borderTopRightRadius: 0, borderBottomRightRadius: 0, borderRight: 'none', height: 'calc(1.5em + .75rem + 2px)' }} + >Прием детей с + + + { + updateField('patientAge', e.target.value) + validateField('patientAge', form.patientAge); + }} + onBlur={handleBlur} + /> + + { + if (patientAgeInputRef.current) patientAgeInputRef.current.focus() + }} + style={{ backgroundColor: 'white', borderTopLeftRadius: 0, borderBottomLeftRadius: 0, borderLeft: 'none', height: 'calc(1.5em + .75rem + 2px)' }} + >лет + +
    + {errors.patientAge && {errors.patientAge}} +
    + } +
    + +
    +
    +
    + +
    +
    +
    + + +
    +
    + + updateField('degree', e.target.value) } + /> +
    +
    +
    + + +
    + +
    + + + + +
    + { + updateField('experience', e); + validateField('experience', e); + }} + className="form-control" + calendarClassName="react-datepicker-bootstrap" + popperClassName="react-datepicker-popper" + showYearPicker + dateFormat="yyyy" + yearItemNumber={10} + /> +
    + {errors.experience && {errors.experience}} +
    + + +
    +
    + updateField('active', e.target.checked)} + /> + +
    +
    +
    + + +
    +
    + + +
    + + updateField('scheduleText', e.target.value)} + /> +
    + +
    +
    + updateField('hideSchedule', e.target.checked)} + /> + +
    + +
    + updateField('onlyOnlineMode', e.target.checked)} + /> + +
    +
    + + + +
    +
    + Расписание из Инфоклиники +
    + + +
    + + + {/* + Boolean(dcodes.length) && + { + setDcodes(prev => + prev.filter(dc => + dc !== String(dcode) + )) + setLocations(prev => + prev.filter(l => + String(l.dcode) !== dcode + )) + }} + />*/ + } + + {locations.length > 0 && +
    +
    + + + + + + + + + + + + + + {locations.map((location, index) => ( + + + + + + + + + + ) + )} + +
    dcodeФилиалОтделениеБлижайшая дата приемаОнлайн приемОтображать на сайте
    { location.dcode }{ filialsList.find(filial => filial.id === location.filial)?.shortName }{ departmentsList.find(department => Number(department.id) === Number(location.department))?.name }{ location.checkedDate ? location.nearestDate : '' }{ location.onlineMode ? 'да' : 'нет' } + { + const checked = e.target.checked; + setLocations(prev => + prev.map(l => + l.key === location.key + ? { ...l, active: checked } + : l + )); + } + //updateField('active', e.target.checked) + } + />
    +
    + + + +
    + } + +
    +
    + + + +
    +
    +
    +
    + Услуги врача +
    + + +
    + + + {Boolean(kodopers) && kodopers.length > 0 && + + } + + {displayKodoper.length > 0 && +
    +
    + + + + + + + + + + + + + { displayKodoper.map((item, index) => + + + + + + + + + )} + +
    Мед. кодУслугаОтделениеФилиалСтоимость
    { item.kodoper }{ item.schname }{ item.specname }{ item.fname }{ `${item.priceInfo.price} ₽` } + +
    +
    +
    +}
    +
    + +
    +
    +
    +
    + Акции +
    + + +
    + + { stocksFromChild.length > 0 && +
    + + + + + + + + + + + { + stocksFromChild.map((stock, index) => + + + + + + + ) + } + +
    НазваниеНачало акцииОкончание акции
    { stock.name }{ stock.startDate }{ stock.endDate } + +
    +
    + } + + { /* + */ + } + +
    +
    + +
    +
    + +
    + + +
    + +
    + + +
    + + +
    +
    + + + +
    +
    + +
    + +
    + + { + + } + +
    +
    + + +
    +
    + +
    + +
    + + { + + } + +
    +
    + + +
    +
    +
    + + +
    + +
    + + +
    + +
    +
    + +
    +
    +
    + + updateField('videoUrl', e.target.value) } + onBlur={handleBlur} + /> + {errors.videoUrl && {errors.videoUrl}} +
    +
    + + updateField('videoCardUrl', e.target.value) } + onBlur={handleBlur} + /> + {errors.videoCardUrl && {errors.videoCardUrl}} +
    +
    +
    + +
    +
    + +
    + { + updateField('prodoctor', e.target.checked) + if (!e.target.checked) { + updateField('prodoctorText', '') + updateField('prodoctorLink', '') + setErrors(prev => ({ ...prev, prodoctorLink: '' })); + } + }} + /> + +
    + + { + form.prodoctor && <> +
    + + updateField('prodoctorText', e.target.value)} + /> +
    + +
    + + { + updateField('prodoctorLink', e.target.value) + validateField('prodoctorLink', form.prodoctorLink) + }} + onBlur={handleBlur} + /> + {errors.prodoctorLink && {errors.prodoctorLink}} +
    + + } + +
    +
    + + +

    Изменения успешно внесены.

    +
    + + setModalDcodes(false)} + departments={departmentsList} + filials={filialsList} + /> + + { + setKodopers(selectedCodopers) + setDisplayKodoper(displayedCodopers) + }} + onCancel={() => setModalKodopers(false)} + /> + + { + // setStocks(selectedStocks) + setStocksFromChild(selectedStocks) + }} + onCancel={() => setModalStocks(false)} + /> + +
    + ); +} diff --git a/src/pages/AddStockPage.jsx b/src/pages/AddStockPage.jsx new file mode 100644 index 0000000..c5580cb --- /dev/null +++ b/src/pages/AddStockPage.jsx @@ -0,0 +1,208 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; + +import { + useCreateStockMutation, + useGetStockQuery, + useUpdateStockMutation, + useUploadStockPictureMutation, +} from '/src/api/apiStock'; +import { TextEditor } from '../components/Editors/TextEditor' +import { LoadingComponent } from '../components/Placeholders/LoadingComponent'; +import { ErrorComponent } from '../components/Placeholders/ErrorComponent'; +import { NotFindElement } from '../components/Placeholders/NotFindElement'; +import { EditElementForm } from '../components/Forms/EditElementForm'; +import Modal from '../components/Modals/Modal'; + +const isValidImage = (file) => { + const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png']; + if (allowedTypes.includes(file.type)) return true; + + const ext = file.name.split('.').pop().toLowerCase(); + return ['jpg', 'jpeg', 'png'].includes(ext); +}; + +export function AddStockPage() { + const navigate = useNavigate(); + const navigateBack = () => navigate( `/promotions` ); + + const [createStock] = useCreateStockMutation(); + const [uploadPicture] = useUploadStockPictureMutation(); + + const [anons, setAnons] = useState('') + const [content, setContent] = useState('') + const [isModalSuccess, setModalSuccess] = useState(false); + + const [form, setForm] = useState({ + name: '', + picture: '', + startDate: '', + endDate: '', + }); + const fileInputRef = useRef(); + + const startDateInputRef = useRef(null); + const endDateInputRef = useRef(null); + + + const handleChange = (key) => (e) => { + setForm(f => ({ ...f, [key]: e.target.value })); + }; + + const handleFile = (e) => { + const file = e.target.files[0]; + if (!file) return window.alert('Файл не выбран') + if (!isValidImage(file)) { + return window.alert('Изображения должны быть только формата JPG, JPEG или PNG'); + } + const url = window.URL.createObjectURL(file); + setForm(f => ({ ...f, _file: file, picture: url })); + }; + + const handleSave = async () => { + try { + const response = await createStock({ + data: { + name: form.name, + anons: anons, + content: content, + startDate: String(form.startDate), + endDate: String(form.endDate), + } + }).unwrap(); + + if (form._file) { + await uploadPicture({ id: response.id, file: form._file }).unwrap(); + } + + + setModalSuccess(true) + window.setTimeout(() => { + navigate( `/promotions/edit/${response.id}` ); + window.location.reload() + }, 2000); + console.log('success update promotion') + + } catch (err) { + console.error('Ошибка при обновлении акции:', err) + } + }; + + return ( + {} } + isAddSpecialist = {true} + > +
    + + +
    + +
    +
    +
    + + { + if (startDateInputRef.current?.showPicker) { + startDateInputRef.current.showPicker(); + } + }} + onChange={handleChange('startDate')} + /> +
    +
    + + { + if (endDateInputRef.current?.showPicker) { + endDateInputRef.current.showPicker(); + } + }} + onChange={handleChange('endDate')} + /> +
    +
    + +
    + +
    +
    + + +
    + +
    + +
    + {form.picture && ( + + )} + + +
    +
    +
    + +
    + + +
    + + + + {/* + + + */} + +

    Изменения успешно внесены.

    +
    +
    + ) +} \ No newline at end of file diff --git a/src/pages/DepartmentsListPage.jsx b/src/pages/DepartmentsListPage.jsx new file mode 100644 index 0000000..cb52193 --- /dev/null +++ b/src/pages/DepartmentsListPage.jsx @@ -0,0 +1,85 @@ +import { useState, useRef, useMemo } from 'react'; +import { useSelector } from 'react-redux'; +import { useNavigate } from 'react-router-dom'; + +import { useGetDepartmentsQuery } from '../api/apiDepartment'; +import { selectUtils } from '../store/slice/utilsSlice'; +/**/ +import { useSortedPaginated } from '../hooks/useSortedPaginated'; +import { useOutsideClick } from '../hooks/useOutsideClick'; +import { useSorting } from '../hooks/useSorting'; +/**/ +import { LoadingComponent } from '../components/Placeholders/LoadingComponent'; +import { ErrorComponent } from '../components/Placeholders/ErrorComponent'; +import { PageNav } from '../components/Paginations/PageNav'; +import { THead } from '../components/Table/THead'; +import { TBody } from '../components/Table/TBody'; + +export const DepartmentsListPage = () => { + const { data: departmentsRaw = [], isLoading, error } = useGetDepartmentsQuery(); + const departments = departmentsRaw.length === 0 ? [] : departmentsRaw.data; + const DEPARTMENTS_COLUMN = useSelector(selectUtils).DEPARTMENTS_COLUMN; + + const ITEMS_PER_PAGE = useSelector(selectUtils).ITEMS_PER_PAGE; + const navigate = useNavigate(); + const goEdit = ( id ) => navigate( `/departments/edit/${ id }` ); + + const [ expandedId, setExpandedId ] = useState( null ); + const [ currentPage, setCurrentPage ] = useState( 1 ); + + const tableRef = useRef( null ); + useOutsideClick( tableRef, () => setExpandedId( null ) ); + + const { sortBy, sortDirection, handleSort } = useSorting(); + + const { paginated, totalPages } = useSortedPaginated( + departments.map(({ did, name, middleName, alias }) => + ({ id: did, name, middleName, alias })), + ITEMS_PER_PAGE, + sortBy, + sortDirection, + currentPage + ); + + if (error) return + + return ( +
    +

    + Отделения +

    + + { isLoading && + + } + + { !isLoading && + <> +
    + + + +
    +
    + + + } + +
    + ) +} diff --git a/src/pages/EditDepartmentPage.jsx b/src/pages/EditDepartmentPage.jsx new file mode 100644 index 0000000..bb69f40 --- /dev/null +++ b/src/pages/EditDepartmentPage.jsx @@ -0,0 +1,120 @@ +import { useEffect, useState } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; +import { useSelector } from 'react-redux'; + +import { useGetDepartmentsQuery, useUpdateDepartmentsMutation } from '../api/apiDepartment'; +import { selectUtils } from '../store/slice/utilsSlice'; +/**/ +import { LoadingComponent } from '../components/Placeholders/LoadingComponent'; +import { ErrorComponent } from '../components/Placeholders/ErrorComponent'; +import { NotFindElement } from '../components/Placeholders/NotFindElement'; +import { EditElementForm } from '../components/Forms/EditElementForm'; +import { ResponseModals } from '../components/Modals/ResponseModals'; + +export const EditDepartmentPage = () => { + const { id } = useParams(); + const { data: departmentsRaw = [], isLoading, error } = useGetDepartmentsQuery(); + + const departments = departmentsRaw.data ?? []; + const department = departments.find(( dept ) => String( dept.did ) === id); + + const RELOAD_TIMEOUT = useSelector(selectUtils).RELOAD_TIMEOUT; + + const [ updateDepartment ] = useUpdateDepartmentsMutation(); + + const navigate = useNavigate(); + const navigateBack = () => navigate( `/departments` ); + + const [ form, setForm ] = useState({ + middleName: '', + alias: '', + }); + const updateField = ( key, value ) => { + const normalized = value === undefined || value === null ? '' : value; + setForm(prev => ({ ...prev, [key]: normalized })); + }; + + const [ modal, setModal ] = useState( undefined); + + useEffect(() => { + if (!department) return; + + const keys = ['middleName','alias']; + const next = {}; + keys.forEach(k => { + const v = department[k]; + next[k] = v === undefined || v === null ? '' : (typeof v === 'number' ? String(v) : v); + }); + setForm(prev => ({ ...prev, ...next })); + }, [ department ]); + + const handleSave = async () => { + setModal('loading'); + + const data = {}; + Object.keys( form ).forEach( key => { + if ( key === 'regionId' ) data[ key ] = Number( form[ key ] ); + else data[ key ] = form[ key ]; + }); + + try { + await updateDepartment( { departmentId: id, data: data } ).unwrap(); + + setModal('success'); + window.setTimeout(() => { window.location.reload() }, RELOAD_TIMEOUT); + } + catch (err) { + setModal('error') + console.error('Filial update error:', error); + } + } + + if ( isLoading ) return + if ( error ) return + if ( !department ) return ( + + ) + + return ( + + +
    + + updateField( 'middleName', e.target.value )} + /> +
    + +
    + + updateField( 'alias', e.target.value )} + /> +
    + + + +
    + ) +} diff --git a/src/pages/EditFilialPage.jsx b/src/pages/EditFilialPage.jsx new file mode 100644 index 0000000..5fc135b --- /dev/null +++ b/src/pages/EditFilialPage.jsx @@ -0,0 +1,328 @@ +import { useEffect, useState, useRef } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; +import { useSelector } from 'react-redux'; + +import { apiUrl } from '@/config/api'; + +import { useGetFilialsQuery, useUpdateFilialMutation, useUploadFilialPictureMutation } from '../api/apiFilial'; +import { selectUtils } from '../store/slice/utilsSlice'; +import { selectRegions } from '../store/slice/regionSlice'; +/**/ +import { LoadingComponent } from '../components/Placeholders/LoadingComponent'; +import { ErrorComponent } from '../components/Placeholders/ErrorComponent'; +import { NotFindElement } from '../components/Placeholders/NotFindElement'; +import { EditElementForm } from '../components/Forms/EditElementForm'; +import { ResponseModals } from '../components/Modals/ResponseModals'; +import { PhoneInput } from '../components/Input/PhoneInput'; + +export const EditFilialPage = () => { + const { id } = useParams(); + const { data: filialsRaw = [], isLoading, loadingError } = useGetFilialsQuery(); + const PHOTO_PLACEHOLDER = '/src/assets/photo-placeholder.png'; + const photoInputRef = useRef(null); + + const filials = filialsRaw.length === 0 ? [] : filialsRaw.data; + const filial = filials.find( ( filial ) => String( filial.fid ) === id ); + + const regions = useSelector( selectRegions ); + const RELOAD_TIMEOUT = useSelector(selectUtils).RELOAD_TIMEOUT; + + const [ updateFilial ] = useUpdateFilialMutation(); + const [uploadPicture] = useUploadFilialPictureMutation(); + + const navigate = useNavigate(); + const navigateBack = () => navigate( `/filials` ); + + const [ form, setForm ] = useState({ + id: '', + regionId: '', + address: '', + name: '', + siteId: '', + company: '', + phone: '', + active: '', + email: '', + fid: '', + origin: '', + picture: null, + policy: '', + }); + const updateField = ( key, value ) => { + const normalized = value === undefined || value === null ? '' : value; + setForm(prev => ({ ...prev, [key]: normalized })); + }; + + const [ modal, setModal ] = useState( undefined ); + const [previewFile, setPreviewFile] = useState(null); + + useEffect(() => { + if (!filial) return; + + const filialData = { + id: filial.id, + regionId: filial.regionId, + address: filial.address, + name: filial.name, + siteId: filial.siteId, + company: filial.company, + phone: filial.phone, + active: filial.active, + email: filial.email, + fid: filial.fid, + origin: filial.origin, + picture: apiUrl(filial.pictureLink), + policy: filial.policy, + } + setForm({... filialData}) + }, [ filial ]); + + const isValidImage = (file) => { + const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png']; + if (allowedTypes.includes(file.type)) return true; + + const ext = file.name.split('.').pop().toLowerCase(); + return ['jpg', 'jpeg', 'png'].includes(ext); + }; + + const handlePhotoUpload = () => { + const file = photoInputRef.current.files[0] + if (!file) return window.alert('Файл не выбран') + if (!isValidImage(file)) { + return window.alert('Изображения должны быть только формата JPG, JPEG или PNG'); + } + updateField('picture', window.URL.createObjectURL(file)); + setPreviewFile(file); + } + + const handleSave = async () => { + setModal('loading'); + + const data = { + id: form.id, + fid: form.fid, + active: form.active, + regionId: Number(form.regionId), + address: form.address || '', + name: form.name || '', + company: form.company || '', + phone: form.phone ? form.phone.replaceAll(' ', '') : '', + email: form.email || '', + policy: form.policy || '', + origin: form.origin || '', + }; + + try { + await updateFilial( { filialId: form.fid, data: form.siteId ? { ...data, siteId: form.siteId } : data } ).unwrap(); + + if (previewFile) { + await uploadPicture({ id: form.id, file: previewFile }).unwrap(); + console.log('success photo update') + } + + setModal('success'); + window.setTimeout(() => { window.location.reload() }, RELOAD_TIMEOUT); + } + catch ( error ) { + setModal('error') + console.error('Filial update error:', error); + } + } + + if ( isLoading ) return + if ( loadingError ) return + if ( !filial ) return ( + + ) + + return ( + + +
    + +
    +
    + Фото врача e.currentTarget.src = PHOTO_PLACEHOLDER } + /> + + +
    +
    + +
    + +
    + +
    +
    + + +
    +
    + + updateField( 'fid', e.target.value )} + /> +
    + +
    + + updateField( 'siteId', e.target.value )} + /> +
    + +
    +
    + +
    + +
    + + updateField( 'name', e.target.value )} + /> +
    + +
    + + updateField( 'company', e.target.value )} + /> +
    +
    +
    + +
    + + + +
    + + updateField( 'address', e.target.value )} + /> +
    + + + +
    + + updateField('phone', val)} + /> +
    + +
    + + updateField( 'email', e.target.value )} + /> +
    + +
    + + updateField( 'origin', e.target.value )} + /> +
    + +
    + + updateField( 'policy', e.target.value )} + /> +
    + + + +
    + ) +} diff --git a/src/pages/EditSpecialistPage.jsx b/src/pages/EditSpecialistPage.jsx new file mode 100644 index 0000000..651d939 --- /dev/null +++ b/src/pages/EditSpecialistPage.jsx @@ -0,0 +1,1609 @@ +import {useEffect, useState, useMemo, useRef} from 'react' +import {useParams, useNavigate, useLocation } from 'react-router-dom' +import DatePicker from "react-datepicker"; + +import { apiUrl } from '@/config/api'; + +import { useUpdateSpecialistMutation, useDeleteSpecialistMutation, useUploadSpecialistPictureMutation } from '../api/apiSpecialist' +import { useCreateLocationMutation, useUpdateLocationMutation, useDeleteLocationMutation } from '/src/api/apiLocation.js' +import { + useCreateCertificateMutation, + useUpdateCertificateMutation, + useUploadSertificatePictureMutation, + useDeleteCertificateMutation, +} from '/src/api/apiCertificate.js' +import { useAddSpecialistMutation, useRemoveSpecialistMutation } from '../api/apiStock' +import { useSpecialist } from '../hooks/useSpecialist'; +// +import { LoadingComponent } from '../components/Placeholders/LoadingComponent'; +import { ErrorComponent } from '../components/Placeholders/ErrorComponent'; +import { NotFindElement } from '../components/Placeholders/NotFindElement'; +import { EditElementForm } from '../components/Forms/EditElementForm'; +import { TagInput } from '../components/Input/Taginput'; +import { TagStaticInput } from '../components/Input/TagStaticInput'; +import { TagKodoperStaticInput } from '../components/Input/TagKodoperStatic'; +import { TextEditor } from '../components/Editors/TextEditor' +import Modal from '../components/Modals/Modal'; +import DcodeModal from '../components/Modals/DcodeModal'; +import KodoperModal from '../components/Modals/KodoperModal'; +import { CertificatesForm } from '../components/Docs/Certificates'; +import { PortfolioForm } from '../components/Docs/Portfolio'; +import { StocksForm } from '../components/Docs/Stocks' +import { StockModal } from '../components/Modals/StockModal' +import PHOTO_PLACEHOLDER from '../assets/photo-placeholder.png' + +const formatStockDate = (date) => { + const dateStart = new Date(date); + + const year = dateStart.getFullYear(); + const month = String(dateStart.getMonth() + 1).padStart(2, '0'); + const day = String(dateStart.getDate()).padStart(2, '0'); + const hours = String(dateStart.getHours()).padStart(2, '0'); + const minutes = String(dateStart.getMinutes()).padStart(2, '0'); + + return `${hours}:${minutes}, ${day}.${month}.${year}`; +} + + const regionOptions = { + 91: 'Саратов' , + 92: 'Волгоград', + 93: 'Воронеж', + 94: 'Краснодар', + }; + + const sTypeOptions = { + 0: 'Взрослый врач', + 1: 'Детский врач', + 2: 'Администрация', + 3: 'Стоматология', + 4: 'Мед. сестра', + }; + + const getYear = (date) => { + const dateObject = new Date(date); + return String(dateObject.getFullYear()) + } + +const formatCategory = (rawCategory) => { + if (!rawCategory) return 'Не указано' + const categoryLowerCase = rawCategory.toLowerCase(); + switch (categoryLowerCase) { + case 'высшая': + case 'ведущий специалист': + return 'Высшая'; + case 'первая': + case 'главный специалист': + return 'Первая'; + case 'вторая': + return 'Вторая'; + default: + return 'Не указано' + } +} + + +export const EditSpecialistPage = () => { + const { id } = useParams(); + const { state } = useLocation(); + + const queryParams = { + search: state?.search ?? '', + region: state?.region ?? '', + page: state?.page ?? null, + } + + const navigate = useNavigate(); + const navigateBack = () => { + let query = ''; + + Object.keys(queryParams).map( param => { + if (queryParams[param]) query += `&${param}=${queryParams[param]}`; + }); + + if (query) query = `?${query.slice(1)}`; + + navigate( `/specialist${query}` ); + } + + const dateInputRef = useRef(null); + const patientAgeInputRef = useRef(null); + + const [ locations, setLocations ] = useState([]); + const [ initialLocations, setInitialLocations ] = useState([]); + + const setFromRawLocations = (rawLocations) => { + const selectedDcodes = [...new Set(rawLocations.map(({dcode}) => dcode))]; + const arr = selectedDcodes.filter(dcode => !dcodes.includes(dcode)).map(dc => String(dc)); + setDcodes(arr) + setLocations(rawLocations) + } + + const [ stocks, setStocks ] = useState([]); + const [ stocksFromChild, setStocksFromChild ] = useState([]); + + const [ anons, setAnons ] = useState(''); + const [ content, setContent ] = useState(''); + + const [displayKodoper, setDisplayKodoper] = useState([]); + + const [errors, setErrors] = useState({ + lastName: '', + firstName: '', + middleName: '', + videoUrl: '', + videoCardUrl: '', + patientAge: '', + prodoctorLink: '', + }); + + const categoryList = [ + 'Не указано', + 'Вторая', + 'Первая', + 'Высшая', + ]; + + const [isModalKodopers, setModalKodopers] = useState(false); + const [kodopers, setKodopers] = useState([]); + const [certificates, setCertificates] = useState([]); + const [portfolio, setPortfolio] = useState([]); + + const [ form, setForm ] = useState({ + nameString: '', + lastName: '', + firstName: '', + middleName: '', + active: false, // boolean + displaySchedule: null, // boolean + // + hideSchedule: false, // booleal + // + alias: undefined, // string + post: '', // string + experience: undefined, // number + sType: null, // number + regionId: null, // number + anons: '', // string + add redactor + content: '', // string + add redactor + tags: [], // json + highlightedTags: [], // json + videoUrl: '', // string + videoCardUrl: '', // string + scheduleText: '', + //isCastom: false, // has autoupdate - boolean + category: '', // +++++++ + previewPicture: undefined, // string + filialId: null, // from locations.locations[0].filial + kodoper: null, // <<<---??? + prodoctor: '', + prodoctorLink: '', + prodoctorText: '', + onlyOnlineMode: '', + // + isChildrenDoctor: undefined, // from sType + patientAge: undefined, // integer + initStocks: [], + //isCastomChecker: undefined, + // + degree: '', + isLeadingSpecialist: false, + isChiefSpecialist: false, + education: '', + academicDegree: '', + professionalCompetencies:'', + advancedTraining: '', + certificates: '', + certificatesGallery: [], + adultsReception: '', + cost: '', + hasPromotion: false, + onlineConsultationLink: '', + onlyOnline: false, + hasProDoctorsAward: false, + proDoctorsAwardText: '', + proDoctorsAwardLink: '', + postTags: [], + operationPhotoUrl: '', + }); + + const updateField = ( key, value ) => { + setForm(prev => ({ ...prev, [key]: value })); + }; + + const [isModalStocks, setModalStocks] = useState(false); + + const regexCyrillic = /^[А-ЯЁ][а-яё]+$/; + const regexRutube = /^https:\/\/rutube\.ru\/.*$/; + const regexProdoctor = /^https:\/\/prodoctorov\.ru\/.*$/; + + const validateField = (field, value) => { + let error = ''; + const currentYear = new Date().getFullYear(); + switch (field) { + case 'lastName': + case 'firstName': + case 'middleName': + if (!value) error = 'Обязательное поле'; + else if (!regexCyrillic.test(value)) error = 'Только кириллица, с заглавной буквы'; + break; + case 'experience': + if (!value) { + error = 'Обязательное поле'; + } else if (Number(getYear(value)) > Number(currentYear)) { + error = 'Год должен быть не больше текущего'; + } + break; + case 'videoUrl': + case 'videoCardUrl': + if (value && !regexRutube.test(value)) error = 'Должно быть ссылкой с rutube'; + break; + case 'prodoctorLink': + if (form.prodoctor) { + if (!value) { + error = 'Укажите ссылку'; + } else { + if (value && !regexProdoctor.test(value)) error = 'Должно быть ссылкой с prodoctorov.ru'; + } + } else { + error = '' + } + break; + case 'patientAge': + if (form.isChildrenDoctor) { + if ( !value ) { + error = 'Укажите возраст'; + } else { + const num = Number(value); + if (!Number.isInteger(num) || num < 0 || num > 18) error = 'Возраст не может быть меньше 0 и больше 18'; + } + } else { + error = '' + } + break; + } + setErrors(prev => ({ ...prev, [field]: error })); + }; + + const handleBlur = e => { + const { name, value } = e.target; + validateField(name, value); + }; + + const isFormValid = () => { + ['lastName', 'firstName', 'middleName', 'videoUrl', 'videoCardUrl', 'patientAge', 'prodoctorLink', 'experience'].forEach(f => validateField(f, form[f])); + const a = form.prodoctor ? ( form.prodoctorLink.length > 0 ) : true; + const b = form.isChildrenDoctor ? ( form.patientAge ) : true; + + return Object.entries(errors).every( + ([key, err]) => { + return !err; + } + ) && form.lastName && form.firstName && form.middleName && a && b && form.experience; + }; + + + const [ tags, setTags ] = useState([]); + const [ highlightedTags, setHighlightedTags ] = useState([]); + const [ postTags, setPostTags ] = useState([]); + const [ dcodes, setDcodes ] = useState([]); + + const photoInputRef = useRef(null) + const photoOperationInputRef = useRef(null) + const certificatesGalleryInputRef = useRef(null) + + const { isLoading, error, specialist, filials, regions, departments, kodoperDetails } = useSpecialist(id); + + const [updateSpecialist, { isLoading: isUpdating, isError: updateError }] = + useUpdateSpecialistMutation(); + const [uploadPicture, { isLoadingPicture, isErrorOicture }] = useUploadSpecialistPictureMutation(); + const [deleteSpecialist, { isLoading: isDeleting, isError: deleteError }] = + useDeleteSpecialistMutation(); + + const [createLocation] = useCreateLocationMutation(); + const [updateLocation]= useUpdateLocationMutation(); + const [deleteLocation] = useDeleteLocationMutation(); + + const [addSpecialistToStock] = useAddSpecialistMutation(); + const [removeSpecialistToStock] = useRemoveSpecialistMutation(); + + const [createCertifcate] = useCreateCertificateMutation(); + const [updateCertifcate] = useUpdateCertificateMutation(); + const [uploadCertifcatePicture] = useUploadSertificatePictureMutation(); + const [deleteCertifcate] = useDeleteCertificateMutation(); + + const filialsList = useMemo(() => { + const arr = filials?.data ?? []; + return arr.map(({ fid, regionId, shortName }) => ({ id: fid, regionId, shortName })); + }, [filials?.data]); + + const departmentsList = useMemo(() => { + const arr = departments?.data ?? []; + return arr.map(({ did, name }) => ({ id: did, name })); + }, [departments?.data]); + + useEffect( () => { + if ( specialist ) { + const initial = specialist.post + ? specialist.post.split(',').map(s => s.trim()) + : []; + const reorderInit = []; + initial.map((element, index) => { + if (element.length < 4) { + if (index > 0) { + reorderInit.pop(); + reorderInit.push(`${ initial[index-1]}, ${element}`); + return + } + reorderInit.push(element); + return + } + reorderInit.push(element); + return + }); + setPostTags(reorderInit); + + if (specialist.locations) { + setInitialLocations(specialist.locations); + const rawLocations = specialist.locations.map(loc => { + return { ...loc, name: specialist.nameString, } + }); + setLocations(rawLocations.map((location) => { + const parsedDate = new Date(location.nearestDate); + const now = new Date(); + if (parsedDate > now) { + return { ...location, checkedDate: true, key: `${location.dcode}${location.department}${location.filial}` } + } + return { ...location, checkedDate: false, key: `${location.dcode}${location.department}${location.filial}` } + })); + } + + updateField('lastName', specialist.fullName?.lastName); + updateField('firstName', specialist.fullName?.firstName); + updateField('middleName', specialist.fullName?.middleName); + updateField('alias', specialist.alias); + updateField('active', specialist.active); + setAnons(specialist.anons); + setContent(specialist.content); + updateField('regionId', specialist.regionId); + updateField('sType', specialist.sType); + updateField('scheduleText', specialist.scheduleText); + updateField('videoUrl', specialist.video); + updateField('videoCardUrl', specialist.videoVertical); + updateField('kodoper', specialist.kodoper); + setKodopers(specialist.kodoper); + updateField('onlyOnlineMode', Boolean(specialist.onlyOnlineMode)); + updateField('prodoctor', specialist.prodoctor); + updateField('degree', specialist.degree); + updateField('prodoctorLink', specialist.prodoctorLink ?? ''); + updateField('prodoctorText', specialist.prodoctorText ?? ''); + setDisplayKodoper([...kodoperDetails]) + if (specialist?.dcodes) setDcodes([...specialist.dcodes.split(',')]) + if ( specialist.tags ) setTags([...specialist.tags]) + if ( specialist.highlightedTags ) setHighlightedTags([...specialist.highlightedTags]) + + if ( specialist.stocks.length > 0 ) { + setStocks([...specialist.stocks]); + setStocksFromChild([...specialist.stocks]) + updateField('initStocks', specialist.stocks); + } + updateField('category', formatCategory(specialist.category)); + + updateField('previewPicture', apiUrl(specialist.pictureLink)); + + const formattedDate = specialist.experience + ? `${specialist.experience}-01-01` + : ''; + updateField('experience', formattedDate); + updateField('hideSchedule', !specialist.displaySchedule); + updateField('patientAge', specialist.patientAge); + updateField('isChildrenDoctor', specialist.sType === 1 ? true : false); + if (specialist.specialistDocs) { + specialist.specialistDocs.forEach(doc => { + if (doc.type === 'certificate') { + setCertificates(prev => { + if (prev.some(item => item.id === doc.id)) { + return prev; + } + return [...prev, doc]; + }); + } + if (doc.type === 'portfolio') { + setPortfolio(prev => { + if (prev.some(item => item.id === doc.id)) { + return prev; + } + return [...prev, doc]; + }); + } + }); + } + } + }, [ specialist, kodoperDetails ] ); + + const [previewFile, setPreviewFile] = useState(null) + + const isValidImage = (file) => { + const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png']; + if (allowedTypes.includes(file.type)) return true; + + const ext = file.name.split('.').pop().toLowerCase(); + return ['jpg', 'jpeg', 'png'].includes(ext); +}; + + const handlePhotoUpload = () => { + const file = photoInputRef.current.files[0] + if (!file) return window.alert('Файл не выбран') + if (!isValidImage(file)) { + return window.alert('Изображения должны быть только формата JPG, JPEG или PNG'); + } + updateField('previewPicture', window.URL.createObjectURL(file)); + setPreviewFile(file); + } + + const handlePhotoOperationUpload = () => { + const file = photoOperationInputRef.current.files[0] + if (!file) return window.alert('Файл не выбран') + updateField('operationPhotoUrl', { file, url: window.URL.createObjectURL(file) }); + } + + const handleWrapper = () => { + if (!isFormValid()) { + window.alert('Пожалуйста, исправьте ошибки в форме'); + return; + } + handleSave(); + } + + const [certsFromChild, setCertsFromChild] = useState([]); + const [portfolioFromChild, setPortfolioFromChild] = useState([]); + + const handleSave = async () => { + if (!isFormValid()) { + window.alert('Пожалуйста, исправьте ошибки в форме'); + return; + } + + + + const arr = []; + + dcodes.map(dcode => { + if (arr.includes(String(dcode))) return + arr.push(String(dcode)) + }) + locations.map(location => { + if (arr.includes(String(location.dcode))) return + arr.push(String(location.dcode)) + }) + + const data = { + nameString: `${form.lastName} ${form.firstName} ${form.middleName}`, + fullName: { + lastName: form.firstName, + firstName: form.lastName, + middleName: form.middleName + }, + active: form.active ?? false, + displaySchedule: !form.hideSchedule, + alias: form.alias ?? '', + degree: form.degree ?? '', + post: postTags.join(', ') ?? '', + experience: getYear(form.experience) ?? '', + sType: Number(form.sType), + regionId: Number(form.regionId), + anons: anons ?? '', + content: content ?? '', + tags: tags ?? [], + highlightedTags: highlightedTags ?? [], + video: form.videoUrl ?? '', + videoVertical: form.videoCardUrl ?? '', + scheduleText: form.scheduleText ?? '', + dcodes: arr.map((dcode) => String(dcode).trim()).join(',') ?? '',// dcodes.map((dcode) => dcode.trim()).join(','), + category: form.category === 'Не указано' ? '' : form.category, + kodoper: kodopers ?? [], + patientAge: form.isChildrenDoctor ? (!isNaN(Number(form.patientAge)) ? Number(form.patientAge) : null) : null, + onlyOnlineMode: form.onlyOnlineMode ?? false, + prodoctor: form.prodoctor, + prodoctorLink: form.prodoctor ? (form.prodoctorLink.length > 0 ? form.prodoctorLink : '') : '', + prodoctorText: form.prodoctor ? (form.prodoctorText.length > 0 ? form.prodoctorText : '') : '', + }; + + const formattedLocations = locations.map(location => ({ + active: location?.active ? location.active : false, + dcode: location.dcode, + department: location.department, + filial: location.filial, + id: location?.id, + onlineMode: location.onlineMode, + nearestDate: location.nearestDate, + })); + + + + function isEqualExceptId(a, b) { + for (const key in a) { + if (key === 'id') continue; + if (a[key] !== b[key]) return false; + } + for (const key in b) { + if (key === 'id') continue; + if (a[key] !== b[key]) return false; + } + return true; +} + +function diffArrays(initial, current) { + const currentMap = new Map(current.map(item => [item.id, item])); + const initialMap = new Map(initial.map(item => [item.id, item])); + + const deletedLocations = []; + const changedLocations = []; + const addedLocations = []; + + for (const item of initial) { + const curr = currentMap.get(item.id); + if (!curr) { + deletedLocations.push(item); + } else if (!isEqualExceptId(item, curr)) { + changedLocations.push({ ...curr }); + } + } + + for (const item of current) { + if (!initialMap.has(item.id)) { + addedLocations.push(item); + } + } + + return { deletedLocations, changedLocations, addedLocations }; +} + + const { deletedLocations, changedLocations, addedLocations } = diffArrays(initialLocations, formattedLocations); + + + try { + await updateSpecialist({ + specialistId: id, + data: data, + }).unwrap(); + console.log('success specialist update') + + for (let i = 0; i < deletedLocations.length; i += 1) { + await deleteLocation(deletedLocations[i].id).unwrap() + } + console.log('success delete locations') + + for (let i = 0; i < addedLocations.length; i += 1) { + const [day, month, year] = addedLocations[i].nearestDate.split('.'); + const isoDate = `${year}-${month}-${day}`; + await createLocation({ specialistId: id, data: { + active: addedLocations[i].active, + dcode: addedLocations[i].dcode, + department: addedLocations[i].department, + filial: addedLocations[i].filial, + nearestDate: isoDate, + onlineMode: addedLocations[i].onlineMode, + } }).unwrap() + } + console.log('success create locations') + + for (let i = 0; i < changedLocations.length; i += 1) { + await updateLocation({ + specialistId: id, + locationId: changedLocations[i].id, + data: { + active: changedLocations[i].active, + }, + }).unwrap() + } + console.log('success update locations') + + + //-------------------------------------------------- + const initMap = new Map([...certificates.map(c => [c.id, c]), ...portfolio.map(c => [c.id, c])]); + const currMap = new Map([...certsFromChild.filter(c => c.id).map(c => [c.id, c]), ...portfolioFromChild.filter(c => c.id).map(c => [c.id, c])]); + + const created = [...certsFromChild.filter(c => c.id == null), ...portfolioFromChild.filter(c => c.id == null)]; + + const deleted = [...certificates.filter(c => !currMap.has(c.id)), ...portfolio.filter(c => !currMap.has(c.id))]; + + const modified = [ + ...certsFromChild + .filter(c => c.id != null && initMap.has(c.id)) + .filter(c => { + const orig = initMap.get(c.id); + return ( + c.name !== orig.name || + c.description !== orig.description || + c.picture !== orig.picture || + c.active !== orig.active + ); + }), + ...portfolioFromChild + .filter(c => c.id != null && initMap.has(c.id)) + .filter(c => { + const orig = initMap.get(c.id); + return ( + c.name !== orig.name || + c.description !== orig.description || + c.picture !== orig.picture || + c.active !== orig.active + ); + }) + ]; + + for (let i = 0; i < created.length; i += 1) { + if (created[i].name.trim().length === 0 && created[i].description.trim().length === 0) continue + const response = await createCertifcate({ + specialistId: id, + data: { + name: created[i].name, + description: String(created[i].description), + active: created[i].active, + type: created[i].type, + }, + }).unwrap() + if (created[i].picture) await uploadCertifcatePicture({ + id: response.id, + file: created[i]._file, + }).unwrap() + } + console.log('success create cert') + + for (let i = 0; i < modified.length; i += 1) { + if (modified[i].name.trim().length === 0 && modified[i].description.trim().length === 0) continue + await updateCertifcate({ + specialistId: id, + id: modified[i].id, + data: { + active: modified[i].active, + description: modified[i].description, + name: modified[i].name, + type: modified[i].type, + }, + }).unwrap() + if (modified[i]?._file) { + await uploadCertifcatePicture({ + id: modified[i].id, + file: modified[i]._file, + }).unwrap() + } + } + console.log('success update cert') + + for (let i = 0; i < deleted.length; i += 1) { + await deleteCertifcate({ + id: deleted[i].id, + }).unwrap() + } + console.log('success delete cert') + + if (previewFile) { + await uploadPicture({ id, file: previewFile }).unwrap(); + console.log('success photo update') + } + + const initIds = new Set(form.initStocks.map(s => s.id)); + const childIds = new Set(stocksFromChild.map(s => s.id)); + + const deletedStocs = form.initStocks.filter(s => !childIds.has(s.id)); + const addedStocks = stocksFromChild.filter(s => !initIds.has(s.id)); + + for (let i = 0; i < addedStocks.length; i += 1) { + await addSpecialistToStock({ + stockId: addedStocks[i].id, + specialistId: id, + }).unwrap() + } + console.log('success added promotions') + + for (let i = 0; i < deletedStocs.length; i += 1) { + await removeSpecialistToStock({ + stockId: deletedStocs[i].id, + specialistId: id, + }).unwrap() + } + console.log('success delete promotions') + + + + setModalSuccess(true) + + window.setTimeout(() => { + window.location.reload() + }, 2000); + + } catch (err) { + console.error('Ошибка при обновлении специалиста:', err) + } + + + } + + const handleDelete = async () => { + + try { + await deleteSpecialist(id).unwrap() + console.log('success delete') + setModalSuccess(true) + window.setTimeout(() => { + navigateBack() + }, 2000); + } catch (err) { + console.error('Ошибка при удалении специалиста:', err) + } + + + + } +/* + useEffect(() => { + if (patientAgeInputRef.current) { + patientAgeInputRef.current.focus(); + } + }, [ form.isChildrenDoctor ]); +*/ + const [isModalCustomOpen, setModalCustomOpen] = useState(false); + const [isModalDeleteOpen, setModalDeleteOpen] = useState(false); + const [isModalSuccess, setModalSuccess] = useState(false); + const [isModalDcodes, setModalDcodes] = useState(false); + + if ( isLoading ) return + if ( error ) return + if ( !specialist ) return + + return ( + setModalDeleteOpen(true) } + // addSpecialist={ navigateAddSpecialist } + > +
    + +
    +
    + +
    +
    + Фото врача e.currentTarget.src = PHOTO_PLACEHOLDER ?? '/assets/photo-placeholder.png' } + /> + + +
    +
    +
    +
    +
    + + updateField('lastName', e.target.value) } + onBlur={handleBlur} + /> + {errors.lastName && {errors.lastName}} +
    +
    + + updateField('firstName', e.target.value) } + onBlur={handleBlur} + /> + {errors.firstName && {errors.firstName}} +
    +
    + + updateField('middleName', e.target.value) } + pattern="[А-ЯЁ][а-яё]+" + title="Только буквы кириллицы, первая буква заглавная" + onBlur={handleBlur} + /> + {errors.middleName && {errors.middleName}} +
    +
    +
    + + updateField('alias', e.target.value) } + /> +
    + +
    +
    + + +
    +
    + +
    +
    + + +
    +
    + +
    + + {form.isChildrenDoctor && +
    +
    + + { + if (patientAgeInputRef.current) patientAgeInputRef.current.focus() + }} + style={{ backgroundColor: 'white', borderTopRightRadius: 0, borderBottomRightRadius: 0, borderRight: 'none', height: 'calc(1.5em + .75rem + 2px)' }} + >Прием детей с + + + { + updateField('patientAge', e.target.value) + validateField('patientAge', form.patientAge); + }} + onBlur={handleBlur} + /> + + { + if (patientAgeInputRef.current) patientAgeInputRef.current.focus() + }} + style={{ backgroundColor: 'white', borderTopLeftRadius: 0, borderBottomLeftRadius: 0, borderLeft: 'none', height: 'calc(1.5em + .75rem + 2px)' }} + >лет + +
    + {errors.patientAge && {errors.patientAge}} +
    + } +
    + +
    +
    +
    + +
    +
    +
    + + +
    +
    + + updateField('degree', e.target.value) } + /> +
    +
    +
    + + +
    + +{/* + +
    + + { + if (dateInputRef.current?.showPicker) { + dateInputRef.current.showPicker(); + } + }} + onChange={e => { + updateField('experience', e.target.value) + }} + /> +
    + +*/} + +
    + +
    + { + updateField('experience', e); + validateField('experience', e); + }} + className="form-control" + calendarClassName="react-datepicker-bootstrap" + popperClassName="react-datepicker-popper" + showYearPicker + dateFormat="yyyy" + yearItemNumber={10} + /> +
    + {errors.experience && {errors.experience}} +
    + + + + + + + +
    +
    + updateField('active', e.target.checked)} + /> + +
    +
    +
    + + +
    +
    + + +
    + + updateField('scheduleText', e.target.value)} + /> +
    + +
    +
    + updateField('hideSchedule', e.target.checked)} + /> + +
    + +
    + updateField('onlyOnlineMode', e.target.checked)} + /> + +
    +
    + + + +
    +
    + Расписание из Инфоклиники +
    + + +
    + + {locations.length > 0 && +
    + {/* +
    + Филиалы: +
    */ + } +
    + + + + + + + + + + + + + + {locations.map((location, index) => { + return ( + + + + + + + + + + ) + } + )} + +
    dcodeФилиалОтделениеБлижайшая дата приемаОнлайн приемОтображать на сайте
    { location.dcode }{ filialsList.find(filial => filial.id === location.filial)?.shortName }{ departmentsList.find(department => Number(department.id) === Number(location.department))?.name }{ location.nearestDate ? location.nearestDate : '' }{ location.onlineMode ? 'да' : 'нет' } + { + const checked = e.target.checked; + setLocations(prev => + prev.map(l => + l.key === location.key + ? { ...l, active: checked } + : l + )); + } + //updateField('active', e.target.checked) + } + />
    +
    + + + +
    + } + + + +
    +
    + + + +
    +
    +
    +
    + Услуги врача +
    + + +
    + + + {Boolean(kodopers) && kodopers.length > 0 && + + } + + {displayKodoper.length > 0 && +
    +
    + Добавленные услуги: +
    +
    + + + + + + + + + + + + + { displayKodoper.map((item, index) => + + + + + + + + + )} + +
    Мед. кодУслугаОтделениеФилиалСтоимость
    { item.kodoper }{ item.schname }{ item.specname }{ item.fname }{ `${item.priceInfo.price} ₽` } + +
    +
    +
    +} + +
    +
    + + +
    +
    +
    +
    + Акции +
    + + +
    + + { stocksFromChild.length > 0 && +
    + + + + + + + + + + + { + stocksFromChild.map((stock, index) => + + + + + + + ) + } + +
    НазваниеНачало акцииОкончание акции
    { stock.name }{ formatStockDate(stock.startDate) }{ formatStockDate(stock.endDate) } + +
    +
    + } + + + +
    +
    + + + + +
    +
    + +
    + + { + /* + updateField('anons', e.target.value)} + /> + */ + } + +
    + +
    + + { + /* + updateField('content', e.target.value)} + /> + */ + } + +
    + + +
    +
    + + + +
    +
    + +
    + +
    + + { + + } + +
    +
    + + +
    +
    + +
    + +
    + + { + + } + +
    +
    + + +
    +
    +
    + + +
    + +
    + + +
    + +
    +
    + +
    +
    +
    + + updateField('videoUrl', e.target.value) } + onBlur={handleBlur} + /> + {errors.videoUrl && {errors.videoUrl}} +
    +
    + + updateField('videoCardUrl', e.target.value) } + onBlur={handleBlur} + /> + {errors.videoCardUrl && {errors.videoCardUrl}} +
    +
    +
    + +
    +
    + +
    + { + updateField('prodoctor', e.target.checked) + if (!e.target.checked) { + updateField('prodoctorText', '') + updateField('prodoctorLink', '') + setErrors(prev => ({ ...prev, prodoctorLink: '' })); + } + }} + /> + +
    + + { + form.prodoctor && <> +
    + + updateField('prodoctorText', e.target.value)} + /> +
    + +
    + + { + updateField('prodoctorLink', e.target.value) + validateField('prodoctorLink', form.prodoctorLink) + }} + onBlur={handleBlur} + /> + {errors.prodoctorLink && {errors.prodoctorLink}} +
    + + } + +
    +
    + + setModalDeleteOpen(false)} + onConfirm={() => { + setModalDeleteOpen(false) + handleDelete() + }} + title="Вы уверены?" + hasButtons={true} + confirmText={'Удалить врача'} + > +

    Этим действием, вы удалите врача.

    +

    Вы уверены?

    +
    + + +

    Изменения успешно внесены.

    +
    + + setModalDcodes(false)} + departments={departmentsList} + filials={filialsList} + /> + + { + setKodopers(selectedCodopers) + setDisplayKodoper(displayedCodopers) + }} + onCancel={() => setModalKodopers(false)} + /> + + { + setStocks(selectedStocks) + }} + onCancel={() => setModalStocks(false)} + /> + + + ); +} diff --git a/src/pages/EditStockPage.jsx b/src/pages/EditStockPage.jsx new file mode 100644 index 0000000..89443b4 --- /dev/null +++ b/src/pages/EditStockPage.jsx @@ -0,0 +1,299 @@ +import { useState, useEffect, useRef } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; + +import { apiUrl } from '@/config/api'; + +import { + useGetStockQuery, + useUpdateStockMutation, + useUploadStockPictureMutation, + useDeleteStockMutation, +} from '/src/api/apiStock'; +/**/ +import { selectUtils } from '../store/slice/utilsSlice'; +/**/ +import { TextEditor } from '../components/Editors/TextEditor' +import { LoadingComponent } from '../components/Placeholders/LoadingComponent'; +import { ErrorComponent } from '../components/Placeholders/ErrorComponent'; +import { NotFindElement } from '../components/Placeholders/NotFindElement'; +import { EditElementForm } from '../components/Forms/EditElementForm'; +import { ResponseModals } from '../components/Modals/ResponseModals'; +/**/ +import { Modal} from '../components/Modals/Modal'; + +const isValidImage = (file) => { + const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png']; + if (allowedTypes.includes(file.type)) return true; + + const ext = file.name.split('.').pop().toLowerCase(); + return ['jpg', 'jpeg', 'png'].includes(ext); +}; + +export function EditStockPage() { + const { id } = useParams(); + const navigate = useNavigate(); + const navigateBack = () => navigate( `/promotions` ); + + const { data: stock, isFetching, error } = useGetStockQuery( { stockId: id } ); + const [ updateStock ] = useUpdateStockMutation(); + const [ uploadPicture ] = useUploadStockPictureMutation(); + const [ deleteStock ] = useDeleteStockMutation(); + + const [ isModalSuccess, setModalSuccess ] = useState( false ); + + const [ errors, setErrors ] = useState({ + name: '', + dateRange: '' + }); + + const [ form, setForm ] = useState({ + name: '', + anons: '', + picture: '', + }); + const [ anons, setAnons ] = useState( '' ); + const [ content, setContent ] = useState( '' ); + + const fileInputRef = useRef(); + + useEffect( () => { + if ( !stock ) return; + + let datetimeLocalStart = ''; + let datetimeLocalEnd = ''; + + if ( stock.startDate ) { + const dateStart = new Date( stock.startDate ); + const yearStart = dateStart.getFullYear(); + const monthStart = String( dateStart.getMonth() + 1 ).padStart( 2, '0' ); + const dayStart = String( dateStart.getDate() ).padStart( 2, '0' ); + const hoursStart = String( dateStart.getHours() ).padStart( 2, '0' ); + const minutesStart = String( dateStart.getMinutes() ).padStart( 2, '0' ); + datetimeLocalStart = `${ yearStart }-${ monthStart }-${ dayStart }T${ hoursStart }:${ minutesStart }`; + } + + if ( stock.endDate ) { + const dateEnd = new Date( stock.endDate ); + const yearEnd = dateEnd.getFullYear(); + const monthEnd = String( dateEnd.getMonth() + 1 ).padStart( 2, '0' ); + const dayEnd = String( dateEnd.getDate() ).padStart( 2, '0' ); + const hoursEnd = String( dateEnd.getHours() ).padStart( 2, '0' ); + const minutesEnd = String( dateEnd.getMinutes() ).padStart( 2, '0' ); + datetimeLocalEnd = `${ yearEnd }-${ monthEnd }-${ dayEnd }T${ hoursEnd }:${ minutesEnd }`; + } + + setForm(prev => ({ + ...prev, + name: stock.name ?? '', + startDate: datetimeLocalStart, + endDate: datetimeLocalEnd, + picture: stock.picture ? apiUrl(`/uploads/${stock.picture}`) : '', + })); + + setAnons( stock.anons ) + setContent( stock.content ) + }, [ stock ]); + + const startDateInputRef = useRef(null); + const endDateInputRef = useRef(null); + + + const handleChange = (key) => (e) => { + setForm(f => ({ ...f, [key]: e.target.value })); + setErrors(err => ({ ...err, [key === 'name' ? 'name' : 'dateRange']: '' })); + }; + + const handleFile = (e) => { + const file = e.target.files[0]; + if (!file) return window.alert('Файл не выбран') + if (!isValidImage(file)) { + return window.alert('Изображения должны быть только формата JPG, JPEG или PNG'); + } + const url = window.URL.createObjectURL(file); + setForm(f => ({ ...f, _file: file, picture: url })); + }; + + const handleSave = async () => { + + let hasError = false; + const newErrors = { name:'', dateRange:'' }; + + if (!form.name.trim()) { + newErrors.name = 'Название не может быть пустым'; + hasError = true; + } + const start = new Date(form.startDate); + const end = new Date(form.endDate); + if (isNaN(start) || isNaN(end) || start > end) { + newErrors.dateRange = 'Дата начал акции должна быть не позже даты окончания'; + hasError = true; + } + if (hasError) { + setErrors(newErrors); + window.alert('Пожалуйста исправьте ошибки в форме.'); + return; + } + + try { + await updateStock({ + stockId: id, + data: { + name: form.name, + anons: anons, + content: content, + startDate: String(form.startDate), + endDate: String(form.endDate), + } + }).unwrap(); + + if (form._file) { + await uploadPicture({ id, file: form._file }).unwrap(); + } + } catch (err) { + console.error('Ошибка при обновлении акции:', err) + } + setModalSuccess(true) + window.setTimeout(() => { + window.location.reload() + }, 2000); + console.log('success update promotion') + }; + + const handleDelete = async () => { + try { + await deleteStock({stockId: id}).unwrap() + console.log('success delete') + setModalSuccess(true) + window.setTimeout(() => { + navigateBack() + }, 2000); + } catch (err) { + console.error('Ошибка при удалении специалиста:', err) + } + + + + } + + if ( isFetching ) return + if ( error ) return + if ( !stock ) return ( + + ) + + return ( + +
    + + + {errors.name && {errors.name}} +
    + +
    +
    +
    + + { + if (startDateInputRef.current?.showPicker) { + startDateInputRef.current.showPicker(); + } + }} + onChange={handleChange('startDate')} + /> +
    +
    + + { + if (endDateInputRef.current?.showPicker) { + endDateInputRef.current.showPicker(); + } + }} + onChange={handleChange('endDate')} + /> +
    +
    + {errors.dateRange && ( +
    + {errors.dateRange} +
    + )} + +
    + +
    +
    + + +
    + +
    + +
    + {form.picture && ( + + )} + + +
    +
    +
    + +
    + + +
    + + +

    Изменения успешно внесены.

    +
    +
    + ) +} \ No newline at end of file diff --git a/src/pages/FilialsListPage.jsx b/src/pages/FilialsListPage.jsx new file mode 100644 index 0000000..f2e62db --- /dev/null +++ b/src/pages/FilialsListPage.jsx @@ -0,0 +1,91 @@ +import { useState, useRef } from 'react'; +import { useSelector } from 'react-redux'; +import { useNavigate } from 'react-router-dom'; + +import { useGetFilialsQuery } from '../api/apiFilial'; +import { selectRegions } from '../store/slice/regionSlice'; +import { selectUtils } from '../store/slice/utilsSlice'; +/**/ +import { useSortedPaginated } from '../hooks/useSortedPaginated'; +import { useOutsideClick } from '../hooks/useOutsideClick'; +import { useSorting } from '../hooks/useSorting'; +/**/ +import { LoadingComponent } from '../components/Placeholders/LoadingComponent'; +import { ErrorComponent } from '../components/Placeholders/ErrorComponent'; +import { PageNav } from '../components/Paginations/PageNav'; +import { THead } from '../components/Table/THead'; +import { TBody } from '../components/Table/TBody'; + +export const FilialsListPage = () => { + const { data: filialsRaw = [], isLoading, error } = useGetFilialsQuery(); + const filials = filialsRaw.length === 0 ? [] : filialsRaw.data; + const regions = useSelector(selectRegions); + const FILIALS_COLUMN = useSelector(selectUtils).FILIALS_COLUMN; + + const ITEMS_PER_PAGE = useSelector(selectUtils).ITEMS_PER_PAGE; + const navigate = useNavigate(); + const goEdit = id => navigate(`/filials/edit/${id}`); + + const [expandedId, setExpandedId] = useState(null); + const [currentPage, setCurrentPage] = useState(1); + + const tableRef = useRef( null ); + useOutsideClick(tableRef, () => setExpandedId( null )); + + const { sortBy, sortDirection, handleSort } = useSorting(); + + const { paginated, totalPages } = useSortedPaginated( + filials.map((filial) => ({ + regionName: regions[ filial.regionId ], + id: filial.fid, + shortName: filial.shortName, + }) + ), + ITEMS_PER_PAGE, + sortBy, + sortDirection, + currentPage + ); + + if ( error ) return + + return ( +
    +

    + Филиалы +

    + + { isLoading && + + } + + { !isLoading && + <> +
    + + + +
    +
    + + + } + +
    + ) +} \ No newline at end of file diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx new file mode 100644 index 0000000..63861ca --- /dev/null +++ b/src/pages/HomePage.jsx @@ -0,0 +1,7 @@ +export const HomePage = () => ( +
    +

    + Главная +

    +
    +) diff --git a/src/pages/InfoclinicListPage.jsx b/src/pages/InfoclinicListPage.jsx new file mode 100644 index 0000000..6b6a2a0 --- /dev/null +++ b/src/pages/InfoclinicListPage.jsx @@ -0,0 +1,203 @@ +import React, { useState, useRef, useEffect } from 'react'; +import { useSearchParams } from 'react-router-dom'; + +import { useGetDepartmentsQuery } from '../api/apiDepartment'; +import { useGetFilialsQuery } from '../api/apiFilial'; +import { useGetIDoctorsQuery } from '../api/apiIDoctor'; + +export const InfoclinicListPage = () => { + const [searchParams, setSearchParams] = useSearchParams(); + const [searchValue, setSearchValue] = useState(() => searchParams.get('search') || ''); + const [currentPage, setCurrentPage] = useState(() => { + const p = Number(searchParams.get('page')); + return Number.isFinite(p) && p > 0 ? p : 1; + }); + const [debouncedSearch, setDebouncedSearch] = useState(searchValue); + + const isFirstLoadRef = useRef(true); + + useEffect(() => { + if (isFirstLoadRef.current) { + isFirstLoadRef.current = false; + return; + } + window.scrollTo(0, 0) + }, [currentPage]); + + useEffect(() => { + const t = window.setTimeout(() => { + if (searchValue.length >= 3 || searchValue.length === 0) { + setDebouncedSearch(searchValue); + } + }, 400); + return () => window.clearTimeout(t); + }, [searchValue]); + + useEffect(() => { + const params = {}; + if (debouncedSearch) params.search = debouncedSearch; + if (currentPage > 1) params.page = String(currentPage); + setSearchParams(params); + }, [debouncedSearch, currentPage, setSearchParams]); + + useEffect(() => { + const search = searchParams.get('search') || ''; + const page = Number(searchParams.get('page')) || 1; + + setSearchValue(search); + setCurrentPage(page); + }, [searchParams]); + + const { data: filialsRaw = [] } = useGetFilialsQuery(); + const filials = filialsRaw.length === 0 ? [] : filialsRaw.data; + + const { data: departmentsRaw = [] } = useGetDepartmentsQuery(); + const departments = departmentsRaw.length === 0 ? [] : departmentsRaw.data; + + const { + data: response = {}, + isFetching, + error + } = useGetIDoctorsQuery({ value: debouncedSearch, page: currentPage, type: 'search' }); + + const items = response?.data ?? []; + + const pagination = response.pagination || {}; + + const renderPagination = () => { + const total = pagination.total_pages || 1; + const current = pagination.current_page || 1; + const pages = new Set([1, total]); + + for (let p = Math.max(2, current - 2); p <= Math.min(total - 1, current + 2); p++) { + pages.add(p); + } + + const sorted = Array.from(pages).sort((a, b) => a - b); + const elems = []; + let last = 0; + + sorted.forEach(page => { + if (last && page - last > 1) { + elems.push( +
  • + +
  • + ); + } + elems.push( +
  • + +
  • + ); + last = page; + }); + + return ( + + ); + }; + + return ( +
    +

    Расписание ИК

    + +
    +
    + + { + setSearchValue(e.target.value); + setCurrentPage(1); + }} + /> +
    +
    + + {isFetching ? ( +

    Загрузка...

    + ) : error ? ( +

    Ошибка при загрузке: {error.message || String(error)}

    + ) : ( +
    +
    + + + + + + + + + + + + + + + + + + + {items.map((specialist, index) => { + return ( + + + + + + + + + + + ); + })} + +
    dcodeФИОФилиалОтделениеБлижайшая дата приемаОнлайн запись
    IDНазваниеIDАдрес
    {specialist.dcode}{specialist.name}{specialist.filial}{ + filials.length > 0 ? filials.find(filial => String(filial.fid) === String(specialist.filial))?.shortName : null + }{specialist.department}{ + departments.length > 0 ? departments.find(department => String(department.did) === String(specialist.department))?.name : null + }{specialist.nearestDate}{specialist.onlineMode ? 'да' : 'нет'}
    +
    + + {renderPagination()} +
    + )} +
    + ); +}; \ No newline at end of file diff --git a/src/pages/LoginPage.jsx b/src/pages/LoginPage.jsx new file mode 100644 index 0000000..8a6471c --- /dev/null +++ b/src/pages/LoginPage.jsx @@ -0,0 +1,78 @@ +import { useState } from 'react'; +import { useSelector } from 'react-redux'; +import { Navigate } from 'react-router-dom'; + +import { useLoginMutation } from '../api/apiSlice' +import { Input } from '../components/Input/Input'; +import { Button } from '../components/Button/Button'; + +export const LoginPage = () => { + const [ login, { isLoading, error }] = useLoginMutation(); + const auth = useSelector((state) => state.auth); + + const [ user, setUser ] = useState(''); + const [ pass, setPass ] = useState(''); + const [ validationError, setValidationError ] = useState(''); + + if (auth.token) { + return + } + + const handleSubmit = async (e) => { + e.preventDefault(); + setValidationError(''); + + if (!user.trim() || !pass.trim()) { + setValidationError('Пожалуйста, заполните оба поля.'); + return + } + + try { + await login({ + username: user, + password: pass, + }).unwrap(); + } catch { + // + } + }; + + return ( +
    +
    +

    + Вход +

    +
    +
    + +
    +
    + +
    + {!validationError && ( + error && ( +
    + { error.status === 500 || error.status === 400 + ? 'Неверный логин или пароль' : null } + { error.status === 'FETCH_ERROR' ? 'Ошибка сети' : null } +
    + ) + ) + } + { validationError && ( +
    + { validationError } +
    + ) + } +
    + +
    +
    +
    +
    + ) +}; diff --git a/src/pages/LostDoctorsPage.jsx b/src/pages/LostDoctorsPage.jsx new file mode 100644 index 0000000..3a86cc7 --- /dev/null +++ b/src/pages/LostDoctorsPage.jsx @@ -0,0 +1,216 @@ +import React, { useState, useEffect, useMemo } from 'react'; + +import { useLostDoctors } from '../hooks/useLostLocations'; + +const getFormatDate = (rawDate) => { + const date = new Date(rawDate); + const day = String(date.getUTCDate()).padStart(2, '0'); + const month = String(date.getUTCMonth() + 1).padStart(2, '0'); + const year = date.getUTCFullYear(); + return `${day}.${month}.${year}`; +} + +function scrollToTop({ smooth = true } = {}) { + if ('scrollBehavior' in document.documentElement.style && smooth) { + window.scrollTo({ top: 0, behavior: 'smooth' }); + } else { + document.documentElement.scrollTop = 0; + document.body.scrollTop = 0; + } +} + +export const LostDoctorsPage = () => { + const [searchValue, setSearchValue] = useState(''); + const [currentPage, setCurrentPage] = useState(1); + + const PAGE_SIZE = 100; + + const { + isLoading, + error, + lostDoctors = [], + filials, + departments, + regions, + } = useLostDoctors(); + + useEffect(() => { + setCurrentPage(1); + }, [searchValue, lostDoctors]); + + // Живой поиск по ФИО (case-insensitive). Если doctor отсутствует — исключаем элемент. + const filtered = useMemo(() => { + const q = searchValue.trim().toLowerCase(); + if (!q) return lostDoctors; + return lostDoctors.filter(ld => { + const name = String(ld?.doctor?.name ?? '').toLowerCase(); + return name.includes(q); + }); + }, [lostDoctors, searchValue]); + + const totalItems = filtered.length; + const totalPages = Math.max(1, Math.ceil(totalItems / PAGE_SIZE)); + + useEffect(() => { + if (currentPage > totalPages) { + setCurrentPage(totalPages); + } + }, [currentPage, totalPages]); + + useEffect(() => { + scrollToTop(); + }, [ currentPage ]) + + const paged = useMemo(() => { + const start = (currentPage - 1) * PAGE_SIZE; + return filtered.slice(start, start + PAGE_SIZE); + }, [filtered, currentPage]); + + const visiblePageNumbers = useMemo(() => { + const maxButtons = 9; + const pages = []; + if (totalPages <= maxButtons) { + for (let i = 1; i <= totalPages; i++) pages.push(i); + return pages; + } + let start = Math.max(1, currentPage - Math.floor(maxButtons / 2)); + let end = start + maxButtons - 1; + if (end > totalPages) { + end = totalPages; + start = end - maxButtons + 1; + } + for (let i = start; i <= end; i++) pages.push(i); + return pages; + }, [totalPages, currentPage]); + + return ( +
    +

    Врачи-потеряшки

    + +
    +
    + + { + setSearchValue(e.target.value); + }} + /> +
    +
    + setSearchValue('')} + /> +
    +
    + + {isLoading || lostDoctors.length === 0 ? ( +

    Загрузка...

    + ) : error ? ( +

    Ошибка при загрузке: {error.message || String(error)}

    + ) : ( + <> +
    +
    + + + + + + + + + + + + + + + + + + + {paged.length === 0 ? ( + + + + ) : ( + paged.map((lostDoctor, index) => + + + + + + + + + + + ) + )} + +
    dcodeФИОФилиалОтделениеБлижайшая дата приемаОнлайн запись
    IDНазваниеIDАдрес
    Ничего не найдено.
    {lostDoctor.doctor.dcode} + {lostDoctor.doctor.name} + + {lostDoctor.emptyLocation.filial} + + { filials.length > 0 ? filials.find(filial => String(filial.fid) === String(lostDoctor.emptyLocation.filial))?.shortName : null } + + {lostDoctor.emptyLocation.department} + + { departments.length > 0 ? departments.find(department => String(department.did) === String(lostDoctor.emptyLocation.department))?.name : null } + + {getFormatDate(lostDoctor.emptyLocation.nearestDate)} + + {lostDoctor.emptyLocation.onlineMode ? 'да' : 'нет'} +
    +
    +
    + + + + + )} +
    + ); +}; diff --git a/src/pages/MainPage.jsx b/src/pages/MainPage.jsx new file mode 100644 index 0000000..d2821ec --- /dev/null +++ b/src/pages/MainPage.jsx @@ -0,0 +1,20 @@ +import { Outlet } from 'react-router-dom'; + +import { Sidebar } from '../components/Sidebar/Sidebar'; +import { Navbar } from '../components/Navbar/Navbar'; + +export const MainPage = () => { + return ( +
    + +
    +
    + +
    + +
    +
    +
    +
    + ) +} diff --git a/src/pages/NotFoundPage.jsx b/src/pages/NotFoundPage.jsx new file mode 100644 index 0000000..e084b75 --- /dev/null +++ b/src/pages/NotFoundPage.jsx @@ -0,0 +1,14 @@ +export const NotFoundPage = () => { + return ( +
    +
    +

    + 404 +

    +

    + Страница не найдена +

    +
    +
    + ) +} diff --git a/src/pages/PricesListPage.jsx b/src/pages/PricesListPage.jsx new file mode 100644 index 0000000..cf5d9b2 --- /dev/null +++ b/src/pages/PricesListPage.jsx @@ -0,0 +1,207 @@ +import { useState } from 'react'; + +import { useGetKodopersQuery } from '/src/api/apiKodoper'; +import { useGetFilialsQuery } from '/src/api/apiFilial'; +import { LoadingComponent } from '../components/Placeholders/LoadingComponent'; +import { ErrorComponent } from '../components/Placeholders/ErrorComponent'; + +const getDateInfo = (dateString) => { + const dateObj = new Date(dateString); + + const date = dateObj.toLocaleDateString('ru-RU'); + const time = dateObj.toLocaleTimeString('ru-RU', { hour12: false, hour: '2-digit', minute: '2-digit' }); + + return { date, time } +} + +export const PricesListPage = () => { + const [searchValue, setSearchValue] = useState(''); + const [currentFilial, setCurrentFilial] = useState(-1); + const [currentPage, setCurrentPage] = useState(1); + + const { data: filialsRaw = {} } = useGetFilialsQuery(); + const filials = filialsRaw.data || []; + const filialOptions = [ { fid: -1, name: 'Все филиалы' }, ...filials ]; + + const { data: response = {}, isFetching, error: queryError } = useGetKodopersQuery( + { value: searchValue, filialId: currentFilial, page: currentPage }, + { skip: false } + ); + + const prices = response.data || []; + const pagination = response.pagination || {}; + + const renderPagination = () => { + const total = pagination.total_pages || 1; + const current = pagination.current_page || 1; + const pages = new Set(); + + pages.add( 1 ); + pages.add( total ); + + for ( let p = current - 2; p <= current + 2; p++ ) { + if ( p > 1 && p < total ) pages.add( p ); + } + + const sorted = Array.from( pages ).sort( ( a, b ) => a - b ); + + const items = []; + let last = 0; + + sorted.forEach( page => { + if ( last && page - last > 1 ) { + items.push( +
  • + +
  • + ); + } + items.push( +
  • + +
  • + ); + last = page; + }); + + return ( + + ) + }; + + return ( + <> +
    +

    + Цены и услуги +

    +
    +
    +
    +
    + + { + setSearchValue( e.target.value ); + setCurrentPage( 1 ); + }} + /> +
    +
    +
    + + +
    +
    + +
    + { isFetching + ? ( + + ) + : queryError + ? ( + + ) + : ( + <> +
    + + + + + + + + + + + + + { prices.length > 0 ? + prices.map( ( item, idx ) => { + const updateDate = getDateInfo(item.dateUpdate); + return ( + + + + + + + + + ) + }) : ( + + + + ) + } + +
    Мед.кодУслугаДата обновленияВремя обновленияФилиалСтоимость
    { item.kodoper }{ item.schname }{ updateDate.date }{ updateDate.time }{ item.fname }{ item.priceInfo.price } ₽
    + По данному запросу ничего не найдено +
    +
    + { renderPagination() } + + ) + } +
    +
    +
    + + ) +} diff --git a/src/pages/SpecialistListPage.jsx b/src/pages/SpecialistListPage.jsx new file mode 100644 index 0000000..e573c0b --- /dev/null +++ b/src/pages/SpecialistListPage.jsx @@ -0,0 +1,281 @@ +import React, { useState, useRef, useEffect } from 'react'; +import { useSearchParams, useNavigate } from 'react-router-dom'; + +import { useOutsideClick } from '../hooks/useOutsideClick'; +import { useGetSpecialistsListQuery } from '../api/apiSpecialist'; + +export const SpecialistListPage = () => { + const navigate = useNavigate(); + const [searchParams, setSearchParams] = useSearchParams(); + const [searchValue, setSearchValue] = useState(() => searchParams.get('search') || ''); + const [regionId, setRegionId] = useState(() => searchParams.get('region') || ''); + const [currentPage, setCurrentPage] = useState(() => { + const p = Number(searchParams.get('page')); + return Number.isFinite(p) && p > 0 ? p : 1; + }); + const [expandedId, setExpandedId] = useState(''); + + const regionOptions = [ + { id: '', label: 'Все регионы' }, + { id: '91', label: 'Саратов' }, + { id: '92', label: 'Волгоград' }, + { id: '93', label: 'Воронеж' }, + { id: '94', label: 'Краснодар' }, + ]; + + const sTypeOptions = { + 0: 'Взрослый врач', + 1: 'Детский врач', + 2: 'Администрация', + 3: 'Стоматология', + 4: 'Мед. сестра', + }; + + const tableRef = useRef(null); + useOutsideClick(tableRef, () => setExpandedId('')); + + const [debouncedSearch, setDebouncedSearch] = useState(searchValue); + + useEffect(() => { + const t = window.setTimeout(() => { + if (searchValue.length >= 3 || searchValue.length === 0) { + setDebouncedSearch(searchValue); + } + }, 400); + return () => window.clearTimeout(t); + }, [searchValue]); + + useEffect(() => { + const params = {}; + if (debouncedSearch) params.search = debouncedSearch; + if (regionId) params.region = regionId; + if (currentPage > 1) params.page = String(currentPage); + setSearchParams(params); + }, [debouncedSearch, regionId, currentPage, setSearchParams]); + + useEffect(() => { + const search = searchParams.get('search') || ''; + const region = searchParams.get('region') || ''; + const page = Number(searchParams.get('page')) || 1; + + setSearchValue(search); + setRegionId(region); + setCurrentPage(page); + }, [searchParams]); + + const { + data: response = {}, + isFetching, + error + } = useGetSpecialistsListQuery({ + regionId, + search: debouncedSearch, + page: currentPage, + }); + + const formatDateToLocal = (dateString) => { + if (!dateString) return ''; + + const date = new Date(dateString); + if (isNaN(date.getTime())) return ''; + + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + + return `${year}-${month}-${day}T${hours}:${minutes}`; + }; + + const items = response.data + ? response.data.map(item => ({ + ...item, + startDate: formatDateToLocal(item.startDate), + endDate: formatDateToLocal(item.endDate) + })) + : []; + + const pagination = response.pagination || {}; + + const renderPagination = () => { + const total = pagination.total_pages || 1; + const current = pagination.current_page || 1; + const pages = new Set([1, total]); + + for (let p = Math.max(2, current - 2); p <= Math.min(total - 1, current + 2); p++) { + pages.add(p); + } + + const sorted = Array.from(pages).sort((a, b) => a - b); + const elems = []; + let last = 0; + + sorted.forEach(page => { + if (last && page - last > 1) { + elems.push( +
  • + +
  • + ); + } + elems.push( +
  • + +
  • + ); + last = page; + }); + + return ( + + ); + }; + + return ( +
    +

    Врачи

    + +
    +
    + navigate('/specialist/add')} + /> +
    + +
    + + +
    + +
    + + { + setSearchValue(e.target.value); + setCurrentPage(1); + }} + /> +
    +
    + + {isFetching ? ( +

    Загрузка...

    + ) : error ? ( +

    Ошибка при загрузке: {error.message || String(error)}

    + ) : ( + <> +
    + + + + + + + + + + + + + + + + {items.map(specialist => { + return ( + + { + setExpandedId(expandedId === specialist.id ? '' : specialist.id); + }} + > + + + + + + + + + + + + {expandedId === specialist.id && ( + + + + )} + + ); + })} + +
    IDФИОДолжностьГородКатегорияНаличие услугНаличие расписанияОтображать на сайтеОтображать расписание
    {specialist.id}{specialist.nameString}{specialist.post}{regionOptions.find(region => Number(region.id) === specialist.regionId)?.label || 'не указан'}{specialist?.sType || specialist?.sType === 0 ? sTypeOptions[Number(specialist.sType)] : 'не указан'}{Array.isArray(specialist.kodoper) ? ( specialist.kodoper.length > 0 ? 'есть' : 'нет' ) : 'нет'}{Array.isArray(specialist.locations) ? ( specialist.locations.length > 0 ? 'есть' : 'нет' ) : 'нет'}{specialist.active ? 'да' : 'нет'}{specialist.displaySchedule ? 'да' : 'нет'}
    + { + e.stopPropagation(); + navigate(`/specialist/edit/${specialist.id}`, { + state: { search: searchValue, region: regionId, page: currentPage } + }); + }} + /> +
    +
    + + {renderPagination()} + + )} +
    + ); +}; \ No newline at end of file diff --git a/src/pages/SpecialistTable.jsx b/src/pages/SpecialistTable.jsx new file mode 100644 index 0000000..7e51918 --- /dev/null +++ b/src/pages/SpecialistTable.jsx @@ -0,0 +1,125 @@ +import React, { useRef } from 'react'; +import { useGetSpecialistsListQuery } from '../api/apiSpecialist'; +import { useNavigate } from 'react-router-dom'; +import { useOutsideClick } from '../hooks/useOutsideClick'; + +export const SpecialistTable = React.memo(({ regionId, search, currentPage, onPageChange }) => { + const navigate = useNavigate(); + const [expandedId, setExpandedId] = React.useState(null); + const tableRef = useRef(null); + useOutsideClick(tableRef, () => setExpandedId(null)); + + + const { data: resp = {}, isFetching, error } = + useGetSpecialistsListQuery({ regionId, search, page: currentPage }); + + const items = resp.data || []; + const pagination = resp.pagination || {}; + + if (isFetching) return

    Загрузка...

    ; + if (error) return

    Ошибка: {String(error)}

    ; + + const formatExp = y => y ? String(y) : '—'; + + const renderPagination = () => { + const total = pagination.total_pages || 1; + const current = pagination.current_page || 1; + const pages = new Set([1, total]); + for (let p = current - 2; p <= current + 2; p++) { + if (p > 1 && p < total) pages.add(p); + } + const sorted = [...pages].sort((a,b)=>a-b); + + let last = 0; + const elems = sorted.flatMap(p => { + const dots = (last && p - last > 1) + ? [
  • + +
  • ] + : []; + const btn = ( +
  • + +
  • + ); + last = p; + return [...dots, btn]; + }); + + return ( + + ); + }; + + return ( +
    +
    + + + + + + + + {items.map(d => ( + + setExpandedId(expandedId===d.id?null:d.id)} + > + + + + + + + {expandedId===d.id && ( + + + + )} + + ))} + +
    IDФИОДолжностьОпытАктивен
    {d.id}{d.nameString}{d.post}{formatExp(d.experience)}{d.active?'✓':'—'}
    + +
    +
    + {renderPagination()} +
    + ); +}); diff --git a/src/pages/StoksListPage.jsx b/src/pages/StoksListPage.jsx new file mode 100644 index 0000000..a7df256 --- /dev/null +++ b/src/pages/StoksListPage.jsx @@ -0,0 +1,238 @@ +import { useState, useRef } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { useGetStocksQuery } from '/src/api/apiStock'; +/**/ +import { useOutsideClick } from '../hooks/useOutsideClick'; +/**/ +import { LoadingComponent } from '../components/Placeholders/LoadingComponent'; +import { ErrorComponent } from '../components/Placeholders/ErrorComponent'; + +export const StocksListPage = () => { + const [ searchValue, setSearchValue ] = useState( '' ); + const [ currentPage, setCurrentPage ] = useState( 1 ); + const [ expandedId, setExpandedId ] = useState( '' ); + + const navigate = useNavigate(); + + const tableRef = useRef( null ); + useOutsideClick( tableRef, () => setExpandedId( null )); + + const { data: response = {}, isFetching, error: queryError } = + useGetStocksQuery( { search: searchValue, page: currentPage } ); + + const stocks = response.data + ? ( response.data.map( init => { + const dateStart = new Date( init.startDate ); + const yearStart = dateStart.getFullYear(); + const monthStart = String( dateStart.getMonth() + 1 ).padStart( 2, '0' ); + const dayStart = String( dateStart.getDate() ).padStart( 2, '0' ); + const hoursStart = String( dateStart.getHours() ).padStart( 2, '0' ); + const minutesStart = String( dateStart.getMinutes() ).padStart( 2, '0' ); + const datetimeLocalStart = `${ yearStart }-${ monthStart }-${ dayStart }T${ hoursStart }:${ minutesStart }`; + + const dateEnd = new Date( init.endDate ); + const yearEnd = dateEnd.getFullYear(); + const monthEnd = String( dateEnd.getMonth() + 1 ).padStart( 2, '0' ); + const dayEnd = String( dateEnd.getDate() ).padStart( 2, '0' ); + const hoursEnd = String( dateEnd.getHours() ).padStart( 2, '0' ); + const minutesEnd = String( dateEnd.getMinutes() ).padStart( 2, '0' ); + const datetimeLocalEnd = `${ yearEnd }-${ monthEnd }-${ dayEnd }T${ hoursEnd }:${ minutesEnd }`; + + return ({ ...init, startDate: datetimeLocalStart, endDate: datetimeLocalEnd }) + })) + : []; + const pagination = response.pagination || {}; + + const renderPagination = () => { + const total = pagination.total_pages || 1; + const current = pagination.current_page || 1; + const pages = new Set( [ 1, total ] ); + + for ( let page = current - 2; page <= current + 2; page += 1 ) { + if ( page > 1 && page < total ) pages.add( page ); + } + + const sorted = Array.from( pages ).sort( ( a, b ) => a - b ); + const elements = []; + let last = 0; + + sorted.forEach( page => { + if ( last && page - last > 1 ) { + elements.push( +
  • + +
  • + ); + } + elements.push( +
  • + +
  • + ); + last = page; + }); + + return ( + + ) + }; + + return ( +
    +

    + Акции +

    +
    +
    + { + e.stopPropagation(); + navigate(`/promotions/create`); + }} + /> +
    +
    + + { + setSearchValue( e.target.value ); + setCurrentPage( 1 ); + }} + /> +
    +
    + + { isFetching + ? ( + + ) + : queryError + ? ( + + ) + : ( + <> +
    + + + + + + + + + + + + {stocks.map( stock => ( + <> + { + if ( expandedId === stock.id ) { + setExpandedId( null ) + return + } + setExpandedId( stock.id ) + }} + > + + + + + + + { expandedId === stock.id && + { + if ( expandedId === stock.id ) { + setExpandedId( null ) + return + } + setExpandedId( stock.id ) + }} + > + + + } + + + ))} + + +
    IDНазваниеНачало акцииОкончание акции
    { stock.id }{ stock.name } + + + +
    + { e.stopPropagation(); navigate(`/promotions/edit/${stock.id}`)}} + /> +
    +
    + + { renderPagination() } + + + ) + } +
    + ) +}; diff --git a/src/pages/UserPage.jsx b/src/pages/UserPage.jsx new file mode 100644 index 0000000..d459c43 --- /dev/null +++ b/src/pages/UserPage.jsx @@ -0,0 +1,21 @@ +import { useSelector } from 'react-redux'; + +export const UserPage = () => { + const userUID = localStorage.getItem('admSovamedUserUID'); + const userRegionId = localStorage.getItem('admSovamedUserRegionId'); + const regions = useSelector( ( state ) => state.region.regions ); + + return ( +
    +

    + Профиль пользователя +

    +

    + ID: {userUID} +

    +

    + Регион: {regions[userRegionId]} +

    +
    + ); +}; diff --git a/src/pages/__test__/LoginPage.test.jsx b/src/pages/__test__/LoginPage.test.jsx new file mode 100644 index 0000000..7578a89 --- /dev/null +++ b/src/pages/__test__/LoginPage.test.jsx @@ -0,0 +1,19 @@ +import { render, screen, fireEvent } from '@testing-library/react'; +import { Provider } from 'react-redux'; +import { BrowserRouter } from 'react-router-dom'; + +import { store } from '../../store/store'; +import { LoginPage } from '../LoginPage'; + +test('shows validation error on empty submit', () => { + render( + + + + + + ); + + fireEvent.click(screen.getByRole('button', { name: /войти/i })); + expect(screen.getByText(/пожалуйста, заполните оба поля/i)).toBeInTheDocument(); +}); diff --git a/src/pages/content/ContentEditPage.jsx b/src/pages/content/ContentEditPage.jsx new file mode 100644 index 0000000..76e3888 --- /dev/null +++ b/src/pages/content/ContentEditPage.jsx @@ -0,0 +1,370 @@ +import { useEffect, useRef, useState } from 'react' +import { useNavigate, useParams } from 'react-router-dom' +import { useSelector } from 'react-redux' + +import { selectRegions } from '../../store/slice/regionSlice' +import { TextEditor } from '../../components/Editors/TextEditor' +import { LoadingComponent } from '../../components/Placeholders/LoadingComponent' +import { ErrorComponent } from '../../components/Placeholders/ErrorComponent' +import { NotFindElement } from '../../components/Placeholders/NotFindElement' +import { EditElementForm } from '../../components/Forms/EditElementForm' +import Modal from '../../components/Modals/Modal' +import { parseSaveError } from '../../utils/parseSaveError' + +const SUCCESS_MODAL_MS = 2000 + +const emptyFormFromConfig = (fields) => { + const form = {} + fields.forEach((field) => { + if (field.type === 'checkbox') { + form[field.key] = false + } else if (field.type === 'number' || field.type === 'region') { + form[field.key] = '' + } else { + form[field.key] = '' + } + }) + return form +} + +const itemToForm = (item, fields) => { + const form = {} + fields.forEach((field) => { + const value = item[field.key] + if (field.type === 'json') { + form[field.key] = value == null ? '' : JSON.stringify(value, null, 2) + } else if (field.type === 'checkbox') { + form[field.key] = Boolean(value) + } else if (field.type === 'region' || field.type === 'number') { + form[field.key] = value ?? '' + } else { + form[field.key] = value ?? '' + } + }) + return form +} + +const formToPayload = (form, fields) => { + const data = {} + fields.forEach((field) => { + const raw = form[field.key] + if (field.type === 'json') { + if (!raw || !String(raw).trim()) { + data[field.key] = null + return + } + try { + data[field.key] = JSON.parse(raw) + } catch { + const error = new Error('Невалидный JSON — проверьте синтаксис') + error.fieldKey = field.key + throw error + } + return + } + if (field.type === 'checkbox') { + data[field.key] = Boolean(raw) + return + } + if (field.type === 'region' || field.type === 'number') { + data[field.key] = raw === '' ? null : Number(raw) + return + } + data[field.key] = raw === '' ? null : raw + }) + return data +} + +const FieldHint = ({ message }) => + message ? {message} : null + +const fieldWrapperClass = (hasError, extra = '') => + ['form-group', extra, hasError ? 'content-field--has-error' : ''].filter(Boolean).join(' ') + +const ContentField = ({ field, form, updateField, regions, fieldErrors }) => { + const value = form[field.key] + const errorMessage = fieldErrors[field.key] + const hasError = Boolean(errorMessage) + const labelClass = hasError ? 'content-field-error-label' : undefined + const controlClass = `form-control${hasError ? ' is-invalid' : ''}` + + if (field.type === 'checkbox') { + return ( +
    + updateField(field.key, e.target.checked)} + /> + + +
    + ) + } + + if (field.type === 'region') { + const selectValue = value === '' || value == null ? '' : String(value) + return ( +
    + + + +
    + ) + } + + if (field.type === 'html') { + return ( +
    + + updateField(field.key, html)} /> + +
    + ) + } + + if (field.type === 'json') { + return ( +
    + +